Implements test shuffling (by Zhanyong Wan, based on Josh Kelley's original patch).
Enables death tests on minGW (by Vlad Losev).
This commit is contained in:
		@@ -659,7 +659,11 @@ static void TestExitMacros() {
 | 
			
		||||
  EXPECT_EXIT(_exit(1),  testing::ExitedWithCode(1),  "");
 | 
			
		||||
  ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), "");
 | 
			
		||||
 | 
			
		||||
#if GTEST_OS_WINDOWS
 | 
			
		||||
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
 | 
			
		||||
  // MinGW (as of MinGW 5.1.6 and MSYS 1.0.11) does not tag crashed
 | 
			
		||||
  // processes with non-zero exit code and does not honor calls to
 | 
			
		||||
  // SetErrorMode(SEM_NOGPFAULTERRORBOX) that are supposed to suppress
 | 
			
		||||
  // error pop-ups.
 | 
			
		||||
  EXPECT_EXIT({
 | 
			
		||||
    testing::GTEST_FLAG(catch_exceptions) = false;
 | 
			
		||||
    *static_cast<int*>(NULL) = 1;
 | 
			
		||||
@@ -671,7 +675,9 @@ static void TestExitMacros() {
 | 
			
		||||
      *static_cast<int*>(NULL) = 1;
 | 
			
		||||
    }, testing::ExitedWithCode(0), "") << "This failure is expected.";
 | 
			
		||||
  }, "This failure is expected.");
 | 
			
		||||
#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
 | 
			
		||||
 | 
			
		||||
#if GTEST_OS_WINDOWS
 | 
			
		||||
  // Of all signals effects on the process exit code, only those of SIGABRT
 | 
			
		||||
  // are documented on Windows.
 | 
			
		||||
  // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										331
									
								
								test/gtest_shuffle_test.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										331
									
								
								test/gtest_shuffle_test.py
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,331 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
#
 | 
			
		||||
# Copyright 2009 Google Inc. All Rights Reserved.
 | 
			
		||||
#
 | 
			
		||||
# Redistribution and use in source and binary forms, with or without
 | 
			
		||||
# modification, are permitted provided that the following conditions are
 | 
			
		||||
# met:
 | 
			
		||||
#
 | 
			
		||||
#     * Redistributions of source code must retain the above copyright
 | 
			
		||||
# notice, this list of conditions and the following disclaimer.
 | 
			
		||||
#     * Redistributions in binary form must reproduce the above
 | 
			
		||||
# copyright notice, this list of conditions and the following disclaimer
 | 
			
		||||
# in the documentation and/or other materials provided with the
 | 
			
		||||
# distribution.
 | 
			
		||||
#     * Neither the name of Google Inc. nor the names of its
 | 
			
		||||
# contributors may be used to endorse or promote products derived from
 | 
			
		||||
# this software without specific prior written permission.
 | 
			
		||||
#
 | 
			
		||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
"""Verifies that test shuffling works."""
 | 
			
		||||
 | 
			
		||||
__author__ = 'wan@google.com (Zhanyong Wan)'
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import gtest_test_utils
 | 
			
		||||
 | 
			
		||||
# Command to run the gtest_shuffle_test_ program.
 | 
			
		||||
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_shuffle_test_')
 | 
			
		||||
 | 
			
		||||
# The environment variables for test sharding.
 | 
			
		||||
TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS'
 | 
			
		||||
SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX'
 | 
			
		||||
 | 
			
		||||
TEST_FILTER = 'A*.A:A*.B:C*'
 | 
			
		||||
 | 
			
		||||
ALL_TESTS = []
 | 
			
		||||
ACTIVE_TESTS = []
 | 
			
		||||
FILTERED_TESTS = []
 | 
			
		||||
SHARDED_TESTS = []
 | 
			
		||||
 | 
			
		||||
SHUFFLED_ALL_TESTS = []
 | 
			
		||||
SHUFFLED_ACTIVE_TESTS = []
 | 
			
		||||
SHUFFLED_FILTERED_TESTS = []
 | 
			
		||||
