# -*- coding: utf-8 -*-
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Test the cbuildbot_run module."""

from __future__ import print_function

import pickle
import sys
import time

import mock

from chromite.cbuildbot import cbuildbot_run
from chromite.lib import config_lib
from chromite.lib import config_lib_unittest
from chromite.lib import cros_test_lib
from chromite.lib import parallel


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


DEFAULT_ARCHIVE_GS_PATH = 'bogus_bucket/TheArchiveBase'
DEFAULT_ARCHIVE_BASE = 'gs://%s' % DEFAULT_ARCHIVE_GS_PATH
DEFAULT_BUILDROOT = '/tmp/foo/bar/buildroot'
DEFAULT_BUILDNUMBER = 12345
DEFAULT_BRANCH = 'TheBranch'
DEFAULT_CHROME_BRANCH = 'TheChromeBranch'
DEFAULT_VERSION_STRING = 'TheVersionString'
DEFAULT_BOARD = 'TheBoard'
DEFAULT_BOT_NAME = 'TheCoolBot'

# pylint: disable=protected-access

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)


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)


class ExceptionsTest(cros_test_lib.TestCase):
  """Test that the exceptions in the module are sane."""

  def _TestException(self, err, expected_startswith):
    """Test that str and pickle behavior of |err| are as expected."""
    err2 = pickle.loads(pickle.dumps(err, pickle.HIGHEST_PROTOCOL))

    self.assertTrue(str(err).startswith(expected_startswith))
    self.assertEqual(str(err), str(err2))

  def testParallelAttributeError(self):
    """Test ParallelAttributeError message and pickle behavior."""
    err1 = cbuildbot_run.ParallelAttributeError('SomeAttr')
    self._TestException(err1, 'No such parallel run attribute')

    err2 = cbuildbot_run.ParallelAttributeError('SomeAttr', 'SomeBoard',
                                                'SomeTarget')
    self._TestException(err2, 'No such board-specific parallel run attribute')

  def testAttrSepCountError(self):
    """Test AttrSepCountError message and pickle behavior."""
    err1 = cbuildbot_run.AttrSepCountError('SomeAttr')
    self._TestException(err1, 'Attribute name has an unexpected number')

  def testAttrNotPickleableError(self):
    """Test AttrNotPickleableError message and pickle behavior."""
    err1 = cbuildbot_run.AttrNotPickleableError('SomeAttr', 'SomeValue')
    self._TestException(err1, 'Run attribute "SomeAttr" value cannot')


# TODO(mtennant): Turn this into a PartialMock.
class _BuilderRunTestCase(cros_test_lib.MockTestCase):
  """Provide methods for creating BuilderRun or ChildBuilderRun."""

  def setUp(self):
    self._manager = parallel.Manager()

    # Mimic entering a 'with' statement.
    # Pylint-1.9 has a false positive on this for some reason.
    self._manager.__enter__()  # pylint: disable=no-value-for-parameter

  def tearDown(self):
    # Mimic exiting a 'with' statement.
    self._manager.__exit__(None, None, None)

  def _NewRunAttributes(self):
    return cbuildbot_run.RunAttributes(self._manager)

  def _NewBuilderRun(self, options=None, config=None):
    """Create a BuilderRun objection from options and config values.

    Args:
      options: Specify options or default to DEFAULT_OPTIONS.
      config: Specify build config or default to DEFAULT_CONFIG.

    Returns:
      BuilderRun object.
    """
    options = options or DEFAULT_OPTIONS
    config = config or DEFAULT_CONFIG
    site_config = config_lib_unittest.MockSiteConfig()
    site_config[config.name] = config

    return cbuildbot_run.BuilderRun(options, site_config, config, self._manager)

  def _NewChildBuilderRun(self, child_index, options=None, config=None):
    """Create a ChildBuilderRun objection from options and config values.

    Args:
      child_index: Index of child config to use within config.
      options: Specify options or default to DEFAULT_OPTIONS.
      config: Specify build config or default to DEFAULT_CONFIG.

    Returns:
      ChildBuilderRun object.
    """
    run = self._NewBuilderRun(options, config)
    return cbuildbot_run.ChildBuilderRun(run, child_index)


class BuilderRunPickleTest(_BuilderRunTestCase):
  """Make sure BuilderRun objects can be pickled."""

  def setUp(self):
    self.real_config = config_lib.GetConfig()['test-ap-group']
    self.PatchObject(cbuildbot_run._BuilderRunBase, 'GetVersion',
                     return_value=DEFAULT_VERSION)

  def _TestPickle(self, run1):
    self.assertEqual(DEFAULT_VERSION, run1.GetVersion())
    run1.attrs.release_tag = 'TheReleaseTag'

    # Accessing a method on BuilderRun has special behavior, so access and
    # use one before pickling.
    patch_after_sync = run1.ShouldPatchAfterSync()

    # Access the archive object before pickling, too.
    upload_url = run1.GetArchive().upload_url

    # Pickle and unpickle run1 into run2.
    run2 = pickle.loads(pickle.dumps(run1, pickle.HIGHEST_PROTOCOL))

    self.assertEqual(run1.buildnumber, run2.buildnumber)
    self.assertEqual(run1.config.boards, run2.config.boards)
    self.assertEqual(run1.options.branch, run2.options.branch)
    self.assertEqual(run1.attrs.release_tag, run2.attrs.release_tag)
    self.assertRaises(AttributeError, getattr, run1.attrs, 'manifest_manager')
    self.assertRaises(AttributeError, getattr, run2.attrs, 'manifest_manager')
    self.assertEqual(patch_after_sync, run2.ShouldPatchAfterSync())
    self.assertEqual(upload_url, run2.GetArchive().upload_url)

    # The attrs objects should be identical.
    self.assertIs(run1.attrs, run2.attrs)

    # And the run objects themselves are different.
    self.assertIsNot(run1, run2)

  def testPickleBuilderRun(self):
    self._TestPickle(self._NewBuilderRun(config=self.real_config))

  def testPickleChildBuilderRun(self):
    self._TestPickle(self._NewChildBuilderRun(0, config=self.real_config))


class BuilderRunTest(_BuilderRunTestCase):
  """Test the BuilderRun class."""

  def testInit(self):
    with mock.patch.object(cbuildbot_run._BuilderRunBase, 'GetVersion') as m:
      m.return_value = DEFAULT_VERSION

      run = self._NewBuilderRun()
      self.assertEqual(DEFAULT_BUILDROOT, run.buildroot)
      self.assertEqual(DEFAULT_BUILDNUMBER, run.buildnumber)
      self.assertEqual(DEFAULT_BRANCH, run.manifest_branch)
      self.assertEqual(DEFAULT_OPTIONS, run.options)
      self.assertEqual(DEFAULT_CONFIG, run.config)
      self.assertTrue(isinstance(run.attrs, cbuildbot_run.RunAttributes))
      self.assertTrue(isinstance(run.GetArchive(),
                                 cbuildbot_run.archive_lib.Archive))

      # Make sure methods behave normally, since BuilderRun messes with them.
      meth1 = run.GetVersionInfo
      meth2 = run.GetVersionInfo
      self.assertEqual(meth1.__name__, meth2.__name__)

      # We actually do not support identity and equality checks right now.
      self.assertNotEqual(meth1, meth2)
      self.assertIsNot(meth1, meth2)

  def testOptions(self):
    options = _ExtendDefaultOptions(foo=True, bar=10)
    run = self._NewBuilderRun(options=options)

    self.assertEqual(True, run.options.foo)
    self.assertEqual(10, run.options.__getattr__('bar'))
    self.assertRaises(AttributeError, run.options.__getattr__, 'baz')

  def testConfig(self):
    config = _ExtendDefaultConfig(foo=True, bar=10)
    run = self._NewBuilderRun(config=config)

    self.assertEqual(True, run.config.foo)
    self.assertEqual(10, run.config.__getattr__('bar'))
    self.assertRaises(AttributeError, run.config.__getattr__, 'baz')

  def testAttrs(self):
    run = self._NewBuilderRun()

    # manifest_manager is a valid run attribute.  It gives Attribute error
    # if accessed before being set, but thereafter works fine.
    self.assertRaises(AttributeError, run.attrs.__getattribute__,
                      'manifest_manager')
    run.attrs.manifest_manager = 'foo'
    self.assertEqual('foo', run.attrs.manifest_manager)
    self.assertEqual('foo', run.attrs.__getattribute__('manifest_manager'))

    # foobar is not a valid run attribute.  It gives AttributeError when
    # accessed or changed.
    self.assertRaises(AttributeError, run.attrs.__getattribute__, 'foobar')
    self.assertRaises(AttributeError, run.attrs.__setattr__, 'foobar', 'foo')

  def testArchive(self):
    run = self._NewBuilderRun()

    with mock.patch.object(cbuildbot_run._BuilderRunBase, 'GetVersion') as m:
      m.return_value = DEFAULT_VERSION

      archive = run.GetArchive()

      # Check archive.archive_path.
      expected = ('%s/%s/%s/%s' %
                  (DEFAULT_BUILDROOT,
                   cbuildbot_run.archive_lib.Archive._BUILDBOT_ARCHIVE,
                   DEFAULT_BOT_NAME, DEFAULT_VERSION))
      self.assertEqual(expected, archive.archive_path)

      # Check archive.upload_url.
      expected = '%s/%s/%s' % (DEFAULT_ARCHIVE_BASE, DEFAULT_BOT_NAME,
                               DEFAULT_VERSION)
      self.assertEqual(expected, archive.upload_url)

      # Check archive.download_url.
      expected = '%s%s/%s/%s' % (
          cbuildbot_run.archive_lib.gs.PRIVATE_BASE_HTTPS_DOWNLOAD_URL,
          DEFAULT_ARCHIVE_GS_PATH, DEFAULT_BOT_NAME, DEFAULT_VERSION)
      self.assertEqual(expected, archive.download_url)

  def testShouldUploadPrebuilts(self):
    # Enabled
    options = _ExtendDefaultOptions(prebuilts=True)
    config = _ExtendDefaultConfig(prebuilts=True)
    run = self._NewBuilderRun(options=options, config=config)
    self.assertTrue(run.ShouldUploadPrebuilts())

    # Config disabled.
    options = _ExtendDefaultOptions(prebuilts=True)
    config = _ExtendDefaultConfig(prebuilts=False)
    run = self._NewBuilderRun(options=options, config=config)
    self.assertFalse(run.ShouldUploadPrebuilts())

    # Option disabled.
    options = _ExtendDefaultOptions(prebuilts=False)
    config = _ExtendDefaultConfig(prebuilts=True)
    run = self._NewBuilderRun(options=options, config=config)
    self.assertFalse(run.ShouldUploadPrebuilts())

  def testShouldPatchAfterSync(self):
    # Enabled
    options = _ExtendDefaultOptions(postsync_patch=True)
    config = _ExtendDefaultConfig(postsync_patch=True)
    run = self._NewBuilderRun(options=options, config=config)
    self.assertTrue(run.ShouldPatchAfterSync())

    # Config disabled.
    options = _ExtendDefaultOptions(postsync_patch=True)
    config = _ExtendDefaultConfig(postsync_patch=False)
    run = self._NewBuilderRun(options=options, config=config)
    self.assertFalse(run.ShouldPatchAfterSync())

    # Option disabled.
    options = _ExtendDefaultOptions(postsync_patch=False)
    config = _ExtendDefaultConfig(postsync_patch=True)
    run = self._NewBuilderRun(options=options, config=config)
    self.assertFalse(run.ShouldPatchAfterSync())

  def testShouldReexecAfterSync(self):
    # Normal Execution
    options = _ExtendDefaultOptions(postsync_reexec=True, resume=False)
    config = _ExtendDefaultConfig(postsync_reexec=True)
    run = self._NewBuilderRun(options=options, config=config)
    self.assertTrue(run.ShouldReexecAfterSync())

    # Normal after Rexec
    options = _ExtendDefaultOptions(postsync_reexec=True, resume=True)
    config = _ExtendDefaultConfig(postsync_reexec=True)
    run = self._NewBuilderRun(options=options, config=config)
    self.assertFalse(run.ShouldReexecAfterSync())

    # Turned off in config.
    options = _ExtendDefaultOptions(postsync_reexec=True, resume=False)
    config = _ExtendDefaultConfig(postsync_reexec=False)
    run = self._NewBuilderRun(options=options, config=config)
    self.assertFalse(run.ShouldReexecAfterSync())

    # Turned off on command line.
    options = _ExtendDefaultOptions(postsync_reexec=False, resume=False)
    config = _ExtendDefaultConfig(postsync_reexec=True)
    run = self._NewBuilderRun(options=options, config=config)
    self.assertFalse(run.ShouldReexecAfterSync())

  def testInProduction(self):
    run = self._NewBuilderRun()
    self.assertFalse(run.InProduction())

  def testInEmailReportingEnvironment(self):
    run = self._NewBuilderRun()
    self.assertFalse(run.InEmailReportingEnvironment())


class GetVersionTest(_BuilderRunTestCase):
  """Test the GetVersion and GetVersionInfo methods of BuilderRun class."""

  # pylint: disable=protected-access

  def testGetVersionInfoNotSet(self):
    """Verify we throw an error when the version hasn't been set."""
    run = self._NewBuilderRun()
    self.assertRaises(RuntimeError, run.GetVersionInfo)

  def testGetVersionInfo(self):
    """Verify we return the right version info value."""
    # Prepare a real BuilderRun object with a version_info tag.
    run = self._NewBuilderRun()
    verinfo = object()
    run.attrs.version_info = verinfo
    result = run.GetVersionInfo()
    self.assertEqual(verinfo, result)

  def _TestGetVersionReleaseTag(self, release_tag, cidb_id=None):
    with mock.patch.object(cbuildbot_run._BuilderRunBase,
                           'GetVersionInfo') as m:
      verinfo_mock = mock.Mock()
      verinfo_mock.chrome_branch = DEFAULT_CHROME_BRANCH
      verinfo_mock.VersionString = mock.Mock(return_value='VS')
      m.return_value = verinfo_mock

      # Prepare a real BuilderRun object with a release tag.
      run = self._NewBuilderRun()
      run.attrs.release_tag = release_tag
      if cidb_id:
        run.attrs.metadata.UpdateWithDict(
            {'build_id': cidb_id})

      # Run the test return the result.
      result = run.GetVersion()
      m.assert_called_once_with()
      if release_tag is None:
        verinfo_mock.VersionString.assert_called_once()

      return result

  def testGetVersionReleaseTag(self):
    result = self._TestGetVersionReleaseTag('RT')
    self.assertEqual('R%s-%s' % (DEFAULT_CHROME_BRANCH, 'RT'), result)

  def testGetVersionNoReleaseTag(self):
    cidb_id = 12345678
    result = self._TestGetVersionReleaseTag(None, cidb_id)
    expected_result = ('R%s-%s-b%s' %
                       (DEFAULT_CHROME_BRANCH, 'VS', cidb_id))
    self.assertEqual(result, expected_result)

  def testGetVersionNoReleaseTagNoCidb(self):
    result = self._TestGetVersionReleaseTag(None)
    expected_result = ('R%s-%s-b%s' %
                       (DEFAULT_CHROME_BRANCH, 'VS', 0))
    self.assertEqual(result, expected_result)


