#!/usr/bin/python

# 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."""

import logging
import os
import cPickle
import sys
import time

sys.path.insert(0, os.path.abspath('%s/../..' % os.path.dirname(__file__)))
from chromite.buildbot import cbuildbot_config
from chromite.buildbot import cbuildbot_run
from chromite.lib import cros_test_lib
from chromite.lib import parallel

import mock

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'

# 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,
    postsync_patch=True,
)
DEFAULT_CONFIG = cbuildbot_config._config(
    name=DEFAULT_BOT_NAME,
    master=True,
    boards=[DEFAULT_BOARD],
    postsync_patch=True,
    child_configs=[cbuildbot_config._config(name='foo', postsync_patch=False,
                                            boards=[]),
                   cbuildbot_config._config(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 cbuildbot_config._config(**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 = cPickle.loads(cPickle.dumps(err, cPickle.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.
    self._manager.__enter__()

  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

    return cbuildbot_run.BuilderRun(options, 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 = cbuildbot_config.config['x86-alex-release-group']
    self.PatchObject(cbuildbot_run._BuilderRunBase, 'GetVersion',
                     return_value=DEFAULT_VERSION)

  def _TestPickle(self, run1):
    self.assertEquals(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 = cPickle.loads(cPickle.dumps(run1, cPickle.HIGHEST_PROTOCOL))

    self.assertEquals(run1.buildnumber, run2.buildnumber)
    self.assertEquals(run1.config.boards, run2.config.boards)
    self.assertEquals(run1.options.branch, run2.options.branch)
    self.assertEquals(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.assertEquals(patch_after_sync, run2.ShouldPatchAfterSync())
    self.assertEquals(upload_url, run2.GetArchive().upload_url)

    # The attrs objects should be identical.
    self.assertTrue(run1.attrs is run2.attrs)

    # And the run objects themselves are different.
    self.assertFalse(run1 is 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.assertEquals(DEFAULT_BUILDROOT, run.buildroot)
      self.assertEquals(DEFAULT_BUILDNUMBER, run.buildnumber)
      self.assertEquals(DEFAULT_BRANCH, run.manifest_branch)
      self.assertEquals(DEFAULT_OPTIONS, run.options)
      self.assertEquals(DEFAULT_CONFIG, run.config)
      self.assertTrue(isinstance(run.attrs, cbuildbot_run.RunAttributes))
      self.assertTrue(isinstance(run.GetArchive(),
                                 cbuildbot_run.cbuildbot_archive.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.assertFalse(meth1 is meth2)

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

    self.assertEquals(True, run.options.foo)
    self.assertEquals(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.assertEquals(True, run.config.foo)
    self.assertEquals(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.assertEquals('foo', run.attrs.manifest_manager)
    self.assertEquals('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.cbuildbot_archive.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.cbuildbot_archive.gs.PRIVATE_BASE_HTTPS_URL,
                   DEFAULT_ARCHIVE_GS_PATH, DEFAULT_BOT_NAME, DEFAULT_VERSION))
      self.assertEqual(expected, archive.download_url)

  def _RunAccessor(self, method_name, options_dict, config_dict):
    """Run the given accessor method of the BuilderRun class.

    Create a BuilderRun object with the options and config provided and
    then return the result of calling the given method on it.

    Args:
      method_name: A BuilderRun method to call, specified by name.
      options_dict: Extend default options with this.
      config_dict: Extend default config with this.

    Returns:
      Result of calling the given method.
    """
    options = _ExtendDefaultOptions(**options_dict)
    config = _ExtendDefaultConfig(**config_dict)
    run = self._NewBuilderRun(options=options, config=config)
    method = getattr(run, method_name)
    self.assertEqual(method.__name__, method_name)
    return method()

  def testDualEnableSetting(self):
    settings = {
        'prebuilts': 'ShouldUploadPrebuilts',
        'postsync_patch': 'ShouldPatchAfterSync',
    }

    # Both option and config enabled should result in True.
    # Create truth table with three variables in this order:
    # <key> option value, <key> config value (e.g. <key> == 'prebuilts').
    truth_table = cros_test_lib.TruthTable(inputs=[(True, True)])

    for inputs in truth_table:
      option_val, config_val = inputs
      for key, accessor in settings.iteritems():
        self.assertEquals(
            self._RunAccessor(accessor, {key: option_val}, {key: config_val}),
            truth_table.GetOutput(inputs))

  def testShouldReexecAfterSync(self):
    # If option and config have postsync_reexec enabled, and this file is not
    # in the build root, then we expect ShouldReexecAfterSync to return True.

    # Construct a truth table across three variables in this order:
    # postsync_reexec option value, postsync_reexec config value, same_root.
    truth_table = cros_test_lib.TruthTable(inputs=[(True, True, False)])

    for inputs in truth_table:
      option_val, config_val, same_root = inputs

      if same_root:
        build_root = os.path.dirname(os.path.dirname(__file__))
      else:
        build_root = DEFAULT_BUILDROOT

      result = self._RunAccessor(
          'ShouldReexecAfterSync',
          {'postsync_reexec': option_val, 'buildroot': build_root},
          {'postsync_reexec': config_val})

      self.assertEquals(result, truth_table.GetOutput(inputs))


class GetVersionTest(_BuilderRunTestCase):
  """Test the GetVersion and GetVersionInfo methods of BuilderRun class."""
  # Access to protected member.
  # pylint: disable=W0212

  def testGetVersionInfo(self):
    verinfo = object()

    with mock.patch('cbuildbot_run.manifest_version.VersionInfo.from_repo',
                    return_value=verinfo) as m:
      result = cbuildbot_run._BuilderRunBase.GetVersionInfo(DEFAULT_BUILDROOT)
      self.assertEquals(result, verinfo)

      m.assert_called_once_with(DEFAULT_BUILDROOT)

  def _TestGetVersionReleaseTag(self, release_tag):
    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

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

      return result

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

  def testGetVersionNoReleaseTag(self):
    result = self._TestGetVersionReleaseTag(None)
    expected_result = ('R%s-%s-b%s' %
                       (DEFAULT_CHROME_BRANCH, 'VS', DEFAULT_BUILDNUMBER))
    self.assertEquals(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.assertEquals(DEFAULT_BUILDROOT, crun.buildroot)
      self.assertEquals(DEFAULT_BUILDNUMBER, crun.buildnumber)
      self.assertEquals(DEFAULT_BRANCH, crun.manifest_branch)
      self.assertEquals(DEFAULT_OPTIONS, crun.options)
      self.assertEquals(DEFAULT_CONFIG.child_configs[0], crun.config)
      self.assertEquals('foo', crun.config.name)
      self.assertTrue(isinstance(crun.attrs, cbuildbot_run.RunAttributes))
      self.assertTrue(isinstance(crun.GetArchive(),
                                 cbuildbot_run.cbuildbot_archive.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.assertFalse(meth1 is 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'
  UNIQUIFIED_BATTR = cbuildbot_run.RunAttributes._GetBoardAttrName(
      BATTR, BOARD, TARGET)

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

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

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

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

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

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

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

    # 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))
    self.assertEqual(value,
                     ra.GetParallel(self.UNIQUIFIED_BATTR))

  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.

    # Attribute starts off not set.
    self.assertFalse(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')

    # self.UNIQUIFIED_BATTR is valid, but only if board/target registered first.
    self.assertRaises(AttributeError, ra.GetBoardParallel,
                      self.BATTR, self.BOARD, self.TARGET)
    self.assertRaises(AttributeError, ra.SetParallel,
                      self.UNIQUIFIED_BATTR, value)
    self.assertRaises(AttributeError, ra.GetParallel, self.UNIQUIFIED_BATTR)


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')


if __name__ == '__main__':
  cros_test_lib.main(level=logging.DEBUG)