SHUFFLED_SHARDED_TESTS = []
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def AlsoRunDisabledTestsFlag():
 | 
			
		||||
  return '--gtest_also_run_disabled_tests'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def FilterFlag(test_filter):
 | 
			
		||||
  return '--gtest_filter=%s' % (test_filter,)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def RepeatFlag(n):
 | 
			
		||||
  return '--gtest_repeat=%s' % (n,)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def ShuffleFlag():
 | 
			
		||||
  return '--gtest_shuffle'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def RandomSeedFlag(n):
 | 
			
		||||
  return '--gtest_random_seed=%s' % (n,)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def RunAndReturnOutput(extra_env, args):
 | 
			
		||||
  """Runs the test program and returns its output."""
 | 
			
		||||
 | 
			
		||||
  try:
 | 
			
		||||
    original_env = os.environ.copy()
 | 
			
		||||
    os.environ.update(extra_env)
 | 
			
		||||
    return gtest_test_utils.Subprocess([COMMAND] + args).output
 | 
			
		||||
  finally:
 | 
			
		||||
    for key in extra_env.iterkeys():
 | 
			
		||||
      if key in original_env:
 | 
			
		||||
        os.environ[key] = original_env[key]
 | 
			
		||||
      else:
 | 
			
		||||
        del os.environ[key]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def GetTestsForAllIterations(extra_env, args):
 | 
			
		||||
  """Runs the test program and returns a list of test lists.
 | 
			
		||||
 | 
			
		||||
  Args:
 | 
			
		||||
    extra_env: a map from environment variables to their values
 | 
			
		||||
    args: command line flags to pass to gtest_shuffle_test_
 | 
			
		||||
 | 
			
		||||
  Returns:
 | 
			
		||||
    A list where the i-th element is the list of tests run in the i-th
 | 
			
		||||
    test iteration.
 | 
			
		||||
  """
 | 
			
		||||
 | 
			
		||||
  test_iterations = []
 | 
			
		||||
  for line in RunAndReturnOutput(extra_env, args).split('\n'):
 | 
			
		||||
    if line.startswith('----'):
 | 
			
		||||
      tests = []
 | 
			
		||||
      test_iterations.append(tests)
 | 
			
		||||
    elif line.strip():
 | 
			
		||||
      tests.append(line.strip())  # 'TestCaseName.TestName'
 | 
			
		||||
 | 
			
		||||
  return test_iterations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def GetTestCases(tests):
 | 
			
		||||
  """Returns a list of test cases in the given full test names.
 | 
			
		||||
 | 
			
		||||
  Args:
 | 
			
		||||
    tests: a list of full test names
 | 
			
		||||
 | 
			
		||||
  Returns:
 | 
			
		||||
    A list of test cases from 'tests', in their original order.
 | 
			
		||||
    Consecutive duplicates are removed.
 | 
			
		||||
  """
 | 
			
		||||
 | 
			
		||||
  test_cases = []
 | 
			
		||||
  for test in tests:
 | 
			
		||||
    test_case = test.split('.')[0]
 | 
			
		||||
    if not test_case in test_cases:
 | 
			
		||||
      test_cases.append(test_case)
 | 
			
		||||
 | 
			
		||||
  return test_cases
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def CalculateTestLists():
 | 
			
		||||
  """Calculates the list of tests run under different flags."""
 | 
			
		||||
 | 
			
		||||
  if not ALL_TESTS:
 | 
			
		||||
    ALL_TESTS.extend(
 | 
			
		||||
        GetTestsForAllIterations({}, [AlsoRunDisabledTestsFlag()])[0])
 | 
			
		||||
 | 
			
		||||
  if not ACTIVE_TESTS:
 | 
			
		||||
    ACTIVE_TESTS.extend(GetTestsForAllIterations({}, [])[0])
 | 
			
		||||
 | 
			
		||||
  if not FILTERED_TESTS:
 | 
			
		||||
    FILTERED_TESTS.extend(
 | 
			
		||||
        GetTestsForAllIterations({}, [FilterFlag(TEST_FILTER)])[0])
 | 
			
		||||
 | 
			
		||||
  if not SHARDED_TESTS:
 | 
			
		||||
    SHARDED_TESTS.extend(
 | 
			
		||||
        GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
 | 
			
		||||
                                  SHARD_INDEX_ENV_VAR: '1'},
 | 
			
		||||
                                 [])[0])
 | 
			
		||||
 | 
			
		||||
  if not SHUFFLED_ALL_TESTS:
 | 
			
		||||
    SHUFFLED_ALL_TESTS.extend(GetTestsForAllIterations(
 | 
			
		||||
        {}, [AlsoRunDisabledTestsFlag(), ShuffleFlag(), RandomSeedFlag(1)])[0])
 | 
			
		||||
 | 
			
		||||
  if not SHUFFLED_ACTIVE_TESTS:
 | 
			
		||||
    SHUFFLED_ACTIVE_TESTS.extend(GetTestsForAllIterations(
 | 
			
		||||
        {}, [ShuffleFlag(), RandomSeedFlag(1)])[0])
 | 
			
		||||
 | 
			
		||||
  if not SHUFFLED_FILTERED_TESTS:
 | 
			
		||||
    SHUFFLED_FILTERED_TESTS.extend(GetTestsForAllIterations(
 | 
			
		||||
        {}, [ShuffleFlag(), RandomSeedFlag(1), FilterFlag(TEST_FILTER)])[0])
 | 
			
		||||
 | 
			
		||||
  if not SHUFFLED_SHARDED_TESTS:
 | 
			
		||||
    SHUFFLED_SHARDED_TESTS.extend(
 | 
			
		||||
        GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
 | 
			
		||||
                                  SHARD_INDEX_ENV_VAR: '1'},
 | 
			
		||||
                                 [ShuffleFlag(), RandomSeedFlag(1)])[0])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GTestShuffleUnitTest(gtest_test_utils.TestCase):
 | 
			
		||||
  """Tests test shuffling."""
 | 
			
		||||
 | 
			
		||||
  def setUp(self):
 | 
			
		||||
    CalculateTestLists()
 | 
			
		||||
 | 
			
		||||
  def testShufflePreservesNumberOfTests(self):
 | 
			
		||||
    self.assertEqual(len(ALL_TESTS), len(SHUFFLED_ALL_TESTS))
 | 
			
		||||
    self.assertEqual(len(ACTIVE_TESTS), len(SHUFFLED_ACTIVE_TESTS))
 | 
			
		||||
    self.assertEqual(len(FILTERED_TESTS), len(SHUFFLED_FILTERED_TESTS))
 | 
			
		||||
    self.assertEqual(len(SHARDED_TESTS), len(SHUFFLED_SHARDED_TESTS))
 | 
			
		||||
 | 
			
		||||
  def testShuffleChangesTestOrder(self):
 | 
			
		||||
    self.assert_(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS)
 | 
			
		||||
    self.assert_(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS)
 | 
			
		||||
    self.assert_(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS,
 | 
			
		||||
                 SHUFFLED_FILTERED_TESTS)
 | 
			
		||||
    self.assert_(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS,
 | 
			
		||||
                 SHUFFLED_SHARDED_TESTS)
 | 
			
		||||
 | 
			
		||||
  def testShuffleChangesTestCaseOrder(self):
 | 
			
		||||
    self.assert_(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS),
 | 
			
		||||
                 GetTestCases(SHUFFLED_ALL_TESTS))
 | 
			
		||||
    self.assert_(
 | 
			
		||||
        GetTestCases(SHUFFLED_ACTIVE_TESTS) != GetTestCases(ACTIVE_TESTS),
 | 
			
		||||
        GetTestCases(SHUFFLED_ACTIVE_TESTS))
 | 
			
		||||
    self.assert_(
 | 
			
		||||
        GetTestCases(SHUFFLED_FILTERED_TESTS) != GetTestCases(FILTERED_TESTS),
 | 
			
		||||
        GetTestCases(SHUFFLED_FILTERED_TESTS))
 | 
			
		||||
    self.assert_(
 | 
			
		||||
        GetTestCases(SHUFFLED_SHARDED_TESTS) != GetTestCases(SHARDED_TESTS),
 | 
			
		||||
        GetTestCases(SHUFFLED_SHARDED_TESTS))
 | 
			
		||||
 | 
			
		||||
  def testShuffleDoesNotRepeatTest(self):
 | 
			
		||||
    for test in SHUFFLED_ALL_TESTS:
 | 
			
		||||
      self.assertEqual(1, SHUFFLED_ALL_TESTS.count(test),
 | 
			
		||||
                       '%s appears more than once' % (test,))
 | 
			
		||||
    for test in SHUFFLED_ACTIVE_TESTS:
 | 
			
		||||
      self.assertEqual(1, SHUFFLED_ACTIVE_TESTS.count(test),
 | 
			
		||||
                       '%s appears more than once' % (test,))
 | 
			
		||||
    for test in SHUFFLED_FILTERED_TESTS:
 | 
			
		||||
      self.assertEqual(1, SHUFFLED_FILTERED_TESTS.count(test),
 | 
			
		||||
                       '%s appears more than once' % (test,))
 | 
			
		||||
    for test in SHUFFLED_SHARDED_TESTS:
 | 
			
		||||
      self.assertEqual(1, SHUFFLED_SHARDED_TESTS.count(test),
 | 
			
		||||
                       '%s appears more than once' % (test,))
 | 
			
		||||
 | 
			
		||||
  def testShuffleDoesNotCreateNewTest(self):
 | 
			
		||||
    for test in SHUFFLED_ALL_TESTS:
 | 
			
		||||
      self.assert_(test in ALL_TESTS, '%s is an invalid test' % (test,))
 | 
			
		||||
    for test in SHUFFLED_ACTIVE_TESTS:
 | 
			
		||||
      self.assert_(test in ACTIVE_TESTS, '%s is an invalid test' % (test,))
 | 
			
		||||
    for test in SHUFFLED_FILTERED_TESTS:
 | 
			
		||||
      self.assert_(test in FILTERED_TESTS, '%s is an invalid test' % (test,))
 | 
			
		||||
    for test in SHUFFLED_SHARDED_TESTS:
 | 
			
		||||
      self.assert_(test in SHARDED_TESTS, '%s is an invalid test' % (test,))
 | 
			
		||||
 | 
			
		||||
  def testShuffleIncludesAllTests(self):
 | 
			
		||||
    for test in ALL_TESTS:
 | 
			
		||||
      self.assert_(test in SHUFFLED_ALL_TESTS, '%s is missing' % (test,))
 | 
			
		||||
    for test in ACTIVE_TESTS:
 | 
			
		||||
      self.assert_(test in SHUFFLED_ACTIVE_TESTS, '%s is missing' % (test,))
 | 
			
		||||
    for test in FILTERED_TESTS:
 | 
			
		||||
      self.assert_(test in SHUFFLED_FILTERED_TESTS, '%s is missing' % (test,))
 | 
			
		||||
    for test in SHARDED_TESTS:
 | 
			
		||||
      self.assert_(test in SHUFFLED_SHARDED_TESTS, '%s is missing' % (test,))
 | 
			
		||||
 | 
			
		||||
  def testShuffleLeavesDeathTestsAtFront(self):
 | 
			
		||||
    non_death_test_found = False
 | 
			
		||||
    for test in SHUFFLED_ACTIVE_TESTS:
 | 
			
		||||
      if 'DeathTest.' in test:
 | 
			
		||||
        self.assert_(not non_death_test_found,
 | 
			
		||||
                     '%s appears after a non-death test' % (test,))
 | 
			
		||||
      else:
 | 
			
		||||
        non_death_test_found = True
 | 
			
		||||
 | 
			
		||||
  def _VerifyTestCasesDoNotInterleave(self, tests):
 | 
			
		||||
    test_cases = []
 | 
			
		||||
    for test in tests:
 | 
			
		||||
      [test_case, _] = test.split('.')
 | 
			
		||||
      if test_cases and test_cases[-1] != test_case:
 | 
			
		||||
        test_cases.append(test_case)
 | 
			
		||||
        self.assertEqual(1, test_cases.count(test_case),
 | 
			
		||||
                         'Test case %s is not grouped together in %s' %
 | 
			
		||||
                         (test_case, tests))
 | 
			
		||||
 | 
			
		||||
  def testShuffleDoesNotInterleaveTestCases(self):
 | 
			
		||||
    self._VerifyTestCasesDoNotInterleave(SHUFFLED_ALL_TESTS)
 | 
			
		||||
    self._VerifyTestCasesDoNotInterleave(SHUFFLED_ACTIVE_TESTS)
 | 
			
		||||
    self._VerifyTestCasesDoNotInterleave(SHUFFLED_FILTERED_TESTS)
 | 
			
		||||
    self._VerifyTestCasesDoNotInterleave(SHUFFLED_SHARDED_TESTS)
 | 
			
		||||
 | 
			
		||||
  def testShuffleRestoresOrderAfterEachIteration(self):
 | 
			
		||||
    # Get the test lists in all 3 iterations, using random seed 1, 2,
 | 
			
		||||
    # and 3 respectively.  Google Test picks a different seed in each
 | 
			
		||||
    # iteration, and this test depends on the current implementation
 | 
			
		||||
    # picking successive numbers.  This dependency is not ideal, but
 | 
			
		||||
    # makes the test much easier to write.
 | 
			
		||||
    [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = (
 | 
			
		||||
        GetTestsForAllIterations(
 | 
			
		||||
            {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)]))
 | 
			
		||||
 | 
			
		||||
    # Make sure running the tests with random seed 1 gets the same
 | 
			
		||||
    # order as in iteration 1 above.
 | 
			
		||||
    [tests_with_seed1] = GetTestsForAllIterations(
 | 
			
		||||
        {}, [ShuffleFlag(), RandomSeedFlag(1)])
 | 
			
		||||
    self.assertEqual(tests_in_iteration1, tests_with_seed1)
 | 
			
		||||
 | 
			
		||||
    # Make sure running the tests with random seed 2 gets the same
 | 
			
		||||
    # order as in iteration 2 above.  Success means that Google Test
 | 
			
		||||
    # correctly restores the test order before re-shuffling at the
 | 
			
		||||
    # beginning of iteration 2.
 | 
			
		||||
    [tests_with_seed2] = GetTestsForAllIterations(
 | 
			
		||||
        {}, [ShuffleFlag(), RandomSeedFlag(2)])
 | 
			
		||||
    self.assertEqual(tests_in_iteration2, tests_with_seed2)
 | 
			
		||||
 | 
			
		||||
    # Make sure running the tests with random seed 3 gets the same
 | 
			
		||||
    # order as in iteration 3 above.  Success means that Google Test
 | 
			
		||||
    # correctly restores the test order before re-shuffling at the
 | 
			
		||||
    # beginning of iteration 3.
 | 
			
		||||
    [tests_with_seed3] = GetTestsForAllIterations(
 | 
			
		||||
        {}, [ShuffleFlag(), RandomSeedFlag(3)])
 | 
			
		||||
    self.assertEqual(tests_in_iteration3, tests_with_seed3)
 | 
			
		||||
 | 
			
		||||
  def testShuffleGeneratesNewOrderInEachIteration(self):
 | 
			
		||||
    [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = (
 | 
			
		||||
        GetTestsForAllIterations(
 | 
			
		||||
            {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)]))
 | 
			
		||||
 | 
			
		||||
    self.assert_(tests_in_iteration1 != tests_in_iteration2,
 | 
			
		||||
                 tests_in_iteration1)
 | 
			
		||||
    self.assert_(tests_in_iteration1 != tests_in_iteration3,
 | 
			
		||||
                 tests_in_iteration1)
 | 
			
		||||
    self.assert_(tests_in_iteration2 != tests_in_iteration3,
 | 
			
		||||
                 tests_in_iteration2)
 | 
			
		||||
 | 
			
		||||
  def testShuffleShardedTestsPreservesPartition(self):
 | 
			
		||||
    # If we run M tests on N shards, the same M tests should be run in
 | 
			
		||||
    # total, regardless of the random seeds used by the shards.
 | 
			
		||||
    [tests1] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
 | 
			
		||||
                                         SHARD_INDEX_ENV_VAR: '0'},
 | 
			
		||||
                                        [ShuffleFlag(), RandomSeedFlag(1)])
 | 
			
		||||
    [tests2] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
 | 
			
		||||
                                         SHARD_INDEX_ENV_VAR: '1'},
 | 
			
		||||
                                        [ShuffleFlag(), RandomSeedFlag(20)])
 | 
			
		||||
    [tests3] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
 | 
			
		||||
                                         SHARD_INDEX_ENV_VAR: '2'},
 | 
			
		||||
                                        [ShuffleFlag(), RandomSeedFlag(25)])
 | 
			
		||||
    sorted_sharded_tests = tests1 + tests2 + tests3
 | 
			
		||||
    sorted_sharded_tests.sort()
 | 
			
		||||
    sorted_active_tests = []
 | 
			
		||||
    sorted_active_tests.extend(ACTIVE_TESTS)
 | 
			
		||||
    sorted_active_tests.sort()
 | 
			
		||||
    self.assertEqual(sorted_active_tests, sorted_sharded_tests)
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
  gtest_test_utils.Main()
 | 
			
		||||
							
								
								
									
										104
									
								
								test/gtest_shuffle_test_.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								test/gtest_shuffle_test_.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
