def testScheduleUnimportantSlaveBuildsFailure(self):
        """Test ScheduleSlaveBuilds with unimportant slave failures."""
        stage = self.ConstructStage()
        self.PatchObject(
            scheduler_stages.ScheduleSlavesStage,
            'PostSlaveBuildToBuildbucket',
            side_effect=buildbucket_lib.BuildbucketResponseException)

        slave_config_map = {
            'slave_external': config_lib.BuildConfig(important=False),
        }
        self.PatchObject(generic_stages.BuilderStage,
                         '_GetSlaveConfigMap',
                         return_value=slave_config_map)
        stage.ScheduleSlaveBuildsViaBuildbucket(important_only=False,
                                                dryrun=True)

        scheduled_slaves = self._run.attrs.metadata.GetValue(
            constants.METADATA_SCHEDULED_IMPORTANT_SLAVES)
        self.assertEqual(len(scheduled_slaves), 0)
        unscheduled_slaves = self._run.attrs.metadata.GetValue(
            constants.METADATA_UNSCHEDULED_SLAVES)
        self.assertEqual(len(unscheduled_slaves), 1)
 def _GetTestConfig(self):
     test_config = config_lib.SiteConfig()
     test_config.Add(
         'master',
         config_lib.BuildConfig(),
         boards=[],
         build_type=self.build_type,
         master=True,
         slave_configs=['test3', 'test5'],
         manifest_version=True,
     )
     test_config.Add(
         'test1',
         config_lib.BuildConfig(),
         boards=['amd64-generic'],
         manifest_version=True,
         build_type=constants.PFQ_TYPE,
         overlays='public',
         important=False,
         chrome_rev=None,
         branch=False,
         internal=False,
         master=False,
     )
     test_config.Add(
         'test2',
         config_lib.BuildConfig(),
         boards=['amd64-generic'],
         manifest_version=False,
         build_type=constants.PFQ_TYPE,
         overlays='public',
         important=True,
         chrome_rev=None,
         branch=False,
         internal=False,
         master=False,
     )
     test_config.Add(
         'test3',
         config_lib.BuildConfig(),
         boards=['amd64-generic'],
         manifest_version=True,
         build_type=constants.PFQ_TYPE,
         overlays='both',
         important=True,
         chrome_rev=None,
         branch=False,
         internal=True,
         master=False,
     )
     test_config.Add(
         'test4',
         config_lib.BuildConfig(),
         boards=['amd64-generic'],
         manifest_version=True,
         build_type=constants.PFQ_TYPE,
         overlays='both',
         important=True,
         chrome_rev=None,
         branch=True,
         internal=True,
         master=False,
     )
     test_config.Add(
         'test5',
         config_lib.BuildConfig(),
         boards=['amd64-generic'],
         manifest_version=True,
         build_type=constants.PFQ_TYPE,
         overlays='public',
         important=True,
         chrome_rev=None,
         branch=False,
         internal=False,
         master=False,
     )
     return test_config
def _ExtendDefaultConfig(**kwargs):
    """Extend DEFAULT_CONFIG with keys/values in kwargs."""
    config_kwargs = DEFAULT_CONFIG.copy()
    config_kwargs.update(kwargs)
    return config_lib.BuildConfig(**config_kwargs)
DEFAULT_OPTIONS = cros_test_lib.EasyAttr(
    archive_base=DEFAULT_ARCHIVE_BASE,
    buildroot=DEFAULT_BUILDROOT,
    buildnumber=DEFAULT_BUILDNUMBER,
    buildbot=True,
    branch=DEFAULT_BRANCH,
    remote_trybot=False,
    debug=False,
    postsync_patch=True,
)
DEFAULT_CONFIG = config_lib.BuildConfig(
    name=DEFAULT_BOT_NAME,
    master=True,
    boards=[DEFAULT_BOARD],
    postsync_patch=True,
    child_configs=[
        config_lib.BuildConfig(name='foo', postsync_patch=False, boards=[]),
        config_lib.BuildConfig(name='bar', postsync_patch=False, boards=[]),
    ],
)

DEFAULT_VERSION = '6543.2.1'


def _ExtendDefaultOptions(**kwargs):
    """Extend DEFAULT_OPTIONS with keys/values in kwargs."""
    options_kwargs = DEFAULT_OPTIONS.copy()
    options_kwargs.update(kwargs)
    return cros_test_lib.EasyAttr(**options_kwargs)

