flags_test.py revision f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbe
1# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4"""Unit tests for the classes in module 'flags'.
5
6Part of the Chrome build flags optimization.
7"""
8
9__author__ = 'yuhenglong@google.com (Yuheng Long)'
10
11import random
12import sys
13import unittest
14
15from flags import Flag
16from flags import FlagSet
17
18# The number of tests to test.
19NUM_TESTS = 20
20
21
22class FlagTest(unittest.TestCase):
23  """This class tests the Flag class."""
24
25  def testInit(self):
26    """The value generated should fall within start and end of the spec.
27
28    If the value is not specified, the value generated should fall within start
29    and end of the spec.
30    """
31
32    for _ in range(NUM_TESTS):
33      start = random.randint(1, sys.maxint - 1)
34      end = random.randint(start + 1, sys.maxint)
35
36      spec = 'flag=[%s-%s]' % (start, end)
37
38      test_flag = Flag(spec)
39
40      value = test_flag.GetValue()
41
42      # If the value is not specified when the flag is constructed, a random
43      # value is chosen. This value should fall within start and end of the
44      # spec.
45      assert start <= value and value < end
46
47  def testEqual(self):
48    """Test the equal operator (==) of the flag.
49
50    Two flags are equal if and only if their spec and value are equal.
51    """
52
53    tests = range(NUM_TESTS)
54
55    # Two tasks having the same spec and value should be equivalent.
56    for test in tests:
57      assert Flag(str(test), test) == Flag(str(test), test)
58
59    # Two tasks having different flag set should be different.
60    for test in tests:
61      flag = Flag(str(test), test)
62      other_flag_sets = [other for other in tests if test != other]
63      for other_test in other_flag_sets:
64        assert flag != Flag(str(other_test), other_test)
65
66  def testFormattedForUse(self):
67    """Test the FormattedForUse method of the flag.
68
69    The FormattedForUse replaces the string within the [] with the actual value.
70    """
71
72    for _ in range(NUM_TESTS):
73      start = random.randint(1, sys.maxint - 1)
74      end = random.randint(start + 1, sys.maxint)
75      value = random.randint(start, end - 1)
76
77      spec = 'flag=[%s-%s]' % (start, end)
78
79      test_flag = Flag(spec, value)
80
81      # For numeric flag, the FormattedForUse replaces the string within the []
82      # with the actual value.
83      test_value = test_flag.FormattedForUse()
84      actual_value = 'flag=%s' % value
85
86      assert test_value == actual_value
87
88    for _ in range(NUM_TESTS):
89      value = random.randint(1, sys.maxint - 1)
90
91      test_flag = Flag('flag', value)
92
93      # For boolean flag, the FormattedForUse returns the spec.
94      test_value = test_flag.FormattedForUse()
95      actual_value = 'flag'
96      assert test_value == actual_value
97
98
99class FlagSetTest(unittest.TestCase):
100  """This class test the FlagSet class."""
101
102  def testEqual(self):
103    """Test the equal method of the Class FlagSet.
104
105    Two FlagSet instances are equal if all their flags are equal.
106    """
107
108    flag_names = range(NUM_TESTS)
109
110    # Two flag sets having the same flags should be equivalent.
111    for flag_name in flag_names:
112      spec = '%s' % flag_name
113
114      assert FlagSet([Flag(spec)]) == FlagSet([Flag(spec)])
115
116    # Two flag sets having different flags should be different.
117    for flag_name in flag_names:
118      spec = '%s' % flag_name
119      flag_set = FlagSet([Flag(spec)])
120      other_flag_sets = [other for other in flag_names if flag_name != other]
121      for other_name in other_flag_sets:
122        other_spec = '%s' % other_name
123        assert flag_set != FlagSet([Flag(other_spec)])
124
125  def testGetItem(self):
126    """Test the get item method of the Class FlagSet.
127
128    The flag set is also indexed by the specs. The flag set should return the
129    appropriate flag given the spec.
130    """
131
132    tests = range(NUM_TESTS)
133
134    specs = [str(spec) for spec in tests]
135    flag_array = [Flag(spec) for spec in specs]
136
137    flag_set = FlagSet(flag_array)
138
139    # Created a dictionary of spec and flag, the flag set should return the flag
140    # the same as this dictionary.
141    spec_flag = dict(zip(specs, flag_array))
142
143    for spec in spec_flag:
144      assert flag_set[spec] == spec_flag[spec]
145
146  def testContain(self):
147    """Test the contain method of the Class FlagSet.
148
149    The flag set is also indexed by the specs. The flag set should return true
150    for spec if it contains a flag containing spec.
151    """
152
153    true_tests = range(NUM_TESTS)
154    false_tests = range(NUM_TESTS, NUM_TESTS * 2)
155
156    specs = [str(spec) for spec in true_tests]
157
158    flag_set = FlagSet([Flag(spec) for spec in specs])
159
160    for spec in specs:
161      assert spec in flag_set
162
163    for spec in false_tests:
164      assert spec not in flag_set
165
166  def testFormattedForUse(self):
167    """Test the FormattedForUse method of the Class FlagSet.
168
169    The output should be a sorted list of strings.
170    """
171
172    flag_names = range(NUM_TESTS)
173    flag_names.reverse()
174    flags = []
175    result = []
176
177    # Construct the flag set.
178    for flag_name in flag_names:
179      spec = '%s' % flag_name
180      flags.append(Flag(spec))
181      result.append(spec)
182
183    flag_set = FlagSet(flags)
184
185    # The results string should be sorted.
186    assert sorted(result) == flag_set.FormattedForUse()
187
188
189if __name__ == '__main__':
190  unittest.main()
191