Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1332)

Side by Side Diff: components/sync/base/unique_position_unittest.cc

Issue 2130453004: [Sync] Move //sync to //components/sync. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sync/internal_api/public/base/unique_position.h" 5 #include "components/sync/base/unique_position.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <functional> 11 #include <functional>
12 #include <memory> 12 #include <memory>
13 #include <string> 13 #include <string>
14 #include <vector> 14 #include <vector>
15 15
16 #include "base/base64.h" 16 #include "base/base64.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/macros.h" 18 #include "base/macros.h"
19 #include "base/sha1.h" 19 #include "base/sha1.h"
20 #include "base/strings/string_number_conversions.h" 20 #include "base/strings/string_number_conversions.h"
21 #include "sync/protocol/unique_position.pb.h" 21 #include "components/sync/protocol/unique_position.pb.h"
22 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
23 23
24 namespace syncer { 24 namespace syncer {
25 25
26 namespace { 26 namespace {
27 27
28 class UniquePositionTest : public ::testing::Test { 28 class UniquePositionTest : public ::testing::Test {
29 protected: 29 protected:
30 // Accessor to fetch the length of the position's internal representation 30 // Accessor to fetch the length of the position's internal representation
31 // We try to avoid having any test expectations on it because this is an 31 // We try to avoid having any test expectations on it because this is an
(...skipping 18 matching lines...) Expand all
50 } 50 }
51 51
52 const size_t kMinLength = UniquePosition::kSuffixLength; 52 const size_t kMinLength = UniquePosition::kSuffixLength;
53 const size_t kGenericPredecessorLength = kMinLength + 2; 53 const size_t kGenericPredecessorLength = kMinLength + 2;
54 const size_t kGenericSuccessorLength = kMinLength + 1; 54 const size_t kGenericSuccessorLength = kMinLength + 1;
55 const size_t kBigPositionLength = kMinLength; 55 const size_t kBigPositionLength = kMinLength;
56 const size_t kSmallPositionLength = kMinLength; 56 const size_t kSmallPositionLength = kMinLength;
57 57
58 // Be careful when adding more prefixes to this list. 58 // Be careful when adding more prefixes to this list.
59 // We have to manually ensure each has a unique suffix. 59 // We have to manually ensure each has a unique suffix.
60 const UniquePosition kGenericPredecessor = FromBytes( 60 const UniquePosition kGenericPredecessor =
61 (std::string(kGenericPredecessorLength, '\x23') + '\xFF')); 61 FromBytes((std::string(kGenericPredecessorLength, '\x23') + '\xFF'));
62 const UniquePosition kGenericSuccessor = FromBytes( 62 const UniquePosition kGenericSuccessor =
63 std::string(kGenericSuccessorLength, '\xAB') + '\xFF'); 63 FromBytes(std::string(kGenericSuccessorLength, '\xAB') + '\xFF');
64 const UniquePosition kBigPosition = FromBytes( 64 const UniquePosition kBigPosition =
65 std::string(kBigPositionLength - 1, '\xFF') + '\xFE' + '\xFF'); 65 FromBytes(std::string(kBigPositionLength - 1, '\xFF') + '\xFE' + '\xFF');
66 const UniquePosition kBigPositionLessTwo = FromBytes( 66 const UniquePosition kBigPositionLessTwo =
67 std::string(kBigPositionLength - 1, '\xFF') + '\xFC' + '\xFF'); 67 FromBytes(std::string(kBigPositionLength - 1, '\xFF') + '\xFC' + '\xFF');
68 const UniquePosition kBiggerPosition = FromBytes( 68 const UniquePosition kBiggerPosition =
69 std::string(kBigPositionLength, '\xFF') + '\xFF'); 69 FromBytes(std::string(kBigPositionLength, '\xFF') + '\xFF');
70 const UniquePosition kSmallPosition = FromBytes( 70 const UniquePosition kSmallPosition =
71 std::string(kSmallPositionLength - 1, '\x00') + '\x01' + '\xFF'); 71 FromBytes(std::string(kSmallPositionLength - 1, '\x00') + '\x01' + '\xFF');
72 const UniquePosition kSmallPositionPlusOne = FromBytes( 72 const UniquePosition kSmallPositionPlusOne =
73 std::string(kSmallPositionLength - 1, '\x00') + '\x02' + '\xFF'); 73 FromBytes(std::string(kSmallPositionLength - 1, '\x00') + '\x02' + '\xFF');
74 const UniquePosition kHugePosition = FromBytes( 74 const UniquePosition kHugePosition = FromBytes(
75 std::string(UniquePosition::kCompressBytesThreshold, '\xFF') + '\xAB'); 75 std::string(UniquePosition::kCompressBytesThreshold, '\xFF') + '\xAB');
76 76
77 const std::string kMinSuffix = 77 const std::string kMinSuffix =
78 std::string(UniquePosition::kSuffixLength - 1, '\x00') + '\x01'; 78 std::string(UniquePosition::kSuffixLength - 1, '\x00') + '\x01';
79 const std::string kMaxSuffix(UniquePosition::kSuffixLength, '\xFF'); 79 const std::string kMaxSuffix(UniquePosition::kSuffixLength, '\xFF');
80 const std::string kNormalSuffix( 80 const std::string kNormalSuffix(
81 "\x68\x44\x6C\x6B\x32\x58\x78\x34\x69\x70\x46\x34\x79\x49" 81 "\x68\x44\x6C\x6B\x32\x58\x78\x34\x69\x70\x46\x34\x79\x49"
82 "\x44\x4F\x66\x4C\x58\x41\x31\x34\x68\x59\x56\x43\x6F\x3D"); 82 "\x44\x4F\x66\x4C\x58\x41\x31\x34\x68\x59\x56\x43\x6F\x3D");
83 83
84 ::testing::AssertionResult LessThan(const char* m_expr, 84 ::testing::AssertionResult LessThan(const char* m_expr,
85 const char* n_expr, 85 const char* n_expr,
86 const UniquePosition &m, 86 const UniquePosition& m,
87 const UniquePosition &n) { 87 const UniquePosition& n) {
88 if (m.LessThan(n)) 88 if (m.LessThan(n))
89 return ::testing::AssertionSuccess(); 89 return ::testing::AssertionSuccess();
90 90
91 return ::testing::AssertionFailure() 91 return ::testing::AssertionFailure() << m_expr << " is not less than "
92 << m_expr << " is not less than " << n_expr 92 << n_expr << " (" << m.ToDebugString()
93 << " (" << m.ToDebugString() << " and " << n.ToDebugString() << ")"; 93 << " and " << n.ToDebugString() << ")";
94 } 94 }
95 95
96 ::testing::AssertionResult Equals(const char* m_expr, 96 ::testing::AssertionResult Equals(const char* m_expr,
97 const char* n_expr, 97 const char* n_expr,
98 const UniquePosition &m, 98 const UniquePosition& m,
99 const UniquePosition &n) { 99 const UniquePosition& n) {
100 if (m.Equals(n)) 100 if (m.Equals(n))
101 return ::testing::AssertionSuccess(); 101 return ::testing::AssertionSuccess();
102 102
103 return ::testing::AssertionFailure() 103 return ::testing::AssertionFailure() << m_expr << " is not equal to "
104 << m_expr << " is not equal to " << n_expr 104 << n_expr << " (" << m.ToDebugString()
105 << " (" << m.ToDebugString() << " != " << n.ToDebugString() << ")"; 105 << " != " << n.ToDebugString() << ")";
106 } 106 }
107 107
108 // Test that the code can read the uncompressed serialization format. 108 // Test that the code can read the uncompressed serialization format.
109 TEST_F(UniquePositionTest, DeserializeObsoleteUncompressedPosition) { 109 TEST_F(UniquePositionTest, DeserializeObsoleteUncompressedPosition) {
110 // We no longer support the encoding data in this format. This hard-coded 110 // We no longer support the encoding data in this format. This hard-coded
111 // input is a serialization of kGenericPredecessor created by an older version 111 // input is a serialization of kGenericPredecessor created by an older version
112 // of this code. 112 // of this code.
113 const char kSerializedCstr[] = { 113 const char kSerializedCstr[] = {
114 '\x0a', '\x1f', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', 114 '\x0a', '\x1f', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23',
115 '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', 115 '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23',
116 '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', 116 '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23', '\x23',
117 '\x23', '\x23', '\x23', '\x23', '\x23', '\xff' }; 117 '\x23', '\x23', '\x23', '\x23', '\x23', '\xff'};
118 const std::string serialized(kSerializedCstr, sizeof(kSerializedCstr)); 118 const std::string serialized(kSerializedCstr, sizeof(kSerializedCstr));
119 119
120 sync_pb::UniquePosition proto; 120 sync_pb::UniquePosition proto;
121 proto.ParseFromString(serialized); 121 proto.ParseFromString(serialized);
122 122
123 // Double-check that this test is testing what we think it tests. 123 // Double-check that this test is testing what we think it tests.
124 EXPECT_TRUE(proto.has_value()); 124 EXPECT_TRUE(proto.has_value());
125 EXPECT_FALSE(proto.has_compressed_value()); 125 EXPECT_FALSE(proto.has_compressed_value());
126 EXPECT_FALSE(proto.has_uncompressed_length()); 126 EXPECT_FALSE(proto.has_uncompressed_length());
127 127
128 UniquePosition pos = UniquePosition::FromProto(proto); 128 UniquePosition pos = UniquePosition::FromProto(proto);
129 EXPECT_PRED_FORMAT2(Equals, kGenericPredecessor, pos); 129 EXPECT_PRED_FORMAT2(Equals, kGenericPredecessor, pos);
130 } 130 }
131 131
132 // Test that the code can read the gzip serialization format. 132 // Test that the code can read the gzip serialization format.
133 TEST_F(UniquePositionTest, DeserializeObsoleteGzippedPosition) { 133 TEST_F(UniquePositionTest, DeserializeObsoleteGzippedPosition) {
134 // We no longer support the encoding data in this format. This hard-coded 134 // We no longer support the encoding data in this format. This hard-coded
135 // input is a serialization of kHugePosition created by an older version of 135 // input is a serialization of kHugePosition created by an older version of
136 // this code. 136 // this code.
137 const char kSerializedCstr[] = { 137 const char kSerializedCstr[] = {
138 '\x12', '\x0d', '\x78', '\x9c', '\xfb', '\xff', '\x7f', '\x60', '\xc1', 138 '\x12', '\x0d', '\x78', '\x9c', '\xfb', '\xff', '\x7f', '\x60', '\xc1',
139 '\x6a', '\x00', '\xa2', '\x4c', '\x80', '\x2c', '\x18', '\x81', '\x01' }; 139 '\x6a', '\x00', '\xa2', '\x4c', '\x80', '\x2c', '\x18', '\x81', '\x01'};
140 const std::string serialized(kSerializedCstr, sizeof(kSerializedCstr)); 140 const std::string serialized(kSerializedCstr, sizeof(kSerializedCstr));
141 141
142 sync_pb::UniquePosition proto; 142 sync_pb::UniquePosition proto;
143 proto.ParseFromString(serialized); 143 proto.ParseFromString(serialized);
144 144
145 // Double-check that this test is testing what we think it tests. 145 // Double-check that this test is testing what we think it tests.
146 EXPECT_FALSE(proto.has_value()); 146 EXPECT_FALSE(proto.has_value());
147 EXPECT_TRUE(proto.has_compressed_value()); 147 EXPECT_TRUE(proto.has_compressed_value());
148 EXPECT_TRUE(proto.has_uncompressed_length()); 148 EXPECT_TRUE(proto.has_uncompressed_length());
149 149
150 UniquePosition pos = UniquePosition::FromProto(proto); 150 UniquePosition pos = UniquePosition::FromProto(proto);
151 EXPECT_PRED_FORMAT2(Equals, kHugePosition, pos); 151 EXPECT_PRED_FORMAT2(Equals, kHugePosition, pos);
152 } 152 }
153 153
154 class RelativePositioningTest : public UniquePositionTest { }; 154 class RelativePositioningTest : public UniquePositionTest {};
155 155
156 const UniquePosition kPositionArray[] = { 156 const UniquePosition kPositionArray[] = {
157 kGenericPredecessor, 157 kGenericPredecessor, kGenericSuccessor, kBigPosition,
158 kGenericSuccessor, 158 kBigPositionLessTwo, kBiggerPosition, kSmallPosition,
159 kBigPosition, 159 kSmallPositionPlusOne,
160 kBigPositionLessTwo,
161 kBiggerPosition,
162 kSmallPosition,
163 kSmallPositionPlusOne,
164 }; 160 };
165 161
166 const UniquePosition kSortedPositionArray[] = { 162 const UniquePosition kSortedPositionArray[] = {
167 kSmallPosition, 163 kSmallPosition, kSmallPositionPlusOne, kGenericPredecessor,
168 kSmallPositionPlusOne, 164 kGenericSuccessor, kBigPositionLessTwo, kBigPosition,
169 kGenericPredecessor, 165 kBiggerPosition,
170 kGenericSuccessor,
171 kBigPositionLessTwo,
172 kBigPosition,
173 kBiggerPosition,
174 }; 166 };
175 167
176 static const size_t kNumPositions = arraysize(kPositionArray); 168 static const size_t kNumPositions = arraysize(kPositionArray);
177 static const size_t kNumSortedPositions = arraysize(kSortedPositionArray); 169 static const size_t kNumSortedPositions = arraysize(kSortedPositionArray);
178 170
179 struct PositionLessThan { 171 struct PositionLessThan {
180 bool operator()(const UniquePosition& a, const UniquePosition& b) { 172 bool operator()(const UniquePosition& a, const UniquePosition& b) {
181 return a.LessThan(b); 173 return a.LessThan(b);
182 } 174 }
183 }; 175 };
184 176
185 // Returns true iff the given position's suffix matches the input parameter. 177 // Returns true iff the given position's suffix matches the input parameter.
186 static bool IsSuffixInUse( 178 static bool IsSuffixInUse(const UniquePosition& pos,
187 const UniquePosition& pos, const std::string& suffix) { 179 const std::string& suffix) {
188 return pos.GetSuffixForTest() == suffix; 180 return pos.GetSuffixForTest() == suffix;
189 } 181 }
190 182
191 // Test some basic properties of comparison and equality. 183 // Test some basic properties of comparison and equality.
192 TEST_F(RelativePositioningTest, ComparisonSanityTest1) { 184 TEST_F(RelativePositioningTest, ComparisonSanityTest1) {
193 const UniquePosition& a = kPositionArray[0]; 185 const UniquePosition& a = kPositionArray[0];
194 ASSERT_TRUE(a.IsValid()); 186 ASSERT_TRUE(a.IsValid());
195 187
196 // Necessarily true for any non-invalid positions. 188 // Necessarily true for any non-invalid positions.
197 EXPECT_TRUE(a.Equals(a)); 189 EXPECT_TRUE(a.Equals(a));
(...skipping 15 matching lines...) Expand all
213 TEST_F(RelativePositioningTest, SortPositions) { 205 TEST_F(RelativePositioningTest, SortPositions) {
214 ASSERT_EQ(kNumPositions, kNumSortedPositions); 206 ASSERT_EQ(kNumPositions, kNumSortedPositions);
215 UniquePosition positions[arraysize(kPositionArray)]; 207 UniquePosition positions[arraysize(kPositionArray)];
216 for (size_t i = 0; i < kNumPositions; ++i) { 208 for (size_t i = 0; i < kNumPositions; ++i) {
217 positions[i] = kPositionArray[i]; 209 positions[i] = kPositionArray[i];
218 } 210 }
219 211
220 std::sort(&positions[0], &positions[kNumPositions], PositionLessThan()); 212 std::sort(&positions[0], &positions[kNumPositions], PositionLessThan());
221 for (size_t i = 0; i < kNumPositions; ++i) { 213 for (size_t i = 0; i < kNumPositions; ++i) {
222 EXPECT_TRUE(positions[i].Equals(kSortedPositionArray[i])) 214 EXPECT_TRUE(positions[i].Equals(kSortedPositionArray[i]))
223 << "i: " << i << ", " 215 << "i: " << i << ", " << positions[i].ToDebugString()
224 << positions[i].ToDebugString() << " != " 216 << " != " << kSortedPositionArray[i].ToDebugString();
225 << kSortedPositionArray[i].ToDebugString();
226 } 217 }
227 } 218 }
228 219
229 // Some more exercise for the comparison function. 220 // Some more exercise for the comparison function.
230 TEST_F(RelativePositioningTest, ReverseSortPositions) { 221 TEST_F(RelativePositioningTest, ReverseSortPositions) {
231 ASSERT_EQ(kNumPositions, kNumSortedPositions); 222 ASSERT_EQ(kNumPositions, kNumSortedPositions);
232 UniquePosition positions[arraysize(kPositionArray)]; 223 UniquePosition positions[arraysize(kPositionArray)];
233 for (size_t i = 0; i < kNumPositions; ++i) { 224 for (size_t i = 0; i < kNumPositions; ++i) {
234 positions[i] = kPositionArray[i]; 225 positions[i] = kPositionArray[i];
235 } 226 }
236 227
237 std::reverse(&positions[0], &positions[kNumPositions]); 228 std::reverse(&positions[0], &positions[kNumPositions]);
238 std::sort(&positions[0], &positions[kNumPositions], PositionLessThan()); 229 std::sort(&positions[0], &positions[kNumPositions], PositionLessThan());
239 for (size_t i = 0; i < kNumPositions; ++i) { 230 for (size_t i = 0; i < kNumPositions; ++i) {
240 EXPECT_TRUE(positions[i].Equals(kSortedPositionArray[i])) 231 EXPECT_TRUE(positions[i].Equals(kSortedPositionArray[i]))
241 << "i: " << i << ", " 232 << "i: " << i << ", " << positions[i].ToDebugString()
242 << positions[i].ToDebugString() << " != " 233 << " != " << kSortedPositionArray[i].ToDebugString();
243 << kSortedPositionArray[i].ToDebugString();
244 } 234 }
245 } 235 }
246 236
247 class PositionInsertTest : 237 class PositionInsertTest : public RelativePositioningTest,
248 public RelativePositioningTest, 238 public ::testing::WithParamInterface<std::string> {};
249 public ::testing::WithParamInterface<std::string> { };
250 239
251 // Exercise InsertBetween with various insertion operations. 240 // Exercise InsertBetween with various insertion operations.
252 TEST_P(PositionInsertTest, InsertBetween) { 241 TEST_P(PositionInsertTest, InsertBetween) {
253 const std::string suffix = GetParam(); 242 const std::string suffix = GetParam();
254 ASSERT_TRUE(UniquePosition::IsValidSuffix(suffix)); 243 ASSERT_TRUE(UniquePosition::IsValidSuffix(suffix));
255 244
256 for (size_t i = 0; i < kNumSortedPositions; ++i) { 245 for (size_t i = 0; i < kNumSortedPositions; ++i) {
257 const UniquePosition& predecessor = kSortedPositionArray[i]; 246 const UniquePosition& predecessor = kSortedPositionArray[i];
258 // Verify our suffixes are unique before we continue. 247 // Verify our suffixes are unique before we continue.
259 if (IsSuffixInUse(predecessor, suffix)) 248 if (IsSuffixInUse(predecessor, suffix))
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 } 368 }
380 369
381 VLOG(1) << "Lengths: " << GetLength(left_pos) << ", " << GetLength(right_pos); 370 VLOG(1) << "Lengths: " << GetLength(left_pos) << ", " << GetLength(right_pos);
382 } 371 }
383 372
384 // Generates suffixes similar to those generated by the directory. 373 // Generates suffixes similar to those generated by the directory.
385 // This may become obsolete if the suffix generation code is modified. 374 // This may become obsolete if the suffix generation code is modified.
386 class SuffixGenerator { 375 class SuffixGenerator {
387 public: 376 public:
388 explicit SuffixGenerator(const std::string& cache_guid) 377 explicit SuffixGenerator(const std::string& cache_guid)
389 : cache_guid_(cache_guid), 378 : cache_guid_(cache_guid), next_id_(-65535) {}
390 next_id_(-65535) {
391 }
392 379
393 std::string NextSuffix() { 380 std::string NextSuffix() {
394 // This is not entirely realistic, but that should be OK. The current 381 // This is not entirely realistic, but that should be OK. The current
395 // suffix format is a base64'ed SHA1 hash, which should be fairly close to 382 // suffix format is a base64'ed SHA1 hash, which should be fairly close to
396 // random anyway. 383 // random anyway.
397 std::string input = cache_guid_ + base::Int64ToString(next_id_--); 384 std::string input = cache_guid_ + base::Int64ToString(next_id_--);
398 std::string output; 385 std::string output;
399 base::Base64Encode(base::SHA1HashString(input), &output); 386 base::Base64Encode(base::SHA1HashString(input), &output);
400 return output; 387 return output;
401 } 388 }
402 389
403 private: 390 private:
404 const std::string cache_guid_; 391 const std::string cache_guid_;
405 int64_t next_id_; 392 int64_t next_id_;
406 }; 393 };
407 394
408 // Cache guids generated in the same style as real clients. 395 // Cache guids generated in the same style as real clients.
409 static const char kCacheGuidStr1[] = "tuiWdG8hV+8y4RT9N5Aikg=="; 396 static const char kCacheGuidStr1[] = "tuiWdG8hV+8y4RT9N5Aikg==";
410 static const char kCacheGuidStr2[] = "yaKb7zHtY06aue9a0vlZgw=="; 397 static const char kCacheGuidStr2[] = "yaKb7zHtY06aue9a0vlZgw==";
411 398
412 class PositionScenariosTest : public UniquePositionTest { 399 class PositionScenariosTest : public UniquePositionTest {
413 public: 400 public:
414 PositionScenariosTest() 401 PositionScenariosTest()
415 : generator1_(std::string(kCacheGuidStr1, arraysize(kCacheGuidStr1)-1)), 402 : generator1_(std::string(kCacheGuidStr1, arraysize(kCacheGuidStr1) - 1)),
416 generator2_(std::string(kCacheGuidStr2, arraysize(kCacheGuidStr2)-1)) { 403 generator2_(
417 } 404 std::string(kCacheGuidStr2, arraysize(kCacheGuidStr2) - 1)) {}
418 405
419 std::string NextClient1Suffix() { 406 std::string NextClient1Suffix() { return generator1_.NextSuffix(); }
420 return generator1_.NextSuffix();
421 }
422 407
423 std::string NextClient2Suffix() { 408 std::string NextClient2Suffix() { return generator2_.NextSuffix(); }
424 return generator2_.NextSuffix();
425 }
426 409
427 private: 410 private:
428 SuffixGenerator generator1_; 411 SuffixGenerator generator1_;
429 SuffixGenerator generator2_; 412 SuffixGenerator generator2_;
430 }; 413 };
431 414
432 // One client creating new bookmarks, always inserting at the end. 415 // One client creating new bookmarks, always inserting at the end.
433 TEST_F(PositionScenariosTest, OneClientInsertAtEnd) { 416 TEST_F(PositionScenariosTest, OneClientInsertAtEnd) {
434 UniquePosition pos = 417 UniquePosition pos = UniquePosition::InitialPosition(NextClient1Suffix());
435 UniquePosition::InitialPosition(NextClient1Suffix());
436 for (int i = 0; i < 1024; i++) { 418 for (int i = 0; i < 1024; i++) {
437 const std::string suffix = NextClient1Suffix(); 419 const std::string suffix = NextClient1Suffix();
438 UniquePosition new_pos = UniquePosition::After(pos, suffix); 420 UniquePosition new_pos = UniquePosition::After(pos, suffix);
439 ASSERT_PRED_FORMAT2(LessThan, pos, new_pos); 421 ASSERT_PRED_FORMAT2(LessThan, pos, new_pos);
440 pos = new_pos; 422 pos = new_pos;
441 } 423 }
442 424
443 VLOG(1) << "Length: " << GetLength(pos); 425 VLOG(1) << "Length: " << GetLength(pos);
444 426
445 // Normally we wouldn't want to make an assertion about the internal 427 // Normally we wouldn't want to make an assertion about the internal
446 // representation of our data, but we make an exception for this case. 428 // representation of our data, but we make an exception for this case.
447 // If this scenario causes lengths to explode, we have a big problem. 429 // If this scenario causes lengths to explode, we have a big problem.
448 EXPECT_LT(GetLength(pos), 500U); 430 EXPECT_LT(GetLength(pos), 500U);
449 } 431 }
450 432
451 // Two clients alternately inserting entries at the end, with a strong 433 // Two clients alternately inserting entries at the end, with a strong
452 // bias towards insertions by the first client. 434 // bias towards insertions by the first client.
453 TEST_F(PositionScenariosTest, TwoClientsInsertAtEnd_A) { 435 TEST_F(PositionScenariosTest, TwoClientsInsertAtEnd_A) {
454 UniquePosition pos = 436 UniquePosition pos = UniquePosition::InitialPosition(NextClient1Suffix());
455 UniquePosition::InitialPosition(NextClient1Suffix());
456 for (int i = 0; i < 1024; i++) { 437 for (int i = 0; i < 1024; i++) {
457 std::string suffix; 438 std::string suffix;
458 if (i % 5 == 0) { 439 if (i % 5 == 0) {
459 suffix = NextClient2Suffix(); 440 suffix = NextClient2Suffix();
460 } else { 441 } else {
461 suffix = NextClient1Suffix(); 442 suffix = NextClient1Suffix();
462 } 443 }
463 444
464 UniquePosition new_pos = UniquePosition::After(pos, suffix); 445 UniquePosition new_pos = UniquePosition::After(pos, suffix);
465 ASSERT_PRED_FORMAT2(LessThan, pos, new_pos); 446 ASSERT_PRED_FORMAT2(LessThan, pos, new_pos);
466 pos = new_pos; 447 pos = new_pos;
467 } 448 }
468 449
469 VLOG(1) << "Length: " << GetLength(pos); 450 VLOG(1) << "Length: " << GetLength(pos);
470 EXPECT_LT(GetLength(pos), 500U); 451 EXPECT_LT(GetLength(pos), 500U);
471 } 452 }
472 453
473 // Two clients alternately inserting entries at the end. 454 // Two clients alternately inserting entries at the end.
474 TEST_F(PositionScenariosTest, TwoClientsInsertAtEnd_B) { 455 TEST_F(PositionScenariosTest, TwoClientsInsertAtEnd_B) {
475 UniquePosition pos = 456 UniquePosition pos = UniquePosition::InitialPosition(NextClient1Suffix());
476 UniquePosition::InitialPosition(NextClient1Suffix());
477 for (int i = 0; i < 1024; i++) { 457 for (int i = 0; i < 1024; i++) {
478 std::string suffix; 458 std::string suffix;
479 if (i % 2 == 0) { 459 if (i % 2 == 0) {
480 suffix = NextClient1Suffix(); 460 suffix = NextClient1Suffix();
481 } else { 461 } else {
482 suffix = NextClient2Suffix(); 462 suffix = NextClient2Suffix();
483 } 463 }
484 464
485 UniquePosition new_pos = UniquePosition::After(pos, suffix); 465 UniquePosition new_pos = UniquePosition::After(pos, suffix);
486 ASSERT_PRED_FORMAT2(LessThan, pos, new_pos); 466 ASSERT_PRED_FORMAT2(LessThan, pos, new_pos);
487 pos = new_pos; 467 pos = new_pos;
488 } 468 }
489 469
490 VLOG(1) << "Length: " << GetLength(pos); 470 VLOG(1) << "Length: " << GetLength(pos);
491 EXPECT_LT(GetLength(pos), 500U); 471 EXPECT_LT(GetLength(pos), 500U);
492 } 472 }
493 473
494 INSTANTIATE_TEST_CASE_P(MinSuffix, PositionInsertTest, 474 INSTANTIATE_TEST_CASE_P(MinSuffix,
475 PositionInsertTest,
495 ::testing::Values(kMinSuffix)); 476 ::testing::Values(kMinSuffix));
496 INSTANTIATE_TEST_CASE_P(MaxSuffix, PositionInsertTest, 477 INSTANTIATE_TEST_CASE_P(MaxSuffix,
478 PositionInsertTest,
497 ::testing::Values(kMaxSuffix)); 479 ::testing::Values(kMaxSuffix));
498 INSTANTIATE_TEST_CASE_P(NormalSuffix, PositionInsertTest, 480 INSTANTIATE_TEST_CASE_P(NormalSuffix,
481 PositionInsertTest,
499 ::testing::Values(kNormalSuffix)); 482 ::testing::Values(kNormalSuffix));
500 483
501 class PositionFromIntTest : public UniquePositionTest { 484 class PositionFromIntTest : public UniquePositionTest {
502 public: 485 public:
503 PositionFromIntTest() 486 PositionFromIntTest()
504 : generator_(std::string(kCacheGuidStr1, arraysize(kCacheGuidStr1)-1)) { 487 : generator_(std::string(kCacheGuidStr1, arraysize(kCacheGuidStr1) - 1)) {
505 } 488 }
506 489
507 protected: 490 protected:
508 static const int64_t kTestValues[]; 491 static const int64_t kTestValues[];
509 static const size_t kNumTestValues; 492 static const size_t kNumTestValues;
510 493
511 std::string NextSuffix() { 494 std::string NextSuffix() { return generator_.NextSuffix(); }
512 return generator_.NextSuffix();
513 }
514 495
515 private: 496 private:
516 SuffixGenerator generator_; 497 SuffixGenerator generator_;
517 }; 498 };
518 499
519 const int64_t PositionFromIntTest::kTestValues[] = {0LL, 500 const int64_t PositionFromIntTest::kTestValues[] = {0LL,
520 1LL, 501 1LL,
521 -1LL, 502 -1LL,
522 2LL, 503 2LL,
523 -2LL, 504 -2LL,
(...skipping 28 matching lines...) Expand all
552 0x112358132134LL, 533 0x112358132134LL,
553 -0x112358132134LL, 534 -0x112358132134LL,
554 0xFEFFBEEFABC1234LL, 535 0xFEFFBEEFABC1234LL,
555 -0xFEFFBEEFABC1234LL, 536 -0xFEFFBEEFABC1234LL,
556 INT64_MAX, 537 INT64_MAX,
557 INT64_MIN, 538 INT64_MIN,
558 INT64_MIN + 1, 539 INT64_MIN + 1,
559 INT64_MAX - 1}; 540 INT64_MAX - 1};
560 541
561 const size_t PositionFromIntTest::kNumTestValues = 542 const size_t PositionFromIntTest::kNumTestValues =
562 arraysize(PositionFromIntTest::kTestValues); 543 arraysize(PositionFromIntTest::kTestValues);
563 544
564 TEST_F(PositionFromIntTest, IsValid) { 545 TEST_F(PositionFromIntTest, IsValid) {
565 for (size_t i = 0; i < kNumTestValues; ++i) { 546 for (size_t i = 0; i < kNumTestValues; ++i) {
566 const UniquePosition pos = 547 const UniquePosition pos =
567 UniquePosition::FromInt64(kTestValues[i], NextSuffix()); 548 UniquePosition::FromInt64(kTestValues[i], NextSuffix());
568 EXPECT_TRUE(pos.IsValid()) << "i = " << i << "; " << pos.ToDebugString(); 549 EXPECT_TRUE(pos.IsValid()) << "i = " << i << "; " << pos.ToDebugString();
569 } 550 }
570 } 551 }
571 552
572 TEST_F(PositionFromIntTest, RoundTripConversion) { 553 TEST_F(PositionFromIntTest, RoundTripConversion) {
573 for (size_t i = 0; i < kNumTestValues; ++i) { 554 for (size_t i = 0; i < kNumTestValues; ++i) {
574 const int64_t expected_value = kTestValues[i]; 555 const int64_t expected_value = kTestValues[i];
575 const UniquePosition pos = 556 const UniquePosition pos =
576 UniquePosition::FromInt64(kTestValues[i], NextSuffix()); 557 UniquePosition::FromInt64(kTestValues[i], NextSuffix());
577 const int64_t value = pos.ToInt64(); 558 const int64_t value = pos.ToInt64();
578 EXPECT_EQ(expected_value, value) << "i = " << i; 559 EXPECT_EQ(expected_value, value) << "i = " << i;
579 } 560 }
580 } 561 }
581 562
582 template <typename T, typename LessThan = std::less<T> > 563 template <typename T, typename LessThan = std::less<T>>
583 class IndexedLessThan { 564 class IndexedLessThan {
584 public: 565 public:
585 explicit IndexedLessThan(const T* values) : values_(values) {} 566 explicit IndexedLessThan(const T* values) : values_(values) {}
586 567
587 bool operator()(int i1, int i2) { 568 bool operator()(int i1, int i2) {
588 return less_than_(values_[i1], values_[i2]); 569 return less_than_(values_[i1], values_[i2]);
589 } 570 }
590 571
591 private: 572 private:
592 const T* values_; 573 const T* values_;
593 LessThan less_than_; 574 LessThan less_than_;
594 }; 575 };
595 576
596 TEST_F(PositionFromIntTest, ConsistentOrdering) { 577 TEST_F(PositionFromIntTest, ConsistentOrdering) {
597 UniquePosition positions[kNumTestValues]; 578 UniquePosition positions[kNumTestValues];
598 std::vector<int> original_ordering(kNumTestValues); 579 std::vector<int> original_ordering(kNumTestValues);
599 std::vector<int> int64_ordering(kNumTestValues); 580 std::vector<int> int64_ordering(kNumTestValues);
600 std::vector<int> position_ordering(kNumTestValues); 581 std::vector<int> position_ordering(kNumTestValues);
601 for (size_t i = 0; i < kNumTestValues; ++i) { 582 for (size_t i = 0; i < kNumTestValues; ++i) {
602 positions[i] = UniquePosition::FromInt64( 583 positions[i] = UniquePosition::FromInt64(kTestValues[i], NextSuffix());
603 kTestValues[i], NextSuffix());
604 original_ordering[i] = int64_ordering[i] = position_ordering[i] = i; 584 original_ordering[i] = int64_ordering[i] = position_ordering[i] = i;
605 } 585 }
606 586
607 std::sort(int64_ordering.begin(), int64_ordering.end(), 587 std::sort(int64_ordering.begin(), int64_ordering.end(),
608 IndexedLessThan<int64_t>(kTestValues)); 588 IndexedLessThan<int64_t>(kTestValues));
609 std::sort(position_ordering.begin(), position_ordering.end(), 589 std::sort(position_ordering.begin(), position_ordering.end(),
610 IndexedLessThan<UniquePosition, PositionLessThan>(positions)); 590 IndexedLessThan<UniquePosition, PositionLessThan>(positions));
611 EXPECT_NE(original_ordering, int64_ordering); 591 EXPECT_NE(original_ordering, int64_ordering);
612 EXPECT_EQ(int64_ordering, position_ordering); 592 EXPECT_EQ(int64_ordering, position_ordering);
613 } 593 }
(...skipping 26 matching lines...) Expand all
640 private: 620 private:
641 UniquePosition MakePosition(const std::string& compressed_prefix, 621 UniquePosition MakePosition(const std::string& compressed_prefix,
642 const std::string& compressed_suffix); 622 const std::string& compressed_suffix);
643 std::string MakeSuffix(char unique_value); 623 std::string MakeSuffix(char unique_value);
644 624
645 protected: 625 protected:
646 std::vector<UniquePosition> positions_; 626 std::vector<UniquePosition> positions_;
647 }; 627 };
648 628
649 UniquePosition CompressedPositionTest::MakePosition( 629 UniquePosition CompressedPositionTest::MakePosition(
650 const std::string& compressed_prefix, 630 const std::string& compressed_prefix,
651 const std::string& compressed_suffix) { 631 const std::string& compressed_suffix) {
652 sync_pb::UniquePosition proto; 632 sync_pb::UniquePosition proto;
653 proto.set_custom_compressed_v1( 633 proto.set_custom_compressed_v1(
654 std::string(compressed_prefix + compressed_suffix)); 634 std::string(compressed_prefix + compressed_suffix));
655 return UniquePosition::FromProto(proto); 635 return UniquePosition::FromProto(proto);
656 } 636 }
657 637
658 std::string CompressedPositionTest::MakeSuffix(char unique_value) { 638 std::string CompressedPositionTest::MakeSuffix(char unique_value) {
659 // We're dealing in compressed positions in this test. That means the 639 // We're dealing in compressed positions in this test. That means the
660 // suffix should be compressed, too. To avoid complication, we use suffixes 640 // suffix should be compressed, too. To avoid complication, we use suffixes
661 // that don't have any repeating digits, and therefore are identical in 641 // that don't have any repeating digits, and therefore are identical in
662 // compressed and uncompressed form. 642 // compressed and uncompressed form.
663 std::string suffix; 643 std::string suffix;
664 for (size_t i = 0; i < UniquePosition::kSuffixLength; ++i) { 644 for (size_t i = 0; i < UniquePosition::kSuffixLength; ++i) {
665 suffix.push_back(static_cast<char>(i)); 645 suffix.push_back(static_cast<char>(i));
666 } 646 }
667 suffix[UniquePosition::kSuffixLength-1] = unique_value; 647 suffix[UniquePosition::kSuffixLength - 1] = unique_value;
668 return suffix; 648 return suffix;
669 } 649 }
670 650
671 // Make sure that serialization and deserialization routines are correct. 651 // Make sure that serialization and deserialization routines are correct.
672 TEST_F(CompressedPositionTest, SerializeAndDeserialize) { 652 TEST_F(CompressedPositionTest, SerializeAndDeserialize) {
673 for (std::vector<UniquePosition>::const_iterator it = positions_.begin(); 653 for (std::vector<UniquePosition>::const_iterator it = positions_.begin();
674 it != positions_.end(); ++it) { 654 it != positions_.end(); ++it) {
675 SCOPED_TRACE("iteration: " + it->ToDebugString()); 655 SCOPED_TRACE("iteration: " + it->ToDebugString());
676 656
677 sync_pb::UniquePosition proto; 657 sync_pb::UniquePosition proto;
678 it->ToProto(&proto); 658 it->ToProto(&proto);
679 UniquePosition deserialized = UniquePosition::FromProto(proto); 659 UniquePosition deserialized = UniquePosition::FromProto(proto);
680 660
681 EXPECT_PRED_FORMAT2(Equals, *it, deserialized); 661 EXPECT_PRED_FORMAT2(Equals, *it, deserialized);
682 } 662 }
683 } 663 }
684 664
685 // Test that deserialization failures of protobufs where we know none of its 665 // Test that deserialization failures of protobufs where we know none of its
686 // fields is not catastrophic. This may happen if all the fields currently 666 // fields is not catastrophic. This may happen if all the fields currently
687 // known to this client become deprecated in the future. 667 // known to this client become deprecated in the future.
688 TEST_F(CompressedPositionTest, DeserializeProtobufFromTheFuture) { 668 TEST_F(CompressedPositionTest, DeserializeProtobufFromTheFuture) {
689 sync_pb::UniquePosition proto; 669 sync_pb::UniquePosition proto;
690 UniquePosition deserialized = UniquePosition::FromProto(proto); 670 UniquePosition deserialized = UniquePosition::FromProto(proto);
691 EXPECT_FALSE(deserialized.IsValid()); 671 EXPECT_FALSE(deserialized.IsValid());
692 } 672 }
693 673
694 // Make sure the comparison functions are working correctly. 674 // Make sure the comparison functions are working correctly.
695 // This requires values in the test harness to be hard-coded in ascending order. 675 // This requires values in the test harness to be hard-coded in ascending order.
696 TEST_F(CompressedPositionTest, OrderingTest) { 676 TEST_F(CompressedPositionTest, OrderingTest) {
697 for (size_t i = 0; i < positions_.size()-1; ++i) { 677 for (size_t i = 0; i < positions_.size() - 1; ++i) {
698 EXPECT_PRED_FORMAT2(LessThan, positions_[i], positions_[i+1]); 678 EXPECT_PRED_FORMAT2(LessThan, positions_[i], positions_[i + 1]);
699 } 679 }
700 } 680 }
701 681
702 } // namespace 682 } // namespace
703 683
704 } // namespace syncer 684 } // namespace syncer
OLDNEW
« no previous file with comments | « components/sync/base/unique_position.cc ('k') | components/sync/base/unrecoverable_error_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698