// Copyright 2023 Google LLC // // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package main import ( "context" "os" "path/filepath" "strings" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.skia.org/infra/go/exec" exec_testutils "go.skia.org/infra/go/exec/testutils" "go.skia.org/infra/go/gcs" "go.skia.org/infra/go/gcs/mocks" "go.skia.org/infra/go/now" infra_testutils "go.skia.org/infra/go/testutils" "go.skia.org/infra/task_driver/go/lib/os_steps" "go.skia.org/infra/task_driver/go/td" "go.skia.org/skia/infra/bots/task_drivers/common" "go.skia.org/skia/infra/bots/task_drivers/testutils" ) func TestRun_Success(t *testing.T) { // Given that we have tests for common.UploadToPerf(), it suffices to test a couple of // "happy" cases here. test := func(name string, tdArgs taskDriverArgs, bazelInvocation []string) { t.Run(name, func(t *testing.T) { // Create fake archive with undeclared test outputs. outputsZIP := filepath.Join(tdArgs.checkoutDir, "bazel-testlogs", "some", "test", "target", "test.outputs", "outputs.zip") require.NoError(t, os.MkdirAll(filepath.Dir(outputsZIP), 0700)) resultsJSONFileContents := `{"foo": "this test requires that this file exists; its contents do not matter"}` testutils.MakeZIP(t, outputsZIP, map[string]string{ "results.json": resultsJSONFileContents, "some-image.png": "fake PNG", "some-plaintext.txt": "fake TXT", }) // Will be returned by the mocked os_steps.TempDir() when the task driver tries to create a // directory in which to extract the undeclared outputs ZIP archive. outputsZIPExtractionDir := t.TempDir() commandCollector := exec.CommandCollector{} gcsClient := mocks.NewGCSClient(t) gcsClient.On("Bucket").Return("skia-perf") gcsClient.On( "SetFileContents", infra_testutils.AnyContext, "nano-json-v1/2022/01/31/01/ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99/BazelTest-Foo-Bar/results_1234567890.json", gcs.FILE_WRITE_OPTS_TEXT, []byte(resultsJSONFileContents)). Return(nil).Once() res := td.RunTestSteps(t, false, func(ctx context.Context) error { // Make sure we use UTC instead of the system timezone. The GCS path reflects the fact that // we convert from UTC+1 to UTC. fakeNow := time.Date(2022, time.January, 31, 2, 2, 3, 0, time.FixedZone("UTC+1", 60*60)) ctx = now.TimeTravelingContext(fakeNow).WithContext(ctx) ctx = td.WithExecRunFn(ctx, commandCollector.Run) var bazelCacheDirPath string ctx, bazelCacheDirPath = common.WithEnoughSpaceOnBazelCachePartitionTestOnlyContext(ctx) // We don't need to assert the exact number of times that os_steps.TempDir() is called // because said function produces a "Creating TempDir" task driver step, and we check the // exact set of steps produced. ctx = context.WithValue(ctx, os_steps.TempDirContextKey, testutils.MakeTempDirMockFn(t, outputsZIPExtractionDir)) err := run(ctx, bazelCacheDirPath, tdArgs, gcsClient) assert.NoError(t, err) return err }) require.Empty(t, res.Errors) require.Empty(t, res.Exceptions) testutils.AssertStepNames(t, res, "Test //some/test:target with config linux_rbe", strings.Join(bazelInvocation, " "), "Creating TempDir", "Extract undeclared outputs archive "+outputsZIP+" into "+outputsZIPExtractionDir, "Extracting file: results.json", "Extracting file: some-image.png", "Not extracting non-PNG / non-JSON file: some-plaintext.txt", "Stat "+outputsZIPExtractionDir+"/results.json", "Read "+outputsZIPExtractionDir+"/results.json", "Upload gs://skia-perf/nano-json-v1/2022/01/31/01/ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99/BazelTest-Foo-Bar/results_1234567890.json", "Clean Bazel cache if disk space is too low", "No need to clear the Bazel cache: free space on partition /mnt/pd0 is 20000000000 bytes, which is above the threshold of 15000000000 bytes", ) // Command "bazelisk test ..." should be called from the checkout directory. assert.Equal(t, tdArgs.checkoutDir, commandCollector.Commands()[0].Dir) exec_testutils.AssertCommandsMatch(t, [][]string{bazelInvocation}, commandCollector.Commands()) gcsClient.AssertExpectations(t) }) } checkoutDir := t.TempDir() test( "post-submit task", taskDriverArgs{ BenchmarkInfo: common.BenchmarkInfo{ GitCommit: "ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99", TaskName: "BazelTest-Foo-Bar", TaskID: "1234567890", }, checkoutDir: checkoutDir, bazelLabel: "//some/test:target", bazelConfig: "linux_rbe", deviceSpecificBazelConfig: "GCE_Debian10_AVX512", }, []string{ "bazelisk", "test", "//some/test:target", "--config=linux_rbe", "--config=GCE_Debian10_AVX512", "--test_output=errors", "--jobs=100", "--test_arg=--gitHash", "--test_arg=ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99", "--test_arg=--links", "--test_arg=task", "--test_arg=https://task-scheduler.skia.org/task/1234567890", }) test( "CL task", taskDriverArgs{ BenchmarkInfo: common.BenchmarkInfo{ GitCommit: "ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99", TaskName: "BazelTest-Foo-Bar", TaskID: "1234567890", ChangelistID: "12345", PatchsetOrder: "3", }, checkoutDir: checkoutDir, bazelLabel: "//some/test:target", bazelConfig: "linux_rbe", deviceSpecificBazelConfig: "GCE_Debian10_AVX512", }, []string{ "bazelisk", "test", "//some/test:target", "--config=linux_rbe", "--config=GCE_Debian10_AVX512", "--test_output=errors", "--jobs=100", "--test_arg=--gitHash", "--test_arg=ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99", "--test_arg=--issue", "--test_arg=12345", "--test_arg=--patchset", "--test_arg=3", "--test_arg=--links", "--test_arg=task", "--test_arg=https://task-scheduler.skia.org/task/1234567890", "--test_arg=changelist", "--test_arg=https://skia-review.googlesource.com/c/skia/+/12345/3", }) }