Adds a Random class to support --gtest_shuffle (by Josh Kelley); Makes the scons script build in a deterministic order (by Zhanyong Wan).
This commit is contained in:
		@@ -748,6 +748,28 @@ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count);
 | 
				
			|||||||
// A helper for suppressing warnings on unreachable code in some macros.
 | 
					// A helper for suppressing warnings on unreachable code in some macros.
 | 
				
			||||||
bool AlwaysTrue();
 | 
					bool AlwaysTrue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A simple Linear Congruential Generator for generating random
 | 
				
			||||||
 | 
					// numbers with a uniform distribution.  Unlike rand() and srand(), it
 | 
				
			||||||
 | 
					// doesn't use global state (and therefore can't interfere with user
 | 
				
			||||||
 | 
					// code).  Unlike rand_r(), it's portable.  An LCG isn't very random,
 | 
				
			||||||
 | 
					// but it's good enough for our purposes.
 | 
				
			||||||
 | 
					class Random {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  static const UInt32 kMaxRange = 1u << 31;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  explicit Random(UInt32 seed) : state_(seed) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void Reseed(UInt32 seed) { state_ = seed; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Generates a random number from [0, range).  Crashes if 'range' is
 | 
				
			||||||
 | 
					  // 0 or greater than kMaxRange.
 | 
				
			||||||
 | 
					  UInt32 Generate(UInt32 range);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  UInt32 state_;
 | 
				
			||||||
 | 
					  GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace internal
 | 
					}  // namespace internal
 | 
				
			||||||
}  // namespace testing
 | 
					}  // namespace testing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -155,11 +155,6 @@ class SConstructHelper:
 | 
				
			|||||||
                     '/OPT:NOICF',
 | 
					                     '/OPT:NOICF',
 | 
				
			||||||
                     ]
 | 
					                     ]
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    # Tell SCons to build depdendencies in random order (apart from the
 | 
					 | 
				
			||||||
    # actual dependency order).  This helps ensure we don't introduce
 | 
					 | 
				
			||||||
    # build files that "accidentally" work sometimes (e.g. when you are
 | 
					 | 
				
			||||||
    # building some targets) and not other times.
 | 
					 | 
				
			||||||
    debug_env.SetOption('random', 1)
 | 
					 | 
				
			||||||
    return debug_env
 | 
					    return debug_env
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def MakeWinOptimizedEnvironment(self, base_environment, name):
 | 
					  def MakeWinOptimizedEnvironment(self, base_environment, name):
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								src/gtest.cc
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/gtest.cc
									
									
									
									
									
								
							@@ -260,6 +260,25 @@ GTEST_DEFINE_bool_(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace internal {
 | 
					namespace internal {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Generates a random number from [0, range), using a Linear
 | 
				
			||||||
 | 
					// Congruential Generator (LCG).  Crashes if 'range' is 0 or greater
 | 
				
			||||||
 | 
					// than kMaxRange.
 | 
				
			||||||
 | 
					UInt32 Random::Generate(UInt32 range) {
 | 
				
			||||||
 | 
					  // These constants are the same as are used in glibc's rand(3).
 | 
				
			||||||
 | 
					  state_ = (1103515245U*state_ + 12345U) % kMaxRange;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GTEST_CHECK_(range > 0)
 | 
				
			||||||
 | 
					      << "Cannot generate a number in the range [0, 0).";
 | 
				
			||||||
 | 
					  GTEST_CHECK_(range <= kMaxRange)
 | 
				
			||||||
 | 
					      << "Generation of a number in [0, " << range << ") was requested, "
 | 
				
			||||||
 | 
					      << "but this can only generate numbers in [0, " << kMaxRange << ").";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Converting via modulus introduces a bit of downward bias, but
 | 
				
			||||||
 | 
					  // it's simple, and a linear congruential generator isn't too good
 | 
				
			||||||
 | 
					  // to begin with.
 | 
				
			||||||
 | 
					  return state_ % range;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// g_help_flag is true iff the --help flag or an equivalent form is
 | 
					// g_help_flag is true iff the --help flag or an equivalent form is
 | 
				
			||||||
// specified on the command line.
 | 
					// specified on the command line.
 | 
				
			||||||
static bool g_help_flag = false;
 | 
					static bool g_help_flag = false;
 | 
				
			||||||
@@ -3815,7 +3834,7 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); }
 | 
				
			|||||||
// considered to be failed, but the rest of the tests will still be
 | 
					// considered to be failed, but the rest of the tests will still be
 | 
				
			||||||
// run.  (We disable exceptions on Linux and Mac OS X, so the issue
 | 
					// run.  (We disable exceptions on Linux and Mac OS X, so the issue
 | 
				
			||||||
// doesn't apply there.)
 | 
					// doesn't apply there.)
 | 
				
			||||||
// When parameterized tests are enabled, it explands and registers
 | 
					// When parameterized tests are enabled, it expands and registers
 | 
				
			||||||
// parameterized tests first in RegisterParameterizedTests().
 | 
					// parameterized tests first in RegisterParameterizedTests().
 | 
				
			||||||
// All other functions called from RunAllTests() may safely assume that
 | 
					// All other functions called from RunAllTests() may safely assume that
 | 
				
			||||||
// parameterized tests are ready to be counted and run.
 | 
					// parameterized tests are ready to be counted and run.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -183,6 +183,7 @@ using testing::internal::TestProperty;
 | 
				
			|||||||
using testing::internal::TestResult;
 | 
					using testing::internal::TestResult;
 | 
				
			||||||
using testing::internal::TestResultAccessor;
 | 
					using testing::internal::TestResultAccessor;
 | 
				
			||||||
using testing::internal::ThreadLocal;
 | 
					using testing::internal::ThreadLocal;
 | 
				
			||||||
 | 
					using testing::internal::UInt32;
 | 
				
			||||||
using testing::internal::Vector;
 | 
					using testing::internal::Vector;
 | 
				
			||||||
using testing::internal::WideStringToUtf8;
 | 
					using testing::internal::WideStringToUtf8;
 | 
				
			||||||
using testing::internal::kTestTypeIdInGoogleTest;
 | 
					using testing::internal::kTestTypeIdInGoogleTest;
 | 
				
			||||||
@@ -499,6 +500,49 @@ TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
#endif  // !GTEST_WIDE_STRING_USES_UTF16_
 | 
					#endif  // !GTEST_WIDE_STRING_USES_UTF16_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Tests the Random class.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(RandomDeathTest, GeneratesCrashesOnInvalidRange) {
 | 
				
			||||||
 | 
					  testing::internal::Random random(42);
 | 
				
			||||||
 | 
					  EXPECT_DEATH_IF_SUPPORTED(
 | 
				
			||||||
 | 
					      random.Generate(0),
 | 
				
			||||||
 | 
					      "Cannot generate a number in the range \\[0, 0\\)");
 | 
				
			||||||
 | 
					  EXPECT_DEATH_IF_SUPPORTED(
 | 
				
			||||||
 | 
					      random.Generate(testing::internal::Random::kMaxRange + 1),
 | 
				
			||||||
 | 
					      "Generation of a number in \\[0, 2147483649\\) was requested, "
 | 
				
			||||||
 | 
					      "but this can only generate numbers in \\[0, 2147483648\\)");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(RandomTest, GeneratesNumbersWithinRange) {
 | 
				
			||||||
 | 
					  const UInt32 kRange = 10000;
 | 
				
			||||||
 | 
					  testing::internal::Random random(12345);
 | 
				
			||||||
 | 
					  for (int i = 0; i < 10; i++) {
 | 
				
			||||||
 | 
					    EXPECT_LT(random.Generate(kRange), kRange) << " for iteration " << i;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  testing::internal::Random random2(testing::internal::Random::kMaxRange);
 | 
				
			||||||
 | 
					  for (int i = 0; i < 10; i++) {
 | 
				
			||||||
 | 
					    EXPECT_LT(random2.Generate(kRange), kRange) << " for iteration " << i;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(RandomTest, RepeatsWhenReseeded) {
 | 
				
			||||||
 | 
					  const int kSeed = 123;
 | 
				
			||||||
 | 
					  const int kArraySize = 10;
 | 
				
			||||||
 | 
					  const UInt32 kRange = 10000;
 | 
				
			||||||
 | 
					  UInt32 values[kArraySize];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  testing::internal::Random random(kSeed);
 | 
				
			||||||
 | 
					  for (int i = 0; i < kArraySize; i++) {
 | 
				
			||||||
 | 
					    values[i] = random.Generate(kRange);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  random.Reseed(kSeed);
 | 
				
			||||||
 | 
					  for (int i = 0; i < kArraySize; i++) {
 | 
				
			||||||
 | 
					    EXPECT_EQ(values[i], random.Generate(kRange)) << " for iteration " << i;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests the Vector class template.
 | 
					// Tests the Vector class template.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests Vector::Clear().
 | 
					// Tests Vector::Clear().
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user