• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
23
24var (
25	// Required properties for this task.
26	// We want the cache to be on a bigger disk than default. The root disk, where the home
27	// directory (and default Bazel cache) lives, is only 15 GB on our GCE VMs.
28	cachePath = flag.String("cache_path", "/mnt/pd0/bazel_cache", "The path where the Bazel cache should live. This should be able to hold tens of GB at least.")
29	cross     = flag.String("cross", "", "An identifier specifying the target platform that Bazel should build for. If empty, Bazel builds for the host platform (the machine on which this executable is run).")
30	config    = flag.String("test_config", "", "A custom configuration specified in //bazel/buildrc. This configuration potentially encapsulates many features and options.")
31	projectId = flag.String("project_id", "", "ID of the Google Cloud project.")
32	taskId    = flag.String("task_id", "", "ID of this task.")
33	taskName  = flag.String("task_name", "", "Name of the task.")
34	workdir   = flag.String("workdir", ".", "Working directory, the root directory of a full Skia checkout")
35	// Optional flags.
36	local  = flag.Bool("local", false, "True if running locally (as opposed to on the CI/CQ)")
37	output = flag.String("o", "", "If provided, dump a JSON blob of step data to the given file. Prints to stdout if '-' is given.")
38)
39
40func main() {
41	// StartRun calls flag.Parse()
42	ctx := td.StartRun(projectId, taskId, taskName, output, local)
43	defer td.EndRun(ctx)
44
45	if *config == "" {
46		td.Fatal(ctx, fmt.Errorf("--test_config is required"))
47	}
48
49	wd, err := os_steps.Abs(ctx, *workdir)
50	if err != nil {
51		td.Fatal(ctx, err)
52	}
53	skiaDir := filepath.Join(wd, "skia")
54
55	opts := bazel.BazelOptions{
56		CachePath: *cachePath,
57	}
58	if err := bazel.EnsureBazelRCFile(ctx, opts); err != nil {
59		td.Fatal(ctx, err)
60	}
61
62	if *cross != "" {
63		// See https://bazel.build/concepts/platforms-intro and https://bazel.build/docs/platforms
64		// when ready to support this.
65		td.Fatal(ctx, fmt.Errorf("cross compilation not yet supported"))
66	}
67
68	if err := bazelTest(ctx, skiaDir, "//tests/...", *config, "--test_output=errors"); err != nil {
69		td.Fatal(ctx, err)
70	}
71}
72
73// bazelBuild builds the target referenced by the given absolute label passing the provided
74// config and any additional args to the build command. Instead of calling Bazel directly, we use
75// Bazelisk to make sure we use the right version of Bazel, as defined in the .bazelversion file
76// at the Skia root.
77func bazelTest(ctx context.Context, checkoutDir, label, config string, args ...string) error {
78	step := fmt.Sprintf("Test %s with config %s and %d extra flags", label, config, len(args))
79	return td.Do(ctx, td.Props(step), func(ctx context.Context) error {
80		runCmd := &sk_exec.Command{
81			Name: "bazelisk",
82			Args: append([]string{"test",
83				label,
84				"--config=" + config, // Should be defined in //bazel/buildrc
85			}, args...),
86			InheritEnv: true, // Makes sure bazelisk is on PATH
87			Dir:        checkoutDir,
88			LogStdout:  true,
89			LogStderr:  true,
90		}
91		_, err := sk_exec.RunCommand(ctx, runCmd)
92		if err != nil {
93			return err
94		}
95		return nil
96	})
97}
98