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