# Access to protected member.
# pylint: disable=W0212

DEFAULT_OPTIONS = cros_test_lib.EasyAttr(
    archive_base=DEFAULT_ARCHIVE_BASE,
    buildroot=DEFAULT_BUILDROOT,
    buildnumber=DEFAULT_BUILDNUMBER,
    buildbot=True,
    branch=DEFAULT_BRANCH,
    remote_trybot=False,
    debug=False,
)
DEFAULT_CONFIG = config_lib.BuildConfig(name=DEFAULT_BOT_NAME,
                                        master=True,
                                        boards=[DEFAULT_BOARD],
                                        child_configs=[
                                            config_lib.BuildConfig(name='foo'),
                                            config_lib.BuildConfig(name='bar'),
                                        ],
                                        gs_path=config_lib.GS_PATH_DEFAULT)


def _ExtendDefaultOptions(**kwargs):
    """Extend DEFAULT_OPTIONS with keys/values in kwargs."""
    options_kwargs = DEFAULT_OPTIONS.copy()
    options_kwargs.update(kwargs)
    return cros_test_lib.EasyAttr(**options_kwargs)


def _ExtendDefaultConfig(**kwargs):
    """Extend DEFAULT_CONFIG with keys/values in kwargs."""
    config_kwargs = DEFAULT_CONFIG.copy()
Exemple #6
0
    def VerifyStage(self,
                    failing,
                    inflight,
                    no_stat,
                    handle_failure=False,
                    handle_timeout=False,
                    sane_tot=True,
                    stage=None,
                    all_slaves=None,
                    slave_stages=None,
                    fatal=True,
                    self_destructed=False):
        """Runs and Verifies PerformStage.

    Args:
      failing: The names of the builders that failed.
      inflight: The names of the buiders that timed out.
      no_stat: The names of the builders that had no status.
      handle_failure: If True, calls HandleValidationFailure.
      handle_timeout: If True, calls HandleValidationTimeout.
      sane_tot: If not true, assumes TOT is not sane.
      stage: If set, use this constructed stage, otherwise create own.
      all_slaves: Optional set of all slave configs.
      slave_stages: Optional list of slave stages.
      fatal: Optional boolean indicating whether the completion_stage failed
        with fatal. Default to True.
      self_destructed: Optional boolean indicating whether the completion_stage
        self_destructed. Default to False.
    """
        if not stage:
            stage = self.ConstructStage()

        stage._run.attrs.metadata.UpdateWithDict(
            {constants.SELF_DESTRUCTED_BUILD: self_destructed})

        # Setup the stage to look at the specified configs.
        all_slaves = list(all_slaves or set(failing + inflight + no_stat))
        all_started_slaves = list(all_slaves or set(failing + inflight))
        configs = [config_lib.BuildConfig(name=x) for x in all_slaves]
        self.PatchObject(stage, '_GetSlaveConfigs', return_value=configs)

        statuses = {}
        for x in failing:
            statuses[x] = builder_status_lib.BuilderStatus(
                constants.BUILDER_STATUS_FAILED, message=None)
        for x in inflight:
            statuses[x] = builder_status_lib.BuilderStatus(
                constants.BUILDER_STATUS_INFLIGHT, message=None)
        for x in no_stat:
            statuses[x] = builder_status_lib.BuilderStatus(
                constants.BUILDER_STATUS_MISSING, message=None)
        self.completion_stage.GetSlaveStatuses.return_value = statuses
        self.completion_stage.GetFatal.return_value = fatal

        # Setup DB and provide list of slave stages.
        mock_cidb = mock.MagicMock()
        cidb.CIDBConnectionFactory.SetupMockCidb(mock_cidb)
        if slave_stages is None:
            slave_stages = []
            critical_stages = (
                relevant_changes.TriageRelevantChanges.STAGE_SYNC)
            for stage_name, slave in itertools.product(critical_stages,
                                                       all_started_slaves):
                slave_stages.append({
                    'name': stage_name,
                    'build_config': slave,
                    'status': constants.BUILDER_STATUS_PASSED
                })
        self.PatchObject(mock_cidb,
                         'GetSlaveStages',
                         return_value=slave_stages)

        # Set up SubmitPartialPool to provide a list of changes to look at.
        self.PatchObject(stage.sync_stage.pool,
                         'SubmitPartialPool',
                         return_value=self.other_changes)

        # Actually run the stage.
        stage.PerformStage()

        if fatal:
            stage.sync_stage.pool.submit_pool_mock.assert_not_called()
            self.mock_record_metrics.assert_called_once_with(False)
        else:
            stage.sync_stage.pool.submit_pool_mock.assert_called_once_with(
                reason=constants.STRATEGY_CQ_SUCCESS)
            self.mock_record_metrics.assert_called_once_with(True)

        if handle_failure:
            stage.sync_stage.pool.handle_failure_mock.assert_called_once_with(
                mock.ANY,
                no_stat=set(no_stat),
                sanity=sane_tot,
                changes=self.other_changes,
                failed_hwtests=mock.ANY)

        if handle_timeout:
            stage.sync_stage.pool.handle_timeout_mock.assert_called_once_with(
                sanity=mock.ANY, changes=self.other_changes)