class ChildBuilderRunTest(_BuilderRunTestCase):
  """Test the ChildBuilderRun class"""

  def testInit(self):
    with mock.patch.object(cbuildbot_run._BuilderRunBase, 'GetVersion') as m:
      m.return_value = DEFAULT_VERSION

      crun = self._NewChildBuilderRun(0)
      self.assertEqual(DEFAULT_BUILDROOT, crun.buildroot)
      self.assertEqual(DEFAULT_BUILDNUMBER, crun.buildnumber)
      self.assertEqual(DEFAULT_BRANCH, crun.manifest_branch)
      self.assertEqual(DEFAULT_OPTIONS, crun.options)
      self.assertEqual(DEFAULT_CONFIG.child_configs[0], crun.config)
      self.assertEqual('foo', crun.config.name)
      self.assertTrue(isinstance(crun.attrs, cbuildbot_run.RunAttributes))
      self.assertTrue(isinstance(crun.GetArchive(),
                                 cbuildbot_run.archive_lib.Archive))

      # Make sure methods behave normally, since BuilderRun messes with them.
      meth1 = crun.GetVersionInfo
      meth2 = crun.GetVersionInfo
      self.assertEqual(meth1.__name__, meth2.__name__)

      # We actually do not support identity and equality checks right now.
      self.assertNotEqual(meth1, meth2)
      self.assertIsNot(meth1, meth2)


