# Copyright (c) 2013 The ChromiumOS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Task unittest.

Part of the Chrome build flags optimization.
"""

__author__ = 'yuhenglong@google.com (Yuheng Long)'

import random
import sys
import unittest

import task
from task import Task

# The number of flags be tested.
NUM_FLAGS = 20

# The random build result values used to test get set result method.
RANDOM_BUILD_RESULT = 100

# The random test result values used to test get set result method.
RANDOM_TESTRESULT = 100


class MockFlagSet(object):
  """This class emulates a set of flags.

  It returns the flags and hash value, when the FormattedForUse method and the
  __hash__ method is called, respectively. These values are initialized when the
  MockFlagSet instance is constructed.
  """

  def __init__(self, flags=0, hash_value=-1):
    self._flags = flags
    self._hash_value = hash_value

  def __eq__(self, other):
    assert isinstance(other, MockFlagSet)
    return self._flags == other.FormattedForUse()

  def FormattedForUse(self):
    return self._flags

  def __hash__(self):
    return self._hash_value

  def GetHash(self):
    return self._hash_value


class TaskTest(unittest.TestCase):
  """This class test the Task class."""

  def testEqual(self):
    """Test the equal method of the task.

    Two tasks are equal if and only if their encapsulated flag_sets are equal.
    """

    flags = range(NUM_FLAGS)

    # Two tasks having the same flag set should be equivalent.
    flag_sets = [MockFlagSet(flag) for flag in flags]
    for flag_set in flag_sets:
      assert Task(flag_set) == Task(flag_set)

    # Two tasks having different flag set should be different.
    for flag_set in flag_sets:
      test_task = Task(flag_set)
      other_flag_sets = [flags for flags in flag_sets if flags != flag_set]
      for flag_set1 in other_flag_sets:
        assert test_task != Task(flag_set1)

  def testHash(self):
    """Test the hash method of the task.

    Two tasks are equal if and only if their encapsulated flag_sets are equal.
    """

    # Random identifier that is not relevant in this test.
    identifier = random.randint(-sys.maxint - 1, -1)

    flag_sets = [MockFlagSet(identifier, value) for value in range(NUM_FLAGS)]
    for flag_set in flag_sets:
      # The hash of a task is the same as the hash of its flag set.
      hash_task = Task(flag_set)
      hash_value = hash(hash_task)
      assert hash_value == flag_set.GetHash()

      # The hash of a task does not change.
      assert hash_value == hash(hash_task)

  def testGetIdentifier(self):
    """Test the get identifier method of the task.

    The get identifier method should returns the flag set in the build stage.
    """

    flag_sets = [MockFlagSet(flag) for flag in range(NUM_FLAGS)]
    for flag_set in flag_sets:
      identifier_task = Task(flag_set)

      identifier = identifier_task.GetIdentifier(task.BUILD_STAGE)

      # The task formats the flag set into a string.
      assert identifier == str(flag_set.FormattedForUse())

  def testGetSetResult(self):
    """Test the get and set result methods of the task.

    The get result method should return the same results as were set.
    """

    flag_sets = [MockFlagSet(flag) for flag in range(NUM_FLAGS)]
    for flag_set in flag_sets:
      result_task = Task(flag_set)

      # The get result method should return the same results as were set, in
      # build stage. Currently, the build result is a 5-element tuple containing
      # the checksum of the result image, the performance cost of the build, the
      # compilation image, the length of the build, and the length of the text
      # section of the build.
      result = tuple([random.randint(0, RANDOM_BUILD_RESULT) for _ in range(5)])
      result_task.SetResult(task.BUILD_STAGE, result)
      assert result == result_task.GetResult(task.BUILD_STAGE)

      # The checksum is the identifier of the test stage.
      identifier = result_task.GetIdentifier(task.TEST_STAGE)
      # The first element of the result tuple is the checksum.
      assert identifier == result[0]

      # The get result method should return the same results as were set, in
      # test stage.
      random_test_result = random.randint(0, RANDOM_TESTRESULT)
      result_task.SetResult(task.TEST_STAGE, random_test_result)
      test_result = result_task.GetResult(task.TEST_STAGE)
      assert test_result == random_test_result

  def testDone(self):
    """Test the done methods of the task.

    The done method should return false is the task has not perform and return
    true after the task is finished.
    """

    flags = range(NUM_FLAGS)

    flag_sets = [MockFlagSet(flag) for flag in flags]
    for flag_set in flag_sets:
      work_task = Task(flag_set)

      # The task has not been compiled nor tested.
      assert not work_task.Done(task.TEST_STAGE)
      assert not work_task.Done(task.BUILD_STAGE)

      # After the task has been compiled, it should indicate finished in BUILD
      # stage.
      result = tuple([random.randint(0, RANDOM_BUILD_RESULT) for _ in range(5)])
      work_task.SetResult(task.BUILD_STAGE, result)
      assert not work_task.Done(task.TEST_STAGE)
      assert work_task.Done(task.BUILD_STAGE)

      # After the task has been tested, it should indicate finished in TEST
      # stage.
      work_task.SetResult(task.TEST_STAGE, random.randint(0, RANDOM_TESTRESULT))
      assert work_task.Done(task.TEST_STAGE)
      assert work_task.Done(task.BUILD_STAGE)


if __name__ == '__main__':
  unittest.main()
