• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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