1*760c253cSXin Li# Copyright 2013 The ChromiumOS Authors 2*760c253cSXin Li# Use of this source code is governed by a BSD-style license that can be 3*760c253cSXin Li# found in the LICENSE file. 4*760c253cSXin Li"""Task unittest. 5*760c253cSXin Li 6*760c253cSXin LiPart of the Chrome build flags optimization. 7*760c253cSXin Li""" 8*760c253cSXin Li 9*760c253cSXin Li__author__ = "[email protected] (Yuheng Long)" 10*760c253cSXin Li 11*760c253cSXin Liimport random 12*760c253cSXin Liimport sys 13*760c253cSXin Liimport unittest 14*760c253cSXin Li 15*760c253cSXin Liimport task 16*760c253cSXin Lifrom task import Task 17*760c253cSXin Li 18*760c253cSXin Li 19*760c253cSXin Li# The number of flags be tested. 20*760c253cSXin LiNUM_FLAGS = 20 21*760c253cSXin Li 22*760c253cSXin Li# The random build result values used to test get set result method. 23*760c253cSXin LiRANDOM_BUILD_RESULT = 100 24*760c253cSXin Li 25*760c253cSXin Li# The random test result values used to test get set result method. 26*760c253cSXin LiRANDOM_TESTRESULT = 100 27*760c253cSXin Li 28*760c253cSXin Li 29*760c253cSXin Liclass MockFlagSet(object): 30*760c253cSXin Li """This class emulates a set of flags. 31*760c253cSXin Li 32*760c253cSXin Li It returns the flags and hash value, when the FormattedForUse method and the 33*760c253cSXin Li __hash__ method is called, respectively. These values are initialized when the 34*760c253cSXin Li MockFlagSet instance is constructed. 35*760c253cSXin Li """ 36*760c253cSXin Li 37*760c253cSXin Li def __init__(self, flags=0, hash_value=-1): 38*760c253cSXin Li self._flags = flags 39*760c253cSXin Li self._hash_value = hash_value 40*760c253cSXin Li 41*760c253cSXin Li def __eq__(self, other): 42*760c253cSXin Li assert isinstance(other, MockFlagSet) 43*760c253cSXin Li return self._flags == other.FormattedForUse() 44*760c253cSXin Li 45*760c253cSXin Li def FormattedForUse(self): 46*760c253cSXin Li return self._flags 47*760c253cSXin Li 48*760c253cSXin Li def __hash__(self): 49*760c253cSXin Li return self._hash_value 50*760c253cSXin Li 51*760c253cSXin Li def GetHash(self): 52*760c253cSXin Li return self._hash_value 53*760c253cSXin Li 54*760c253cSXin Li 55*760c253cSXin Liclass TaskTest(unittest.TestCase): 56*760c253cSXin Li """This class test the Task class.""" 57*760c253cSXin Li 58*760c253cSXin Li def testEqual(self): 59*760c253cSXin Li """Test the equal method of the task. 60*760c253cSXin Li 61*760c253cSXin Li Two tasks are equal if and only if their encapsulated flag_sets are equal. 62*760c253cSXin Li """ 63*760c253cSXin Li 64*760c253cSXin Li flags = range(NUM_FLAGS) 65*760c253cSXin Li 66*760c253cSXin Li # Two tasks having the same flag set should be equivalent. 67*760c253cSXin Li flag_sets = [MockFlagSet(flag) for flag in flags] 68*760c253cSXin Li for flag_set in flag_sets: 69*760c253cSXin Li assert Task(flag_set) == Task(flag_set) 70*760c253cSXin Li 71*760c253cSXin Li # Two tasks having different flag set should be different. 72*760c253cSXin Li for flag_set in flag_sets: 73*760c253cSXin Li test_task = Task(flag_set) 74*760c253cSXin Li other_flag_sets = [ 75*760c253cSXin Li flags for flags in flag_sets if flags != flag_set 76*760c253cSXin Li ] 77*760c253cSXin Li for flag_set1 in other_flag_sets: 78*760c253cSXin Li assert test_task != Task(flag_set1) 79*760c253cSXin Li 80*760c253cSXin Li def testHash(self): 81*760c253cSXin Li """Test the hash method of the task. 82*760c253cSXin Li 83*760c253cSXin Li Two tasks are equal if and only if their encapsulated flag_sets are equal. 84*760c253cSXin Li """ 85*760c253cSXin Li 86*760c253cSXin Li # Random identifier that is not relevant in this test. 87*760c253cSXin Li identifier = random.randint(-sys.maxint - 1, -1) 88*760c253cSXin Li 89*760c253cSXin Li flag_sets = [ 90*760c253cSXin Li MockFlagSet(identifier, value) for value in range(NUM_FLAGS) 91*760c253cSXin Li ] 92*760c253cSXin Li for flag_set in flag_sets: 93*760c253cSXin Li # The hash of a task is the same as the hash of its flag set. 94*760c253cSXin Li hash_task = Task(flag_set) 95*760c253cSXin Li hash_value = hash(hash_task) 96*760c253cSXin Li assert hash_value == flag_set.GetHash() 97*760c253cSXin Li 98*760c253cSXin Li # The hash of a task does not change. 99*760c253cSXin Li assert hash_value == hash(hash_task) 100*760c253cSXin Li 101*760c253cSXin Li def testGetIdentifier(self): 102*760c253cSXin Li """Test the get identifier method of the task. 103*760c253cSXin Li 104*760c253cSXin Li The get identifier method should returns the flag set in the build stage. 105*760c253cSXin Li """ 106*760c253cSXin Li 107*760c253cSXin Li flag_sets = [MockFlagSet(flag) for flag in range(NUM_FLAGS)] 108*760c253cSXin Li for flag_set in flag_sets: 109*760c253cSXin Li identifier_task = Task(flag_set) 110*760c253cSXin Li 111*760c253cSXin Li identifier = identifier_task.GetIdentifier(task.BUILD_STAGE) 112*760c253cSXin Li 113*760c253cSXin Li # The task formats the flag set into a string. 114*760c253cSXin Li assert identifier == str(flag_set.FormattedForUse()) 115*760c253cSXin Li 116*760c253cSXin Li def testGetSetResult(self): 117*760c253cSXin Li """Test the get and set result methods of the task. 118*760c253cSXin Li 119*760c253cSXin Li The get result method should return the same results as were set. 120*760c253cSXin Li """ 121*760c253cSXin Li 122*760c253cSXin Li flag_sets = [MockFlagSet(flag) for flag in range(NUM_FLAGS)] 123*760c253cSXin Li for flag_set in flag_sets: 124*760c253cSXin Li result_task = Task(flag_set) 125*760c253cSXin Li 126*760c253cSXin Li # The get result method should return the same results as were set, in 127*760c253cSXin Li # build stage. Currently, the build result is a 5-element tuple containing 128*760c253cSXin Li # the checksum of the result image, the performance cost of the build, the 129*760c253cSXin Li # compilation image, the length of the build, and the length of the text 130*760c253cSXin Li # section of the build. 131*760c253cSXin Li result = tuple( 132*760c253cSXin Li [random.randint(0, RANDOM_BUILD_RESULT) for _ in range(5)] 133*760c253cSXin Li ) 134*760c253cSXin Li result_task.SetResult(task.BUILD_STAGE, result) 135*760c253cSXin Li assert result == result_task.GetResult(task.BUILD_STAGE) 136*760c253cSXin Li 137*760c253cSXin Li # The checksum is the identifier of the test stage. 138*760c253cSXin Li identifier = result_task.GetIdentifier(task.TEST_STAGE) 139*760c253cSXin Li # The first element of the result tuple is the checksum. 140*760c253cSXin Li assert identifier == result[0] 141*760c253cSXin Li 142*760c253cSXin Li # The get result method should return the same results as were set, in 143*760c253cSXin Li # test stage. 144*760c253cSXin Li random_test_result = random.randint(0, RANDOM_TESTRESULT) 145*760c253cSXin Li result_task.SetResult(task.TEST_STAGE, random_test_result) 146*760c253cSXin Li test_result = result_task.GetResult(task.TEST_STAGE) 147*760c253cSXin Li assert test_result == random_test_result 148*760c253cSXin Li 149*760c253cSXin Li def testDone(self): 150*760c253cSXin Li """Test the done methods of the task. 151*760c253cSXin Li 152*760c253cSXin Li The done method should return false is the task has not perform and return 153*760c253cSXin Li true after the task is finished. 154*760c253cSXin Li """ 155*760c253cSXin Li 156*760c253cSXin Li flags = range(NUM_FLAGS) 157*760c253cSXin Li 158*760c253cSXin Li flag_sets = [MockFlagSet(flag) for flag in flags] 159*760c253cSXin Li for flag_set in flag_sets: 160*760c253cSXin Li work_task = Task(flag_set) 161*760c253cSXin Li 162*760c253cSXin Li # The task has not been compiled nor tested. 163*760c253cSXin Li assert not work_task.Done(task.TEST_STAGE) 164*760c253cSXin Li assert not work_task.Done(task.BUILD_STAGE) 165*760c253cSXin Li 166*760c253cSXin Li # After the task has been compiled, it should indicate finished in BUILD 167*760c253cSXin Li # stage. 168*760c253cSXin Li result = tuple( 169*760c253cSXin Li [random.randint(0, RANDOM_BUILD_RESULT) for _ in range(5)] 170*760c253cSXin Li ) 171*760c253cSXin Li work_task.SetResult(task.BUILD_STAGE, result) 172*760c253cSXin Li assert not work_task.Done(task.TEST_STAGE) 173*760c253cSXin Li assert work_task.Done(task.BUILD_STAGE) 174*760c253cSXin Li 175*760c253cSXin Li # After the task has been tested, it should indicate finished in TEST 176*760c253cSXin Li # stage. 177*760c253cSXin Li work_task.SetResult( 178*760c253cSXin Li task.TEST_STAGE, random.randint(0, RANDOM_TESTRESULT) 179*760c253cSXin Li ) 180*760c253cSXin Li assert work_task.Done(task.TEST_STAGE) 181*760c253cSXin Li assert work_task.Done(task.BUILD_STAGE) 182*760c253cSXin Li 183*760c253cSXin Li 184*760c253cSXin Liif __name__ == "__main__": 185*760c253cSXin Li unittest.main() 186