blob: ba272d914cf6647d2a6d344ac7f86c2263bd6a45 [file] [log] [blame]
package analysisserver
import (
"context"
"net"
"path/filepath"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"google.golang.org/grpc"
"google.golang.org/protobuf/testing/protocmp"
"go.skia.org/infra/cabe/go/backends"
cpb "go.skia.org/infra/cabe/go/proto"
"go.skia.org/infra/cabe/go/replaybackends"
"go.skia.org/infra/bazel/go/bazel"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const (
fakeBenchmarkName = "fake benchmark name"
)
func startTestServer(t *testing.T, casResultReader backends.CASResultReader, swarmingTaskReader backends.SwarmingTaskReader) (cpb.AnalysisClient, func()) {
serverListener, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
server := grpc.NewServer()
cpb.RegisterAnalysisServer(server, New(casResultReader, swarmingTaskReader))
go func() {
require.NoError(t, server.Serve(serverListener))
}()
clientConn, err := grpc.Dial(
serverListener.Addr().String(),
grpc.WithInsecure(),
grpc.WithBlock(),
grpc.WithTimeout(2*time.Second))
require.NoError(t, err)
closer := func() {
// server.Stop will close the listener for us:
// https://pkg.go.dev/google.golang.org/grpc#Server.Stop
// Explicitly closing the listener causes the server.Serve
// call to return an error, which causes this test to fail
// even when the code under test behaves as expected.
server.Stop()
}
client := cpb.NewAnalysisClient(clientConn)
return client, closer
}
func TestAnalysisServiceServer_GetAnalysis(t *testing.T) {
test := func(name string, request *cpb.GetAnalysisRequest, wantFirstResult *cpb.AnalysisResult, wantError bool) {
t.Run(name, func(t *testing.T) {
ctx := context.Background()
path := filepath.Join(
bazel.RunfilesDir(),
"external/cabe_replay_data",
// https://pinpoint-dot-chromeperf.appspot.com/job/16f46f1c260000
"pinpoint_16f46f1c260000.zip")
benchmarkName := "fake benchmark name"
replayer := replaybackends.FromZipFile(
path,
benchmarkName,
)
client, closer := startTestServer(t, replayer.CASResultReader, replayer.SwarmingTaskReader)
defer closer()
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := client.GetAnalysis(ctx, request)
if wantError {
require.Error(t, err)
} else {
require.NoError(t, err)
}
if request.ExperimentSpec == nil {
assert.NotNil(t, r.InferredExperimentSpec)
} else {
assert.Nil(t, r.InferredExperimentSpec)
}
diff := cmp.Diff(wantFirstResult, r.Results[0], cmpopts.EquateEmpty(), cmpopts.EquateApprox(0, 0.03), protocmp.Transform())
assert.Equal(t, diff, "", "diff should be empty")
})
}
cabeSpec := &cpb.ExperimentSpec{
Analysis: &cpb.AnalysisSpec{
Benchmark: []*cpb.Benchmark{{
Name: fakeBenchmarkName,
Workload: []string{
"Compositing.Display.DrawToSwapUs",
"Graphics.Smoothness.Jank.AllAnimations",
"Graphics.Smoothness.Jank.AllSequences",
"Graphics.Smoothness.PercentDroppedFrames3.AllAnimations",
"Graphics.Smoothness.PercentDroppedFrames3.AllSequences",
"Memory.GPU.PeakMemoryUsage2.PageLoad",
"metrics_duration",
"motionmark",
"motionmarkLower",
"motionmarkUpper",
"renderingMetric_duration",
"trace_import_duration",
"umaMetric_duration",
},
}},
},
Common: &cpb.ArmSpec{
BuildSpec: []*cpb.BuildSpec{{
GitilesCommit: &cpb.GitilesCommit{
Project: "chromium",
Id: "b692c01",
},
}},
RunSpec: []*cpb.RunSpec{{
Os: "Mac",
SyntheticProductName: "Macmini9,1_arm64-64-Apple_M1_apple m1_16384_1_5693005.2",
}},
},
Control: &cpb.ArmSpec{},
Treatment: &cpb.ArmSpec{
BuildSpec: []*cpb.BuildSpec{{
GerritChanges: []*cpb.GerritChange{{
PatchsetHash: "d4565f9",
}},
}},
},
}
analysisResults := []*cpb.AnalysisResult{
{
ExperimentSpec: &cpb.ExperimentSpec{
Common: cabeSpec.Common,
Control: cabeSpec.Control,
Treatment: cabeSpec.Treatment,
Analysis: &cpb.AnalysisSpec{
Benchmark: []*cpb.Benchmark{
{
Name: fakeBenchmarkName,
Workload: []string{"Compositing.Display.DrawToSwapUs"},
},
},
},
},
Statistic: &cpb.Statistic{
Upper: -64.67566905094428,
Lower: -67.77167618955136,
PValue: 3.610001186871159e-12,
ControlMedian: 12861.869927307689,
TreatmentMedian: 4220.841672500003,
},
},
}
test("basic request, no experiment spec", &cpb.GetAnalysisRequest{PinpointJobId: "123"}, analysisResults[0], false)
test("basic request, including experiment spec", &cpb.GetAnalysisRequest{
PinpointJobId: "123",
ExperimentSpec: &cpb.ExperimentSpec{
Common: cabeSpec.Common,
Control: cabeSpec.Control,
Treatment: cabeSpec.Treatment,
Analysis: &cpb.AnalysisSpec{
Benchmark: []*cpb.Benchmark{
{
Name: fakeBenchmarkName,
Workload: []string{"Compositing.Display.DrawToSwapUs"},
},
},
},
},
}, analysisResults[0], false)
}