blob: d81f7f7410d6e0bb9c959cae8eecc339380c50d0 [file] [log] [blame]
package backends
import (
"bytes"
"context"
"fmt"
"strings"
"go.skia.org/infra/go/skerr"
"go.skia.org/infra/go/sklog"
"go.skia.org/infra/perf/go/perfresults"
rbeclient "github.com/bazelbuild/remote-apis-sdks/go/pkg/client"
"github.com/bazelbuild/remote-apis-sdks/go/pkg/digest"
repb "github.com/bazelbuild/remote-apis/build/bazel/remote/execution/v2"
)
const (
resultsFilename = "perf_results.json"
)
// FetchBenchmarkJSON fetches the benchmark results json files from the CAS root at rootDigest.
// It returns a map of benchmark name to perfresults.PerfResults parsed from the json bytes.
func FetchBenchmarkJSON(ctx context.Context, c *rbeclient.Client, rootDigest string) (map[string]perfresults.PerfResults, error) {
raw, err := FetchBenchmarkJSONRaw(ctx, c, rootDigest)
if err != nil {
return nil, err
}
ret := make(map[string]perfresults.PerfResults)
for benchmark, blob := range raw {
res, err := perfresults.NewResults(bytes.NewReader(blob))
if err != nil {
return nil, skerr.Wrapf(err, "unmarshaling benchmark json")
}
ret[benchmark] = *res
}
return ret, nil
}
// FetchBenchmarkJSONRaw fetches the benchmark results json files from the CAS root at rootDigest.
// It returns a map of benchmark name to raw json bytes.
func FetchBenchmarkJSONRaw(ctx context.Context, c *rbeclient.Client, rootDigest string) (map[string][]byte, error) {
d, err := digest.NewFromString(rootDigest)
if err != nil {
return nil, fmt.Errorf("failed to parse digest %q: %v", rootDigest, err)
}
rootDir := &repb.Directory{}
if _, err := c.ReadProto(ctx, d, rootDir); err != nil {
return nil, fmt.Errorf("failed to read root directory proto: %v", err)
}
dirs, err := c.GetDirectoryTree(ctx, d.ToProto())
if err != nil {
return nil, fmt.Errorf("failed to call GetDirectoryTree: %v", err)
}
t := &repb.Tree{
Root: rootDir,
Children: dirs,
}
outputs, err := c.FlattenTree(t, "")
if err != nil {
return nil, fmt.Errorf("failed to call FlattenTree: %v", err)
}
ret := make(map[string][]byte)
for path, output := range outputs {
if strings.HasSuffix(path, resultsFilename) {
parts := strings.Split(path, "/")
if len(parts) != 2 {
sklog.Errorf("unexpected output path format: %q", path)
}
benchmark := parts[0]
d, err := digest.New(output.Digest.Hash, output.Digest.Size)
if err != nil {
return nil, err
}
blob, _, err := c.ReadBlob(ctx, d)
if err != nil {
return nil, err
}
ret[benchmark] = blob
}
}
return ret, nil
}