From d36c0c538a545fac5d9db6ba65c525246d4efa95 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Wed, 29 Mar 2017 14:32:48 -0700 Subject: Down-integrate from google3. --- src/google/protobuf/map_test.cc | 176 ++++++++++++++++++++-------------------- 1 file changed, 90 insertions(+), 86 deletions(-) (limited to 'src/google/protobuf/map_test.cc') diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index 43fe0f44..3fe44512 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -54,10 +54,13 @@ #include #include #include -#include #include +#include #include #include +#include +#include +#include #include #include #include @@ -70,12 +73,8 @@ #include #include #include -#include -#include -#include -#include #include -#include +#include #include #include #include @@ -97,17 +96,15 @@ void MapTestForceDeterministic() { // Map API Test ===================================================== -// Parameterized tests on whether to use old style maps. -class MapImplTest : public testing::TestWithParam { +class MapImplTest : public ::testing::Test { protected: MapImplTest() - : map_ptr_(new Map(GetParam())), + : map_ptr_(new Map()), map_(*map_ptr_), const_map_(*map_ptr_) { EXPECT_TRUE(map_.empty()); EXPECT_EQ(0, map_.size()); } - ~MapImplTest() {} void ExpectSingleElement(int32 key, int32 value) { EXPECT_FALSE(map_.empty()); @@ -178,7 +175,7 @@ class MapImplTest : public testing::TestWithParam { const Map& const_map_; }; -TEST_P(MapImplTest, OperatorBracket) { +TEST_F(MapImplTest, OperatorBracket) { int32 key = 0; int32 value1 = 100; int32 value2 = 101; @@ -192,7 +189,7 @@ TEST_P(MapImplTest, OperatorBracket) { ExpectSingleElement(key, value2); } -TEST_P(MapImplTest, OperatorBracketNonExist) { +TEST_F(MapImplTest, OperatorBracketNonExist) { int32 key = 0; int32 default_value = 0; @@ -200,7 +197,7 @@ TEST_P(MapImplTest, OperatorBracketNonExist) { ExpectSingleElement(key, default_value); } -TEST_P(MapImplTest, MutableAt) { +TEST_F(MapImplTest, MutableAt) { int32 key = 0; int32 value1 = 100; int32 value2 = 101; @@ -214,15 +211,15 @@ TEST_P(MapImplTest, MutableAt) { #ifdef PROTOBUF_HAS_DEATH_TEST -TEST_P(MapImplTest, MutableAtNonExistDeathTest) { +TEST_F(MapImplTest, MutableAtNonExistDeathTest) { EXPECT_DEATH(map_.at(0), ""); } -TEST_P(MapImplTest, ImmutableAtNonExistDeathTest) { +TEST_F(MapImplTest, ImmutableAtNonExistDeathTest) { EXPECT_DEATH(const_map_.at(0), ""); } -TEST_P(MapImplTest, UsageErrors) { +TEST_F(MapImplTest, UsageErrors) { MapKey key; key.SetInt64Value(1); EXPECT_DEATH(key.GetUInt64Value(), @@ -239,23 +236,23 @@ TEST_P(MapImplTest, UsageErrors) { #endif // PROTOBUF_HAS_DEATH_TEST -TEST_P(MapImplTest, CountNonExist) { +TEST_F(MapImplTest, CountNonExist) { EXPECT_EQ(0, map_.count(0)); } -TEST_P(MapImplTest, MutableFindNonExist) { +TEST_F(MapImplTest, MutableFindNonExist) { EXPECT_TRUE(map_.end() == map_.find(0)); } -TEST_P(MapImplTest, ImmutableFindNonExist) { +TEST_F(MapImplTest, ImmutableFindNonExist) { EXPECT_TRUE(const_map_.end() == const_map_.find(0)); } -TEST_P(MapImplTest, ConstEnd) { +TEST_F(MapImplTest, ConstEnd) { EXPECT_TRUE(const_map_.end() == const_map_.cend()); } -TEST_P(MapImplTest, GetReferenceFromIterator) { +TEST_F(MapImplTest, GetReferenceFromIterator) { for (int i = 0; i < 10; i++) { map_[i] = i; } @@ -278,7 +275,7 @@ TEST_P(MapImplTest, GetReferenceFromIterator) { } } -TEST_P(MapImplTest, IteratorBasic) { +TEST_F(MapImplTest, IteratorBasic) { map_[0] = 0; // Default constructible (per forward iterator requirements). @@ -320,10 +317,9 @@ static int k2 = 1321555333; // A naive begin() implementation will cause begin() to get slower and slower // if one erases elements at the "front" of the hash map, and we'd like to // avoid that, as std::unordered_map does. -TEST_P(MapImplTest, BeginIsFast) { - // Disable this test for both new and old implementations. - if (/*GetParam()*/true) return; - Map map(false); // This test uses new-style maps only. +TEST_F(MapImplTest, BeginIsFast) { + if (true) return; // TODO(gpike): make this less flaky and re-enable it. + Map map; const int kTestSize = 250000; // Create a random-looking map of size n. Use non-negative integer keys. uint32 frog = 123983; @@ -371,7 +367,7 @@ TEST_P(MapImplTest, BeginIsFast) { // Try to create kTestSize keys that will land in just a few buckets, and // time the insertions, to get a rough estimate of whether an O(n^2) worst case // was triggered. This test is a hacky, but probably better than nothing. -TEST_P(MapImplTest, HashFlood) { +TEST_F(MapImplTest, HashFlood) { const int kTestSize = 1024; // must be a power of 2 std::set s; for (int i = 0; s.size() < kTestSize; i++) { @@ -404,6 +400,22 @@ TEST_P(MapImplTest, HashFlood) { EXPECT_LE(x1, x0 * 20); } +TEST_F(MapImplTest, CopyIteratorStressTest) { + std::vector::iterator> v; + const int kIters = 1e5; + for (uint32 i = 0; i < kIters; i++) { + int32 key = (3 + i * (5 + i * (-8 + i * (62 + i)))) & 0x77777777; + map_[key] = i; + v.push_back(map_.find(key)); + } + for (std::vector::iterator>::const_iterator it = v.begin(); + it != v.end(); it++) { + Map::iterator i = *it; + ASSERT_EQ(i->first, (*it)->first); + ASSERT_EQ(i->second, (*it)->second); + } +} + template static void TestValidityForAllKeysExcept(int key_to_avoid, const T& check_map, @@ -468,11 +480,11 @@ static void TestOldVersusNewIterator(int skip, Map* m) { } // Create and test an n-element Map, with emphasis on iterator correctness. -static void StressTestIterators(int n, bool test_old_style_proto2_maps) { +static void StressTestIterators(int n) { GOOGLE_LOG(INFO) << "StressTestIterators " << n; GOOGLE_CHECK_GT(n, 0); // Create a random-looking map of size n. Use non-negative integer keys. - Map m(test_old_style_proto2_maps); + Map m; uint32 frog = 123987 + n; int last_key = 0; int counter = 0; @@ -530,10 +542,7 @@ static void StressTestIterators(int n, bool test_old_style_proto2_maps) { } } -TEST_P(MapImplTest, IteratorInvalidation) { - // As multiple underlying hash_map implementations do not follow the - // validation requirement, the test is disabled for old-style maps. - if (GetParam()) return; +TEST_F(MapImplTest, IteratorInvalidation) { // Create a set of pseudo-random sizes to test. #ifndef NDEBUG const int kMaxSizeToTest = 100 * 1000; @@ -555,15 +564,12 @@ TEST_P(MapImplTest, IteratorInvalidation) { s.insert(3); // Now, the real work. for (std::set::iterator i = s.begin(); i != s.end(); ++i) { - StressTestIterators(*i, GetParam()); + StressTestIterators(*i); } } // Test that erase() revalidates iterators. -TEST_P(MapImplTest, EraseRevalidates) { - // As multiple underlying hash_map implementations do not follow the - // validation requirement, the test is disabled for old-style maps. - if (GetParam()) return; +TEST_F(MapImplTest, EraseRevalidates) { map_[3] = map_[13] = map_[20] = 0; const int initial_size = map_.size(); EXPECT_EQ(3, initial_size); @@ -595,7 +601,7 @@ bool IsConstHelper(const T& /*t*/) { return true; } -TEST_P(MapImplTest, IteratorConstness) { +TEST_F(MapImplTest, IteratorConstness) { map_[0] = 0; EXPECT_TRUE(IsConstHelper(*map_.cbegin())); EXPECT_TRUE(IsConstHelper(*const_map_.begin())); @@ -608,14 +614,14 @@ bool IsForwardIteratorHelper(T /*t*/) { return false; } -TEST_P(MapImplTest, IteratorCategory) { +TEST_F(MapImplTest, IteratorCategory) { EXPECT_TRUE(IsForwardIteratorHelper( std::iterator_traits::iterator>::iterator_category())); EXPECT_TRUE(IsForwardIteratorHelper(std::iterator_traits< Map::const_iterator>::iterator_category())); } -TEST_P(MapImplTest, InsertSingle) { +TEST_F(MapImplTest, InsertSingle) { int32 key = 0; int32 value1 = 100; int32 value2 = 101; @@ -640,7 +646,7 @@ TEST_P(MapImplTest, InsertSingle) { EXPECT_FALSE(result2.second); } -TEST_P(MapImplTest, InsertByIterator) { +TEST_F(MapImplTest, InsertByIterator) { int32 key1 = 0; int32 key2 = 1; int32 value1a = 100; @@ -663,7 +669,7 @@ TEST_P(MapImplTest, InsertByIterator) { ExpectElements(map1); } -TEST_P(MapImplTest, EraseSingleByKey) { +TEST_F(MapImplTest, EraseSingleByKey) { int32 key = 0; int32 value = 100; @@ -681,7 +687,7 @@ TEST_P(MapImplTest, EraseSingleByKey) { EXPECT_EQ(0, map_.erase(key)); } -TEST_P(MapImplTest, EraseMutipleByKey) { +TEST_F(MapImplTest, EraseMutipleByKey) { // erase in one specific order to trigger corner cases for (int i = 0; i < 5; i++) { map_[i] = i; @@ -708,7 +714,7 @@ TEST_P(MapImplTest, EraseMutipleByKey) { EXPECT_TRUE(map_.end() == map_.find(2)); } -TEST_P(MapImplTest, EraseSingleByIterator) { +TEST_F(MapImplTest, EraseSingleByIterator) { int32 key = 0; int32 value = 100; @@ -723,7 +729,7 @@ TEST_P(MapImplTest, EraseSingleByIterator) { EXPECT_TRUE(map_.begin() == map_.end()); } -TEST_P(MapImplTest, ValidIteratorAfterErase) { +TEST_F(MapImplTest, ValidIteratorAfterErase) { for (int i = 0; i < 10; i++) { map_[i] = i; } @@ -743,7 +749,7 @@ TEST_P(MapImplTest, ValidIteratorAfterErase) { EXPECT_EQ(5, map_.size()); } -TEST_P(MapImplTest, EraseByIterator) { +TEST_F(MapImplTest, EraseByIterator) { int32 key1 = 0; int32 key2 = 1; int32 value1 = 100; @@ -764,7 +770,7 @@ TEST_P(MapImplTest, EraseByIterator) { EXPECT_TRUE(map_.begin() == map_.end()); } -TEST_P(MapImplTest, Clear) { +TEST_F(MapImplTest, Clear) { int32 key = 0; int32 value = 100; @@ -798,16 +804,16 @@ static void CopyConstructorHelper(Arena* arena, Map* m) { EXPECT_EQ(value2, other.at(key2)); } -TEST_P(MapImplTest, CopyConstructorWithArena) { +TEST_F(MapImplTest, CopyConstructorWithArena) { Arena a; CopyConstructorHelper(&a, &map_); } -TEST_P(MapImplTest, CopyConstructorWithoutArena) { +TEST_F(MapImplTest, CopyConstructorWithoutArena) { CopyConstructorHelper(NULL, &map_); } -TEST_P(MapImplTest, IterConstructor) { +TEST_F(MapImplTest, IterConstructor) { int32 key1 = 0; int32 key2 = 1; int32 value1 = 100; @@ -817,15 +823,14 @@ TEST_P(MapImplTest, IterConstructor) { map[key1] = value1; map[key2] = value2; - Map new_map(map.begin(), map.end(), - GetParam()); + Map new_map(map.begin(), map.end()); EXPECT_EQ(2, new_map.size()); EXPECT_EQ(value1, new_map.at(key1)); EXPECT_EQ(value2, new_map.at(key2)); } -TEST_P(MapImplTest, Assigner) { +TEST_F(MapImplTest, Assigner) { int32 key1 = 0; int32 key2 = 1; int32 value1 = 100; @@ -837,7 +842,7 @@ TEST_P(MapImplTest, Assigner) { map_.insert(map.begin(), map.end()); - Map other(GetParam()); + Map other; int32 key_other = 123; int32 value_other = 321; other[key_other] = value_other; @@ -855,16 +860,9 @@ TEST_P(MapImplTest, Assigner) { EXPECT_EQ(2, other.size()); EXPECT_EQ(value1, other.at(key1)); EXPECT_EQ(value2, other.at(key2)); - - // Try assignment to a map with a different choice of "style." - Map m(!GetParam()); - m = other; - EXPECT_EQ(2, m.size()); - EXPECT_EQ(value1, m.at(key1)); - EXPECT_EQ(value2, m.at(key2)); } -TEST_P(MapImplTest, Rehash) { +TEST_F(MapImplTest, Rehash) { const int test_size = 50; std::map reference_map; for (int i = 0; i < test_size; i++) { @@ -881,7 +879,7 @@ TEST_P(MapImplTest, Rehash) { EXPECT_TRUE(map_.empty()); } -TEST_P(MapImplTest, EqualRange) { +TEST_F(MapImplTest, EqualRange) { int key = 100, key_missing = 101; map_[key] = 100; @@ -905,14 +903,14 @@ TEST_P(MapImplTest, EqualRange) { EXPECT_TRUE(const_map_.end() == const_range.second); } -TEST_P(MapImplTest, ConvertToStdMap) { +TEST_F(MapImplTest, ConvertToStdMap) { map_[100] = 101; std::map std_map(map_.begin(), map_.end()); EXPECT_EQ(1, std_map.size()); EXPECT_EQ(101, std_map[100]); } -TEST_P(MapImplTest, ConvertToStdVectorOfPairs) { +TEST_F(MapImplTest, ConvertToStdVectorOfPairs) { map_[100] = 101; std::vector > std_vec(map_.begin(), map_.end()); EXPECT_EQ(1, std_vec.size()); @@ -920,8 +918,8 @@ TEST_P(MapImplTest, ConvertToStdVectorOfPairs) { EXPECT_EQ(101, std_vec[0].second); } -TEST_P(MapImplTest, SwapSameStyle) { - Map another(GetParam()); // same old_style_ value +TEST_F(MapImplTest, SwapBasic) { + Map another; map_[9398] = 41999; another[9398] = 41999; another[8070] = 42056; @@ -933,23 +931,10 @@ TEST_P(MapImplTest, SwapSameStyle) { testing::Pair(9398, 41999))); } -TEST_P(MapImplTest, SwapDifferentStyle) { - Map another(!GetParam()); // different old_style_ value - map_[9398] = 41999; - another[9398] = 41999; - another[8070] = 42056; - another.swap(map_); - EXPECT_THAT(another, testing::UnorderedElementsAre( - testing::Pair(9398, 41999))); - EXPECT_THAT(map_, testing::UnorderedElementsAre( - testing::Pair(8070, 42056), - testing::Pair(9398, 41999))); -} - -TEST_P(MapImplTest, SwapArena) { +TEST_F(MapImplTest, SwapArena) { Arena arena1, arena2; - Map m1(&arena1, false); - Map m2(&arena2, false); + Map m1(&arena1); + Map m2(&arena2); map_[9398] = 41999; m1[9398] = 41999; m1[8070] = 42056; @@ -969,8 +954,6 @@ TEST_P(MapImplTest, SwapArena) { testing::Pair(9398, 41999))); } -INSTANTIATE_TEST_CASE_P(BoolSequence, MapImplTest, testing::Bool()); - // Map Field Reflection Test ======================================== static int Func(int i, int j) { @@ -2980,6 +2963,27 @@ TEST(MapSerializationTest, Deterministic) { TestDeterministicSerialization(t, "golden_message_maps"); } +TEST(MapSerializationTest, DeterministicSubmessage) { + protobuf_unittest::TestSubmessageMaps p; + protobuf_unittest::TestMaps t; + const string filename = "golden_message_maps"; + string golden; + GOOGLE_CHECK_OK(File::GetContents( + TestSourceDir() + "/google/protobuf/testdata/" + filename, + &golden, true)); + t.ParseFromString(golden); + *(p.mutable_m()) = t; + std::vector v; + // Use multiple attempts to increase the chance of a failure if something is + // buggy. For example, each separate copy of a map might use a different + // randomly-chosen hash function. + const int kAttempts = 10; + for (int i = 0; i < kAttempts; i++) { + protobuf_unittest::TestSubmessageMaps q(p); + ASSERT_EQ(DeterministicSerialization(q), DeterministicSerialization(p)); + } +} + // Text Format Test ================================================= TEST(TextFormatMapTest, SerializeAndParse) { -- cgit v1.2.3