media/webrtc/trunk/testing/gtest/test/gtest_shuffle_test.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 #!/usr/bin/env python
michael@0 2 #
michael@0 3 # Copyright 2009 Google Inc. All Rights Reserved.
michael@0 4 #
michael@0 5 # Redistribution and use in source and binary forms, with or without
michael@0 6 # modification, are permitted provided that the following conditions are
michael@0 7 # met:
michael@0 8 #
michael@0 9 # * Redistributions of source code must retain the above copyright
michael@0 10 # notice, this list of conditions and the following disclaimer.
michael@0 11 # * Redistributions in binary form must reproduce the above
michael@0 12 # copyright notice, this list of conditions and the following disclaimer
michael@0 13 # in the documentation and/or other materials provided with the
michael@0 14 # distribution.
michael@0 15 # * Neither the name of Google Inc. nor the names of its
michael@0 16 # contributors may be used to endorse or promote products derived from
michael@0 17 # this software without specific prior written permission.
michael@0 18 #
michael@0 19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 30
michael@0 31 """Verifies that test shuffling works."""
michael@0 32
michael@0 33 __author__ = 'wan@google.com (Zhanyong Wan)'
michael@0 34
michael@0 35 import os
michael@0 36 import gtest_test_utils
michael@0 37
michael@0 38 # Command to run the gtest_shuffle_test_ program.
michael@0 39 COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_shuffle_test_')
michael@0 40
michael@0 41 # The environment variables for test sharding.
michael@0 42 TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS'
michael@0 43 SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX'
michael@0 44
michael@0 45 TEST_FILTER = 'A*.A:A*.B:C*'
michael@0 46
michael@0 47 ALL_TESTS = []
michael@0 48 ACTIVE_TESTS = []
michael@0 49 FILTERED_TESTS = []
michael@0 50 SHARDED_TESTS = []
michael@0 51
michael@0 52 SHUFFLED_ALL_TESTS = []
michael@0 53 SHUFFLED_ACTIVE_TESTS = []
michael@0 54 SHUFFLED_FILTERED_TESTS = []
michael@0 55 SHUFFLED_SHARDED_TESTS = []
michael@0 56
michael@0 57
michael@0 58 def AlsoRunDisabledTestsFlag():
michael@0 59 return '--gtest_also_run_disabled_tests'
michael@0 60
michael@0 61
michael@0 62 def FilterFlag(test_filter):
michael@0 63 return '--gtest_filter=%s' % (test_filter,)
michael@0 64
michael@0 65
michael@0 66 def RepeatFlag(n):
michael@0 67 return '--gtest_repeat=%s' % (n,)
michael@0 68
michael@0 69
michael@0 70 def ShuffleFlag():
michael@0 71 return '--gtest_shuffle'
michael@0 72
michael@0 73
michael@0 74 def RandomSeedFlag(n):
michael@0 75 return '--gtest_random_seed=%s' % (n,)
michael@0 76
michael@0 77
michael@0 78 def RunAndReturnOutput(extra_env, args):
michael@0 79 """Runs the test program and returns its output."""
michael@0 80
michael@0 81 environ_copy = os.environ.copy()
michael@0 82 environ_copy.update(extra_env)
michael@0 83
michael@0 84 return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy,
michael@0 85 capture_stderr=False).output
michael@0 86
michael@0 87
michael@0 88 def GetTestsForAllIterations(extra_env, args):
michael@0 89 """Runs the test program and returns a list of test lists.
michael@0 90
michael@0 91 Args:
michael@0 92 extra_env: a map from environment variables to their values
michael@0 93 args: command line flags to pass to gtest_shuffle_test_
michael@0 94
michael@0 95 Returns:
michael@0 96 A list where the i-th element is the list of tests run in the i-th
michael@0 97 test iteration.
michael@0 98 """
michael@0 99
michael@0 100 test_iterations = []
michael@0 101 for line in RunAndReturnOutput(extra_env, args).split('\n'):
michael@0 102 if line.startswith('----'):
michael@0 103 tests = []
michael@0 104 test_iterations.append(tests)
michael@0 105 elif line.strip():
michael@0 106 tests.append(line.strip()) # 'TestCaseName.TestName'
michael@0 107
michael@0 108 return test_iterations
michael@0 109
michael@0 110
michael@0 111 def GetTestCases(tests):
michael@0 112 """Returns a list of test cases in the given full test names.
michael@0 113
michael@0 114 Args:
michael@0 115 tests: a list of full test names
michael@0 116
michael@0 117 Returns:
michael@0 118 A list of test cases from 'tests', in their original order.
michael@0 119 Consecutive duplicates are removed.
michael@0 120 """
michael@0 121
michael@0 122 test_cases = []
michael@0 123 for test in tests:
michael@0 124 test_case = test.split('.')[0]
michael@0 125 if not test_case in test_cases:
michael@0 126 test_cases.append(test_case)
michael@0 127
michael@0 128 return test_cases
michael@0 129
michael@0 130
michael@0 131 def CalculateTestLists():
michael@0 132 """Calculates the list of tests run under different flags."""
michael@0 133
michael@0 134 if not ALL_TESTS:
michael@0 135 ALL_TESTS.extend(
michael@0 136 GetTestsForAllIterations({}, [AlsoRunDisabledTestsFlag()])[0])
michael@0 137
michael@0 138 if not ACTIVE_TESTS:
michael@0 139 ACTIVE_TESTS.extend(GetTestsForAllIterations({}, [])[0])
michael@0 140
michael@0 141 if not FILTERED_TESTS:
michael@0 142 FILTERED_TESTS.extend(
michael@0 143 GetTestsForAllIterations({}, [FilterFlag(TEST_FILTER)])[0])
michael@0 144
michael@0 145 if not SHARDED_TESTS:
michael@0 146 SHARDED_TESTS.extend(
michael@0 147 GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
michael@0 148 SHARD_INDEX_ENV_VAR: '1'},
michael@0 149 [])[0])
michael@0 150
michael@0 151 if not SHUFFLED_ALL_TESTS:
michael@0 152 SHUFFLED_ALL_TESTS.extend(GetTestsForAllIterations(
michael@0 153 {}, [AlsoRunDisabledTestsFlag(), ShuffleFlag(), RandomSeedFlag(1)])[0])
michael@0 154
michael@0 155 if not SHUFFLED_ACTIVE_TESTS:
michael@0 156 SHUFFLED_ACTIVE_TESTS.extend(GetTestsForAllIterations(
michael@0 157 {}, [ShuffleFlag(), RandomSeedFlag(1)])[0])
michael@0 158
michael@0 159 if not SHUFFLED_FILTERED_TESTS:
michael@0 160 SHUFFLED_FILTERED_TESTS.extend(GetTestsForAllIterations(
michael@0 161 {}, [ShuffleFlag(), RandomSeedFlag(1), FilterFlag(TEST_FILTER)])[0])
michael@0 162
michael@0 163 if not SHUFFLED_SHARDED_TESTS:
michael@0 164 SHUFFLED_SHARDED_TESTS.extend(
michael@0 165 GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
michael@0 166 SHARD_INDEX_ENV_VAR: '1'},
michael@0 167 [ShuffleFlag(), RandomSeedFlag(1)])[0])
michael@0 168
michael@0 169
michael@0 170 class GTestShuffleUnitTest(gtest_test_utils.TestCase):
michael@0 171 """Tests test shuffling."""
michael@0 172
michael@0 173 def setUp(self):
michael@0 174 CalculateTestLists()
michael@0 175
michael@0 176 def testShufflePreservesNumberOfTests(self):
michael@0 177 self.assertEqual(len(ALL_TESTS), len(SHUFFLED_ALL_TESTS))
michael@0 178 self.assertEqual(len(ACTIVE_TESTS), len(SHUFFLED_ACTIVE_TESTS))
michael@0 179 self.assertEqual(len(FILTERED_TESTS), len(SHUFFLED_FILTERED_TESTS))
michael@0 180 self.assertEqual(len(SHARDED_TESTS), len(SHUFFLED_SHARDED_TESTS))
michael@0 181
michael@0 182 def testShuffleChangesTestOrder(self):
michael@0 183 self.assert_(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS)
michael@0 184 self.assert_(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS)
michael@0 185 self.assert_(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS,
michael@0 186 SHUFFLED_FILTERED_TESTS)
michael@0 187 self.assert_(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS,
michael@0 188 SHUFFLED_SHARDED_TESTS)
michael@0 189
michael@0 190 def testShuffleChangesTestCaseOrder(self):
michael@0 191 self.assert_(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS),
michael@0 192 GetTestCases(SHUFFLED_ALL_TESTS))
michael@0 193 self.assert_(
michael@0 194 GetTestCases(SHUFFLED_ACTIVE_TESTS) != GetTestCases(ACTIVE_TESTS),
michael@0 195 GetTestCases(SHUFFLED_ACTIVE_TESTS))
michael@0 196 self.assert_(
michael@0 197 GetTestCases(SHUFFLED_FILTERED_TESTS) != GetTestCases(FILTERED_TESTS),
michael@0 198 GetTestCases(SHUFFLED_FILTERED_TESTS))
michael@0 199 self.assert_(
michael@0 200 GetTestCases(SHUFFLED_SHARDED_TESTS) != GetTestCases(SHARDED_TESTS),
michael@0 201 GetTestCases(SHUFFLED_SHARDED_TESTS))
michael@0 202
michael@0 203 def testShuffleDoesNotRepeatTest(self):
michael@0 204 for test in SHUFFLED_ALL_TESTS:
michael@0 205 self.assertEqual(1, SHUFFLED_ALL_TESTS.count(test),
michael@0 206 '%s appears more than once' % (test,))
michael@0 207 for test in SHUFFLED_ACTIVE_TESTS:
michael@0 208 self.assertEqual(1, SHUFFLED_ACTIVE_TESTS.count(test),
michael@0 209 '%s appears more than once' % (test,))
michael@0 210 for test in SHUFFLED_FILTERED_TESTS:
michael@0 211 self.assertEqual(1, SHUFFLED_FILTERED_TESTS.count(test),
michael@0 212 '%s appears more than once' % (test,))
michael@0 213 for test in SHUFFLED_SHARDED_TESTS:
michael@0 214 self.assertEqual(1, SHUFFLED_SHARDED_TESTS.count(test),
michael@0 215 '%s appears more than once' % (test,))
michael@0 216
michael@0 217 def testShuffleDoesNotCreateNewTest(self):
michael@0 218 for test in SHUFFLED_ALL_TESTS:
michael@0 219 self.assert_(test in ALL_TESTS, '%s is an invalid test' % (test,))
michael@0 220 for test in SHUFFLED_ACTIVE_TESTS:
michael@0 221 self.assert_(test in ACTIVE_TESTS, '%s is an invalid test' % (test,))
michael@0 222 for test in SHUFFLED_FILTERED_TESTS:
michael@0 223 self.assert_(test in FILTERED_TESTS, '%s is an invalid test' % (test,))
michael@0 224 for test in SHUFFLED_SHARDED_TESTS:
michael@0 225 self.assert_(test in SHARDED_TESTS, '%s is an invalid test' % (test,))
michael@0 226
michael@0 227 def testShuffleIncludesAllTests(self):
michael@0 228 for test in ALL_TESTS:
michael@0 229 self.assert_(test in SHUFFLED_ALL_TESTS, '%s is missing' % (test,))
michael@0 230 for test in ACTIVE_TESTS:
michael@0 231 self.assert_(test in SHUFFLED_ACTIVE_TESTS, '%s is missing' % (test,))
michael@0 232 for test in FILTERED_TESTS:
michael@0 233 self.assert_(test in SHUFFLED_FILTERED_TESTS, '%s is missing' % (test,))
michael@0 234 for test in SHARDED_TESTS:
michael@0 235 self.assert_(test in SHUFFLED_SHARDED_TESTS, '%s is missing' % (test,))
michael@0 236
michael@0 237 def testShuffleLeavesDeathTestsAtFront(self):
michael@0 238 non_death_test_found = False
michael@0 239 for test in SHUFFLED_ACTIVE_TESTS:
michael@0 240 if 'DeathTest.' in test:
michael@0 241 self.assert_(not non_death_test_found,
michael@0 242 '%s appears after a non-death test' % (test,))
michael@0 243 else:
michael@0 244 non_death_test_found = True
michael@0 245
michael@0 246 def _VerifyTestCasesDoNotInterleave(self, tests):
michael@0 247 test_cases = []
michael@0 248 for test in tests:
michael@0 249 [test_case, _] = test.split('.')
michael@0 250 if test_cases and test_cases[-1] != test_case:
michael@0 251 test_cases.append(test_case)
michael@0 252 self.assertEqual(1, test_cases.count(test_case),
michael@0 253 'Test case %s is not grouped together in %s' %
michael@0 254 (test_case, tests))
michael@0 255
michael@0 256 def testShuffleDoesNotInterleaveTestCases(self):
michael@0 257 self._VerifyTestCasesDoNotInterleave(SHUFFLED_ALL_TESTS)
michael@0 258 self._VerifyTestCasesDoNotInterleave(SHUFFLED_ACTIVE_TESTS)
michael@0 259 self._VerifyTestCasesDoNotInterleave(SHUFFLED_FILTERED_TESTS)
michael@0 260 self._VerifyTestCasesDoNotInterleave(SHUFFLED_SHARDED_TESTS)
michael@0 261
michael@0 262 def testShuffleRestoresOrderAfterEachIteration(self):
michael@0 263 # Get the test lists in all 3 iterations, using random seed 1, 2,
michael@0 264 # and 3 respectively. Google Test picks a different seed in each
michael@0 265 # iteration, and this test depends on the current implementation
michael@0 266 # picking successive numbers. This dependency is not ideal, but
michael@0 267 # makes the test much easier to write.
michael@0 268 [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = (
michael@0 269 GetTestsForAllIterations(
michael@0 270 {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)]))
michael@0 271
michael@0 272 # Make sure running the tests with random seed 1 gets the same
michael@0 273 # order as in iteration 1 above.
michael@0 274 [tests_with_seed1] = GetTestsForAllIterations(
michael@0 275 {}, [ShuffleFlag(), RandomSeedFlag(1)])
michael@0 276 self.assertEqual(tests_in_iteration1, tests_with_seed1)
michael@0 277
michael@0 278 # Make sure running the tests with random seed 2 gets the same
michael@0 279 # order as in iteration 2 above. Success means that Google Test
michael@0 280 # correctly restores the test order before re-shuffling at the
michael@0 281 # beginning of iteration 2.
michael@0 282 [tests_with_seed2] = GetTestsForAllIterations(
michael@0 283 {}, [ShuffleFlag(), RandomSeedFlag(2)])
michael@0 284 self.assertEqual(tests_in_iteration2, tests_with_seed2)
michael@0 285
michael@0 286 # Make sure running the tests with random seed 3 gets the same
michael@0 287 # order as in iteration 3 above. Success means that Google Test
michael@0 288 # correctly restores the test order before re-shuffling at the
michael@0 289 # beginning of iteration 3.
michael@0 290 [tests_with_seed3] = GetTestsForAllIterations(
michael@0 291 {}, [ShuffleFlag(), RandomSeedFlag(3)])
michael@0 292 self.assertEqual(tests_in_iteration3, tests_with_seed3)
michael@0 293
michael@0 294 def testShuffleGeneratesNewOrderInEachIteration(self):
michael@0 295 [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = (
michael@0 296 GetTestsForAllIterations(
michael@0 297 {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)]))
michael@0 298
michael@0 299 self.assert_(tests_in_iteration1 != tests_in_iteration2,
michael@0 300 tests_in_iteration1)
michael@0 301 self.assert_(tests_in_iteration1 != tests_in_iteration3,
michael@0 302 tests_in_iteration1)
michael@0 303 self.assert_(tests_in_iteration2 != tests_in_iteration3,
michael@0 304 tests_in_iteration2)
michael@0 305
michael@0 306 def testShuffleShardedTestsPreservesPartition(self):
michael@0 307 # If we run M tests on N shards, the same M tests should be run in
michael@0 308 # total, regardless of the random seeds used by the shards.
michael@0 309 [tests1] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
michael@0 310 SHARD_INDEX_ENV_VAR: '0'},
michael@0 311 [ShuffleFlag(), RandomSeedFlag(1)])
michael@0 312 [tests2] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
michael@0 313 SHARD_INDEX_ENV_VAR: '1'},
michael@0 314 [ShuffleFlag(), RandomSeedFlag(20)])
michael@0 315 [tests3] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
michael@0 316 SHARD_INDEX_ENV_VAR: '2'},
michael@0 317 [ShuffleFlag(), RandomSeedFlag(25)])
michael@0 318 sorted_sharded_tests = tests1 + tests2 + tests3
michael@0 319 sorted_sharded_tests.sort()
michael@0 320 sorted_active_tests = []
michael@0 321 sorted_active_tests.extend(ACTIVE_TESTS)
michael@0 322 sorted_active_tests.sort()
michael@0 323 self.assertEqual(sorted_active_tests, sorted_sharded_tests)
michael@0 324
michael@0 325 if __name__ == '__main__':
michael@0 326 gtest_test_utils.Main()

mercurial