1// Copyright 2023 Google LLC 2// 3// Use of this source code is governed by a BSD-style license that can be 4// found in the LICENSE file. 5 6package main 7 8import ( 9 "context" 10 "os" 11 "path/filepath" 12 "strings" 13 "testing" 14 "time" 15 16 "github.com/stretchr/testify/assert" 17 "github.com/stretchr/testify/require" 18 "go.skia.org/infra/go/exec" 19 exec_testutils "go.skia.org/infra/go/exec/testutils" 20 "go.skia.org/infra/go/gcs" 21 "go.skia.org/infra/go/gcs/mocks" 22 "go.skia.org/infra/go/now" 23 infra_testutils "go.skia.org/infra/go/testutils" 24 "go.skia.org/infra/task_driver/go/lib/os_steps" 25 "go.skia.org/infra/task_driver/go/td" 26 "go.skia.org/skia/infra/bots/task_drivers/common" 27 "go.skia.org/skia/infra/bots/task_drivers/testutils" 28) 29 30func TestRun_Success(t *testing.T) { 31 // Given that we have tests for common.UploadToPerf(), it suffices to test a couple of 32 // "happy" cases here. 33 34 test := func(name string, tdArgs taskDriverArgs, bazelInvocation []string) { 35 t.Run(name, func(t *testing.T) { 36 // Create fake archive with undeclared test outputs. 37 outputsZIP := filepath.Join(tdArgs.checkoutDir, "bazel-testlogs", "some", "test", "target", "test.outputs", "outputs.zip") 38 require.NoError(t, os.MkdirAll(filepath.Dir(outputsZIP), 0700)) 39 resultsJSONFileContents := `{"foo": "this test requires that this file exists; its contents do not matter"}` 40 testutils.MakeZIP(t, outputsZIP, map[string]string{ 41 "results.json": resultsJSONFileContents, 42 "some-image.png": "fake PNG", 43 "some-plaintext.txt": "fake TXT", 44 }) 45 46 // Will be returned by the mocked os_steps.TempDir() when the task driver tries to create a 47 // directory in which to extract the undeclared outputs ZIP archive. 48 outputsZIPExtractionDir := t.TempDir() 49 50 commandCollector := exec.CommandCollector{} 51 52 gcsClient := mocks.NewGCSClient(t) 53 gcsClient.On("Bucket").Return("skia-perf") 54 gcsClient.On( 55 "SetFileContents", 56 infra_testutils.AnyContext, 57 "nano-json-v1/2022/01/31/01/ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99/BazelTest-Foo-Bar/results_1234567890.json", 58 gcs.FILE_WRITE_OPTS_TEXT, 59 []byte(resultsJSONFileContents)). 60 Return(nil).Once() 61 62 res := td.RunTestSteps(t, false, func(ctx context.Context) error { 63 // Make sure we use UTC instead of the system timezone. The GCS path reflects the fact that 64 // we convert from UTC+1 to UTC. 65 fakeNow := time.Date(2022, time.January, 31, 2, 2, 3, 0, time.FixedZone("UTC+1", 60*60)) 66 ctx = now.TimeTravelingContext(fakeNow).WithContext(ctx) 67 ctx = td.WithExecRunFn(ctx, commandCollector.Run) 68 var bazelCacheDirPath string 69 ctx, bazelCacheDirPath = common.WithEnoughSpaceOnBazelCachePartitionTestOnlyContext(ctx) 70 71 // We don't need to assert the exact number of times that os_steps.TempDir() is called 72 // because said function produces a "Creating TempDir" task driver step, and we check the 73 // exact set of steps produced. 74 ctx = context.WithValue(ctx, os_steps.TempDirContextKey, testutils.MakeTempDirMockFn(t, outputsZIPExtractionDir)) 75 76 err := run(ctx, bazelCacheDirPath, tdArgs, gcsClient) 77 78 assert.NoError(t, err) 79 return err 80 }) 81 82 require.Empty(t, res.Errors) 83 require.Empty(t, res.Exceptions) 84 85 testutils.AssertStepNames(t, res, 86 "Test //some/test:target with config linux_rbe", 87 strings.Join(bazelInvocation, " "), 88 "Creating TempDir", 89 "Extract undeclared outputs archive "+outputsZIP+" into "+outputsZIPExtractionDir, 90 "Extracting file: results.json", 91 "Extracting file: some-image.png", 92 "Not extracting non-PNG / non-JSON file: some-plaintext.txt", 93 "Stat "+outputsZIPExtractionDir+"/results.json", 94 "Read "+outputsZIPExtractionDir+"/results.json", 95 "Upload gs://skia-perf/nano-json-v1/2022/01/31/01/ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99/BazelTest-Foo-Bar/results_1234567890.json", 96 "Clean Bazel cache if disk space is too low", 97 "No need to clear the Bazel cache: free space on partition /mnt/pd0 is 20000000000 bytes, which is above the threshold of 15000000000 bytes", 98 ) 99 100 // Command "bazelisk test ..." should be called from the checkout directory. 101 assert.Equal(t, tdArgs.checkoutDir, commandCollector.Commands()[0].Dir) 102 exec_testutils.AssertCommandsMatch(t, [][]string{bazelInvocation}, commandCollector.Commands()) 103 104 gcsClient.AssertExpectations(t) 105 }) 106 } 107 108 checkoutDir := t.TempDir() 109 110 test( 111 "post-submit task", 112 taskDriverArgs{ 113 BenchmarkInfo: common.BenchmarkInfo{ 114 GitCommit: "ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99", 115 TaskName: "BazelTest-Foo-Bar", 116 TaskID: "1234567890", 117 }, 118 checkoutDir: checkoutDir, 119 bazelLabel: "//some/test:target", 120 bazelConfig: "linux_rbe", 121 deviceSpecificBazelConfig: "GCE_Debian10_AVX512", 122 }, 123 []string{ 124 "bazelisk", 125 "test", 126 "//some/test:target", 127 "--config=linux_rbe", 128 "--config=GCE_Debian10_AVX512", 129 "--test_output=errors", 130 "--jobs=100", 131 "--test_arg=--gitHash", 132 "--test_arg=ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99", 133 "--test_arg=--links", 134 "--test_arg=task", 135 "--test_arg=https://task-scheduler.skia.org/task/1234567890", 136 }) 137 138 test( 139 "CL task", 140 taskDriverArgs{ 141 BenchmarkInfo: common.BenchmarkInfo{ 142 GitCommit: "ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99", 143 TaskName: "BazelTest-Foo-Bar", 144 TaskID: "1234567890", 145 ChangelistID: "12345", 146 PatchsetOrder: "3", 147 }, 148 checkoutDir: checkoutDir, 149 bazelLabel: "//some/test:target", 150 bazelConfig: "linux_rbe", 151 deviceSpecificBazelConfig: "GCE_Debian10_AVX512", 152 }, 153 []string{ 154 "bazelisk", 155 "test", 156 "//some/test:target", 157 "--config=linux_rbe", 158 "--config=GCE_Debian10_AVX512", 159 "--test_output=errors", 160 "--jobs=100", 161 "--test_arg=--gitHash", 162 "--test_arg=ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99", 163 "--test_arg=--issue", 164 "--test_arg=12345", 165 "--test_arg=--patchset", 166 "--test_arg=3", 167 "--test_arg=--links", 168 "--test_arg=task", 169 "--test_arg=https://task-scheduler.skia.org/task/1234567890", 170 "--test_arg=changelist", 171 "--test_arg=https://skia-review.googlesource.com/c/skia/+/12345/3", 172 }) 173} 174