// Copyright 2009, Google Inc.
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Redistribution and use in source and binary forms, with or without
 | 
			
		||||
// modification, are permitted provided that the following conditions are
 | 
			
		||||
// met:
 | 
			
		||||
//
 | 
			
		||||
//     * Redistributions of source code must retain the above copyright
 | 
			
		||||
// notice, this list of conditions and the following disclaimer.
 | 
			
		||||
//     * Redistributions in binary form must reproduce the above
 | 
			
		||||
// copyright notice, this list of conditions and the following disclaimer
 | 
			
		||||
// in the documentation and/or other materials provided with the
 | 
			
		||||
// distribution.
 | 
			
		||||
//     * Neither the name of Google Inc. nor the names of its
 | 
			
		||||
// contributors may be used to endorse or promote products derived from
 | 
			
		||||
// this software without specific prior written permission.
 | 
			
		||||
//
 | 
			
		||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
//
 | 
			
		||||
// Author: wan@google.com (Zhanyong Wan)
 | 
			
		||||
 | 
			
		||||
// Verifies that test shuffling works.
 | 
			
		||||
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
using ::testing::EmptyTestEventListener;
 | 
			
		||||
using ::testing::InitGoogleTest;
 | 
			
		||||
using ::testing::Message;
 | 
			
		||||
