OLD | NEW |
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 """Utility class to build the Skia master BuildFactory's. | 6 """Utility class to build the Skia master BuildFactory's. |
7 | 7 |
8 Based on gclient_factory.py and adds Skia-specific steps.""" | 8 Based on gclient_factory.py and adds Skia-specific steps.""" |
9 | 9 |
10 | 10 |
11 from buildbot.process.properties import WithProperties | 11 from buildbot.process.properties import WithProperties |
12 from config_private import AUTOGEN_SVN_BASEURL, SKIA_SVN_BASEURL | 12 from config_private import AUTOGEN_SVN_BASEURL, SKIA_SVN_BASEURL |
13 from master.factory import gclient_factory | 13 from master.factory import gclient_factory |
14 from master.factory.build_factory import BuildFactory | 14 from master.factory.build_factory import BuildFactory |
15 from skia_master_scripts import commands as skia_commands | 15 from skia_master_scripts import commands as skia_commands |
16 import config | 16 import config |
17 import config_private | 17 import config_private |
18 import ntpath | 18 import ntpath |
| 19 import os |
19 import posixpath | 20 import posixpath |
| 21 import utils |
20 | 22 |
21 | 23 |
22 # TODO(epoger): My intent is to make the build steps identical on all platforms | 24 # TODO(epoger): My intent is to make the build steps identical on all platforms |
23 # and thus remove the need for the whole target_platform parameter. | 25 # and thus remove the need for the whole target_platform parameter. |
24 # For now, these must match the target_platform values used in | 26 # For now, these must match the target_platform values used in |
25 # third_party/chromium_buildbot/scripts/master/factory/gclient_factory.py , | 27 # third_party/chromium_buildbot/scripts/master/factory/gclient_factory.py , |
26 # because we pass these values into GClientFactory.__init__() . | 28 # because we pass these values into GClientFactory.__init__() . |
27 TARGET_PLATFORM_LINUX = 'linux' | 29 TARGET_PLATFORM_LINUX = 'linux' |
28 TARGET_PLATFORM_MAC = 'mac' | 30 TARGET_PLATFORM_MAC = 'mac' |
29 TARGET_PLATFORM_WIN32 = 'win32' | 31 TARGET_PLATFORM_WIN32 = 'win32' |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 | 108 |
107 # Set _default_clobber based on config.Master | 109 # Set _default_clobber based on config.Master |
108 self._default_clobber = getattr(config.Master, 'default_clobber', False) | 110 self._default_clobber = getattr(config.Master, 'default_clobber', False) |
109 | 111 |
110 self._do_upload_results = do_upload_results | 112 self._do_upload_results = do_upload_results |
111 self._do_upload_bench_results = do_upload_results and \ | 113 self._do_upload_bench_results = do_upload_results and \ |
112 perf_output_basedir != None | 114 perf_output_basedir != None |
113 self._do_patch_step = do_patch_step | 115 self._do_patch_step = do_patch_step |
114 | 116 |
115 if not environment_variables: | 117 if not environment_variables: |
116 my_env_vars = {} | 118 self._env_vars = {} |
117 else: | 119 else: |
118 my_env_vars = dict(environment_variables) | 120 self._env_vars = dict(environment_variables) |
119 gyp_defines = my_env_vars.get('GYP_DEFINES', '') | 121 gyp_defines = self._env_vars.get('GYP_DEFINES', '') |
120 my_env_vars['GYP_DEFINES'] = gyp_defines + \ | 122 self._env_vars['GYP_DEFINES'] = gyp_defines + \ |
121 ' skia_warnings_as_errors=%d' % int(compile_warnings_as_errors) | 123 ' skia_warnings_as_errors=%d' % int(compile_warnings_as_errors) |
122 | 124 |
123 # Get an implementation of SkiaCommands as appropriate for | 125 # Get an implementation of SkiaCommands as appropriate for |
124 # this target_platform. | 126 # this target_platform. |
125 workdir = self.TargetPathJoin('build', build_subdir) | 127 workdir = self.TargetPathJoin('build', build_subdir) |
126 self._skia_cmd_obj = skia_commands.SkiaCommands( | 128 self._skia_cmd_obj = skia_commands.SkiaCommands( |
127 target_platform=target_platform, factory=self, | 129 target_platform=target_platform, factory=self, |
128 configuration=configuration, workdir=workdir, | 130 configuration=configuration, workdir=workdir, |
129 target_arch=None, default_timeout=default_timeout, | 131 target_arch=None, default_timeout=default_timeout, |
130 environment_variables=my_env_vars) | 132 environment_variables=self._env_vars) |
131 | 133 |
132 self._perf_output_basedir = perf_output_basedir | 134 self._perf_output_basedir = perf_output_basedir |
133 | 135 |
134 self._configuration = configuration | 136 self._configuration = configuration |
135 if self._configuration not in CONFIGURATIONS: | 137 if self._configuration not in CONFIGURATIONS: |
136 raise ValueError('Invalid configuration %s. Must be one of: %s' % ( | 138 raise ValueError('Invalid configuration %s. Must be one of: %s' % ( |
137 self._configuration, CONFIGURATIONS)) | 139 self._configuration, CONFIGURATIONS)) |
138 | 140 |
139 self._skia_svn_username_file = '.skia_svn_username' | 141 self._skia_svn_username_file = '.skia_svn_username' |
140 self._skia_svn_password_file = '.skia_svn_password' | 142 self._skia_svn_password_file = '.skia_svn_password' |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 '--make_flags', '"%s"' % ' '.join(self._make_flags), | 179 '--make_flags', '"%s"' % ' '.join(self._make_flags), |
178 '--test_args', '"%s"' % ' '.join(test_args), | 180 '--test_args', '"%s"' % ' '.join(test_args), |
179 '--gm_args', '"%s"' % ' '.join(gm_args), | 181 '--gm_args', '"%s"' % ' '.join(gm_args), |
180 '--bench_args', '"%s"' % ' '.join(bench_args), | 182 '--bench_args', '"%s"' % ' '.join(bench_args), |
181 '--num_cores', WithProperties('%(num_cores:-None)s'), | 183 '--num_cores', WithProperties('%(num_cores:-None)s'), |
182 '--is_try', str(self._do_patch_step), | 184 '--is_try', str(self._do_patch_step), |
183 '--bench_pictures_cfg', bench_pictures_cfg, | 185 '--bench_pictures_cfg', bench_pictures_cfg, |
184 ] | 186 ] |
185 BuildFactory.__init__(self, build_factory_properties=properties) | 187 BuildFactory.__init__(self, build_factory_properties=properties) |
186 | 188 |
| 189 def Validate(self): |
| 190 """ Validate the Factory against the known good configuration. """ |
| 191 test_dir = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, |
| 192 'tools', 'tests', 'factory_configuration') |
| 193 expected_dir = os.path.join(test_dir, 'expected') |
| 194 actual_dir = os.path.join(test_dir, 'actual') |
| 195 if not os.path.exists(actual_dir): |
| 196 os.makedirs(actual_dir) |
| 197 try: |
| 198 expectation = open(os.path.join(expected_dir, self._builder_name)).read() |
| 199 except IOError: |
| 200 raise Exception('Warning: No expected factory configuration for %s.' % |
| 201 self._builder_name) |
| 202 self_as_string = utils.ToString(self.__dict__) |
| 203 with open(os.path.join(actual_dir, self._builder_name), 'w') as f: |
| 204 f.write(self_as_string) |
| 205 if self_as_string != expectation: |
| 206 raise ValueError('Factory configuration for %s does not match ' |
| 207 'expectation!' % self._builder_name) |
| 208 |
187 def AddSlaveScript(self, script, description, args=None, timeout=None, | 209 def AddSlaveScript(self, script, description, args=None, timeout=None, |
188 halt_on_failure=False, is_upload_step=False, | 210 halt_on_failure=False, is_upload_step=False, |
189 is_rebaseline_step=False, get_props_from_stdout=None, | 211 is_rebaseline_step=False, get_props_from_stdout=None, |
190 workdir=None): | 212 workdir=None): |
191 """ Add a BuildStep consisting of a python script. | 213 """ Add a BuildStep consisting of a python script. |
192 | 214 |
193 script: which slave-side python script to run. | 215 script: which slave-side python script to run. |
194 description: string briefly describing the BuildStep. | 216 description: string briefly describing the BuildStep. |
195 args: optional list of strings; arguments to pass to the script. | 217 args: optional list of strings; arguments to pass to the script. |
196 timeout: optional integer; maximum time for the BuildStep to complete. | 218 timeout: optional integer; maximum time for the BuildStep to complete. |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 self.UploadBenchGraphs() | 512 self.UploadBenchGraphs() |
491 | 513 |
492 def Build(self, clobber=None): | 514 def Build(self, clobber=None): |
493 """Build and return the complete BuildFactory. | 515 """Build and return the complete BuildFactory. |
494 | 516 |
495 clobber: boolean indicating whether we should clean before building | 517 clobber: boolean indicating whether we should clean before building |
496 """ | 518 """ |
497 self.CommonSteps(clobber) | 519 self.CommonSteps(clobber) |
498 self.NonPerfSteps() | 520 self.NonPerfSteps() |
499 self.PerfSteps() | 521 self.PerfSteps() |
| 522 self.Validate() |
500 return self | 523 return self |
501 | 524 |
502 def BuildCompileOnly(self, clobber=None): | 525 def BuildCompileOnly(self, clobber=None): |
503 """Build and return the complete BuildFactory, with only the compile step. | 526 """Build and return the complete BuildFactory, with only the compile step. |
504 Does not build in one step; the assumption is that if we're only performing | 527 Does not build in one step; the assumption is that if we're only performing |
505 the compile, we want as much information as possible about *which* compile | 528 the compile, we want as much information as possible about *which* compile |
506 steps are passing and failing. | 529 steps are passing and failing. |
507 | 530 |
508 clobber: boolean indicating whether we should clean before building | 531 clobber: boolean indicating whether we should clean before building |
509 """ | 532 """ |
510 self.UpdateSteps() | 533 self.UpdateSteps() |
511 self.Compile(clobber=clobber, build_in_one_step=False) | 534 self.Compile(clobber=clobber, build_in_one_step=False) |
| 535 self.Validate() |
512 return self | 536 return self |
513 | 537 |
514 def BuildNoPerf(self, clobber=None): | 538 def BuildNoPerf(self, clobber=None): |
515 """Build and return the complete BuildFactory, without the benchmarking | 539 """Build and return the complete BuildFactory, without the benchmarking |
516 steps. | 540 steps. |
517 | 541 |
518 clobber: boolean indicating whether we should clean before building | 542 clobber: boolean indicating whether we should clean before building |
519 """ | 543 """ |
520 self.CommonSteps(clobber) | 544 self.CommonSteps(clobber) |
521 self.NonPerfSteps() | 545 self.NonPerfSteps() |
| 546 self.Validate() |
522 return self | 547 return self |
523 | 548 |
524 def BuildPerfOnly(self, clobber=None): | 549 def BuildPerfOnly(self, clobber=None): |
525 """Build and return the complete BuildFactory, with only the benchmarking | 550 """Build and return the complete BuildFactory, with only the benchmarking |
526 steps. | 551 steps. |
527 | 552 |
528 clobber: boolean indicating whether we should clean before building | 553 clobber: boolean indicating whether we should clean before building |
529 """ | 554 """ |
530 if not self._perf_output_basedir: | 555 if not self._perf_output_basedir: |
531 raise ValueError( | 556 raise ValueError( |
532 'BuildPerfOnly requires perf_output_basedir to be defined.') | 557 'BuildPerfOnly requires perf_output_basedir to be defined.') |
533 if self._configuration != CONFIG_RELEASE: | 558 if self._configuration != CONFIG_RELEASE: |
534 raise ValueError('BuildPerfOnly should run in %s configuration.' % | 559 raise ValueError('BuildPerfOnly should run in %s configuration.' % |
535 CONFIG_RELEASE) | 560 CONFIG_RELEASE) |
536 self.CommonSteps(clobber) | 561 self.CommonSteps(clobber) |
537 self.PerfSteps() | 562 self.PerfSteps() |
| 563 self.Validate() |
538 return self | 564 return self |
OLD | NEW |