xref: /aosp_15_r20/external/skia/infra/bots/task_drivers/cpu_tests/cpu_tests.go (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1// Copyright 2022 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//
6// This executable runs a Bazel(isk) test command for //tests/... using the provided
7// config (which is assumed to be in //bazel/buildrc) and any provided Bazel args.
8// This handles any setup needed to run Bazel on our CI machines before running the task, like
9// setting up logs and the Bazel cache.
10package main
11
12import (
13	"context"
14	"flag"
15	"fmt"
16	"path/filepath"
17
18	sk_exec "go.skia.org/infra/go/exec"
19	"go.skia.org/infra/task_driver/go/lib/bazel"
20	"go.skia.org/infra/task_driver/go/lib/os_steps"
21	"go.skia.org/infra/task_driver/go/td"
22	"go.skia.org/skia/infra/bots/task_drivers/common"
23)
24
25var (
26	// Required properties for this task.
27	// We want the cache to be on a bigger disk than default. The root disk, where the home
28	// directory (and default Bazel cache) lives, is only 15 GB on our GCE VMs.
29	projectId = flag.String("project_id", "", "ID of the Google Cloud project.")
30	taskId    = flag.String("task_id", "", "ID of this task.")
31	taskName  = flag.String("task_name", "", "Name of the task.")
32	workdir   = flag.String("workdir", ".", "Working directory, the root directory of a full Skia checkout")
33	// Optional flags.
34	local  = flag.Bool("local", false, "True if running locally (as opposed to on the CI/CQ)")
35	output = flag.String("o", "", "If provided, dump a JSON blob of step data to the given file. Prints to stdout if '-' is given.")
36)
37
38func main() {
39	bazelFlags := common.MakeBazelFlags(common.MakeBazelFlagsOpts{
40		Label:  true,
41		Config: true,
42	})
43
44	// StartRun calls flag.Parse()
45	ctx := td.StartRun(projectId, taskId, taskName, output, local)
46	defer td.EndRun(ctx)
47
48	bazelFlags.Validate(ctx)
49
50	wd, err := os_steps.Abs(ctx, *workdir)
51	if err != nil {
52		td.Fatal(ctx, err)
53	}
54	skiaDir := filepath.Join(wd, "skia")
55
56	opts := bazel.BazelOptions{
57		CachePath: *bazelFlags.CacheDir,
58	}
59	if err := bazel.EnsureBazelRCFile(ctx, opts); err != nil {
60		td.Fatal(ctx, err)
61	}
62
63	if err := bazelTest(ctx, skiaDir, *bazelFlags.Label, *bazelFlags.Config, "--test_output=errors"); err != nil {
64		td.Fatal(ctx, err)
65	}
66
67	if !*local {
68		if err := common.BazelCleanIfLowDiskSpace(ctx, *bazelFlags.CacheDir, skiaDir, "bazelisk"); err != nil {
69			td.Fatal(ctx, err)
70		}
71	}
72}
73
74// bazelBuild builds the target referenced by the given absolute label passing the provided
75// config and any additional args to the build command. Instead of calling Bazel directly, we use
76// Bazelisk to make sure we use the right version of Bazel, as defined in the .bazelversion file
77// at the Skia root.
78func bazelTest(ctx context.Context, checkoutDir, label, config string, extraArgs ...string) error {
79	step := fmt.Sprintf("Test %s with config %s and %d extra flags", label, config, len(extraArgs))
80	return td.Do(ctx, td.Props(step), func(ctx context.Context) error {
81		runCmd := &sk_exec.Command{
82			Name: "bazelisk",
83			Args: append([]string{
84				"test",
85				label,
86				"--config=" + config, // Should be defined in //bazel/buildrc
87			}, extraArgs...),
88			InheritEnv: true, // Makes sure bazelisk is on PATH
89			Dir:        checkoutDir,
90			LogStdout:  true,
91			LogStderr:  true,
92		}
93		_, err := sk_exec.RunCommand(ctx, runCmd)
94		if err != nil {
95			return err
96		}
97		return nil
98	})
99}
100