Exemple #7
0
    def testApplyCallable(self):
        # Callable that adds a configurable amount.
        append = lambda x: lambda base: base + ' ' + x

        site_config = config_lib.SiteConfig()

        site_config.AddTemplate('add1', foo=append('one'))
        site_config.AddTemplate('add2', foo=append('two'))
        site_config.AddTemplate('fixed', foo='fixed')

        site_config.AddTemplate('derived', site_config.templates.add1)

        site_config.AddTemplate('stacked', site_config.templates.add1,
                                site_config.templates.add2)

        site_config.AddTemplate('stackedDeep',
                                site_config.templates.fixed,
                                site_config.templates.add1,
                                site_config.templates.add1,
                                site_config.templates.add1,
                                foo=append('deep'))

        site_config.AddTemplate('stackedDeeper',
                                site_config.templates.stacked,
                                site_config.templates.stackedDeep,
                                foo=append('deeper'))

        base = config_lib.BuildConfig(foo='base')

        # Basic apply.
        result = base.derive(site_config.templates.add1)
        self.assertEqual(result.foo, 'base one')

        # Callable template + local callable.
        result = base.derive(site_config.templates.add1, foo=append('local'))
        self.assertEqual(result.foo, 'base one local')

        # Callable template + local fixed.
        result = base.derive(site_config.templates.add1, foo='local')
        self.assertEqual(result.foo, 'local')

        # Derived template.
        result = base.derive(site_config.templates.derived)
        self.assertEqual(result.foo, 'base one')

        # Template with fixed override after stacking template (all callable magic
        # should disappear).
        result = base.derive(site_config.templates.fixed)
        self.assertEqual(result.foo, 'fixed')

        # Template with stacked.
        result = base.derive(site_config.templates.stacked)
        self.assertEqual(result.foo, 'base one two')

        # Callables on top of fixed from template.
        result = base.derive(site_config.templates.stackedDeep)
        self.assertEqual(result.foo, 'fixed one one one deep')

        # Just get crazy with it.
        result = base.derive(site_config.templates.stackedDeeper)
        self.assertEqual(result.foo, 'fixed one one one deep deeper')

        # Ensure objects derived from weren't modified.
        self.assertEqual(base.foo, 'base')
        self.assertEqual(site_config.templates.fixed.foo, 'fixed')