class RunAttributesTest(_BuilderRunTestCase):
  """Test the RunAttributes class."""

  BOARD = 'SomeBoard'
  TARGET = 'SomeConfigName'
  VALUE = 'AnyValueWillDo'

  # Any valid board-specific attribute will work here.
  BATTR = 'breakpad_symbols_generated'

  def testRegisterBoardTarget(self):
    """Test behavior of attributes before and after registering board target."""
    ra = self._NewRunAttributes()

    with self.assertRaises(AssertionError):
      ra.HasBoardParallel(self.BATTR, self.BOARD, self.TARGET)

    ra.RegisterBoardAttrs(self.BOARD, self.TARGET)

    self.assertFalse(ra.HasBoardParallel(self.BATTR, self.BOARD, self.TARGET))

    ra.SetBoardParallel(self.BATTR, 'TheValue', self.BOARD, self.TARGET)

    self.assertTrue(ra.HasBoardParallel(self.BATTR, self.BOARD, self.TARGET))

  def testSetGet(self):
    """Test simple set/get of regular and parallel run attributes."""
    ra = self._NewRunAttributes()
    value = 'foobar'

    # The __slots__ logic above confuses pylint.
    # https://bitbucket.org/logilab/pylint/issue/380/
    # pylint: disable=assigning-non-slot

    # Set/Get a regular run attribute using direct access.
    ra.release_tag = value
    self.assertEqual(value, ra.release_tag)

    # Set/Get of a parallel run attribute using direct access fails.
    self.assertRaises(AttributeError, setattr, ra, 'unittest_value', value)
    self.assertRaises(AttributeError, getattr, ra, 'unittest_value')

    # Set/Get of a parallel run attribute with supported interface.
    ra.SetParallel('unittest_value', value)
    self.assertEqual(value, ra.GetParallel('unittest_value'))

    # Set/Get a board parallel run attribute, testing both the encouraged
    # interface and the underlying interface.
    ra.RegisterBoardAttrs(self.BOARD, self.TARGET)
    ra.SetBoardParallel(self.BATTR, value, self.BOARD, self.TARGET)
    self.assertEqual(value,
                     ra.GetBoardParallel(self.BATTR, self.BOARD, self.TARGET))

  def testSetDefault(self):
    """Test setting default value of parallel run attributes."""
    ra = self._NewRunAttributes()
    value = 'foobar'

    # Attribute starts off not set.
    self.assertFalse(ra.HasParallel('unittest_value'))

    # Use SetParallelDefault to set it.
    ra.SetParallelDefault('unittest_value', value)
    self.assertTrue(ra.HasParallel('unittest_value'))
    self.assertEqual(value, ra.GetParallel('unittest_value'))

    # Calling SetParallelDefault again has no effect.
    ra.SetParallelDefault('unittest_value', 'junk')
    self.assertTrue(ra.HasParallel('unittest_value'))
    self.assertEqual(value, ra.GetParallel('unittest_value'))

    # Run through same sequence for a board-specific attribute.
    with self.assertRaises(AssertionError):
      ra.HasBoardParallel(self.BATTR, self.BOARD, self.TARGET)
    ra.RegisterBoardAttrs(self.BOARD, self.TARGET)
    self.assertFalse(ra.HasBoardParallel(self.BATTR, self.BOARD, self.TARGET))

    # Use SetBoardParallelDefault to set it.
    ra.SetBoardParallelDefault(self.BATTR, value, self.BOARD, self.TARGET)
    self.assertTrue(ra.HasBoardParallel(self.BATTR, self.BOARD, self.TARGET))
    self.assertEqual(value,
                     ra.GetBoardParallel(self.BATTR, self.BOARD, self.TARGET))

    # Calling SetBoardParallelDefault again has no effect.
    ra.SetBoardParallelDefault(self.BATTR, 'junk', self.BOARD, self.TARGET)
    self.assertTrue(ra.HasBoardParallel(self.BATTR, self.BOARD, self.TARGET))
    self.assertEqual(value,
                     ra.GetBoardParallel(self.BATTR, self.BOARD, self.TARGET))

  def testAttributeError(self):
    """Test accessing run attributes that do not exist."""
    ra = self._NewRunAttributes()
    value = 'foobar'

    # Set/Get on made up attribute name.
    self.assertRaises(AttributeError, setattr, ra, 'foo', value)
    self.assertRaises(AttributeError, getattr, ra, 'foo')

    # A board/target value is valid, but only if it is registered first.
    self.assertRaises(AssertionError, ra.GetBoardParallel,
                      self.BATTR, self.BOARD, self.TARGET)
    ra.RegisterBoardAttrs(self.BOARD, self.TARGET)
    self.assertRaises(AttributeError, ra.GetBoardParallel,
                      self.BATTR, self.BOARD, self.TARGET)