using ::testing::Test;
 | 
			
		||||
using ::testing::TestEventListeners;
 | 
			
		||||
using ::testing::TestInfo;
 | 
			
		||||
using ::testing::UnitTest;
 | 
			
		||||
using ::testing::internal::String;
 | 
			
		||||
using ::testing::internal::scoped_ptr;
 | 
			
		||||
 | 
			
		||||
// The test methods are empty, as the sole purpose of this program is
 | 
			
		||||
// to print the test names before/after shuffling.
 | 
			
		||||
 | 
			
		||||
class A : public Test {};
 | 
			
		||||
TEST_F(A, A) {}
 | 
			
		||||
TEST_F(A, B) {}
 | 
			
		||||
 | 
			
		||||
TEST(ADeathTest, A) {}
 | 
			
		||||
TEST(ADeathTest, B) {}
 | 
			
		||||
TEST(ADeathTest, C) {}
 | 
			
		||||
 | 
			
		||||
TEST(B, A) {}
 | 
			
		||||
TEST(B, B) {}
 | 
			
		||||
TEST(B, C) {}
 | 
			
		||||
TEST(B, DISABLED_D) {}
 | 
			
		||||
TEST(B, DISABLED_E) {}
 | 
			
		||||
 | 
			
		||||
TEST(BDeathTest, A) {}
 | 
			
		||||