Exemple #8
0
 def testApplyMixed(self):
     # Apply simple values..
     config = config_lib.BuildConfig()
     config.apply(self.fooConfig, self.barConfig, a=1, b=2, bar=3)
     self.assertEqual(config, dict(name='bar', foo=1, bar=3, a=1, b=2))
    def testAddForBoards(self):
        per_board = {
            'foo': config_lib.BuildConfig(value='foo'),
            'bar': config_lib.BuildConfig(value='bar'),
            'multiboard': config_lib.BuildConfig(boards=['foo', 'bar']),
        }

        # Test the minimal invocation.
        self.site_config.AddForBoards(
            'minimal',
            ['foo', 'bar'],
        )

        self.assertIn('foo-minimal', self.site_config)
        self.assertEqual(self.site_config['foo-minimal'].boards, ['foo'])
        self.assertEqual(self.site_config['bar-minimal'].boards, ['bar'])

        # Test a partial set of per-board values specified.
        self.site_config.AddForBoards(
            'partial_per_board',
            ['foo', 'no_per'],
            per_board,
        )

        self.assertIn('foo-partial_per_board', self.site_config)
        self.assertIn('no_per-partial_per_board', self.site_config)
        self.assertEqual(self.site_config['foo-partial_per_board'].value,
                         'foo')

        # Test all boards with per_board values specified, and test we can
        # override board listing in per_board values.
        self.site_config.AddForBoards(
            'per_board',
            ['foo', 'bar', 'multiboard'],
            per_board,
        )

        self.assertEqual(self.site_config['foo-per_board'].value, 'foo')
        self.assertEqual(self.site_config['bar-per_board'].value, 'bar')
        self.assertEqual(self.site_config['multiboard-per_board'].boards,
                         ['foo', 'bar'])

        # Test using a template
        self.site_config.AddForBoards(
            'template',
            ['foo', 'bar'],
            None,
            self.site_config.templates.template,
        )

        self.assertEqual(self.site_config['foo-template'].value, 'template')

        # Test a template, and a mixin.
        self.site_config.AddForBoards(
            'mixin',
            ['foo', 'bar'],
            None,
            self.site_config.templates.template,
            self.site_config.templates.mixin,
        )

        self.assertEqual(self.site_config['foo-mixin'].value, 'mixin')

        # Test a template, and a mixin, and a per-board.
        self.site_config.AddForBoards(
            'mixin_per_board',
            ['foo', 'bar'],
            per_board,
            self.site_config.templates.template,
            self.site_config.templates.mixin,
        )

        self.assertEqual(self.site_config['foo-mixin_per_board'].value, 'foo')

        # Test a template, and a mixin, and a per-board, and an override.
        self.site_config.AddForBoards(
            'override',
            ['foo', 'bar'],
            per_board,
            self.site_config.templates.template,
            self.site_config.templates.mixin,
            value='override',
        )

        self.assertEqual(self.site_config['foo-override'].value, 'override')