class BoardRunAttributesTest(_BuilderRunTestCase):
  """Test the BoardRunAttributes class."""

  BOARD = 'SomeBoard'
  TARGET = 'SomeConfigName'
  VALUE = 'AnyValueWillDo'

  # Any valid board-specific attribute will work here.
  BATTR = 'breakpad_symbols_generated'

  class _SetAttr(object):
    """Stage-like class to set attr on a BoardRunAttributes obj."""
    def __init__(self, bra, attr, value, delay=1):
      self.bra = bra
      self.attr = attr
      self.value = value
      self.delay = delay

    def Run(self):
      if self.delay:
        time.sleep(self.delay)
      self.bra.SetParallel(self.attr, self.value)

  class _WaitForAttr(object):
    """Stage-like class to wait for attr on BoardRunAttributes obj."""
    def __init__(self, bra, attr, expected_value, timeout=10):
      self.bra = bra
      self.attr = attr
      self.expected_value = expected_value
      self.timeout = timeout

    def GetParallel(self):
      return self.bra.GetParallel(self.attr, timeout=self.timeout)

  class _CheckWaitForAttr(_WaitForAttr):
    """Stage-like class to wait for then check attr on BoardRunAttributes."""
    def Run(self):
      value = self.GetParallel()
      assert value == self.expected_value, \
          ('For run attribute %s expected value %r but got %r.' %
           (self.attr, self.expected_value, value))

  class _TimeoutWaitForAttr(_WaitForAttr):
    """Stage-like class to time-out waiting for attr on BoardRunAttributes."""
    def Run(self):
      try:
        self.GetParallel()
        assert False, 'Expected AttrTimeoutError'
      except cbuildbot_run.AttrTimeoutError:
        pass

  def setUp(self):
    self.ra = self._NewRunAttributes()
    self.bra = self.ra.RegisterBoardAttrs(self.BOARD, self.TARGET)

  def _TestParallelSetGet(self, stage_args):
    """Helper to run "stages" in parallel, according to |stage_args|.

    Args:
      stage_args: List of tuples of the form (stage_object, extra_args, ...)
        where stage_object has a Run method which takes a BoardRunAttributes
        object as the first argument and extra_args for the remaining arguments.
    """
    stages = [a[0](self.bra, *a[1:]) for a in stage_args]
    steps = [stage.Run for stage in stages]

    parallel.RunParallelSteps(steps)

  def testParallelSetGetFast(self):
    """Pass the parallel run attribute around with no delay."""
    stage_args = [
        (self._CheckWaitForAttr, self.BATTR, self.VALUE),
        (self._SetAttr, self.BATTR, self.VALUE),
    ]
    self._TestParallelSetGet(stage_args)
    self.assertRaises(AttributeError,
                      getattr, self.bra, self.BATTR)
    self.assertEqual(self.VALUE, self.bra.GetParallel(self.BATTR))

  def testParallelSetGetSlow(self):
    """Pass the parallel run attribute around with a delay."""
    stage_args = [
        (self._SetAttr, self.BATTR, self.VALUE, 10),
        (self._TimeoutWaitForAttr, self.BATTR, self.VALUE, 2),
    ]
    self._TestParallelSetGet(stage_args)
    self.assertEqual(self.VALUE, self.bra.GetParallel(self.BATTR))

  def testParallelSetGetManyGets(self):
    """Set the parallel run attribute in one stage, access in many stages."""
    stage_args = [
        (self._SetAttr, self.BATTR, self.VALUE, 8),
        (self._CheckWaitForAttr, self.BATTR, self.VALUE, 16),
        (self._CheckWaitForAttr, self.BATTR, self.VALUE, 16),
        (self._CheckWaitForAttr, self.BATTR, self.VALUE, 16),
        (self._TimeoutWaitForAttr, self.BATTR, self.VALUE, 1),
    ]
    self._TestParallelSetGet(stage_args)
    self.assertEqual(self.VALUE, self.bra.GetParallel(self.BATTR))

  def testParallelSetGetManySets(self):
    """Set the parallel run attribute in many stages, access in one stage."""
    # Three "stages" set the value, with increasing delays.  The stage that
    # checks the value should get the first value set.
    stage_args = [
        (self._SetAttr, self.BATTR, self.VALUE + '1', 1),
        (self._SetAttr, self.BATTR, self.VALUE + '2', 11),
        (self._CheckWaitForAttr, self.BATTR, self.VALUE + '1', 12),
    ]
    self._TestParallelSetGet(stage_args)
    self.assertEqual(self.VALUE + '2', self.bra.GetParallel(self.BATTR))

  def testSetGet(self):
    """Test that board-specific attrs do not work with set/get directly."""
    self.assertRaises(AttributeError, setattr,
                      self.bra, 'breakpad_symbols_generated', self.VALUE)
    self.assertRaises(AttributeError, getattr,
                      self.bra, 'breakpad_symbols_generated')

  def testAccessRegularRunAttr(self):
    """Test that regular attributes are not known to BoardRunAttributes."""
    self.assertRaises(AttributeError, getattr, self.bra, 'release_tag')
    self.assertRaises(AttributeError, setattr, self.bra, 'release_tag', 'foo')
