def testPreParseArguments(self):
    """Test that we can correctly extract branch values from cbuildbot args."""
    CASES = (
        (['--buildroot', '/buildroot', 'daisy-incremental'],
         (None, '/buildroot', None)),

        (['--buildbot', '--buildroot', '/buildroot',
          '--git-cache-dir', '/git-cache',
          '-b', 'release-R57-9202.B',
          'daisy-incremental'],
         ('release-R57-9202.B', '/buildroot', '/git-cache')),

        (['--debug', '--buildbot', '--notests',
          '--buildroot', '/buildroot',
          '--git-cache-dir', '/git-cache',
          '--branch', 'release-R57-9202.B',
          'daisy-incremental'],
         ('release-R57-9202.B', '/buildroot', '/git-cache')),
    )

    for cmd_args, expected in CASES:
      expected_branch, expected_buildroot, expected_cache_dir = expected

      options = cbuildbot_launch.PreParseArguments(cmd_args)

      self.assertEqual(options.branch, expected_branch)
      self.assertEqual(options.buildroot, expected_buildroot)
      self.assertEqual(options.git_cache_dir, expected_cache_dir)
    def testGetCurrentBuildStateNoArgs(self):
        """Tests GetCurrentBuildState without arguments."""
        options = cbuildbot_launch.PreParseArguments(
            ['--buildroot', self.root, 'config'])
        state = cbuildbot_launch.GetCurrentBuildState(options, 'master')

        expected_state = build_summary.BuildSummary(
            status=constants.BUILDER_STATUS_INFLIGHT,
            buildroot_layout=2,
            branch='master')
        self.assertEqual(state, expected_state)
    def testGetCurrentBuildStateLayout(self):
        """Test that GetCurrentBuildState uses the current buildroot layout."""
        # Change to a future version.
        self.PatchObject(cbuildbot_launch, 'BUILDROOT_BUILDROOT_LAYOUT', 22)

        options = cbuildbot_launch.PreParseArguments(
            ['--buildroot', self.root, 'config'])
        state = cbuildbot_launch.GetCurrentBuildState(options, 'branchA')

        expected_state = build_summary.BuildSummary(
            status=constants.BUILDER_STATUS_INFLIGHT,
            buildroot_layout=22,
            branch='branchA')
        self.assertEqual(state, expected_state)
    def testGetCurrentBuildStateHasArgs(self):
        """Tests GetCurrentBuildState with arguments."""
        options = cbuildbot_launch.PreParseArguments([
            '--buildroot', self.root, '--buildnumber', '20',
            '--master-build-id', '50', 'config'
        ])
        state = cbuildbot_launch.GetCurrentBuildState(options, 'branchA')

        expected_state = build_summary.BuildSummary(
            build_number=20,
            master_build_id=50,
            status=constants.BUILDER_STATUS_INFLIGHT,
            buildroot_layout=2,
            branch='branchA')
        self.assertEqual(state, expected_state)
  def testMainMax(self):
    """Test a larger set of command line options."""
    self.PatchObject(osutils, 'SafeMakedirs', autospec=True)
    self.PatchObject(commands, 'GetTargetChromiteApiVersion',
                     autospec=True, return_value=(constants.REEXEC_API_MAJOR,
                                                  constants.REEXEC_API_MINOR))
    mock_repo = mock.MagicMock()
    mock_repo.branch = 'branch'
    mock_repo.directory = '/root/repository'

    mock_summary = build_summary.BuildSummary(
        build_number=313,
        master_build_id=123123123,
        status=constants.BUILDER_STATUS_FAILED,
        buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
        branch='branch')

    mock_get_last_build_state = self.PatchObject(
        cbuildbot_launch, 'GetLastBuildState', autospec=True,
        return_value=mock_summary)
    mock_repo_create = self.PatchObject(repository, 'RepoRepository',
                                        autospec=True, return_value=mock_repo)
    mock_clean = self.PatchObject(cbuildbot_launch, 'CleanBuildRoot',
                                  autospec=True)
    mock_checkout = self.PatchObject(cbuildbot_launch, 'InitialCheckout',
                                     autospec=True)
    mock_cleanup_chroot = self.PatchObject(cbuildbot_launch, 'CleanupChroot',
                                           autospec=True)
    mock_set_last_build_state = self.PatchObject(
        cbuildbot_launch, 'SetLastBuildState', autospec=True)
    argv = ['--buildroot', '/root',
            '--branch', 'branch',
            '--git-cache-dir', '/git-cache',
            '--cache-dir', '/cache',
            '--remote-trybot',
            '--master-build-id', '123456789',
            '--buildnumber', '314',
            'config']
    options = cbuildbot_launch.PreParseArguments(argv)
    cbuildbot_launch._main(options, argv)

    # Did we create the repo instance correctly?
    self.assertEqual(mock_repo_create.mock_calls,
                     [mock.call(EXPECTED_MANIFEST_URL, '/root/repository',
                                git_cache_dir='/git-cache', branch='branch')])

    # Ensure we look up the previous status.
    self.assertEqual(mock_get_last_build_state.mock_calls, [
        mock.call('/root')])

    # Ensure we clean, as expected.
    self.assertEqual(mock_clean.mock_calls, [
        mock.call('/root',
                  mock_repo,
                  '/cache',
                  build_summary.BuildSummary(
                      build_number=314,
                      master_build_id=123456789,
                      status=mock.ANY,
                      branch='branch',
                      buildroot_layout=2
                  ))])

    # Ensure we checkout, as expected.
    self.assertEqual(mock_checkout.mock_calls,
                     [mock.call(mock_repo)])

    # Ensure we invoke cbuildbot, as expected.
    self.assertCommandCalled(
        [
            '/root/repository/chromite/bin/cbuildbot',
            'config',
            '--buildroot', '/root/repository',
            '--branch', 'branch',
            '--git-cache-dir', '/git-cache',
            '--cache-dir', '/cache',
            '--remote-trybot',
            '--master-build-id', '123456789',
            '--buildnumber', '314',
            '--previous-build-state',
            'eyJicmFuY2giOiJicmFuY2giLCJidWlsZF9udW1iZXIiOjMxMywiYnVpbGRyb290X'
            '2xheW91dCI6MiwibWFzdGVyX2J1aWxkX2lkIjoxMjMxMjMxMjMsInN0YXR1cyI6Im'
            'ZhaWwifQ==',
            '--workspace', '/root/workspace',
            '--cache-dir', '/cache',
        ],
        extra_env={'PATH': mock.ANY},
        cwd='/root/repository',
        check=False)

    # Ensure we write the final build state, as expected.
    final_state = build_summary.BuildSummary(
        build_number=314,
        master_build_id=123456789,
        status=constants.BUILDER_STATUS_PASSED,
        buildroot_layout=2,
        branch='branch')
    self.assertEqual(mock_set_last_build_state.mock_calls, [
        mock.call('/root', final_state)])

    # Ensure we clean the chroot, as expected.
    mock_cleanup_chroot.assert_called_once_with('/root/repository')
  def testMainMin(self):
    """Test a minimal set of command line options."""
    self.PatchObject(osutils, 'SafeMakedirs', autospec=True)
    self.PatchObject(commands, 'GetTargetChromiteApiVersion',
                     autospec=True, return_value=(constants.REEXEC_API_MAJOR,
                                                  constants.REEXEC_API_MINOR))
    mock_repo = mock.MagicMock()
    mock_repo.branch = 'master'
    mock_repo.directory = '/root/repository'

    mock_repo_create = self.PatchObject(repository, 'RepoRepository',
                                        autospec=True, return_value=mock_repo)
    mock_clean = self.PatchObject(cbuildbot_launch, 'CleanBuildRoot',
                                  autospec=True)
    mock_checkout = self.PatchObject(cbuildbot_launch, 'InitialCheckout',
                                     autospec=True)
    mock_cleanup_chroot = self.PatchObject(cbuildbot_launch, 'CleanupChroot',
                                           autospec=True)
    mock_set_last_build_state = self.PatchObject(
        cbuildbot_launch, 'SetLastBuildState', autospec=True)

    expected_build_state = build_summary.BuildSummary(
        build_number=0, master_build_id=0, status=mock.ANY,
        buildroot_layout=2, branch='master')

    argv = ['-r', '/root', 'config']
    options = cbuildbot_launch.PreParseArguments(argv)
    cbuildbot_launch._main(options, argv)

    # Did we create the repo instance correctly?
    self.assertEqual(mock_repo_create.mock_calls,
                     [mock.call(EXPECTED_MANIFEST_URL, '/root/repository',
                                git_cache_dir=None, branch='master')])

    # Ensure we clean, as expected.
    self.assertEqual(mock_clean.mock_calls, [
        mock.call('/root', mock_repo, '/root/repository/.cache',
                  expected_build_state)])

    # Ensure we checkout, as expected.
    self.assertEqual(mock_checkout.mock_calls,
                     [mock.call(mock_repo)])

    # Ensure we invoke cbuildbot, as expected.
    self.assertCommandCalled(
        [
            '/root/repository/chromite/bin/cbuildbot',
            'config',
            '-r', '/root/repository',
            '--workspace', '/root/workspace',
            '--cache-dir', '/root/repository/.cache',
            # The duplication is a bug, but not harmful.
            '--cache-dir', '/root/repository/.cache',
        ],
        extra_env={'PATH': mock.ANY},
        cwd='/root/repository',
        check=False)

    # Ensure we saved the final state, as expected.
    self.assertEqual(expected_build_state.status,
                     constants.BUILDER_STATUS_PASSED)
    self.assertEqual(mock_set_last_build_state.mock_calls, [
        mock.call('/root', expected_build_state)])

    # Ensure we clean the chroot, as expected.
    mock_cleanup_chroot.assert_called_once_with('/root/repository')