Exemple #10
0
def ApplyCustomOverrides(site_config):
    """Method with to override specific flags for specific builders.

  Generally try really hard to avoid putting anything here that isn't
  a really special case for a single specific builder. This is performed
  after every other bit of processing, so it always has the final say.

  Args:
    site_config: config_lib.SiteConfig containing builds to have their
                 waterfall values updated.
  """

    overwritten_configs = {
        'lakitu-release':
        config_lib.BuildConfig().apply(
            site_config.templates.lakitu_test_customizations, ),

        # This is the full build of open-source overlay.
        'lakitu-full':
        config_lib.BuildConfig().apply(
            # logging_CrashSender is expected to fail for lakitu-full.
            # See b/111567339 for more details.
            useflags=config_lib.append_useflags(['-tests_logging_CrashSender'
                                                 ]), ),
        'lakitu-gpu-release':
        config_lib.BuildConfig().apply(
            site_config.templates.lakitu_test_customizations, ),
        'lakitu-nc-release':
        config_lib.BuildConfig().apply(signer_tests=False, ),
        'lakitu-st-release':
        config_lib.BuildConfig().apply(
            site_config.templates.lakitu_test_customizations, ),
        'lakitu_next-release':
        config_lib.BuildConfig().apply(
            site_config.templates.lakitu_test_customizations,
            signer_tests=False,
        ),
        'guado_labstation-release': {
            'hw_tests': [],
            # 'hwqual':False,
            'image_test': False,
            # 'images':['test'],
            'signer_tests': False,
            'vm_tests': [],
        },
        'fizz-labstation-release': {
            'hw_tests': [],
            'image_test': False,
            'signer_tests': False,
            'vm_tests': [],
        },
        'betty-arc64-nyc-android-pfq':
        site_config.templates.tast_vm_android_pfq_tests,
        'betty-nyc-android-pfq':
        site_config.templates.tast_vm_android_pfq_tests,
        'betty-pi-arc-pi-android-pfq':
        site_config.templates.tast_vm_android_pfq_tests,

        # There's no amd64-generic-release builder, so we use amd64-generic-full
        # to validate informational Tast tests on amd64-generic:
        # https://crbug.com/946858
        'amd64-generic-full':
        site_config.templates.tast_vm_canary_tests,
        'betty-arc64-release':
        site_config.templates.tast_vm_canary_tests,
        'betty-pi-arc-release':
        site_config.templates.tast_vm_canary_tests,
        'betty-release':
        site_config.templates.tast_vm_canary_tests,
    }

    for config_name, overrides in overwritten_configs.items():
        # TODO: Turn this assert into a unittest.
        # config = site_config[config_name]
        # for k, v in overrides.items():
        #   assert config[k] != v, ('Unnecessary override: %s: %s' %
        #                           (config_name, k))
        site_config[config_name].apply(**overrides)
    def VerifyStage(self,
                    failing,
                    inflight,
                    handle_failure=True,
                    handle_timeout=False,
                    sane_tot=True,
                    submit_partial=False,
                    alert=False,
                    stage=None,
                    all_slaves=None,
                    slave_stages=None,
                    do_submit_partial=True,
                    build_passed=False):
        """Runs and Verifies PerformStage.

    Args:
      failing: The names of the builders that failed.
      inflight: The names of the buiders that timed out.
      handle_failure: If True, calls HandleValidationFailure.
      handle_timeout: If True, calls HandleValidationTimeout.
      sane_tot: If not true, assumes TOT is not sane.
      submit_partial: If True, submit partial pool will submit some changes.
      alert: If True, sends out an alert email for infra failures.
      stage: If set, use this constructed stage, otherwise create own.
      all_slaves: Optional set of all slave configs.
      slave_stages: Optional list of slave stages.
      do_submit_partial: If True, assert that there was no call to
                         SubmitPartialPool.
      build_passed: Whether the build passed or failed.
    """
        if not stage:
            stage = self.ConstructStage()

        # Setup the stage to look at the specified configs.
        all_slaves = list(all_slaves or set(failing + inflight))
        configs = [config_lib.BuildConfig(name=x) for x in all_slaves]
        self.PatchObject(stage, '_GetSlaveConfigs', return_value=configs)

        # Setup builder statuses.
        stage._run.attrs.manifest_manager = mock.MagicMock()
        statuses = {}
        for x in failing:
            statuses[x] = manifest_version.BuilderStatus(
                constants.BUILDER_STATUS_FAILED, message=None)
        for x in inflight:
            statuses[x] = manifest_version.BuilderStatus(
                constants.BUILDER_STATUS_INFLIGHT, message=None)
        if self._run.config.master:
            self.PatchObject(stage._run.attrs.manifest_manager,
                             'GetBuildersStatus',
                             return_value=statuses)
        else:
            self.PatchObject(stage,
                             '_GetLocalBuildStatus',
                             return_value=statuses)

        # Setup DB and provide list of slave stages.
        mock_cidb = mock.MagicMock()
        cidb.CIDBConnectionFactory.SetupMockCidb(mock_cidb)
        if slave_stages is None:
            slave_stages = []
            critical_stages = (
                completion_stages.CommitQueueCompletionStage._CRITICAL_STAGES)
            for stage_name, slave in itertools.product(critical_stages,
                                                       all_slaves):
                slave_stages.append({
                    'name': stage_name,
                    'build_config': slave,
                    'status': constants.BUILDER_STATUS_PASSED
                })
        self.PatchObject(mock_cidb,
                         'GetSlaveStages',
                         return_value=slave_stages)

        # Set up SubmitPartialPool to provide a list of changes to look at.
        if submit_partial:
            spmock = self.PatchObject(stage.sync_stage.pool,
                                      'SubmitPartialPool',
                                      return_value=self.other_changes)
            handlefailure_changes = self.other_changes
        else:
            spmock = self.PatchObject(stage.sync_stage.pool,
                                      'SubmitPartialPool',
                                      return_value=self.changes)
            handlefailure_changes = self.changes

        # Track whether 'HandleSuccess' is called.
        success_mock = self.PatchObject(stage, 'HandleSuccess')

        # Actually run the stage.
        if build_passed:
            stage.PerformStage()
        else:
            with self.assertRaises(
                    completion_stages.ImportantBuilderFailedException):
                stage.PerformStage()

        # Verify the calls.
        self.assertEqual(success_mock.called, build_passed)

        if not build_passed and self._run.config.master:
            self.tot_sanity_mock.assert_called_once_with(mock.ANY, mock.ANY)

            if alert:
                self.alert_email_mock.called_once_with(mock.ANY, mock.ANY,
                                                       mock.ANY, mock.ANY)

            self.assertEqual(do_submit_partial, spmock.called)

            if handle_failure:
                stage.sync_stage.pool.handle_failure_mock.assert_called_once_with(
                    mock.ANY,
                    no_stat=set([]),
                    sanity=sane_tot,
                    changes=handlefailure_changes)

            if handle_timeout:
                stage.sync_stage.pool.handle_timeout_mock.assert_called_once_with(
                    sanity=mock.ANY, changes=self.changes)