#!/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.

import logging
import os
import cPickle
import sys

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

import mock

DEFAULT_BUILDROOT = '/tmp/foo/bar/buildroot'
DEFAULT_BUILDNUMBER = 12345
DEFAULT_BRANCH = 'TheBranch'
DEFAULT_CHROME_BRANCH = 'TheChromeBranch'
DEFAULT_VERSION_STRING = 'TheVersionString'
DEFAULT_BOARD = 'TheBoard'

DEFAULT_OPTIONS = cros_test_lib.EasyAttr(buildroot=DEFAULT_BUILDROOT,
                                         buildnumber=DEFAULT_BUILDNUMBER,
                                         branch=DEFAULT_BRANCH,
                                        )
DEFAULT_CONFIG = cros_test_lib.EasyAttr(
    master=True,
    boards=[DEFAULT_BOARD],
    child_configs=[cros_test_lib.EasyAttr(name='foo'),
                   cros_test_lib.EasyAttr(name='bar'),
                  ])


def _NewBuilderRun(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)


def _NewChildBuilderRun(child_index, options=None, config=None):
  """Create a ChildBuilderRun 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:
    ChildBuilderRun object.
  """
  run = _NewBuilderRun(options, config)
  return cbuildbot_run.ChildBuilderRun(run, child_index)


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 cros_test_lib.EasyAttr(**config_kwargs)


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

  def testPickleBuilderRun(self):
    run1 = _NewBuilderRun()
    run1.attrs.release_tag = 'TheReleaseTag'
    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')

  def testPickleChildBuilderRun(self):
    run1 = _NewChildBuilderRun(0)
    run1.attrs.release_tag = 'TheReleaseTag'
    run2 = cPickle.loads(cPickle.dumps(run1, cPickle.HIGHEST_PROTOCOL))

    self.assertEquals(run1.child_index, run2.child_index)
    self.assertEquals(run1.buildnumber, run2.buildnumber)
    self.assertEquals(run1.config.name, run2.config.name)
    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')


class BuilderRunTest(cros_test_lib.TestCase):
  """Test the BuilderRun class."""

  def testInit(self):
    run = _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))

  def testOptions(self):
    options = _ExtendDefaultOptions(foo=True, bar=10)
    run = _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 = _ExtendDefaultOptions(foo=True, bar=10)
    run = _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 = _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 _RunAccessor(self, method, 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: A BuilderRun method to call.
      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 = _NewBuilderRun(options=options, config=config)
    return method(run)

  def testDualEnableSetting(self):
    settings = {
        'prebuilts': cbuildbot_run.BuilderRun.ShouldUploadPrebuilts,
        'postsync_patch': cbuildbot_run.BuilderRun.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(
          cbuildbot_run.BuilderRun.ShouldReexecAfterSync,
          {'postsync_reexec': option_val, 'buildroot': build_root},
          {'postsync_reexec': config_val})

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


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

  def testGetVersionInfo(self):
    verinfo = object()

    with mock.patch('cbuildbot_run.manifest_version.VersionInfo.from_repo',
                    return_value=verinfo) as m:
      result = cbuildbot_run.BuilderRun.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.BuilderRun, '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 = _NewBuilderRun()
      if release_tag is not None:
        run.attrs.release_tag = 'RT'

      # 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(cros_test_lib.TestCase):
  """Test the ChildBuilderRun class"""

  def testInit(self):
    crun = _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.assertEquals(0, crun.child_index)
    self.assertTrue(isinstance(crun.attrs, cbuildbot_run.RunAttributes))


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