blob: a9c8dfaf871f92b0574c41c68817d226f0d44afb [file] [log] [blame]
borenetdb182c72016-09-30 12:53:12 -07001// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package main
6
7/*
8 Generate the tasks.json file.
9*/
10
11import (
borenetdb182c72016-09-30 12:53:12 -070012 "encoding/json"
Eric Boren27225492017-02-01 15:56:55 -050013 "flag"
borenetdb182c72016-09-30 12:53:12 -070014 "fmt"
Eric Boren27225492017-02-01 15:56:55 -050015 "io/ioutil"
borenetdb182c72016-09-30 12:53:12 -070016 "os"
17 "path"
Eric Boren7e3a3642017-06-14 15:25:31 -040018 "path/filepath"
Eric Boren27225492017-02-01 15:56:55 -050019 "regexp"
Eric Boren7e3a3642017-06-14 15:25:31 -040020 "runtime"
borenetdb182c72016-09-30 12:53:12 -070021 "sort"
Kevin Lubick32f318b2017-10-17 13:40:52 -040022 "strconv"
borenetdb182c72016-09-30 12:53:12 -070023 "strings"
Eric Boren4b254b92016-11-08 12:55:32 -050024 "time"
borenetdb182c72016-09-30 12:53:12 -070025
26 "github.com/skia-dev/glog"
Eric Boren7e3a3642017-06-14 15:25:31 -040027 "go.skia.org/infra/go/sklog"
borenetdb182c72016-09-30 12:53:12 -070028 "go.skia.org/infra/go/util"
29 "go.skia.org/infra/task_scheduler/go/specs"
30)
31
32const (
Kevin Lubick814b1492017-11-29 14:45:14 -050033 BUNDLE_RECIPES_NAME = "Housekeeper-PerCommit-BundleRecipes"
34 ISOLATE_SKIMAGE_NAME = "Housekeeper-PerCommit-IsolateSkImage"
35 ISOLATE_SKP_NAME = "Housekeeper-PerCommit-IsolateSKP"
36 ISOLATE_SVG_NAME = "Housekeeper-PerCommit-IsolateSVG"
37 ISOLATE_NDK_LINUX_NAME = "Housekeeper-PerCommit-IsolateAndroidNDKLinux"
Stephan Altmueller2a552172018-02-20 11:40:25 -050038 ISOLATE_SDK_LINUX_NAME = "Housekeeper-PerCommit-IsolateAndroidSDKLinux"
Kevin Lubick814b1492017-11-29 14:45:14 -050039 ISOLATE_WIN_TOOLCHAIN_NAME = "Housekeeper-PerCommit-IsolateWinToolchain"
40 ISOLATE_WIN_VULKAN_SDK_NAME = "Housekeeper-PerCommit-IsolateWinVulkanSDK"
Eric Boren8b3f9e62017-04-04 09:06:16 -040041
Eric Boren170c39c2017-11-15 11:22:57 -050042 DEFAULT_OS_DEBIAN = "Debian-9.1"
43 DEFAULT_OS_LINUX_GCE = "Debian-9.2"
Ben Wagner5a9df182018-02-09 11:21:15 -050044 DEFAULT_OS_MAC = "Mac-10.13.3"
Eric Boren170c39c2017-11-15 11:22:57 -050045 DEFAULT_OS_UBUNTU = "Ubuntu-14.04"
46 DEFAULT_OS_WIN = "Windows-2016Server-14393"
borenetdb182c72016-09-30 12:53:12 -070047
borenetdb182c72016-09-30 12:53:12 -070048 // Name prefix for upload jobs.
49 PREFIX_UPLOAD = "Upload"
50)
51
52var (
53 // "Constants"
54
Eric Boren27225492017-02-01 15:56:55 -050055 // Top-level list of all jobs to run at each commit; loaded from
56 // jobs.json.
57 JOBS []string
58
Eric Boren27225492017-02-01 15:56:55 -050059 // General configuration information.
60 CONFIG struct {
Kevin Lubickc795a4c2017-10-09 15:26:19 -040061 GsBucketCoverage string `json:"gs_bucket_coverage"`
62 GsBucketGm string `json:"gs_bucket_gm"`
63 GsBucketNano string `json:"gs_bucket_nano"`
Yuqian Li2ebf3d12017-10-24 09:43:21 -040064 GsBucketCalm string `json:"gs_bucket_calm"`
Kevin Lubickc795a4c2017-10-09 15:26:19 -040065 NoUpload []string `json:"no_upload"`
66 Pool string `json:"pool"`
borenetdb182c72016-09-30 12:53:12 -070067 }
68
Ben Wagner3d2a2f72017-06-13 17:01:16 -040069 // alternateSwarmDimensions can be set in an init function to override the default swarming bot
70 // dimensions for the given task.
71 alternateSwarmDimensions func(parts map[string]string) []string
72
Eric Borenfd4d60e2017-09-15 10:35:44 -040073 // internalHardwareLabelFn can be set in an init function to provide an
74 // internal_hardware_label variable to the recipe.
Eric Boren4dc4aaf2017-09-15 14:09:07 -040075 internalHardwareLabelFn func(parts map[string]string) *int
Eric Boren053d7a42017-09-15 08:35:31 -040076
borenetdb182c72016-09-30 12:53:12 -070077 // Defines the structure of job names.
78 jobNameSchema *JobNameSchema
Eric Boren27225492017-02-01 15:56:55 -050079
Eric Borenf4a5fc72017-06-06 08:27:09 -040080 // Git 2.13.
Eric Boren9d78afd2017-12-07 14:54:05 +000081 cipdGit1 = &specs.CipdPackage{
82 Name: fmt.Sprintf("infra/git/${platform}"),
83 Path: "git",
84 Version: fmt.Sprintf("version:2.13.0.chromium9"),
Eric Borenf4a5fc72017-06-06 08:27:09 -040085 }
Eric Boren9d78afd2017-12-07 14:54:05 +000086 cipdGit2 = &specs.CipdPackage{
87 Name: fmt.Sprintf("infra/tools/git/${platform}"),
88 Path: "git",
89 Version: fmt.Sprintf("git_revision:a78b5f3658c0578a017db48df97d20ac09822bcd"),
90 }
Eric Borenf4a5fc72017-06-06 08:27:09 -040091
Eric Boren27225492017-02-01 15:56:55 -050092 // Flags.
Eric Boren1f8be682017-02-07 09:16:30 -050093 builderNameSchemaFile = flag.String("builder_name_schema", "", "Path to the builder_name_schema.json file. If not specified, uses infra/bots/recipe_modules/builder_name_schema/builder_name_schema.json from this repo.")
94 assetsDir = flag.String("assets_dir", "", "Directory containing assets.")
95 cfgFile = flag.String("cfg_file", "", "JSON file containing general configuration information.")
Eric Boren1f8be682017-02-07 09:16:30 -050096 jobsFile = flag.String("jobs", "", "JSON file containing jobs to run.")
borenetdb182c72016-09-30 12:53:12 -070097)
98
Eric Borenfd4d60e2017-09-15 10:35:44 -040099// internalHardwareLabel returns the internal ID for the bot, if any.
Eric Boren4dc4aaf2017-09-15 14:09:07 -0400100func internalHardwareLabel(parts map[string]string) *int {
Eric Borenfd4d60e2017-09-15 10:35:44 -0400101 if internalHardwareLabelFn != nil {
102 return internalHardwareLabelFn(parts)
Eric Boren053d7a42017-09-15 08:35:31 -0400103 }
104 return nil
105}
106
Eric Boren27225492017-02-01 15:56:55 -0500107// linuxGceDimensions are the Swarming dimensions for Linux GCE
108// instances.
109func linuxGceDimensions() []string {
110 return []string{
Ben Wagner4c9842e2017-09-25 12:56:53 -0400111 // Specify CPU to avoid running builds on bots with a more unique CPU.
112 "cpu:x86-64-Haswell_GCE",
Eric Boren27225492017-02-01 15:56:55 -0500113 "gpu:none",
Eric Boren170c39c2017-11-15 11:22:57 -0500114 fmt.Sprintf("os:%s", DEFAULT_OS_LINUX_GCE),
Eric Boren27225492017-02-01 15:56:55 -0500115 fmt.Sprintf("pool:%s", CONFIG.Pool),
116 }
117}
118
borenetdb182c72016-09-30 12:53:12 -0700119// deriveCompileTaskName returns the name of a compile task based on the given
120// job name.
121func deriveCompileTaskName(jobName string, parts map[string]string) string {
Ravi Mistryd4731e92018-01-02 14:54:43 -0500122 if strings.Contains(jobName, "Bookmaker") {
Ravi Mistryedc4f3e2017-12-08 12:58:20 -0500123 return "Build-Debian9-GCC-x86_64-Release"
124 } else if parts["role"] == "Housekeeper" {
Eric Borenbb198fb2017-06-28 11:45:54 -0400125 return "Build-Debian9-GCC-x86_64-Release-Shared"
Yuqian Li4a577af2018-01-05 11:13:43 -0500126 } else if parts["role"] == "Test" || parts["role"] == "Perf" || parts["role"] == "Calmbench" {
borenetdb182c72016-09-30 12:53:12 -0700127 task_os := parts["os"]
Ben Wagner988d15e2017-04-27 13:08:50 -0400128 ec := []string{}
129 if val := parts["extra_config"]; val != "" {
130 ec = strings.Split(val, "_")
Ben Wagnerdba0bc82017-12-11 13:27:27 -0500131 ignore := []string{"Skpbench", "AbandonGpuContext", "PreAbandonGpuContext", "Valgrind", "ReleaseAndAbandonGpuContext", "CCPR", "FSAA", "FAAA", "FDAA", "NativeFonts", "GDI", "NoGPUThreads"}
Ben Wagner988d15e2017-04-27 13:08:50 -0400132 keep := make([]string, 0, len(ec))
133 for _, part := range ec {
134 if !util.In(part, ignore) {
135 keep = append(keep, part)
136 }
137 }
138 ec = keep
Eric Boren6ec17e32017-04-26 14:25:29 -0400139 }
borenetdb182c72016-09-30 12:53:12 -0700140 if task_os == "Android" {
Ben Wagner988d15e2017-04-27 13:08:50 -0400141 if !util.In("Android", ec) {
142 ec = append([]string{"Android"}, ec...)
borenetdb182c72016-09-30 12:53:12 -0700143 }
Eric Borenbb198fb2017-06-28 11:45:54 -0400144 task_os = "Debian9"
Kevin Lubickdcd2a902017-03-08 14:01:01 -0500145 } else if task_os == "Chromecast" {
Eric Borenbb198fb2017-06-28 11:45:54 -0400146 task_os = "Debian9"
Ben Wagner988d15e2017-04-27 13:08:50 -0400147 ec = append([]string{"Chromecast"}, ec...)
Kevin Lubickcb6f3982017-04-07 10:04:08 -0400148 } else if strings.Contains(task_os, "ChromeOS") {
Kevin Lubickb718fbb2017-11-02 09:34:08 -0400149 ec = append([]string{"Chromebook", "GLES"}, ec...)
Eric Borenbb198fb2017-06-28 11:45:54 -0400150 task_os = "Debian9"
borenetdb182c72016-09-30 12:53:12 -0700151 } else if task_os == "iOS" {
Ben Wagner988d15e2017-04-27 13:08:50 -0400152 ec = append([]string{task_os}, ec...)
borenetdb182c72016-09-30 12:53:12 -0700153 task_os = "Mac"
154 } else if strings.Contains(task_os, "Win") {
155 task_os = "Win"
Eric Borenbb198fb2017-06-28 11:45:54 -0400156 } else if strings.Contains(task_os, "Ubuntu") || strings.Contains(task_os, "Debian") {
157 task_os = "Debian9"
borenetdb182c72016-09-30 12:53:12 -0700158 }
Eric Boren50831302016-11-18 13:10:51 -0500159 jobNameMap := map[string]string{
borenetdb182c72016-09-30 12:53:12 -0700160 "role": "Build",
161 "os": task_os,
162 "compiler": parts["compiler"],
163 "target_arch": parts["arch"],
164 "configuration": parts["configuration"],
Eric Boren50831302016-11-18 13:10:51 -0500165 }
Ben Wagner988d15e2017-04-27 13:08:50 -0400166 if len(ec) > 0 {
167 jobNameMap["extra_config"] = strings.Join(ec, "_")
Eric Boren50831302016-11-18 13:10:51 -0500168 }
169 name, err := jobNameSchema.MakeJobName(jobNameMap)
borenetdb182c72016-09-30 12:53:12 -0700170 if err != nil {
171 glog.Fatal(err)
172 }
173 return name
174 } else {
175 return jobName
176 }
177}
178
179// swarmDimensions generates swarming bot dimensions for the given task.
180func swarmDimensions(parts map[string]string) []string {
Ben Wagner3d2a2f72017-06-13 17:01:16 -0400181 if alternateSwarmDimensions != nil {
182 return alternateSwarmDimensions(parts)
183 }
184 return defaultSwarmDimensions(parts)
185}
186
187// defaultSwarmDimensions generates default swarming bot dimensions for the given task.
188func defaultSwarmDimensions(parts map[string]string) []string {
borenetdb182c72016-09-30 12:53:12 -0700189 d := map[string]string{
Eric Boren27225492017-02-01 15:56:55 -0500190 "pool": CONFIG.Pool,
borenetdb182c72016-09-30 12:53:12 -0700191 }
192 if os, ok := parts["os"]; ok {
Ben Wagner3d2a2f72017-06-13 17:01:16 -0400193 d["os"], ok = map[string]string{
Kevin Lubick291547d2017-03-21 09:25:34 -0400194 "Android": "Android",
195 "Chromecast": "Android",
Kevin Lubickcb6f3982017-04-07 10:04:08 -0400196 "ChromeOS": "ChromeOS",
Eric Borenbb198fb2017-06-28 11:45:54 -0400197 "Debian9": DEFAULT_OS_DEBIAN,
Ben Wagnerd3fdcc92017-11-14 13:30:04 -0500198 "Mac": DEFAULT_OS_MAC,
Eric Borenbb198fb2017-06-28 11:45:54 -0400199 "Ubuntu14": DEFAULT_OS_UBUNTU,
Kevin Lubick291547d2017-03-21 09:25:34 -0400200 "Ubuntu16": "Ubuntu-16.10",
Eric Boren810c2b62017-07-11 08:11:15 -0400201 "Ubuntu17": "Ubuntu-17.04",
Ben Wagnerd3fdcc92017-11-14 13:30:04 -0500202 "Win": DEFAULT_OS_WIN,
Ben Wagner40226b42017-05-02 13:13:13 -0400203 "Win10": "Windows-10-15063",
Kevin Lubick291547d2017-03-21 09:25:34 -0400204 "Win2k8": "Windows-2008ServerR2-SP1",
Ben Wagnerd3fdcc92017-11-14 13:30:04 -0500205 "Win2016": DEFAULT_OS_WIN,
Ben Wagner56738d82017-04-18 15:38:15 -0400206 "Win7": "Windows-7-SP1",
Kevin Lubick291547d2017-03-21 09:25:34 -0400207 "Win8": "Windows-8.1-SP0",
Stephan Altmuellerddad85b2017-05-19 13:08:19 -0400208 "iOS": "iOS-10.3.1",
Eric Boren54ff2fc2016-12-02 12:09:10 -0500209 }[os]
Ben Wagner3d2a2f72017-06-13 17:01:16 -0400210 if !ok {
211 glog.Fatalf("Entry %q not found in OS mapping.", os)
212 }
Ben Wagnerb3c90fc2018-02-23 11:17:03 -0500213 if os == "Win10" {
214 // Transition to new Win image by model name.
215 _, ok = map[string]bool{
Ben Wagnere16ba2c2018-02-27 15:12:03 -0500216 "AlphaR2": true,
Ben Wagnerb3c90fc2018-02-23 11:17:03 -0500217 "NUC5i7RYH": true,
Ben Wagnerc657fa62018-02-26 16:42:21 -0500218 "NUC6i5SYK": true,
Ben Wagnerb3c90fc2018-02-23 11:17:03 -0500219 "NUCD34010WYKH": true,
Ben Wagnerc4205252018-02-27 15:54:02 -0500220 "ShuttleC": true,
Ben Wagnerb3c90fc2018-02-23 11:17:03 -0500221 }[parts["model"]]
222 if ok {
223 d["os"] = "Windows-10-16299.248"
224 }
225 }
borenetdb182c72016-09-30 12:53:12 -0700226 } else {
Eric Borenbb198fb2017-06-28 11:45:54 -0400227 d["os"] = DEFAULT_OS_DEBIAN
borenetdb182c72016-09-30 12:53:12 -0700228 }
Yuqian Liab246cb2017-11-02 13:48:23 -0400229 if parts["role"] == "Test" || parts["role"] == "Perf" || parts["role"] == "Calmbench" {
Kevin Lubick291547d2017-03-21 09:25:34 -0400230 if strings.Contains(parts["os"], "Android") || strings.Contains(parts["os"], "Chromecast") {
borenetdb182c72016-09-30 12:53:12 -0700231 // For Android, the device type is a better dimension
232 // than CPU or GPU.
Ben Wagner36682782017-06-14 10:01:45 -0400233 deviceInfo, ok := map[string][]string{
Ben Wagner3d2a2f72017-06-13 17:01:16 -0400234 "AndroidOne": {"sprout", "MOB30Q"},
Kevin Lubickc2f3e8d2018-01-24 15:48:26 -0500235 "Chorizo": {"chorizo", "1.30_109591"},
Ben Wagner0762bdf2017-11-28 09:41:48 -0500236 "GalaxyS6": {"zerofltetmo", "NRD90M_G920TUVU5FQK1"},
Ben Wagner3d2a2f72017-06-13 17:01:16 -0400237 "GalaxyS7_G930A": {"heroqlteatt", "NRD90M_G930AUCS4BQC2"},
238 "GalaxyS7_G930FD": {"herolte", "NRD90M_G930FXXU1DQAS"},
Ben Wagner3d2a2f72017-06-13 17:01:16 -0400239 "MotoG4": {"athene", "NPJ25.93-14"},
Ben Wagneree3123c2017-12-06 16:29:04 -0500240 "NVIDIA_Shield": {"foster", "NRD90M_1915764_848"},
Ben Wagneree3123c2017-12-06 16:29:04 -0500241 "Nexus5": {"hammerhead", "M4B30Z_3437181"},
Ben Wagnereb549c82017-11-17 08:59:44 -0500242 "Nexus5x": {"bullhead", "OPR6.170623.023"},
Ben Wagneree3123c2017-12-06 16:29:04 -0500243 "Nexus7": {"grouper", "LMY47V_1836172"}, // 2012 Nexus 7
Ben Wagner9539a8c2017-11-02 14:09:32 -0400244 "NexusPlayer": {"fugu", "OPR6.170623.021"},
Kevin Lubickb5d82b42018-02-20 10:29:45 -0500245 "Pixel": {"sailfish", "OPM1.171019.016"},
Kevin Lubickb018f7b2017-10-31 14:44:08 -0400246 "Pixel2XL": {"taimen", "OPD1.170816.023"},
Kevin Lubick674027a2017-10-31 09:47:38 -0400247 "PixelC": {"dragon", "OPR1.170623.034"},
Ben Wagner36682782017-06-14 10:01:45 -0400248 }[parts["model"]]
Eric Boren27225492017-02-01 15:56:55 -0500249 if !ok {
Ben Wagner36682782017-06-14 10:01:45 -0400250 glog.Fatalf("Entry %q not found in Android mapping.", parts["model"])
Eric Boren27225492017-02-01 15:56:55 -0500251 }
Eric Boren4b254b92016-11-08 12:55:32 -0500252 d["device_type"] = deviceInfo[0]
253 d["device_os"] = deviceInfo[1]
Kevin Lubick4fd283e2017-12-07 11:19:31 -0500254 // TODO(kjlubick): Remove the python dimension after we have removed the
255 // Nexus5x devices from the local lab (on Monday, Dec 11, 2017 should be fine).
Kevin Lubick0f727ff2017-12-06 15:05:29 -0500256 d["python"] = "2.7.9" // This indicates a RPI, e.g. in Skolo. Golo is 2.7.12
Kevin Lubick4fd283e2017-12-07 11:19:31 -0500257 if parts["model"] == "Nexus5x" {
258 d["python"] = "2.7.12"
259 }
borenetdb182c72016-09-30 12:53:12 -0700260 } else if strings.Contains(parts["os"], "iOS") {
Ben Wagner3d2a2f72017-06-13 17:01:16 -0400261 device, ok := map[string]string{
Eric Boren792079c2016-11-09 14:03:20 -0500262 "iPadMini4": "iPad5,1",
Stephan Altmueller63e843d2017-04-25 11:38:38 -0400263 "iPhone6": "iPhone7,2",
264 "iPhone7": "iPhone9,1",
265 "iPadPro": "iPad6,3",
borenetdb182c72016-09-30 12:53:12 -0700266 }[parts["model"]]
Ben Wagner3d2a2f72017-06-13 17:01:16 -0400267 if !ok {
268 glog.Fatalf("Entry %q not found in iOS mapping.", parts["model"])
269 }
270 d["device"] = device
borenetdb182c72016-09-30 12:53:12 -0700271 } else if parts["cpu_or_gpu"] == "CPU" {
Ben Wagner4c9842e2017-09-25 12:56:53 -0400272 modelMapping, ok := map[string]map[string]string{
273 "AVX": {
274 "MacMini7.1": "x86-64-E5-2697_v2",
275 "Golo": "x86-64-E5-2670",
276 },
277 "AVX2": {
Ben Wagner85fb42a2017-11-07 16:57:37 -0500278 "GCE": "x86-64-Haswell_GCE",
Mike Klein9a01a212017-11-03 12:19:54 -0400279 "NUC5i7RYH": "x86-64-i7-5557U",
Ben Wagner4c9842e2017-09-25 12:56:53 -0400280 },
Ben Wagnerb268d232017-09-28 16:38:34 -0400281 "AVX512": {
282 "GCE": "x86-64-Skylake_GCE",
283 },
borenetdb182c72016-09-30 12:53:12 -0700284 }[parts["cpu_or_gpu_value"]]
Ben Wagner3d2a2f72017-06-13 17:01:16 -0400285 if !ok {
286 glog.Fatalf("Entry %q not found in CPU mapping.", parts["cpu_or_gpu_value"])
287 }
Ben Wagner4c9842e2017-09-25 12:56:53 -0400288 cpu, ok := modelMapping[parts["model"]]
289 if !ok {
290 glog.Fatalf("Entry %q not found in %q model mapping.", parts["model"], parts["cpu_or_gpu_value"])
borenetdb182c72016-09-30 12:53:12 -0700291 }
Ben Wagner4c9842e2017-09-25 12:56:53 -0400292 d["cpu"] = cpu
Eric Boren170c39c2017-11-15 11:22:57 -0500293 if parts["model"] == "GCE" && d["os"] == DEFAULT_OS_DEBIAN {
294 d["os"] = DEFAULT_OS_LINUX_GCE
295 }
Ben Wagnerf53e6c92017-12-14 13:15:01 -0500296 if parts["model"] == "GCE" && d["os"] == DEFAULT_OS_WIN {
Ben Wagner832415e2017-12-15 11:23:40 -0500297 // Use normal-size machines for Test and Perf tasks on Win GCE.
Ben Wagnerf53e6c92017-12-14 13:15:01 -0500298 d["machine_type"] = "n1-standard-16"
299 }
borenetdb182c72016-09-30 12:53:12 -0700300 } else {
Ben Wagner1d060782017-06-14 10:34:18 -0400301 if strings.Contains(parts["os"], "Win") {
302 gpu, ok := map[string]string{
Ben Wagner0d2b0912017-08-15 12:43:55 -0400303 "GT610": "10de:104a-22.21.13.8205",
Ben Wagner85fb42a2017-11-07 16:57:37 -0500304 "GTX1070": "10de:1ba1-23.21.13.8813",
305 "GTX660": "10de:11c0-23.21.13.8813",
306 "GTX960": "10de:1401-23.21.13.8813",
Ben Wagner90e88aa2018-02-26 23:38:52 -0500307 "IntelHD4400": "8086:0a16-20.19.15.4835",
Ben Wagner1d060782017-06-14 10:34:18 -0400308 "IntelIris540": "8086:1926-21.20.16.4590",
Ben Wagner90e88aa2018-02-26 23:38:52 -0500309 "IntelIris6100": "8086:162b-20.19.15.4835",
Ben Wagner2040ed22017-11-22 11:22:22 -0500310 "RadeonHD7770": "1002:683d-22.19.165.512",
Ben Wagner1d060782017-06-14 10:34:18 -0400311 "RadeonR9M470X": "1002:6646-22.19.165.512",
Ben Wagnerae532f62017-08-02 23:24:16 -0400312 "QuadroP400": "10de:1cb3-22.21.13.8205",
Ben Wagner1d060782017-06-14 10:34:18 -0400313 }[parts["cpu_or_gpu_value"]]
314 if !ok {
315 glog.Fatalf("Entry %q not found in Win GPU mapping.", parts["cpu_or_gpu_value"])
316 }
317 d["gpu"] = gpu
Ben Wagner08435892017-02-18 23:28:26 -0500318
Ben Wagner4b1df022017-06-15 12:28:04 -0400319 // Specify cpu dimension for NUCs and ShuttleCs. We temporarily have two
320 // types of machines with a GTX960.
321 cpu, ok := map[string]string{
322 "NUC6i7KYK": "x86-64-i7-6770HQ",
323 "ShuttleC": "x86-64-i7-6700K",
Ben Wagner1d060782017-06-14 10:34:18 -0400324 }[parts["model"]]
325 if ok {
Ben Wagner4b1df022017-06-15 12:28:04 -0400326 d["cpu"] = cpu
Ben Wagner1d060782017-06-14 10:34:18 -0400327 }
Eric Borenbb198fb2017-06-28 11:45:54 -0400328 } else if strings.Contains(parts["os"], "Ubuntu") || strings.Contains(parts["os"], "Debian") {
Ben Wagner1d060782017-06-14 10:34:18 -0400329 gpu, ok := map[string]string{
Ben Wagner1d060782017-06-14 10:34:18 -0400330 // Intel drivers come from CIPD, so no need to specify the version here.
331 "IntelBayTrail": "8086:0f31",
332 "IntelHD2000": "8086:0102",
333 "IntelHD405": "8086:22b1",
Ben Wagnerab10c822017-12-19 15:14:12 -0500334 "IntelIris640": "8086:5926",
Ben Wagnerc274ec42017-08-03 22:29:22 -0400335 "QuadroP400": "10de:1cb3-384.59",
Ben Wagner1d060782017-06-14 10:34:18 -0400336 }[parts["cpu_or_gpu_value"]]
337 if !ok {
338 glog.Fatalf("Entry %q not found in Ubuntu GPU mapping.", parts["cpu_or_gpu_value"])
339 }
340 d["gpu"] = gpu
341 } else if strings.Contains(parts["os"], "Mac") {
342 gpu, ok := map[string]string{
Ben Wagner1d8726f2018-02-02 14:47:31 -0500343 "IntelHD6000": "8086:1626",
Ben Wagnerdf430052018-02-08 16:57:04 -0500344 "IntelHD615": "8086:591e",
Ben Wagnercc4221b2017-08-17 17:29:04 -0400345 "IntelIris5100": "8086:0a2e",
Ben Wagner1d060782017-06-14 10:34:18 -0400346 }[parts["cpu_or_gpu_value"]]
347 if !ok {
348 glog.Fatalf("Entry %q not found in Mac GPU mapping.", parts["cpu_or_gpu_value"])
349 }
350 d["gpu"] = gpu
Ben Wagnere7b8fea2018-02-09 10:29:09 -0500351 // Yuck. We have two different types of MacMini7,1 with the same GPU but different CPUs.
352 if parts["cpu_or_gpu_value"] == "IntelIris5100" {
353 // Run all tasks on Golo machines for now.
354 d["cpu"] = "x86-64-i7-4578U"
355 }
Ben Wagner1d060782017-06-14 10:34:18 -0400356 } else if strings.Contains(parts["os"], "ChromeOS") {
Kevin Lubick64ca6be2017-12-04 15:43:31 -0500357 version, ok := map[string]string{
358 "MaliT604": "9901.12.0",
359 "MaliT764": "10172.0.0",
360 "MaliT860": "10172.0.0",
Kevin Lubick0b1b9c22017-12-08 14:14:38 -0500361 "PowerVRGX6250": "10176.5.0",
Kevin Lubick64ca6be2017-12-04 15:43:31 -0500362 "TegraK1": "10172.0.0",
363 "IntelHDGraphics615": "10032.17.0",
Ben Wagner1d060782017-06-14 10:34:18 -0400364 }[parts["cpu_or_gpu_value"]]
365 if !ok {
366 glog.Fatalf("Entry %q not found in ChromeOS GPU mapping.", parts["cpu_or_gpu_value"])
367 }
Kevin Lubick64ca6be2017-12-04 15:43:31 -0500368 d["gpu"] = parts["cpu_or_gpu_value"]
369 d["release_version"] = version
Ben Wagner1d060782017-06-14 10:34:18 -0400370 } else {
371 glog.Fatalf("Unknown GPU mapping for OS %q.", parts["os"])
Ben Wagner08435892017-02-18 23:28:26 -0500372 }
borenetdb182c72016-09-30 12:53:12 -0700373 }
374 } else {
375 d["gpu"] = "none"
Eric Borenbb198fb2017-06-28 11:45:54 -0400376 if d["os"] == DEFAULT_OS_DEBIAN {
Kevin Lubick4610a9b2017-03-22 15:54:54 -0400377 return linuxGceDimensions()
Ben Wagnerd3fdcc92017-11-14 13:30:04 -0500378 } else if d["os"] == DEFAULT_OS_WIN {
379 // Windows CPU bots.
Ben Wagnera78f1bc2017-09-26 18:19:56 -0400380 d["cpu"] = "x86-64-Haswell_GCE"
Ben Wagner832415e2017-12-15 11:23:40 -0500381 // Use many-core machines for Build tasks on Win GCE, except for Goma.
382 if strings.Contains(parts["extra_config"], "Goma") {
383 d["machine_type"] = "n1-standard-16"
384 } else {
385 d["machine_type"] = "n1-highcpu-64"
386 }
Ben Wagnerd3fdcc92017-11-14 13:30:04 -0500387 } else if d["os"] == DEFAULT_OS_MAC {
388 // Mac CPU bots.
Ben Wagnera78f1bc2017-09-26 18:19:56 -0400389 d["cpu"] = "x86-64-E5-2697_v2"
Kevin Lubick4610a9b2017-03-22 15:54:54 -0400390 }
borenetdb182c72016-09-30 12:53:12 -0700391 }
Kevin Lubick4610a9b2017-03-22 15:54:54 -0400392
borenetdb182c72016-09-30 12:53:12 -0700393 rv := make([]string, 0, len(d))
394 for k, v := range d {
395 rv = append(rv, fmt.Sprintf("%s:%s", k, v))
396 }
397 sort.Strings(rv)
398 return rv
399}
400
Eric Boren7e3a3642017-06-14 15:25:31 -0400401// relpath returns the relative path to the given file from the config file.
402func relpath(f string) string {
403 _, filename, _, _ := runtime.Caller(0)
404 dir := path.Dir(filename)
405 rel := dir
406 if *cfgFile != "" {
407 rel = path.Dir(*cfgFile)
408 }
409 rv, err := filepath.Rel(rel, path.Join(dir, f))
410 if err != nil {
411 sklog.Fatal(err)
412 }
413 return rv
414}
415
Eric Boren8b3f9e62017-04-04 09:06:16 -0400416// bundleRecipes generates the task to bundle and isolate the recipes.
417func bundleRecipes(b *specs.TasksCfgBuilder) string {
418 b.MustAddTask(BUNDLE_RECIPES_NAME, &specs.TaskSpec{
Eric Boren9d78afd2017-12-07 14:54:05 +0000419 CipdPackages: []*specs.CipdPackage{cipdGit1, cipdGit2},
420 Dimensions: linuxGceDimensions(),
421 ExtraArgs: []string{
422 "--workdir", "../../..", "bundle_recipes",
423 fmt.Sprintf("buildername=%s", BUNDLE_RECIPES_NAME),
424 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
Eric Boren8b3f9e62017-04-04 09:06:16 -0400425 },
Eric Boren9d78afd2017-12-07 14:54:05 +0000426 Isolate: relpath("bundle_recipes.isolate"),
Kevin Lubick07072942017-05-11 13:35:23 -0400427 Priority: 0.7,
Eric Boren8b3f9e62017-04-04 09:06:16 -0400428 })
429 return BUNDLE_RECIPES_NAME
430}
431
Eric Boren23a6ec62017-04-07 08:31:22 -0400432// useBundledRecipes returns true iff the given bot should use bundled recipes
433// instead of syncing recipe DEPS itself.
434func useBundledRecipes(parts map[string]string) bool {
435 // Use bundled recipes for all test/perf tasks.
436 return true
437}
438
Kevin Lubick07072942017-05-11 13:35:23 -0400439type isolateAssetCfg struct {
Eric Boren9d78afd2017-12-07 14:54:05 +0000440 isolateFile string
441 cipdPkg string
Kevin Lubick07072942017-05-11 13:35:23 -0400442}
443
444var ISOLATE_ASSET_MAPPING = map[string]isolateAssetCfg{
445 ISOLATE_SKIMAGE_NAME: {
Eric Boren9d78afd2017-12-07 14:54:05 +0000446 isolateFile: "isolate_skimage.isolate",
447 cipdPkg: "skimage",
Kevin Lubick07072942017-05-11 13:35:23 -0400448 },
449 ISOLATE_SKP_NAME: {
Eric Boren9d78afd2017-12-07 14:54:05 +0000450 isolateFile: "isolate_skp.isolate",
451 cipdPkg: "skp",
Kevin Lubick07072942017-05-11 13:35:23 -0400452 },
453 ISOLATE_SVG_NAME: {
Eric Boren9d78afd2017-12-07 14:54:05 +0000454 isolateFile: "isolate_svg.isolate",
455 cipdPkg: "svg",
Kevin Lubick07072942017-05-11 13:35:23 -0400456 },
Kevin Lubick814b1492017-11-29 14:45:14 -0500457 ISOLATE_NDK_LINUX_NAME: {
Eric Boren9d78afd2017-12-07 14:54:05 +0000458 isolateFile: "isolate_ndk_linux.isolate",
459 cipdPkg: "android_ndk_linux",
Kevin Lubick814b1492017-11-29 14:45:14 -0500460 },
Stephan Altmueller2a552172018-02-20 11:40:25 -0500461 ISOLATE_SDK_LINUX_NAME: {
462 isolateFile: "isolate_android_sdk_linux.isolate",
463 cipdPkg: "android_sdk_linux",
464 },
Kevin Lubick814b1492017-11-29 14:45:14 -0500465 ISOLATE_WIN_TOOLCHAIN_NAME: {
Eric Boren9d78afd2017-12-07 14:54:05 +0000466 isolateFile: "isolate_win_toolchain.isolate",
467 cipdPkg: "win_toolchain",
Kevin Lubick814b1492017-11-29 14:45:14 -0500468 },
469 ISOLATE_WIN_VULKAN_SDK_NAME: {
Eric Boren9d78afd2017-12-07 14:54:05 +0000470 isolateFile: "isolate_win_vulkan_sdk.isolate",
471 cipdPkg: "win_vulkan_sdk",
Kevin Lubick814b1492017-11-29 14:45:14 -0500472 },
Kevin Lubick07072942017-05-11 13:35:23 -0400473}
474
Eric Boren9d78afd2017-12-07 14:54:05 +0000475// bundleRecipes generates the task to bundle and isolate the recipes.
Kevin Lubick07072942017-05-11 13:35:23 -0400476func isolateCIPDAsset(b *specs.TasksCfgBuilder, name string) string {
477 b.MustAddTask(name, &specs.TaskSpec{
478 CipdPackages: []*specs.CipdPackage{
Eric Boren9d78afd2017-12-07 14:54:05 +0000479 b.MustGetCipdPackageFromAsset(ISOLATE_ASSET_MAPPING[name].cipdPkg),
Kevin Lubick07072942017-05-11 13:35:23 -0400480 },
481 Dimensions: linuxGceDimensions(),
Eric Boren9d78afd2017-12-07 14:54:05 +0000482 Isolate: relpath(ISOLATE_ASSET_MAPPING[name].isolateFile),
Kevin Lubick07072942017-05-11 13:35:23 -0400483 Priority: 0.7,
484 })
485 return name
486}
487
Kevin Lubick90189522017-05-15 08:30:27 -0400488// getIsolatedCIPDDeps returns the slice of Isolate_* tasks a given task needs.
489// This allows us to save time on I/O bound bots, like the RPIs.
490func getIsolatedCIPDDeps(parts map[string]string) []string {
491 deps := []string{}
Kevin Lubick07072942017-05-11 13:35:23 -0400492 // Only do this on the RPIs for now. Other, faster machines shouldn't see much
493 // benefit and we don't need the extra complexity, for now
Kevin Lubick90189522017-05-15 08:30:27 -0400494 rpiOS := []string{"Android", "ChromeOS", "iOS"}
495
496 if o := parts["os"]; strings.Contains(o, "Chromecast") {
497 // Chromecasts don't have enough disk space to fit all of the content,
498 // so we do a subset of the skps.
499 deps = append(deps, ISOLATE_SKP_NAME)
500 } else if e := parts["extra_config"]; strings.Contains(e, "Skpbench") {
501 // Skpbench only needs skps
502 deps = append(deps, ISOLATE_SKP_NAME)
503 } else if util.In(o, rpiOS) {
504 deps = append(deps, ISOLATE_SKP_NAME)
505 deps = append(deps, ISOLATE_SVG_NAME)
506 deps = append(deps, ISOLATE_SKIMAGE_NAME)
507 }
508
509 return deps
Kevin Lubick07072942017-05-11 13:35:23 -0400510}
511
borenetdb182c72016-09-30 12:53:12 -0700512// compile generates a compile task. Returns the name of the last task in the
513// generated chain of tasks, which the Job should add as a dependency.
boreneted20a702016-10-20 11:04:31 -0700514func compile(b *specs.TasksCfgBuilder, name string, parts map[string]string) string {
borenetdb182c72016-09-30 12:53:12 -0700515 // Collect the necessary CIPD packages.
516 pkgs := []*specs.CipdPackage{}
Eric Boren9d78afd2017-12-07 14:54:05 +0000517 deps := []string{}
borenetdb182c72016-09-30 12:53:12 -0700518
519 // Android bots require a toolchain.
520 if strings.Contains(name, "Android") {
Ravi Mistry5e967422018-02-01 13:38:13 -0500521 if parts["extra_config"] == "Android_Framework" {
522 // Do not need a toolchain when building the
523 // Android Framework.
524 } else if strings.Contains(name, "Mac") {
boreneted20a702016-10-20 11:04:31 -0700525 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("android_ndk_darwin"))
Mike Klein86c2c0f2016-11-02 13:13:16 -0400526 } else if strings.Contains(name, "Win") {
Mike Kleine9215f02016-11-02 15:44:26 -0400527 pkg := b.MustGetCipdPackageFromAsset("android_ndk_windows")
528 pkg.Path = "n"
529 pkgs = append(pkgs, pkg)
borenetdb182c72016-09-30 12:53:12 -0700530 } else {
Kevin Lubick814b1492017-11-29 14:45:14 -0500531 deps = append(deps, isolateCIPDAsset(b, ISOLATE_NDK_LINUX_NAME))
borenetdb182c72016-09-30 12:53:12 -0700532 }
Kevin Lubickdcd2a902017-03-08 14:01:01 -0500533 } else if strings.Contains(name, "Chromecast") {
534 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("cast_toolchain"))
Kevin Lubickffce0792017-05-24 15:30:35 -0400535 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("chromebook_arm_gles"))
Kevin Lubick261ea192017-04-05 07:32:45 -0400536 } else if strings.Contains(name, "Chromebook") {
537 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("clang_linux"))
Kevin Lubickb718fbb2017-11-02 09:34:08 -0400538 if parts["target_arch"] == "x86_64" {
539 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("chromebook_x86_64_gles"))
540 } else if parts["target_arch"] == "arm" {
541 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("armhf_sysroot"))
542 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("chromebook_arm_gles"))
543 }
Eric Borenbb198fb2017-06-28 11:45:54 -0400544 } else if strings.Contains(name, "Debian") {
Kevin Lubick9c7dcac2017-01-18 09:24:56 -0500545 if strings.Contains(name, "Clang") {
546 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("clang_linux"))
547 }
548 if strings.Contains(name, "Vulkan") {
549 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("linux_vulkan_sdk"))
550 }
Kevin Lubickebf648e2017-09-21 13:45:16 -0400551 if strings.Contains(name, "EMCC") {
552 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("emscripten_sdk"))
553 }
Mike Klein27dcee12016-11-09 16:31:42 -0500554 } else if strings.Contains(name, "Win") {
Kevin Lubick814b1492017-11-29 14:45:14 -0500555 deps = append(deps, isolateCIPDAsset(b, ISOLATE_WIN_TOOLCHAIN_NAME))
Mike Klein8e3c42b2017-07-31 14:57:20 -0400556 if strings.Contains(name, "Clang") {
557 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("clang_win"))
558 }
borenetdb182c72016-09-30 12:53:12 -0700559 if strings.Contains(name, "Vulkan") {
Kevin Lubick814b1492017-11-29 14:45:14 -0500560 deps = append(deps, isolateCIPDAsset(b, ISOLATE_WIN_VULKAN_SDK_NAME))
borenetdb182c72016-09-30 12:53:12 -0700561 }
562 }
563
Stephan Altmueller5f3b9402017-03-20 13:38:45 -0400564 dimensions := swarmDimensions(parts)
Stephan Altmueller5f3b9402017-03-20 13:38:45 -0400565
borenetdb182c72016-09-30 12:53:12 -0700566 // Add the task.
boreneted20a702016-10-20 11:04:31 -0700567 b.MustAddTask(name, &specs.TaskSpec{
borenetdb182c72016-09-30 12:53:12 -0700568 CipdPackages: pkgs,
Eric Boren9d78afd2017-12-07 14:54:05 +0000569 Dimensions: dimensions,
570 Dependencies: deps,
571 ExtraArgs: []string{
572 "--workdir", "../../..", "compile",
skia.buildbots2478c732016-11-04 14:37:26 -0400573 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
borenetdb182c72016-09-30 12:53:12 -0700574 fmt.Sprintf("buildername=%s", name),
borenetdb182c72016-09-30 12:53:12 -0700575 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
576 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
Eric Boren09419502017-04-21 09:37:37 -0400577 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
borenet98b2e7a2016-10-13 06:23:45 -0700578 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
skia.buildbots2478c732016-11-04 14:37:26 -0400579 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
580 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
borenetdb182c72016-09-30 12:53:12 -0700581 },
Eric Boren9d78afd2017-12-07 14:54:05 +0000582 Isolate: relpath("compile_skia.isolate"),
583 Priority: 0.8,
boreneted20a702016-10-20 11:04:31 -0700584 })
Eric Boren8615fe52016-12-12 14:30:12 -0500585 // All compile tasks are runnable as their own Job. Assert that the Job
586 // is listed in JOBS.
587 if !util.In(name, JOBS) {
588 glog.Fatalf("Job %q is missing from the JOBS list!", name)
589 }
Ravi Mistry6f136222017-12-12 17:08:24 -0500590
591 // Upload the skiaserve binary only for Linux Android compile bots.
592 // See skbug.com/7399 for context.
593 if parts["configuration"] == "Release" &&
594 parts["extra_config"] == "Android" &&
595 !strings.Contains(parts["os"], "Win") &&
596 !strings.Contains(parts["os"], "Mac") {
597 uploadName := fmt.Sprintf("%s%s%s", PREFIX_UPLOAD, jobNameSchema.Sep, name)
598 b.MustAddTask(uploadName, &specs.TaskSpec{
599 Dependencies: []string{name},
600 Dimensions: linuxGceDimensions(),
601 ExtraArgs: []string{
602 "--workdir", "../../..", "upload_skiaserve",
603 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
604 fmt.Sprintf("buildername=%s", name),
605 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
606 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
607 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
608 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
609 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
610 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
611 },
612 // We're using the same isolate as upload_dm_results
613 Isolate: relpath("upload_dm_results.isolate"),
614 Priority: 0.8,
615 })
616 return uploadName
617 }
618
borenetdb182c72016-09-30 12:53:12 -0700619 return name
620}
621
622// recreateSKPs generates a RecreateSKPs task. Returns the name of the last
623// task in the generated chain of tasks, which the Job should add as a
624// dependency.
Eric Boren9d78afd2017-12-07 14:54:05 +0000625func recreateSKPs(b *specs.TasksCfgBuilder, name string) string {
Eric Boren4b254b92016-11-08 12:55:32 -0500626 b.MustAddTask(name, &specs.TaskSpec{
Eric Boren9d78afd2017-12-07 14:54:05 +0000627 CipdPackages: []*specs.CipdPackage{b.MustGetCipdPackageFromAsset("go")},
628 Dimensions: linuxGceDimensions(),
629 ExecutionTimeout: 4 * time.Hour,
630 ExtraArgs: []string{
631 "--workdir", "../../..", "recreate_skps",
Eric Boren4b254b92016-11-08 12:55:32 -0500632 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
633 fmt.Sprintf("buildername=%s", name),
Eric Boren4b254b92016-11-08 12:55:32 -0500634 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
635 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
Eric Boren09419502017-04-21 09:37:37 -0400636 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
Eric Boren4b254b92016-11-08 12:55:32 -0500637 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
638 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
639 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
640 },
Eric Boren9d78afd2017-12-07 14:54:05 +0000641 IoTimeout: 40 * time.Minute,
642 Isolate: relpath("compile_skia.isolate"),
643 Priority: 0.8,
Eric Boren4b254b92016-11-08 12:55:32 -0500644 })
borenetdb182c72016-09-30 12:53:12 -0700645 return name
646}
647
Ravi Mistry01b48e72017-05-17 14:28:06 -0400648// updateMetaConfig generates a UpdateMetaConfig task. Returns the name of the
649// last task in the generated chain of tasks, which the Job should add as a
650// dependency.
Eric Boren9d78afd2017-12-07 14:54:05 +0000651func updateMetaConfig(b *specs.TasksCfgBuilder, name string) string {
Ravi Mistry01b48e72017-05-17 14:28:06 -0400652 b.MustAddTask(name, &specs.TaskSpec{
Stephan Altmuellerddad85b2017-05-19 13:08:19 -0400653 CipdPackages: []*specs.CipdPackage{},
Eric Boren9d78afd2017-12-07 14:54:05 +0000654 Dimensions: linuxGceDimensions(),
655 ExtraArgs: []string{
656 "--workdir", "../../..", "update_meta_config",
Ravi Mistry01b48e72017-05-17 14:28:06 -0400657 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
658 fmt.Sprintf("buildername=%s", name),
659 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
660 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
661 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
662 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
663 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
664 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
665 },
Eric Boren9d78afd2017-12-07 14:54:05 +0000666 Isolate: relpath("meta_config.isolate"),
667 Priority: 0.8,
Ravi Mistry01b48e72017-05-17 14:28:06 -0400668 })
669 return name
670}
671
borenetdb182c72016-09-30 12:53:12 -0700672// ctSKPs generates a CT SKPs task. Returns the name of the last task in the
673// generated chain of tasks, which the Job should add as a dependency.
Eric Boren9d78afd2017-12-07 14:54:05 +0000674func ctSKPs(b *specs.TasksCfgBuilder, name string) string {
Eric Boren4b254b92016-11-08 12:55:32 -0500675 b.MustAddTask(name, &specs.TaskSpec{
Ben Wagner21c3fb92017-08-04 14:13:27 -0400676 CipdPackages: []*specs.CipdPackage{},
Eric Boren9d78afd2017-12-07 14:54:05 +0000677 Dimensions: []string{
678 "pool:SkiaCT",
679 fmt.Sprintf("os:%s", DEFAULT_OS_LINUX_GCE),
680 },
681 ExecutionTimeout: 24 * time.Hour,
682 ExtraArgs: []string{
683 "--workdir", "../../..", "ct_skps",
Eric Boren4b254b92016-11-08 12:55:32 -0500684 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
685 fmt.Sprintf("buildername=%s", name),
Eric Boren4b254b92016-11-08 12:55:32 -0500686 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
687 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
Eric Boren09419502017-04-21 09:37:37 -0400688 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
Eric Boren4b254b92016-11-08 12:55:32 -0500689 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
690 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
691 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
692 },
Eric Boren9d78afd2017-12-07 14:54:05 +0000693 IoTimeout: time.Hour,
694 Isolate: relpath("ct_skps_skia.isolate"),
695 Priority: 0.8,
Eric Boren4b254b92016-11-08 12:55:32 -0500696 })
borenetdb182c72016-09-30 12:53:12 -0700697 return name
698}
699
Eric Borenf7928b42017-07-28 07:35:28 -0400700// checkGeneratedFiles verifies that no generated SKSL files have been edited
701// by hand.
Eric Boren9d78afd2017-12-07 14:54:05 +0000702func checkGeneratedFiles(b *specs.TasksCfgBuilder, name string) string {
Eric Borenf7928b42017-07-28 07:35:28 -0400703 b.MustAddTask(name, &specs.TaskSpec{
704 CipdPackages: []*specs.CipdPackage{},
Eric Boren9d78afd2017-12-07 14:54:05 +0000705 Dimensions: linuxGceDimensions(),
706 ExtraArgs: []string{
707 "--workdir", "../../..", "check_generated_files",
Eric Borenf7928b42017-07-28 07:35:28 -0400708 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
709 fmt.Sprintf("buildername=%s", name),
710 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
711 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
712 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
713 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
714 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
715 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
716 },
Eric Boren9d78afd2017-12-07 14:54:05 +0000717 Isolate: relpath("compile_skia.isolate"),
718 Priority: 0.8,
Eric Borenf7928b42017-07-28 07:35:28 -0400719 })
720 return name
721}
722
borenetdb182c72016-09-30 12:53:12 -0700723// housekeeper generates a Housekeeper task. Returns the name of the last task
724// in the generated chain of tasks, which the Job should add as a dependency.
Eric Boren9d78afd2017-12-07 14:54:05 +0000725func housekeeper(b *specs.TasksCfgBuilder, name, compileTaskName string) string {
Eric Boren4b254b92016-11-08 12:55:32 -0500726 b.MustAddTask(name, &specs.TaskSpec{
Eric Boren22f5ef72016-12-02 11:01:33 -0500727 CipdPackages: []*specs.CipdPackage{b.MustGetCipdPackageFromAsset("go")},
Eric Boren9d78afd2017-12-07 14:54:05 +0000728 Dependencies: []string{compileTaskName},
729 Dimensions: linuxGceDimensions(),
730 ExtraArgs: []string{
731 "--workdir", "../../..", "housekeeper",
Eric Boren4b254b92016-11-08 12:55:32 -0500732 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
733 fmt.Sprintf("buildername=%s", name),
Eric Boren4b254b92016-11-08 12:55:32 -0500734 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
735 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
Eric Boren09419502017-04-21 09:37:37 -0400736 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
Eric Boren4b254b92016-11-08 12:55:32 -0500737 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
738 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
739 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
740 },
Eric Boren9d78afd2017-12-07 14:54:05 +0000741 Isolate: relpath("housekeeper_skia.isolate"),
742 Priority: 0.8,
Eric Boren4b254b92016-11-08 12:55:32 -0500743 })
borenetdb182c72016-09-30 12:53:12 -0700744 return name
745}
746
Ravi Mistryedc4f3e2017-12-08 12:58:20 -0500747// bookmaker generates a Bookmaker task. Returns the name of the last task
748// in the generated chain of tasks, which the Job should add as a dependency.
749func bookmaker(b *specs.TasksCfgBuilder, name, compileTaskName string) string {
750 b.MustAddTask(name, &specs.TaskSpec{
751 CipdPackages: []*specs.CipdPackage{b.MustGetCipdPackageFromAsset("go")},
752 Dependencies: []string{compileTaskName},
753 Dimensions: linuxGceDimensions(),
754 ExtraArgs: []string{
755 "--workdir", "../../..", "bookmaker",
756 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
757 fmt.Sprintf("buildername=%s", name),
758 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
759 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
760 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
761 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
762 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
763 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
764 },
765 Isolate: relpath("compile_skia.isolate"),
766 Priority: 0.8,
767 ExecutionTimeout: 2 * time.Hour,
768 IoTimeout: 2 * time.Hour,
769 })
770 return name
771}
772
Ravi Mistry5e967422018-02-01 13:38:13 -0500773// androidFrameworkCompile generates an Android Framework Compile task. Returns
774// the name of the last task in the generated chain of tasks, which the Job
775// should add as a dependency.
776func androidFrameworkCompile(b *specs.TasksCfgBuilder, name string) string {
777 b.MustAddTask(name, &specs.TaskSpec{
778 Dimensions: linuxGceDimensions(),
779 ExtraArgs: []string{
780 "--workdir", "../../..", "android_compile",
781 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
782 fmt.Sprintf("buildername=%s", name),
783 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
784 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
785 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
786 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
787 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
788 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
789 },
790 Isolate: relpath("compile_skia.isolate"),
791 Priority: 0.8,
792 })
793 return name
794}
795
borenet2dbbfa52016-10-14 06:32:09 -0700796// infra generates an infra_tests task. Returns the name of the last task in the
797// generated chain of tasks, which the Job should add as a dependency.
Eric Boren9d78afd2017-12-07 14:54:05 +0000798func infra(b *specs.TasksCfgBuilder, name string) string {
boreneted20a702016-10-20 11:04:31 -0700799 b.MustAddTask(name, &specs.TaskSpec{
Eric Boren9d78afd2017-12-07 14:54:05 +0000800 CipdPackages: []*specs.CipdPackage{b.MustGetCipdPackageFromAsset("go")},
801 Dimensions: linuxGceDimensions(),
802 ExtraArgs: []string{
803 "--workdir", "../../..", "infra",
skia.buildbots2478c732016-11-04 14:37:26 -0400804 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
borenet2dbbfa52016-10-14 06:32:09 -0700805 fmt.Sprintf("buildername=%s", name),
borenet2dbbfa52016-10-14 06:32:09 -0700806 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
807 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
Eric Boren09419502017-04-21 09:37:37 -0400808 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
borenet2dbbfa52016-10-14 06:32:09 -0700809 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
skia.buildbots2478c732016-11-04 14:37:26 -0400810 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
811 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
borenet2dbbfa52016-10-14 06:32:09 -0700812 },
Eric Boren9d78afd2017-12-07 14:54:05 +0000813 Isolate: relpath("infra_skia.isolate"),
814 Priority: 0.8,
boreneted20a702016-10-20 11:04:31 -0700815 })
borenet2dbbfa52016-10-14 06:32:09 -0700816 return name
817}
818
Yuqian Li4a577af2018-01-05 11:13:43 -0500819func getParentRevisionName(compileTaskName string, parts map[string]string) string {
820 if parts["extra_config"] == "" {
821 return compileTaskName + "-ParentRevision"
822 } else {
823 return compileTaskName + "_ParentRevision"
824 }
825}
826
Yuqian Lic81aaaa2017-10-16 12:24:43 -0400827// calmbench generates a calmbench task. Returns the name of the last task in the
828// generated chain of tasks, which the Job should add as a dependency.
Yuqian Li4a577af2018-01-05 11:13:43 -0500829func calmbench(b *specs.TasksCfgBuilder, name string, parts map[string]string, compileTaskName string, compileParentName string) string {
Yuqian Lic81aaaa2017-10-16 12:24:43 -0400830 s := &specs.TaskSpec{
Yuqian Li4a577af2018-01-05 11:13:43 -0500831 Dependencies: []string{compileTaskName, compileParentName},
Yuqian Lic81aaaa2017-10-16 12:24:43 -0400832 CipdPackages: []*specs.CipdPackage{b.MustGetCipdPackageFromAsset("clang_linux")},
Eric Boren9d78afd2017-12-07 14:54:05 +0000833 Dimensions: swarmDimensions(parts),
834 ExtraArgs: []string{
835 "--workdir", "../../..", "calmbench",
Yuqian Lic81aaaa2017-10-16 12:24:43 -0400836 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
837 fmt.Sprintf("buildername=%s", name),
838 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
839 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
840 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
841 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
842 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
843 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
844 },
Yuqian Li4a577af2018-01-05 11:13:43 -0500845 Isolate: relpath("calmbench.isolate"),
Eric Boren9d78afd2017-12-07 14:54:05 +0000846 Priority: 0.8,
Yuqian Lic81aaaa2017-10-16 12:24:43 -0400847 }
848
849 s.Dependencies = append(s.Dependencies, ISOLATE_SKP_NAME, ISOLATE_SVG_NAME)
850
851 b.MustAddTask(name, s)
852
Yuqian Li2ebf3d12017-10-24 09:43:21 -0400853 // Upload results if necessary.
854 if strings.Contains(name, "Release") && doUpload(name) {
855 uploadName := fmt.Sprintf("%s%s%s", PREFIX_UPLOAD, jobNameSchema.Sep, name)
856 b.MustAddTask(uploadName, &specs.TaskSpec{
Eric Boren9d78afd2017-12-07 14:54:05 +0000857 Dependencies: []string{name},
858 Dimensions: linuxGceDimensions(),
859 ExtraArgs: []string{
860 "--workdir", "../../..", "upload_calmbench_results",
Yuqian Li2ebf3d12017-10-24 09:43:21 -0400861 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
862 fmt.Sprintf("buildername=%s", name),
863 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
864 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
865 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
866 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
867 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
868 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
869 fmt.Sprintf("gs_bucket=%s", CONFIG.GsBucketCalm),
870 },
Eric Boren9d78afd2017-12-07 14:54:05 +0000871 // We're using the same isolate as upload_nano_results
872 Isolate: relpath("upload_nano_results.isolate"),
873 Priority: 0.8,
Yuqian Li2ebf3d12017-10-24 09:43:21 -0400874 })
875 return uploadName
876 }
877
Yuqian Lic81aaaa2017-10-16 12:24:43 -0400878 return name
879}
880
borenetdb182c72016-09-30 12:53:12 -0700881// doUpload indicates whether the given Job should upload its results.
882func doUpload(name string) bool {
Eric Boren27225492017-02-01 15:56:55 -0500883 for _, s := range CONFIG.NoUpload {
884 m, err := regexp.MatchString(s, name)
885 if err != nil {
886 glog.Fatal(err)
887 }
888 if m {
borenetdb182c72016-09-30 12:53:12 -0700889 return false
890 }
891 }
892 return true
893}
894
895// test generates a Test task. Returns the name of the last task in the
896// generated chain of tasks, which the Job should add as a dependency.
boreneted20a702016-10-20 11:04:31 -0700897func test(b *specs.TasksCfgBuilder, name string, parts map[string]string, compileTaskName string, pkgs []*specs.CipdPackage) string {
Kevin Lubick4f0f9332018-01-12 14:31:48 -0500898 deps := []string{compileTaskName}
899 if strings.Contains(name, "Android_ASAN") {
900 deps = append(deps, isolateCIPDAsset(b, ISOLATE_NDK_LINUX_NAME))
901 }
902
Eric Boren4b254b92016-11-08 12:55:32 -0500903 s := &specs.TaskSpec{
Eric Boren9d78afd2017-12-07 14:54:05 +0000904 CipdPackages: pkgs,
Kevin Lubick4f0f9332018-01-12 14:31:48 -0500905 Dependencies: deps,
Eric Boren9d78afd2017-12-07 14:54:05 +0000906 Dimensions: swarmDimensions(parts),
907 ExecutionTimeout: 4 * time.Hour,
908 Expiration: 20 * time.Hour,
909 ExtraArgs: []string{
910 "--workdir", "../../..", "test",
skia.buildbots2478c732016-11-04 14:37:26 -0400911 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
Eric Boren9a9e3872017-11-29 12:33:22 -0500912 fmt.Sprintf("buildbucket_build_id=%s", specs.PLACEHOLDER_BUILDBUCKET_BUILD_ID),
borenetdb182c72016-09-30 12:53:12 -0700913 fmt.Sprintf("buildername=%s", name),
borenetdb182c72016-09-30 12:53:12 -0700914 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
915 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
Eric Boren09419502017-04-21 09:37:37 -0400916 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
borenet98b2e7a2016-10-13 06:23:45 -0700917 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
skia.buildbots2478c732016-11-04 14:37:26 -0400918 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
919 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
borenetdb182c72016-09-30 12:53:12 -0700920 },
Eric Boren9d78afd2017-12-07 14:54:05 +0000921 IoTimeout: 40 * time.Minute,
922 Isolate: relpath("test_skia.isolate"),
923 MaxAttempts: 1,
924 Priority: 0.8,
925 }
926 if useBundledRecipes(parts) {
927 s.Dependencies = append(s.Dependencies, BUNDLE_RECIPES_NAME)
928 if strings.Contains(parts["os"], "Win") {
929 s.Isolate = relpath("test_skia_bundled_win.isolate")
930 } else {
931 s.Isolate = relpath("test_skia_bundled_unix.isolate")
932 }
Eric Boren8b3f9e62017-04-04 09:06:16 -0400933 }
Kevin Lubick90189522017-05-15 08:30:27 -0400934 if deps := getIsolatedCIPDDeps(parts); len(deps) > 0 {
935 s.Dependencies = append(s.Dependencies, deps...)
Kevin Lubick07072942017-05-11 13:35:23 -0400936 }
Eric Boren4b254b92016-11-08 12:55:32 -0500937 if strings.Contains(parts["extra_config"], "Valgrind") {
938 s.ExecutionTimeout = 9 * time.Hour
939 s.Expiration = 48 * time.Hour
940 s.IoTimeout = time.Hour
Eric Borend696df72017-05-31 15:09:10 -0400941 s.CipdPackages = append(s.CipdPackages, b.MustGetCipdPackageFromAsset("valgrind"))
Kevin Lubickea613822017-12-04 10:20:23 -0500942 s.Dimensions = append(s.Dimensions, "valgrind:1")
Eric Boren4b254b92016-11-08 12:55:32 -0500943 } else if strings.Contains(parts["extra_config"], "MSAN") {
944 s.ExecutionTimeout = 9 * time.Hour
Ben Wagnera6b2ba22017-06-08 10:34:17 -0400945 } else if parts["arch"] == "x86" && parts["configuration"] == "Debug" {
946 // skia:6737
947 s.ExecutionTimeout = 6 * time.Hour
Eric Boren4b254b92016-11-08 12:55:32 -0500948 }
Eric Borenfd4d60e2017-09-15 10:35:44 -0400949 iid := internalHardwareLabel(parts)
Eric Boren053d7a42017-09-15 08:35:31 -0400950 if iid != nil {
Eric Boren4dc4aaf2017-09-15 14:09:07 -0400951 s.ExtraArgs = append(s.ExtraArgs, fmt.Sprintf("internal_hardware_label=%d", *iid))
Eric Boren053d7a42017-09-15 08:35:31 -0400952 }
Eric Boren4b254b92016-11-08 12:55:32 -0500953 b.MustAddTask(name, s)
954
Kevin Lubickc795a4c2017-10-09 15:26:19 -0400955 // Upload results if necessary. TODO(kjlubick): If we do coverage analysis at the same
956 // time as normal tests (which would be nice), cfg.json needs to have Coverage removed.
borenetdb182c72016-09-30 12:53:12 -0700957 if doUpload(name) {
958 uploadName := fmt.Sprintf("%s%s%s", PREFIX_UPLOAD, jobNameSchema.Sep, name)
boreneted20a702016-10-20 11:04:31 -0700959 b.MustAddTask(uploadName, &specs.TaskSpec{
Eric Boren9d78afd2017-12-07 14:54:05 +0000960 Dependencies: []string{name},
961 Dimensions: linuxGceDimensions(),
962 ExtraArgs: []string{
963 "--workdir", "../../..", "upload_dm_results",
skia.buildbots2478c732016-11-04 14:37:26 -0400964 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
borenetdb182c72016-09-30 12:53:12 -0700965 fmt.Sprintf("buildername=%s", name),
borenetdb182c72016-09-30 12:53:12 -0700966 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
967 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
Eric Boren09419502017-04-21 09:37:37 -0400968 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
borenet98b2e7a2016-10-13 06:23:45 -0700969 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
skia.buildbots2478c732016-11-04 14:37:26 -0400970 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
971 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
Eric Boren965861b2017-02-06 15:38:41 -0500972 fmt.Sprintf("gs_bucket=%s", CONFIG.GsBucketGm),
borenetdb182c72016-09-30 12:53:12 -0700973 },
Eric Boren9d78afd2017-12-07 14:54:05 +0000974 Isolate: relpath("upload_dm_results.isolate"),
975 Priority: 0.8,
boreneted20a702016-10-20 11:04:31 -0700976 })
borenetdb182c72016-09-30 12:53:12 -0700977 return uploadName
Kevin Lubick32f318b2017-10-17 13:40:52 -0400978 }
979
980 return name
981}
982
983func coverage(b *specs.TasksCfgBuilder, name string, parts map[string]string, compileTaskName string, pkgs []*specs.CipdPackage) string {
984 shards := 1
985 deps := []string{}
986
987 tf := parts["test_filter"]
988 if strings.Contains(tf, "Shard") {
989 // Expected Shard_NN
990 shardstr := strings.Split(tf, "_")[1]
991 var err error
992 shards, err = strconv.Atoi(shardstr)
993 if err != nil {
994 glog.Fatalf("Expected int for number of shards %q in %s: %s", shardstr, name, err)
995 }
996 }
997 for i := 0; i < shards; i++ {
998 n := strings.Replace(name, tf, fmt.Sprintf("shard_%02d_%02d", i, shards), 1)
999 s := &specs.TaskSpec{
Eric Boren9d78afd2017-12-07 14:54:05 +00001000 CipdPackages: pkgs,
1001 Dependencies: []string{compileTaskName},
1002 Dimensions: swarmDimensions(parts),
1003 ExecutionTimeout: 4 * time.Hour,
1004 Expiration: 20 * time.Hour,
1005 ExtraArgs: []string{
1006 "--workdir", "../../..", "test",
Kevin Lubickc795a4c2017-10-09 15:26:19 -04001007 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
Kevin Lubick32f318b2017-10-17 13:40:52 -04001008 fmt.Sprintf("buildername=%s", n),
Kevin Lubickc795a4c2017-10-09 15:26:19 -04001009 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
1010 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
1011 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
1012 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
1013 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
1014 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
Kevin Lubickc795a4c2017-10-09 15:26:19 -04001015 },
Eric Boren9d78afd2017-12-07 14:54:05 +00001016 IoTimeout: 40 * time.Minute,
1017 Isolate: relpath("test_skia.isolate"),
1018 MaxAttempts: 1,
1019 Priority: 0.8,
1020 }
1021 if useBundledRecipes(parts) {
1022 s.Dependencies = append(s.Dependencies, BUNDLE_RECIPES_NAME)
1023 if strings.Contains(parts["os"], "Win") {
1024 s.Isolate = relpath("test_skia_bundled_win.isolate")
1025 } else {
1026 s.Isolate = relpath("test_skia_bundled_unix.isolate")
1027 }
Kevin Lubick32f318b2017-10-17 13:40:52 -04001028 }
1029 if deps := getIsolatedCIPDDeps(parts); len(deps) > 0 {
1030 s.Dependencies = append(s.Dependencies, deps...)
1031 }
1032 b.MustAddTask(n, s)
1033 deps = append(deps, n)
borenetdb182c72016-09-30 12:53:12 -07001034 }
Kevin Lubickc795a4c2017-10-09 15:26:19 -04001035
Kevin Lubick32f318b2017-10-17 13:40:52 -04001036 uploadName := fmt.Sprintf("%s%s%s", "Upload", jobNameSchema.Sep, name)
1037 // We need clang_linux to get access to the llvm-profdata and llvm-cov binaries
1038 // which are used to deal with the raw coverage data output by the Test step.
1039 pkgs = append([]*specs.CipdPackage{}, b.MustGetCipdPackageFromAsset("clang_linux"))
1040 deps = append(deps, compileTaskName)
1041
1042 b.MustAddTask(uploadName, &specs.TaskSpec{
1043 // A dependency on compileTaskName makes the TaskScheduler link the
1044 // isolated output of the compile step to the input of the upload step,
1045 // which gives us access to the instrumented binary. The binary is
1046 // needed to figure out symbol names and line numbers.
1047 Dependencies: deps,
1048 Dimensions: linuxGceDimensions(),
1049 CipdPackages: pkgs,
Eric Boren9d78afd2017-12-07 14:54:05 +00001050 ExtraArgs: []string{
1051 "--workdir", "../../..", "upload_coverage_results",
Kevin Lubick32f318b2017-10-17 13:40:52 -04001052 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
1053 fmt.Sprintf("buildername=%s", name),
1054 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
1055 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
1056 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
1057 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
1058 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
1059 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
1060 fmt.Sprintf("gs_bucket=%s", CONFIG.GsBucketCoverage),
1061 },
Eric Boren9d78afd2017-12-07 14:54:05 +00001062 Isolate: relpath("upload_coverage_results.isolate"),
Kevin Lubick32f318b2017-10-17 13:40:52 -04001063 Priority: 0.8,
1064 })
1065 return uploadName
borenetdb182c72016-09-30 12:53:12 -07001066}
1067
1068// perf generates a Perf task. Returns the name of the last task in the
1069// generated chain of tasks, which the Job should add as a dependency.
boreneted20a702016-10-20 11:04:31 -07001070func perf(b *specs.TasksCfgBuilder, name string, parts map[string]string, compileTaskName string, pkgs []*specs.CipdPackage) string {
Eric Boren768f52f2017-04-10 08:14:33 -04001071 recipe := "perf"
Eric Boren9d78afd2017-12-07 14:54:05 +00001072 isolate := relpath("perf_skia.isolate")
Kevin Lubickb03b5ac2016-11-14 13:42:27 -05001073 if strings.Contains(parts["extra_config"], "Skpbench") {
Eric Boren768f52f2017-04-10 08:14:33 -04001074 recipe = "skpbench"
Eric Boren9d78afd2017-12-07 14:54:05 +00001075 isolate = relpath("skpbench_skia.isolate")
1076 if useBundledRecipes(parts) {
1077 if strings.Contains(parts["os"], "Win") {
1078 isolate = relpath("skpbench_skia_bundled_win.isolate")
1079 } else {
1080 isolate = relpath("skpbench_skia_bundled_unix.isolate")
1081 }
1082 }
1083 } else if useBundledRecipes(parts) {
1084 if strings.Contains(parts["os"], "Win") {
1085 isolate = relpath("perf_skia_bundled_win.isolate")
1086 } else {
1087 isolate = relpath("perf_skia_bundled_unix.isolate")
1088 }
Kevin Lubickb03b5ac2016-11-14 13:42:27 -05001089 }
Eric Boren4b254b92016-11-08 12:55:32 -05001090 s := &specs.TaskSpec{
Eric Boren9d78afd2017-12-07 14:54:05 +00001091 CipdPackages: pkgs,
1092 Dependencies: []string{compileTaskName},
1093 Dimensions: swarmDimensions(parts),
1094 ExecutionTimeout: 4 * time.Hour,
1095 Expiration: 20 * time.Hour,
1096 ExtraArgs: []string{
1097 "--workdir", "../../..", recipe,
skia.buildbots2478c732016-11-04 14:37:26 -04001098 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
borenetdb182c72016-09-30 12:53:12 -07001099 fmt.Sprintf("buildername=%s", name),
borenetdb182c72016-09-30 12:53:12 -07001100 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
1101 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
Eric Boren09419502017-04-21 09:37:37 -04001102 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
borenet98b2e7a2016-10-13 06:23:45 -07001103 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
skia.buildbots2478c732016-11-04 14:37:26 -04001104 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
1105 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
borenetdb182c72016-09-30 12:53:12 -07001106 },
Eric Boren9d78afd2017-12-07 14:54:05 +00001107 IoTimeout: 40 * time.Minute,
1108 Isolate: isolate,
1109 MaxAttempts: 1,
1110 Priority: 0.8,
1111 }
1112 if useBundledRecipes(parts) {
1113 s.Dependencies = append(s.Dependencies, BUNDLE_RECIPES_NAME)
Eric Boren8b3f9e62017-04-04 09:06:16 -04001114 }
Kevin Lubick90189522017-05-15 08:30:27 -04001115 if deps := getIsolatedCIPDDeps(parts); len(deps) > 0 {
1116 s.Dependencies = append(s.Dependencies, deps...)
1117 }
1118
Eric Boren4b254b92016-11-08 12:55:32 -05001119 if strings.Contains(parts["extra_config"], "Valgrind") {
1120 s.ExecutionTimeout = 9 * time.Hour
1121 s.Expiration = 48 * time.Hour
1122 s.IoTimeout = time.Hour
Eric Borenc5a073d2017-06-01 07:13:33 -04001123 s.CipdPackages = append(s.CipdPackages, b.MustGetCipdPackageFromAsset("valgrind"))
Kevin Lubickea613822017-12-04 10:20:23 -05001124 s.Dimensions = append(s.Dimensions, "valgrind:1")
Eric Boren4b254b92016-11-08 12:55:32 -05001125 } else if strings.Contains(parts["extra_config"], "MSAN") {
1126 s.ExecutionTimeout = 9 * time.Hour
Ben Wagnera6b2ba22017-06-08 10:34:17 -04001127 } else if parts["arch"] == "x86" && parts["configuration"] == "Debug" {
1128 // skia:6737
1129 s.ExecutionTimeout = 6 * time.Hour
Eric Boren4b254b92016-11-08 12:55:32 -05001130 }
Eric Borenfd4d60e2017-09-15 10:35:44 -04001131 iid := internalHardwareLabel(parts)
Eric Boren053d7a42017-09-15 08:35:31 -04001132 if iid != nil {
Eric Boren4dc4aaf2017-09-15 14:09:07 -04001133 s.ExtraArgs = append(s.ExtraArgs, fmt.Sprintf("internal_hardware_label=%d", *iid))
Eric Boren053d7a42017-09-15 08:35:31 -04001134 }
Eric Boren4b254b92016-11-08 12:55:32 -05001135 b.MustAddTask(name, s)
1136
borenetdb182c72016-09-30 12:53:12 -07001137 // Upload results if necessary.
1138 if strings.Contains(name, "Release") && doUpload(name) {
1139 uploadName := fmt.Sprintf("%s%s%s", PREFIX_UPLOAD, jobNameSchema.Sep, name)
boreneted20a702016-10-20 11:04:31 -07001140 b.MustAddTask(uploadName, &specs.TaskSpec{
Eric Boren9d78afd2017-12-07 14:54:05 +00001141 Dependencies: []string{name},
1142 Dimensions: linuxGceDimensions(),
1143 ExtraArgs: []string{
1144 "--workdir", "../../..", "upload_nano_results",
skia.buildbots2478c732016-11-04 14:37:26 -04001145 fmt.Sprintf("repository=%s", specs.PLACEHOLDER_REPO),
borenetdb182c72016-09-30 12:53:12 -07001146 fmt.Sprintf("buildername=%s", name),
borenetdb182c72016-09-30 12:53:12 -07001147 fmt.Sprintf("swarm_out_dir=%s", specs.PLACEHOLDER_ISOLATED_OUTDIR),
1148 fmt.Sprintf("revision=%s", specs.PLACEHOLDER_REVISION),
Eric Boren09419502017-04-21 09:37:37 -04001149 fmt.Sprintf("patch_repo=%s", specs.PLACEHOLDER_PATCH_REPO),
borenet98b2e7a2016-10-13 06:23:45 -07001150 fmt.Sprintf("patch_storage=%s", specs.PLACEHOLDER_PATCH_STORAGE),
skia.buildbots2478c732016-11-04 14:37:26 -04001151 fmt.Sprintf("patch_issue=%s", specs.PLACEHOLDER_ISSUE),
1152 fmt.Sprintf("patch_set=%s", specs.PLACEHOLDER_PATCHSET),
Eric Boren965861b2017-02-06 15:38:41 -05001153 fmt.Sprintf("gs_bucket=%s", CONFIG.GsBucketNano),
borenetdb182c72016-09-30 12:53:12 -07001154 },
Eric Boren9d78afd2017-12-07 14:54:05 +00001155 Isolate: relpath("upload_nano_results.isolate"),
1156 Priority: 0.8,
boreneted20a702016-10-20 11:04:31 -07001157 })
borenetdb182c72016-09-30 12:53:12 -07001158 return uploadName
1159 }
1160 return name
1161}
1162
1163// process generates tasks and jobs for the given job name.
boreneted20a702016-10-20 11:04:31 -07001164func process(b *specs.TasksCfgBuilder, name string) {
borenetdb182c72016-09-30 12:53:12 -07001165 deps := []string{}
1166
Eric Boren8b3f9e62017-04-04 09:06:16 -04001167 // Bundle Recipes.
1168 if name == BUNDLE_RECIPES_NAME {
1169 deps = append(deps, bundleRecipes(b))
1170 }
1171
Kevin Lubick07072942017-05-11 13:35:23 -04001172 // Isolate CIPD assets.
Kevin Lubick07072942017-05-11 13:35:23 -04001173 if _, ok := ISOLATE_ASSET_MAPPING[name]; ok {
1174 deps = append(deps, isolateCIPDAsset(b, name))
1175 }
1176
borenetdb182c72016-09-30 12:53:12 -07001177 parts, err := jobNameSchema.ParseJobName(name)
1178 if err != nil {
1179 glog.Fatal(err)
1180 }
1181
1182 // RecreateSKPs.
1183 if strings.Contains(name, "RecreateSKPs") {
Eric Boren9d78afd2017-12-07 14:54:05 +00001184 deps = append(deps, recreateSKPs(b, name))
borenetdb182c72016-09-30 12:53:12 -07001185 }
1186
Ravi Mistry01b48e72017-05-17 14:28:06 -04001187 // UpdateMetaConfig bot.
1188 if strings.Contains(name, "UpdateMetaConfig") {
Eric Boren9d78afd2017-12-07 14:54:05 +00001189 deps = append(deps, updateMetaConfig(b, name))
Ravi Mistry01b48e72017-05-17 14:28:06 -04001190 }
1191
borenetdb182c72016-09-30 12:53:12 -07001192 // CT bots.
1193 if strings.Contains(name, "-CT_") {
Eric Boren9d78afd2017-12-07 14:54:05 +00001194 deps = append(deps, ctSKPs(b, name))
borenetdb182c72016-09-30 12:53:12 -07001195 }
1196
borenet2dbbfa52016-10-14 06:32:09 -07001197 // Infra tests.
1198 if name == "Housekeeper-PerCommit-InfraTests" {
Eric Boren9d78afd2017-12-07 14:54:05 +00001199 deps = append(deps, infra(b, name))
borenet2dbbfa52016-10-14 06:32:09 -07001200 }
1201
borenetdb182c72016-09-30 12:53:12 -07001202 // Compile bots.
1203 if parts["role"] == "Build" {
Ravi Mistry5e967422018-02-01 13:38:13 -05001204 if parts["extra_config"] == "Android_Framework" {
1205 // Android Framework compile tasks use a different recipe.
1206 deps = append(deps, androidFrameworkCompile(b, name))
1207 } else {
1208 deps = append(deps, compile(b, name, parts))
1209 }
borenetdb182c72016-09-30 12:53:12 -07001210 }
1211
Eric Borenf5a90e82016-11-15 15:18:20 -05001212 // Most remaining bots need a compile task.
borenetdb182c72016-09-30 12:53:12 -07001213 compileTaskName := deriveCompileTaskName(name, parts)
borenet52383432016-10-17 10:17:53 -07001214 compileTaskParts, err := jobNameSchema.ParseJobName(compileTaskName)
1215 if err != nil {
1216 glog.Fatal(err)
1217 }
Yuqian Li4a577af2018-01-05 11:13:43 -05001218 compileParentName := getParentRevisionName(compileTaskName, compileTaskParts)
1219 compileParentParts, err := jobNameSchema.ParseJobName(compileParentName)
1220 if err != nil {
1221 glog.Fatal(err)
1222 }
1223
Eric Boren628e78b2016-11-17 11:33:27 -05001224 // These bots do not need a compile task.
Yuqian Li4a577af2018-01-05 11:13:43 -05001225 if parts["role"] != "Build" &&
Eric Borenb8ab7f72017-04-10 11:00:09 -04001226 name != "Housekeeper-PerCommit-BundleRecipes" &&
Eric Borenf5a90e82016-11-15 15:18:20 -05001227 name != "Housekeeper-PerCommit-InfraTests" &&
Eric Borenf7928b42017-07-28 07:35:28 -04001228 name != "Housekeeper-PerCommit-CheckGeneratedFiles" &&
Ravi Mistry5e967422018-02-01 13:38:13 -05001229 !strings.Contains(name, "Android_Framework") &&
Eric Boren71b762f2016-11-30 14:05:16 -05001230 !strings.Contains(name, "RecreateSKPs") &&
Ravi Mistry01b48e72017-05-17 14:28:06 -04001231 !strings.Contains(name, "UpdateMetaConfig") &&
Ben Wagner50b84682017-06-12 13:03:29 -04001232 !strings.Contains(name, "-CT_") &&
1233 !strings.Contains(name, "Housekeeper-PerCommit-Isolate") {
boreneted20a702016-10-20 11:04:31 -07001234 compile(b, compileTaskName, compileTaskParts)
Ben Wagner4c39c0d2018-01-10 11:14:52 -05001235 if parts["role"] == "Calmbench" {
Yuqian Li4a577af2018-01-05 11:13:43 -05001236 compile(b, compileParentName, compileParentParts)
1237 }
borenet52383432016-10-17 10:17:53 -07001238 }
borenetdb182c72016-09-30 12:53:12 -07001239
Eric Borenf7928b42017-07-28 07:35:28 -04001240 // Housekeepers.
Eric Boren22f5ef72016-12-02 11:01:33 -05001241 if name == "Housekeeper-PerCommit" {
Eric Boren9d78afd2017-12-07 14:54:05 +00001242 deps = append(deps, housekeeper(b, name, compileTaskName))
borenetdb182c72016-09-30 12:53:12 -07001243 }
Eric Borenf7928b42017-07-28 07:35:28 -04001244 if name == "Housekeeper-PerCommit-CheckGeneratedFiles" {
Eric Boren9d78afd2017-12-07 14:54:05 +00001245 deps = append(deps, checkGeneratedFiles(b, name))
Eric Borenf7928b42017-07-28 07:35:28 -04001246 }
Ravi Mistryd4731e92018-01-02 14:54:43 -05001247 if strings.Contains(name, "Bookmaker") {
Ravi Mistryedc4f3e2017-12-08 12:58:20 -05001248 deps = append(deps, bookmaker(b, name, compileTaskName))
1249 }
borenetdb182c72016-09-30 12:53:12 -07001250
1251 // Common assets needed by the remaining bots.
Kevin Lubick07072942017-05-11 13:35:23 -04001252
1253 pkgs := []*specs.CipdPackage{}
1254
Kevin Lubick90189522017-05-15 08:30:27 -04001255 if deps := getIsolatedCIPDDeps(parts); len(deps) == 0 {
Kevin Lubick07072942017-05-11 13:35:23 -04001256 pkgs = []*specs.CipdPackage{
1257 b.MustGetCipdPackageFromAsset("skimage"),
1258 b.MustGetCipdPackageFromAsset("skp"),
1259 b.MustGetCipdPackageFromAsset("svg"),
1260 }
borenetdb182c72016-09-30 12:53:12 -07001261 }
Kevin Lubick90189522017-05-15 08:30:27 -04001262
Ben Wagner5655ba42017-10-02 10:48:32 -04001263 if strings.Contains(name, "Ubuntu") || strings.Contains(name, "Debian") {
1264 if strings.Contains(name, "SAN") {
1265 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("clang_linux"))
1266 }
Kevin Lubick35115eb2017-02-17 10:25:34 -05001267 if strings.Contains(name, "Vulkan") {
1268 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("linux_vulkan_sdk"))
1269 }
Ben Wagner5655ba42017-10-02 10:48:32 -04001270 if strings.Contains(name, "Intel") && strings.Contains(name, "GPU") {
1271 if strings.Contains(name, "Release") {
1272 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("linux_vulkan_intel_driver_release"))
1273 } else {
1274 pkgs = append(pkgs, b.MustGetCipdPackageFromAsset("linux_vulkan_intel_driver_debug"))
1275 }
Kevin Lubick0a51b482017-02-06 12:45:29 -05001276 }
1277 }
borenetdb182c72016-09-30 12:53:12 -07001278
1279 // Test bots.
Kevin Lubick32f318b2017-10-17 13:40:52 -04001280
1281 if parts["role"] == "Test" {
1282 if strings.Contains(parts["extra_config"], "Coverage") {
1283 deps = append(deps, coverage(b, name, parts, compileTaskName, pkgs))
1284 } else if !strings.Contains(name, "-CT_") {
1285 deps = append(deps, test(b, name, parts, compileTaskName, pkgs))
1286 }
1287
borenetdb182c72016-09-30 12:53:12 -07001288 }
1289
1290 // Perf bots.
Eric Boren71b762f2016-11-30 14:05:16 -05001291 if parts["role"] == "Perf" && !strings.Contains(name, "-CT_") {
boreneted20a702016-10-20 11:04:31 -07001292 deps = append(deps, perf(b, name, parts, compileTaskName, pkgs))
borenetdb182c72016-09-30 12:53:12 -07001293 }
1294
Yuqian Li4a577af2018-01-05 11:13:43 -05001295 // Calmbench bots.
1296 if parts["role"] == "Calmbench" {
1297 deps = append(deps, calmbench(b, name, parts, compileTaskName, compileParentName))
1298 }
1299
borenetdb182c72016-09-30 12:53:12 -07001300 // Add the Job spec.
Eric Borenf5a90e82016-11-15 15:18:20 -05001301 j := &specs.JobSpec{
borenetdb182c72016-09-30 12:53:12 -07001302 Priority: 0.8,
1303 TaskSpecs: deps,
Eric Borenba937a42017-07-31 10:41:15 -04001304 Trigger: specs.TRIGGER_ANY_BRANCH,
Eric Borenf5a90e82016-11-15 15:18:20 -05001305 }
Eric Borenba937a42017-07-31 10:41:15 -04001306 if strings.Contains(name, "-Nightly-") {
1307 j.Trigger = specs.TRIGGER_NIGHTLY
Ravi Mistryf06dae82017-10-16 10:31:41 -04001308 } else if strings.Contains(name, "-Weekly-") || strings.Contains(name, "CT_DM_1m_SKPs") {
Eric Borenba937a42017-07-31 10:41:15 -04001309 j.Trigger = specs.TRIGGER_WEEKLY
1310 } else if strings.Contains(name, "Flutter") || strings.Contains(name, "PDFium") || strings.Contains(name, "CommandBuffer") {
1311 j.Trigger = specs.TRIGGER_MASTER_ONLY
Eric Boren71b762f2016-11-30 14:05:16 -05001312 }
Eric Boren8615fe52016-12-12 14:30:12 -05001313 b.MustAddJob(name, j)
borenetdb182c72016-09-30 12:53:12 -07001314}
1315
Eric Boren27225492017-02-01 15:56:55 -05001316func loadJson(flag *string, defaultFlag string, val interface{}) {
1317 if *flag == "" {
1318 *flag = defaultFlag
1319 }
1320 b, err := ioutil.ReadFile(*flag)
1321 if err != nil {
1322 glog.Fatal(err)
1323 }
1324 if err := json.Unmarshal(b, val); err != nil {
1325 glog.Fatal(err)
1326 }
1327}
1328
borenetdb182c72016-09-30 12:53:12 -07001329// Regenerate the tasks.json file.
1330func main() {
boreneted20a702016-10-20 11:04:31 -07001331 b := specs.MustNewTasksCfgBuilder()
Eric Boren27225492017-02-01 15:56:55 -05001332 b.SetAssetsDir(*assetsDir)
1333 infraBots := path.Join(b.CheckoutRoot(), "infra", "bots")
1334
1335 // Load the jobs from a JSON file.
1336 loadJson(jobsFile, path.Join(infraBots, "jobs.json"), &JOBS)
1337
Eric Boren27225492017-02-01 15:56:55 -05001338 // Load general config information from a JSON file.
1339 loadJson(cfgFile, path.Join(infraBots, "cfg.json"), &CONFIG)
1340
borenetdb182c72016-09-30 12:53:12 -07001341 // Create the JobNameSchema.
Eric Boren1f8be682017-02-07 09:16:30 -05001342 if *builderNameSchemaFile == "" {
1343 *builderNameSchemaFile = path.Join(b.CheckoutRoot(), "infra", "bots", "recipe_modules", "builder_name_schema", "builder_name_schema.json")
1344 }
1345 schema, err := NewJobNameSchema(*builderNameSchemaFile)
borenetdb182c72016-09-30 12:53:12 -07001346 if err != nil {
1347 glog.Fatal(err)
1348 }
1349 jobNameSchema = schema
1350
borenetdb182c72016-09-30 12:53:12 -07001351 // Create Tasks and Jobs.
boreneted20a702016-10-20 11:04:31 -07001352 for _, name := range JOBS {
1353 process(b, name)
borenetdb182c72016-09-30 12:53:12 -07001354 }
1355
boreneted20a702016-10-20 11:04:31 -07001356 b.MustFinish()
borenetdb182c72016-09-30 12:53:12 -07001357}
1358
1359// TODO(borenet): The below really belongs in its own file, probably next to the
1360// builder_name_schema.json file.
1361
1362// JobNameSchema is a struct used for (de)constructing Job names in a
1363// predictable format.
1364type JobNameSchema struct {
1365 Schema map[string][]string `json:"builder_name_schema"`
1366 Sep string `json:"builder_name_sep"`
1367}
1368
1369// NewJobNameSchema returns a JobNameSchema instance based on the given JSON
1370// file.
1371func NewJobNameSchema(jsonFile string) (*JobNameSchema, error) {
1372 var rv JobNameSchema
1373 f, err := os.Open(jsonFile)
1374 if err != nil {
1375 return nil, err
1376 }
1377 defer util.Close(f)
1378 if err := json.NewDecoder(f).Decode(&rv); err != nil {
1379 return nil, err
1380 }
1381 return &rv, nil
1382}
1383
1384// ParseJobName splits the given Job name into its component parts, according
1385// to the schema.
1386func (s *JobNameSchema) ParseJobName(n string) (map[string]string, error) {
1387 split := strings.Split(n, s.Sep)
1388 if len(split) < 2 {
1389 return nil, fmt.Errorf("Invalid job name: %q", n)
1390 }
1391 role := split[0]
1392 split = split[1:]
1393 keys, ok := s.Schema[role]
1394 if !ok {
1395 return nil, fmt.Errorf("Invalid job name; %q is not a valid role.", role)
1396 }
1397 extraConfig := ""
1398 if len(split) == len(keys)+1 {
1399 extraConfig = split[len(split)-1]
1400 split = split[:len(split)-1]
1401 }
1402 if len(split) != len(keys) {
1403 return nil, fmt.Errorf("Invalid job name; %q has incorrect number of parts.", n)
1404 }
1405 rv := make(map[string]string, len(keys)+2)
1406 rv["role"] = role
1407 if extraConfig != "" {
1408 rv["extra_config"] = extraConfig
1409 }
1410 for i, k := range keys {
1411 rv[k] = split[i]
1412 }
1413 return rv, nil
1414}
1415
1416// MakeJobName assembles the given parts of a Job name, according to the schema.
1417func (s *JobNameSchema) MakeJobName(parts map[string]string) (string, error) {
1418 role, ok := parts["role"]
1419 if !ok {
1420 return "", fmt.Errorf("Invalid job parts; jobs must have a role.")
1421 }
1422 keys, ok := s.Schema[role]
1423 if !ok {
1424 return "", fmt.Errorf("Invalid job parts; unknown role %q", role)
1425 }
1426 rvParts := make([]string, 0, len(parts))
1427 rvParts = append(rvParts, role)
1428 for _, k := range keys {
1429 v, ok := parts[k]
1430 if !ok {
1431 return "", fmt.Errorf("Invalid job parts; missing %q", k)
1432 }
1433 rvParts = append(rvParts, v)
1434 }
1435 if _, ok := parts["extra_config"]; ok {
1436 rvParts = append(rvParts, parts["extra_config"])
1437 }
1438 return strings.Join(rvParts, s.Sep), nil
1439}