From b727b13b371c02598242821ea230ed2e9f53e305 Mon Sep 17 00:00:00 2001 From: Taras Madan Date: Wed, 6 Nov 2024 17:18:44 +0100 Subject: dashboard/app: read lines coverage from spanner We currently merge bigquery data for every line coverage request. Let's read cached lines coverage data from spanner instead. It allows to get only 1 file version from git and skip the data merge step. --- pkg/coveragedb/spanner.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'pkg/coveragedb') diff --git a/pkg/coveragedb/spanner.go b/pkg/coveragedb/spanner.go index 0ff3a3197..54fa2e192 100644 --- a/pkg/coveragedb/spanner.go +++ b/pkg/coveragedb/spanner.go @@ -6,6 +6,7 @@ package coveragedb import ( "context" "fmt" + "os" "time" "cloud.google.com/go/civil" @@ -89,6 +90,64 @@ func SaveMergeResult(ctx context.Context, projectID string, covMap map[string]*C return nil } +type linesCoverage struct { + LinesInstrumented []int64 + HitCounts []int64 +} + +func linesCoverageStmt(ns, filepath, commit string, timePeriod TimePeriod) spanner.Statement { + return spanner.Statement{ + SQL: ` +select + linesinstrumented, + hitcounts +from merge_history + join files + on merge_history.session = files.session +where + namespace=$1 and dateto=$2 and duration=$3 and filepath=$4 and commit=$5`, + Params: map[string]interface{}{ + "p1": ns, + "p2": timePeriod.DateTo, + "p3": timePeriod.Days, + "p4": filepath, + "p5": commit, + }, + } +} + +func ReadLinesHitCount(ctx context.Context, ns, commit, file string, tp TimePeriod, +) (map[int]int, error) { + projectID := os.Getenv("GOOGLE_CLOUD_PROJECT") + client, err := NewClient(ctx, projectID) + if err != nil { + return nil, fmt.Errorf("spanner.NewClient: %w", err) + } + defer client.Close() + + stmt := linesCoverageStmt(ns, file, commit, tp) + iter := client.Single().Query(ctx, stmt) + defer iter.Stop() + + row, err := iter.Next() + if err == iterator.Done { + return nil, nil + } + if err != nil { + return nil, fmt.Errorf("iter.Next: %w", err) + } + var r linesCoverage + if err = row.ToStruct(&r); err != nil { + return nil, fmt.Errorf("failed to row.ToStruct() spanner DB: %w", err) + } + + res := map[int]int{} + for i, instrLine := range r.LinesInstrumented { + res[int(instrLine)] = int(r.HitCounts[i]) + } + return res, nil +} + func historyMutation(session string, template *HistoryRecord, totalRows int64) *spanner.Mutation { historyInsert, err := spanner.InsertOrUpdateStruct("merge_history", &HistoryRecord{ Session: session, -- cgit mrf-deployment