普通文本  |  175行  |  5.53 KB

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