TEST(BDeathTest, B) {}
 | 
			
		||||
 | 
			
		||||
TEST(C, A) {}
 | 
			
		||||
TEST(C, B) {}
 | 
			
		||||
TEST(C, C) {}
 | 
			
		||||
TEST(C, DISABLED_D) {}
 | 
			
		||||
 | 
			
		||||
TEST(CDeathTest, A) {}
 | 
			
		||||
 | 
			
		||||
TEST(DISABLED_D, A) {}
 | 
			
		||||
TEST(DISABLED_D, DISABLED_B) {}
 | 
			
		||||
 | 
			
		||||
// This printer prints the full test names only, starting each test
 | 
			
		||||
// iteration with a "----" marker.
 | 
			
		||||
class TestNamePrinter : public EmptyTestEventListener {
 | 
			
		||||
 public:
 | 
			
		||||
  virtual void OnTestIterationStart(const UnitTest& /* unit_test */,
 | 
			
		||||
                                    int /* iteration */) {
 | 
			
		||||
    printf("----\n");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual void OnTestStart(const TestInfo& test_info) {
 | 
			
		||||
    printf("%s.%s\n", test_info.test_case_name(), test_info.name());
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv) {
 | 
			
		||||
  InitGoogleTest(&argc, argv);
 | 
			
		||||
 | 
			
		||||
  // Replaces the default printer with TestNamePrinter, which prints
 | 
			
		||||
  // the test name only.
 | 
			
		||||
  TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
 | 
			
		||||
  delete listeners.Release(listeners.default_result_printer());
 | 
			
		||||
  listeners.Append(new TestNamePrinter);
 | 
			
		||||
 | 
			
		||||
  return RUN_ALL_TESTS();
 | 
			
		||||
}
 | 
			
		||||
@@ -180,6 +180,19 @@ using testing::internal::kMaxRandomSeed;
 | 
			
		||||
using testing::internal::kTestTypeIdInGoogleTest;
 | 
			
		||||
using testing::internal::scoped_ptr;
 | 
			
		||||
 | 
			
		||||
class TestingVector : public Vector<int> {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
::std::ostream& operator<<(::std::ostream& os,
 | 
			
		||||
                           const TestingVector& vector) {
 | 
			
		||||
  os << "{ ";
 | 
			
		||||
  for (int i = 0; i < vector.size(); i++) {
 | 
			
		||||
    os << vector.GetElement(i) << " ";
 | 
			
		||||
  }
 | 
			
		||||
  os << "}";
 | 
			
		||||
  return os;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This line tests that we can define tests in an unnamed namespace.
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
@@ -677,6 +690,53 @@ TEST(VectorTest, GetElementOr) {
 | 
			
		||||
  EXPECT_EQ('x', a.GetElementOr(2, 'x'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(VectorTest, Swap) {
 | 
			
		||||
  Vector<int> a;
 | 
			
		||||
  a.PushBack(0);
 | 
			
		||||
  a.PushBack(1);
 | 
			
		||||
  a.PushBack(2);
 | 
			
		||||
 | 
			
		||||
  // Swaps an element with itself.
 | 
			
		||||
  a.Swap(0, 0);
 | 
			
		||||
  ASSERT_EQ(0, a.GetElement(0));
 | 
			
		||||
  ASSERT_EQ(1, a.GetElement(1));
 | 
			
		||||
  ASSERT_EQ(2, a.GetElement(2));
 | 
			
		||||
 | 
			
		||||
  // Swaps two different elements where the indices go up.
 | 
			
		||||
  a.Swap(0, 1);
 | 
			
		||||
  ASSERT_EQ(1, a.GetElement(0));
 | 
			
		||||
  ASSERT_EQ(0, a.GetElement(1));
 | 
			
		||||
  ASSERT_EQ(2, a.GetElement(2));
 | 
			
		||||
 | 
			
		||||
  // Swaps two different elements where the indices go down.
 | 
			
		||||
  a.Swap(2, 0);
 | 
			
		||||
  ASSERT_EQ(2, a.GetElement(0));
 | 
			
		||||
  ASSERT_EQ(0, a.GetElement(1));
 | 
			
		||||
  ASSERT_EQ(1, a.GetElement(2));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(VectorTest, Clone) {
 | 
			
		||||
  // Clones an empty Vector.
 | 
			
		||||
  Vector<int> a;
 | 
			
		||||
  scoped_ptr<Vector<int> > empty(a.Clone());
 | 
			
		||||
  EXPECT_EQ(0, empty->size());
 | 
			
		||||
 | 
			
		||||
  // Clones a singleton.
 | 
			
		||||
  a.PushBack(42);
 | 
			
		||||
  scoped_ptr<Vector<int> > singleton(a.Clone());
 | 
			
		||||
  ASSERT_EQ(1, singleton->size());
 | 
			
		||||
  EXPECT_EQ(42, singleton->GetElement(0));
 | 
			
		||||
 | 
			
		||||
  // Clones a Vector with more elements.
 | 
			
		||||
  a.PushBack(43);
 | 
			
		||||
  a.PushBack(44);
 | 
			
		||||
  scoped_ptr<Vector<int> > big(a.Clone());
 | 
			
		||||
  ASSERT_EQ(3, big->size());
 | 
			
		||||
  EXPECT_EQ(42, big->GetElement(0));
 | 
			
		||||
  EXPECT_EQ(43, big->GetElement(1));
 | 
			
		||||
  EXPECT_EQ(44, big->GetElement(2));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tests Vector::Erase().
 | 
			
		||||
TEST(VectorDeathTest, Erase) {
 | 
			
		||||
  Vector<int> a;
 | 
			
		||||
@@ -740,23 +800,252 @@ TEST(VectorDeathTest, Erase) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tests the GetElement accessor.
 | 
			
		||||
TEST(ListDeathTest, GetElement) {
 | 
			
		||||
TEST(VectorDeathTest, GetElement) {
 | 
			
		||||
  Vector<int> a;
 | 
			
		||||
  a.PushBack(0);
 | 
			
		||||
  a.PushBack(1);
 | 
			
		||||
  a.PushBack(2);
 | 
			
		||||
  const Vector<int>& b = a;
 | 
			
		||||
 | 
			
		||||
  EXPECT_EQ(0, b.GetElement(0));
 | 
			
		||||
  EXPECT_EQ(1, b.GetElement(1));
 | 
			
		||||
  EXPECT_EQ(2, b.GetElement(2));
 | 
			
		||||
  EXPECT_DEATH_IF_SUPPORTED(
 | 
			
		||||
      b.GetElement(3),
 | 
			
		||||
      "Invalid Vector index 3: must be in range \\[0, 2\\]\\.");
 | 
			
		||||
  EXPECT_DEATH_IF_SUPPORTED(
 | 
			
		||||
      b.GetElement(-1),
 | 
			
		||||
      "Invalid Vector index -1: must be in range \\[0, 2\\]\\.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tests the GetMutableElement accessor.
 | 
			
		||||
TEST(VectorDeathTest, GetMutableElement) {
 | 
			
		||||
  Vector<int> a;
 | 
			
		||||
  a.PushBack(0);
 | 
			
		||||
  a.PushBack(1);
 | 
			
		||||
  a.PushBack(2);
 | 
			
		||||
 | 
			
		||||
  EXPECT_EQ(0, a.GetElement(0));
 | 
			
		||||
  EXPECT_EQ(1, a.GetElement(1));
 | 
			
		||||
  EXPECT_EQ(2, a.GetElement(2));
 | 
			
		||||
  EXPECT_EQ(0, a.GetMutableElement(0));
 | 
			
		||||
  EXPECT_EQ(1, a.GetMutableElement(1));
 | 
			
		||||
  EXPECT_EQ(2, a.GetMutableElement(2));
 | 
			
		||||
 | 
			
		||||
  a.GetMutableElement(0) = 42;
 | 
			
		||||
  EXPECT_EQ(42, a.GetMutableElement(0));
 | 
			
		||||
  EXPECT_EQ(1, a.GetMutableElement(1));
 | 
			
		||||
  EXPECT_EQ(2, a.GetMutableElement(2));
 | 
			
		||||
 | 
			
		||||
  EXPECT_DEATH_IF_SUPPORTED(
 | 
			
		||||
      a.GetElement(3),
 | 
			
		||||
      a.GetMutableElement(3),
 | 
			
		||||
      "Invalid Vector index 3: must be in range \\[0, 2\\]\\.");
 | 
			
		||||
  EXPECT_DEATH_IF_SUPPORTED(
 | 
			
		||||
      a.GetElement(-1),
 | 
			
		||||
      a.GetMutableElement(-1),
 | 
			
		||||
      "Invalid Vector index -1: must be in range \\[0, 2\\]\\.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(VectorDeathTest, Swap) {
 | 
			
		||||
  Vector<int> a;
 | 
			
		||||
  a.PushBack(0);
 | 
			
		||||
  a.PushBack(1);
 | 
			
		||||
  a.PushBack(2);
 | 
			
		||||
 | 
			
		||||
  EXPECT_DEATH_IF_SUPPORTED(
 | 
			
		||||
      a.Swap(-1, 1),
 | 
			
		||||
      "Invalid first swap element -1: must be in range \\[0, 2\\]");
 | 
			
		||||
  EXPECT_DEATH_IF_SUPPORTED(
 | 
			
		||||
      a.Swap(3, 1),
 | 
			
		||||
      "Invalid first swap element 3: must be in range \\[0, 2\\]");
 | 
			
		||||
  EXPECT_DEATH_IF_SUPPORTED(
 | 
			
		||||
      a.Swap(1, -1),
 | 
			
		||||
      "Invalid second swap element -1: must be in range \\[0, 2\\]");
 | 
			
		||||
  EXPECT_DEATH_IF_SUPPORTED(
 | 
			
		||||
      a.Swap(1, 3),
 | 
			
		||||
      "Invalid second swap element 3: must be in range \\[0, 2\\]");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(VectorDeathTest, ShuffleRange) {
 | 
			
		||||
  Vector<int> a;
 | 
			
		||||
  a.PushBack(0);
 | 
			
		||||
  a.PushBack(1);
 | 
			
		||||
  a.PushBack(2);
 | 
			
		||||
  testing::internal::Random random(1);
 | 
			
		||||
 | 
			
		||||
  EXPECT_DEATH_IF_SUPPORTED(
 | 
			
		||||
      a.ShuffleRange(&random, -1, 1),
 | 
			
		||||
      "Invalid shuffle range start -1: must be in range \\[0, 3\\]");
 | 
			
		||||
  EXPECT_DEATH_IF_SUPPORTED(
 | 
			
		||||
      a.ShuffleRange(&random, 4, 4),
 | 
			
		||||
      "Invalid shuffle range start 4: must be in range \\[0, 3\\]");
 | 
			
		||||
  EXPECT_DEATH_IF_SUPPORTED(
 | 
			
		||||
      a.ShuffleRange(&random, 3, 2),
 | 
			
		||||
      "Invalid shuffle range finish 2: must be in range \\[3, 3\\]");
 | 
			
		||||
  EXPECT_DEATH_IF_SUPPORTED(
 | 
			
		||||
      a.ShuffleRange(&random, 3, 4),
 | 
			
		||||
      "Invalid shuffle range finish 4: must be in range \\[3, 3\\]");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class VectorShuffleTest : public Test {
 | 
			
		||||
 protected:
 | 
			
		||||
  static const int kVectorSize = 20;
 | 
			
		||||
 | 
			
		||||
  VectorShuffleTest() : random_(1) {
 | 
			
		||||
    for (int i = 0; i < kVectorSize; i++) {
 | 
			
		||||
      vector_.PushBack(i);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static bool VectorIsCorrupt(const TestingVector& vector) {
 | 
			
		||||
    if (kVectorSize != vector.size()) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool found_in_vector[kVectorSize] = { false };
 | 
			
		||||
    for (int i = 0; i < vector.size(); i++) {
 | 
			
		||||
      const int e = vector.GetElement(i);
 | 
			
		||||
      if (e < 0 || e >= kVectorSize || found_in_vector[e]) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      found_in_vector[e] = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Vector size is correct, elements' range is correct, no
 | 
			
		||||
    // duplicate elements.  Therefore no corruption has occurred.
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static bool VectorIsNotCorrupt(const TestingVector& vector) {
 | 
			
		||||
    return !VectorIsCorrupt(vector);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static bool RangeIsShuffled(const TestingVector& vector, int begin, int end) {
 | 
			
		||||
    for (int i = begin; i < end; i++) {
 | 
			
		||||
      if (i != vector.GetElement(i)) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static bool RangeIsUnshuffled(
 | 
			
		||||
      const TestingVector& vector, int begin, int end) {
 | 
			
		||||
    return !RangeIsShuffled(vector, begin, end);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static bool VectorIsShuffled(const TestingVector& vector) {
 | 
			
		||||
    return RangeIsShuffled(vector, 0, vector.size());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static bool VectorIsUnshuffled(const TestingVector& vector) {
 | 
			
		||||
    return !VectorIsShuffled(vector);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  testing::internal::Random random_;
 | 
			
		||||
  TestingVector vector_;
 | 
			
		||||
};  // class VectorShuffleTest
 | 
			
		||||
 | 
			
		||||
const int VectorShuffleTest::kVectorSize;
 | 
			
		||||
 | 
			
		||||
TEST_F(VectorShuffleTest, HandlesEmptyRange) {
 | 
			
		||||
  // Tests an empty range at the beginning...
 | 
			
		||||
  vector_.ShuffleRange(&random_, 0, 0);
 | 
			
		||||
  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
 | 
			
		||||
  ASSERT_PRED1(VectorIsUnshuffled, vector_);
 | 
			
		||||
 | 
			
		||||
  // ...in the middle...
 | 
			
		||||
  vector_.ShuffleRange(&random_, kVectorSize/2, kVectorSize/2);
 | 
			
		||||
  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
 | 
			
		||||
  ASSERT_PRED1(VectorIsUnshuffled, vector_);
 | 
			
		||||
 | 
			
		||||
  // ...at the end...
 | 
			
		||||
  vector_.ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1);
 | 
			
		||||
  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
 | 
			
		||||
  ASSERT_PRED1(VectorIsUnshuffled, vector_);
 | 
			
		||||
 | 
			
		||||
  // ...and past the end.
 | 
			
		||||
  vector_.ShuffleRange(&random_, kVectorSize, kVectorSize);
 | 
			
		||||
  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
 | 
			
		||||
  ASSERT_PRED1(VectorIsUnshuffled, vector_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) {
 | 
			
		||||
  // Tests a size one range at the beginning...
 | 
			
		||||
  vector_.ShuffleRange(&random_, 0, 1);
 | 
			
		||||
  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
 | 
			
		||||
  ASSERT_PRED1(VectorIsUnshuffled, vector_);
 | 
			
		||||
 | 
			
		||||
  // ...in the middle...
 | 
			
		||||
  vector_.ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1);
 | 
			
		||||
  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
 | 
			
		||||
  ASSERT_PRED1(VectorIsUnshuffled, vector_);
 | 
			
		||||
 | 
			
		||||
  // ...and at the end.
 | 
			
		||||
  vector_.ShuffleRange(&random_, kVectorSize - 1, kVectorSize);
 | 
			
		||||
  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
 | 
			
		||||
  ASSERT_PRED1(VectorIsUnshuffled, vector_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Because we use our own random number generator and a fixed seed,
 | 
			
		||||
// we can guarantee that the following "random" tests will succeed.
 | 
			
		||||
 | 
			
		||||
TEST_F(VectorShuffleTest, ShufflesEntireVector) {
 | 
			
		||||
  vector_.Shuffle(&random_);
 | 
			
		||||
  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
 | 
			
		||||
  EXPECT_FALSE(VectorIsUnshuffled(vector_)) << vector_;
 | 
			
		||||
 | 
			
		||||
  // Tests the first and last elements in particular to ensure that
 | 
			
		||||
  // there are no off-by-one problems in our shuffle algorithm.
 | 
			
		||||
  EXPECT_NE(0, vector_.GetElement(0));
 | 
			
		||||
  EXPECT_NE(kVectorSize - 1, vector_.GetElement(kVectorSize - 1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(VectorShuffleTest, ShufflesStartOfVector) {
 | 
			
		||||
  const int kRangeSize = kVectorSize/2;
 | 
			
		||||
 | 
			
		||||
  vector_.ShuffleRange(&random_, 0, kRangeSize);
 | 
			
		||||
 | 
			
		||||
  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
 | 
			
		||||
  EXPECT_PRED3(RangeIsShuffled, vector_, 0, kRangeSize);
 | 
			
		||||
  EXPECT_PRED3(RangeIsUnshuffled, vector_, kRangeSize, kVectorSize);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(VectorShuffleTest, ShufflesEndOfVector) {
 | 
			
		||||
  const int kRangeSize = kVectorSize / 2;
 | 
			
		||||
  vector_.ShuffleRange(&random_, kRangeSize, kVectorSize);
 | 
			
		||||
 | 
			
		||||
  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
 | 
			
		||||
  EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize);
 | 
			
		||||
  EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, kVectorSize);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) {
 | 
			
		||||
  int kRangeSize = kVectorSize/3;
 | 
			
		||||
  vector_.ShuffleRange(&random_, kRangeSize, 2*kRangeSize);
 | 
			
		||||
 | 
			
		||||
  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
 | 
			
		||||
  EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize);
 | 
			
		||||
  EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, 2*kRangeSize);
 | 
			
		||||
  EXPECT_PRED3(RangeIsUnshuffled, vector_, 2*kRangeSize, kVectorSize);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(VectorShuffleTest, ShufflesRepeatably) {
 | 
			
		||||
  TestingVector vector2;
 | 
			
		||||
  for (int i = 0; i < kVectorSize; i++) {
 | 
			
		||||
    vector2.PushBack(i);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  random_.Reseed(1234);
 | 
			
		||||
  vector_.Shuffle(&random_);
 | 
			
		||||
  random_.Reseed(1234);
 | 
			
		||||
  vector2.Shuffle(&random_);
 | 
			
		||||
 | 
			
		||||
  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
 | 
			
		||||
  ASSERT_PRED1(VectorIsNotCorrupt, vector2);
 | 
			
		||||
 | 
			
		||||
  for (int i = 0; i < kVectorSize; i++) {
 | 
			
		||||
    EXPECT_EQ(vector_.GetElement(i), vector2.GetElement(i))
 | 
			
		||||
        << " where i is " << i;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tests the size of the AssertHelper class.
 | 
			
		||||
 | 
			
		||||
TEST(AssertHelperTest, AssertHelperIsSmall) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user