Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Side by Side Diff: ct/go/worker_scripts/run_chromium_analysis/main.go

Issue 1995023002: Backend for new run_chromium_analysis CT task (Closed) Base URL: https://skia.googlesource.com/buildbot@ct-7-run_lua
Patch Set: Remove testing code Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Application that captures SKPs from CT's webpage archives. 1 // run_chromium_analysis is an application that runs the specified benchmark ove r
2 // CT's webpage archives. It is intended to be run on swarming bots.
2 package main 3 package main
3 4
4 import ( 5 import (
6 "bytes"
5 "flag" 7 "flag"
6 "fmt"
7 "io/ioutil" 8 "io/ioutil"
8 "os" 9 "os"
9 "path"
10 "path/filepath" 10 "path/filepath"
11 "strconv"
12 "sync" 11 "sync"
13 "time" 12 "time"
14 13
15 "github.com/skia-dev/glog" 14 "github.com/skia-dev/glog"
16 15
16 "strings"
17
17 "go.skia.org/infra/ct/go/util" 18 "go.skia.org/infra/ct/go/util"
18 "go.skia.org/infra/ct/go/worker_scripts/worker_common" 19 "go.skia.org/infra/ct/go/worker_scripts/worker_common"
19 "go.skia.org/infra/go/common" 20 "go.skia.org/infra/go/common"
20 skutil "go.skia.org/infra/go/util" 21 skutil "go.skia.org/infra/go/util"
21 ) 22 )
22 23
23 const ( 24 const (
24 » // The number of goroutines that will run in parallel to capture SKPs. 25 » // The number of goroutines that will run in parallel to run benchmarks.
25 WORKER_POOL_SIZE = 10 26 WORKER_POOL_SIZE = 10
26 ) 27 )
27 28
28 var ( 29 var (
29 » startRange = flag.Int("start_range", 1, "The number this worker will capture SKPs from.") 30 » startRange = flag.Int("start_range", 1, "The number this worker will run benchmarks from.")
30 » num = flag.Int("num", 100, "The total number of SKPs to c apture starting from the start_range.") 31 » num = flag.Int("num", 100, "The total number of benchmark s to run starting from the start_range.")
31 » pagesetType = flag.String("pageset_type", util.PAGESET_TYPE_MOBIL E_10k, "The type of pagesets to create SKPs from. Eg: 10k, Mobile10k, All.") 32 » pagesetType = flag.String("pageset_type", util.PAGESET_TYPE_MOBIL E_10k, "The type of pagesets to create from the Alexa CSV list. Eg: 10k, Mobile1 0k, All.")
dogben 2016/05/19 21:06:41 s/to create from the Alexa CSV list/to analyze/
rmistry 2016/05/20 11:07:16 Done.
32 » chromiumBuild = flag.String("chromium_build", "", "The chromium bui ld that will be used to create the SKPs.") 33 » chromiumBuild = flag.String("chromium_build", "", "The chromium bui ld to use.")
33 runID = flag.String("run_id", "", "The unique run id (typic ally requester + timestamp).") 34 runID = flag.String("run_id", "", "The unique run id (typic ally requester + timestamp).")
34 » targetPlatform = flag.String("target_platform", util.PLATFORM_LINUX, "The platform the benchmark will run on (Android / Linux).") 35 » benchmarkName = flag.String("benchmark_name", "", "The telemetry be nchmark to run on this worker.")
35 » chromeCleanerTimer = flag.Duration("cleaner_timer", 30*time.Minute, "How often all chrome processes will be killed on this slave.") 36 » benchmarkExtraArgs = flag.String("benchmark_extra_args", "", "The extra arguments that are passed to the specified benchmark.")
37 » browserExtraArgs = flag.String("browser_extra_args", "", "The extra ar guments that are passed to the browser while running the benchmark.")
38 » chromeCleanerTimer = flag.Duration("cleaner_timer", 15*time.Minute, "How often all chrome processes will be killed on this slave.")
36 ) 39 )
37 40
38 func main() { 41 func main() {
39 defer common.LogPanic() 42 defer common.LogPanic()
40 worker_common.Init() 43 worker_common.Init()
41 » defer util.TimeTrack(time.Now(), "Capturing SKPs") 44 » defer util.TimeTrack(time.Now(), "Running Chromium Perf")
dogben 2016/05/19 21:06:41 s/Perf/Analysis/
rmistry 2016/05/20 11:07:16 Done.
42 defer glog.Flush() 45 defer glog.Flush()
43 46
44 // Validate required arguments. 47 // Validate required arguments.
45 if *chromiumBuild == "" { 48 if *chromiumBuild == "" {
46 glog.Error("Must specify --chromium_build") 49 glog.Error("Must specify --chromium_build")
47 return 50 return
48 } 51 }
49 if *runID == "" { 52 if *runID == "" {
50 glog.Error("Must specify --run_id") 53 glog.Error("Must specify --run_id")
51 return 54 return
52 } 55 }
53 » if *targetPlatform == util.PLATFORM_ANDROID { 56 » if *benchmarkName == "" {
54 » » glog.Error("Android is not yet supported for capturing SKPs.") 57 » » glog.Error("Must specify --benchmark_name")
55 return 58 return
56 } 59 }
57 60
58 // Reset the local chromium checkout. 61 // Reset the local chromium checkout.
59 if err := util.ResetCheckout(util.ChromiumSrcDir); err != nil { 62 if err := util.ResetCheckout(util.ChromiumSrcDir); err != nil {
60 glog.Errorf("Could not reset %s: %s", util.ChromiumSrcDir, err) 63 glog.Errorf("Could not reset %s: %s", util.ChromiumSrcDir, err)
61 return 64 return
62 } 65 }
63 // Sync the local chromium checkout. 66 // Sync the local chromium checkout.
64 if err := util.SyncDir(util.ChromiumSrcDir); err != nil { 67 if err := util.SyncDir(util.ChromiumSrcDir); err != nil {
65 glog.Errorf("Could not gclient sync %s: %s", util.ChromiumSrcDir , err) 68 glog.Errorf("Could not gclient sync %s: %s", util.ChromiumSrcDir , err)
66 return 69 return
67 } 70 }
68 71
69 // Instantiate GsUtil object. 72 // Instantiate GsUtil object.
70 gs, err := util.NewGsUtil(nil) 73 gs, err := util.NewGsUtil(nil)
71 if err != nil { 74 if err != nil {
72 glog.Error(err) 75 glog.Error(err)
73 return 76 return
74 } 77 }
75 78
79 // Download the benchmark patch for this run from Google storage.
80 benchmarkPatchName := *runID + ".benchmark.patch"
81 benchmarkPatchLocalPath := filepath.Join(os.TempDir(), benchmarkPatchNam e)
dogben 2016/05/19 21:06:41 nit: ioutil.TempDir or ioutil.TempFile
rmistry 2016/05/20 11:07:16 Done.
82 remotePatchesDir := filepath.Join(util.ChromiumPerfRunsDir, *runID)
83 benchmarkPatchRemotePath := filepath.Join(remotePatchesDir, benchmarkPat chName)
84 respBody, err := gs.GetRemoteFileContents(benchmarkPatchRemotePath)
85 if err != nil {
86 glog.Errorf("Could not fetch %s: %s", benchmarkPatchRemotePath, err)
87 return
88 }
89 defer skutil.Close(respBody)
90 buf := new(bytes.Buffer)
91 if _, err := buf.ReadFrom(respBody); err != nil {
92 glog.Errorf("Could not read from %s: %s", benchmarkPatchRemotePa th, err)
93 return
94 }
95 if err := ioutil.WriteFile(benchmarkPatchLocalPath, buf.Bytes(), 0666); err != nil {
dogben 2016/05/19 21:06:41 nit: os.Create + io.Copy is probably slightly bett
rmistry 2016/05/20 11:07:16 This is also how the poller creates local patches,
96 glog.Errorf("Unable to create file %s: %s", benchmarkPatchLocalP ath, err)
97 return
98 }
99 defer skutil.Remove(benchmarkPatchLocalPath)
100 // Apply benchmark patch to the local chromium checkout.
101 if buf.Len() > 10 {
dogben 2016/05/19 21:06:41 (io.Copy returns the number of bytes copied)
rmistry 2016/05/20 11:07:16 Acknowledged.
102 if err := util.ApplyPatch(benchmarkPatchLocalPath, util.Chromium SrcDir); err != nil {
103 glog.Errorf("Could not apply Telemetry's patch in %s: %s ", util.ChromiumSrcDir, err)
104 return
105 }
106 }
107
76 // Download the specified chromium build. 108 // Download the specified chromium build.
77 if err := gs.DownloadChromiumBuild(*chromiumBuild); err != nil { 109 if err := gs.DownloadChromiumBuild(*chromiumBuild); err != nil {
78 glog.Error(err) 110 glog.Error(err)
79 return 111 return
80 } 112 }
81 » // Delete the chromium build to save space when we are done. 113 » //Delete the chromium build to save space when we are done.
82 defer skutil.RemoveAll(filepath.Join(util.ChromiumBuildsDir, *chromiumBu ild)) 114 defer skutil.RemoveAll(filepath.Join(util.ChromiumBuildsDir, *chromiumBu ild))
115
83 chromiumBinary := filepath.Join(util.ChromiumBuildsDir, *chromiumBuild, util.BINARY_CHROME) 116 chromiumBinary := filepath.Join(util.ChromiumBuildsDir, *chromiumBuild, util.BINARY_CHROME)
84 if *targetPlatform == util.PLATFORM_ANDROID {
85 // Install the APK on the Android device.
86 if err := util.InstallChromeAPK(*chromiumBuild); err != nil {
87 glog.Errorf("Could not install the chromium APK: %s", er r)
88 return
89 }
90 }
91 117
92 // Download pagesets if they do not exist locally. 118 // Download pagesets if they do not exist locally.
93 pathToPagesets := filepath.Join(util.PagesetsDir, *pagesetType) 119 pathToPagesets := filepath.Join(util.PagesetsDir, *pagesetType)
94 if _, err := gs.DownloadSwarmingArtifacts(pathToPagesets, util.PAGESETS_ DIR_NAME, *pagesetType, *startRange, *num); err != nil { 120 if _, err := gs.DownloadSwarmingArtifacts(pathToPagesets, util.PAGESETS_ DIR_NAME, *pagesetType, *startRange, *num); err != nil {
95 glog.Error(err) 121 glog.Error(err)
96 return 122 return
97 } 123 }
98 defer skutil.RemoveAll(pathToPagesets) 124 defer skutil.RemoveAll(pathToPagesets)
99 125
100 // Download archives if they do not exist locally. 126 // Download archives if they do not exist locally.
101 pathToArchives := filepath.Join(util.WebArchivesDir, *pagesetType) 127 pathToArchives := filepath.Join(util.WebArchivesDir, *pagesetType)
102 » archivesToIndex, err := gs.DownloadSwarmingArtifacts(pathToArchives, uti l.WEB_ARCHIVES_DIR_NAME, *pagesetType, *startRange, *num) 128 » if _, err := gs.DownloadSwarmingArtifacts(pathToArchives, util.WEB_ARCHI VES_DIR_NAME, *pagesetType, *startRange, *num); err != nil {
103 » if err != nil {
104 glog.Error(err) 129 glog.Error(err)
105 return 130 return
106 } 131 }
107 defer skutil.RemoveAll(pathToArchives) 132 defer skutil.RemoveAll(pathToArchives)
108 133
109 » // Create the dir that SKPs will be stored in. 134 » // Establish nopatch output paths.
110 » pathToSkps := filepath.Join(util.SkpsDir, *pagesetType, *chromiumBuild) 135 » localOutputDir := filepath.Join(util.StorageDir, util.BenchmarkRunsDir, *runID)
111 » // Delete and remake the local SKPs directory. 136 » skutil.RemoveAll(localOutputDir)
112 » skutil.RemoveAll(pathToSkps) 137 » skutil.MkdirAll(localOutputDir, 0700)
113 » skutil.MkdirAll(pathToSkps, 0700) 138 » defer skutil.RemoveAll(localOutputDir)
114 » defer skutil.RemoveAll(pathToSkps) 139 » remoteDir := filepath.Join(util.BenchmarkRunsDir, *runID)
115 140
116 » // Construct path to the ct_run_benchmark python script. 141 » // Construct path to CT's python scripts.
117 pathToPyFiles := util.GetPathToPyFiles(!*worker_common.Local) 142 pathToPyFiles := util.GetPathToPyFiles(!*worker_common.Local)
118 143
119 timeoutSecs := util.PagesetTypeToInfo[*pagesetType].CaptureSKPsTimeoutSe cs
120 fileInfos, err := ioutil.ReadDir(pathToPagesets) 144 fileInfos, err := ioutil.ReadDir(pathToPagesets)
121 if err != nil { 145 if err != nil {
122 glog.Errorf("Unable to read the pagesets dir %s: %s", pathToPage sets, err) 146 glog.Errorf("Unable to read the pagesets dir %s: %s", pathToPage sets, err)
123 return 147 return
124 } 148 }
125 149
150 glog.Infoln("===== Going to run the task with parallel chrome processes =====")
151
126 // Create channel that contains all pageset file names. This channel wil l 152 // Create channel that contains all pageset file names. This channel wil l
127 // be consumed by the worker pool. 153 // be consumed by the worker pool.
128 pagesetRequests := util.GetClosedChannelOfPagesets(fileInfos) 154 pagesetRequests := util.GetClosedChannelOfPagesets(fileInfos)
129 155
130 var wg sync.WaitGroup 156 var wg sync.WaitGroup
131 // Use a RWMutex for the chromeProcessesCleaner goroutine to communicate to 157 // Use a RWMutex for the chromeProcessesCleaner goroutine to communicate to
132 // the workers (acting as "readers") when it wants to be the "writer" an d 158 // the workers (acting as "readers") when it wants to be the "writer" an d
133 // kill all zombie chrome processes. 159 // kill all zombie chrome processes.
134 var mutex sync.RWMutex 160 var mutex sync.RWMutex
135 161
136 // Loop through workers in the worker pool. 162 // Loop through workers in the worker pool.
137 for i := 0; i < WORKER_POOL_SIZE; i++ { 163 for i := 0; i < WORKER_POOL_SIZE; i++ {
138 // Increment the WaitGroup counter. 164 // Increment the WaitGroup counter.
139 wg.Add(1) 165 wg.Add(1)
140 166
141 // Create and run a goroutine closure that captures SKPs. 167 // Create and run a goroutine closure that captures SKPs.
dogben 2016/05/19 21:06:41 nit: update comment
rmistry 2016/05/20 11:07:16 Done.
142 go func() { 168 go func() {
143 // Decrement the WaitGroup counter when the goroutine co mpletes. 169 // Decrement the WaitGroup counter when the goroutine co mpletes.
144 defer wg.Done() 170 defer wg.Done()
145 171
146 for pagesetName := range pagesetRequests { 172 for pagesetName := range pagesetRequests {
147 173
148 mutex.RLock() 174 mutex.RLock()
149 175 » » » » if err := util.RunBenchmark(pagesetName, pathToP agesets, pathToPyFiles, localOutputDir, *chromiumBuild, chromiumBinary, *runID, *browserExtraArgs, *benchmarkName, "Linux", *benchmarkExtraArgs, *pagesetType, - 1); err != nil {
150 » » » » // Read the pageset. 176 » » » » » glog.Errorf("Error while running withpat ch benchmark: %s", err)
151 » » » » pagesetPath := filepath.Join(pathToPagesets, pag esetName) 177 » » » » » return
152 » » » » decodedPageset, err := util.ReadPageset(pagesetP ath)
153 » » » » if err != nil {
154 » » » » » glog.Errorf("Could not read %s: %s", pag esetPath, err)
155 » » » » » continue
156 } 178 }
157
158 glog.Infof("===== Processing %s =====", pagesetP ath)
159
160 skutil.LogErr(os.Chdir(pathToPyFiles))
161 index, ok := archivesToIndex[decodedPageset.Arch iveDataFile]
162 if !ok {
163 glog.Errorf("%s not found in the archive sToIndex map", decodedPageset.ArchiveDataFile)
164 continue
165 }
166 args := []string{
167 filepath.Join(util.TelemetryBinariesDir, util.BINARY_RUN_BENCHMARK),
168 util.BenchmarksToTelemetryName[util.BENC HMARK_SKPICTURE_PRINTER],
169 "--also-run-disabled-tests",
170 "--page-repeat=1", // Only need one run for SKPs.
171 "--skp-outdir=" + path.Join(pathToSkps, strconv.Itoa(index)),
172 "--extra-browser-args=" + util.DEFAULT_B ROWSER_ARGS,
173 "--user-agent=" + decodedPageset.UserAge nt,
174 "--urls-list=" + decodedPageset.UrlsList ,
175 "--archive-data-file=" + decodedPageset. ArchiveDataFile,
176 }
177 // Figure out which browser and device should be used.
178 if *targetPlatform == util.PLATFORM_ANDROID {
179 args = append(args, "--browser=android-c hromium")
180 } else {
181 args = append(args, "--browser=exact", " --browser-executable="+chromiumBinary)
182 args = append(args, "--device=desktop")
183 }
184 // Set the PYTHONPATH to the pagesets and the te lemetry dirs.
185 env := []string{
186 fmt.Sprintf("PYTHONPATH=%s:%s:%s:%s:$PYT HONPATH", pathToPagesets, util.TelemetryBinariesDir, util.TelemetrySrcDir, util. CatapultSrcDir),
187 "DISPLAY=:0",
188 }
189 skutil.LogErr(
190 util.ExecuteCmd("python", args, env, tim e.Duration(timeoutSecs)*time.Second, nil, nil))
191
192 mutex.RUnlock() 179 mutex.RUnlock()
193 } 180 }
194 }() 181 }()
195 } 182 }
196 183
197 if !*worker_common.Local { 184 if !*worker_common.Local {
198 // Start the cleaner. 185 // Start the cleaner.
199 go util.ChromeProcessesCleaner(&mutex, *chromeCleanerTimer) 186 go util.ChromeProcessesCleaner(&mutex, *chromeCleanerTimer)
200 } 187 }
201 188
202 // Wait for all spawned goroutines to complete. 189 // Wait for all spawned goroutines to complete.
203 wg.Wait() 190 wg.Wait()
204 191
205 » // Move and validate all SKP files. 192 » // If "--output-format=csv-pivot-table" was specified then merge all CSV files and upload.
206 » if err := util.ValidateSKPs(pathToSkps, pathToPyFiles); err != nil { 193 » if strings.Contains(*benchmarkExtraArgs, "--output-format=csv-pivot-tabl e") {
207 » » glog.Error(err) 194 » » if err := util.MergeUploadCSVFilesOnWorkers(localOutputDir, path ToPyFiles, *runID, remoteDir, gs, *startRange); err != nil {
208 » » return 195 » » » glog.Errorf("Error while processing withpatch CSV files: %s", err)
209 » } 196 » » » return
210 197 » » }
211 » // Upload SKPs dir to Google Storage.
212 » if err := gs.UploadSwarmingArtifacts(util.SKPS_DIR_NAME, *pagesetType); err != nil {
213 » » glog.Error(err)
214 » » return
215 } 198 }
216 } 199 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698