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

Side by Side Diff: sync/internal_api/public/util/proto_value_ptr_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
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "sync/internal_api/public/util/proto_value_ptr.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "base/macros.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace syncer {
14
15 namespace {
16
17 // Simple test struct that wraps an integer
18 struct IntValue {
19 public:
20 explicit IntValue(int value) { value_ = value; }
21 int value() { return value_; }
22
23 private:
24 int value_;
25 };
26
27 // TestValue class is used as a template argument with ProtoValuePtr<T>
28 class TestValue {
29 public:
30 TestValue() : value_(nullptr), is_default_(false) {}
31 explicit TestValue(int value)
32 : value_(new IntValue(value)), is_default_(false) {}
33
34 ~TestValue() { g_delete_count++; }
35
36 static void ResetCounters() {
37 g_copy_count = 0;
38 g_parse_count = 0;
39 g_delete_count = 0;
40 }
41
42 static int copy_count() { return g_copy_count; }
43 static int parse_count() { return g_parse_count; }
44 static int delete_count() { return g_delete_count; }
45
46 int value() const { return value_->value(); }
47 IntValue* value_ptr() const { return value_.get(); }
48 bool is_initialized() const { return !!value_; }
49 bool is_default() const { return is_default_; }
50
51 // TestValue uses the default traits struct with ProtoValuePtr<TestValue>.
52 // The following 4 functions are expected by the traits struct to exist
53 // in this class.
54 void CopyFrom(const TestValue& from) {
55 // Expected to always copy from an initialized instance
56 // to an uninitialized one.
57 // Not expected either value to be default.
58 ASSERT_FALSE(is_initialized());
59 ASSERT_FALSE(is_default());
60 ASSERT_TRUE(from.is_initialized());
61 ASSERT_FALSE(from.is_default());
62 value_.reset(new IntValue(from.value()));
63 g_copy_count++;
64 }
65
66 void Swap(TestValue* src) {
67 // Expected to always swap with an initialized instance.
68 // The current instance must always be an uninitialized one.
69 // Not expected either value to be default.
70 ASSERT_FALSE(is_initialized());
71 ASSERT_FALSE(is_default());
72 ASSERT_TRUE(src->is_initialized());
73 ASSERT_FALSE(src->is_default());
74 // Not exactly swap, but good enough for the test.
75 value_ = std::move(src->value_);
76 }
77
78 void ParseFromArray(const void* blob, int length) {
79 // Similarly to CopyFrom this is expected to be called on
80 // an uninitialized instance.
81 ASSERT_FALSE(is_initialized());
82 ASSERT_FALSE(is_default());
83 // The blob is an address of an integer
84 ASSERT_EQ(static_cast<int>(sizeof(int)), length);
85 value_.reset(new IntValue(*static_cast<const int*>(blob)));
86 g_parse_count++;
87 }
88
89 int ByteSize() const { return is_initialized() ? sizeof(int) : 0; }
90
91 static const TestValue& default_instance() {
92 static TestValue default_instance;
93 default_instance.is_default_ = true;
94 return default_instance;
95 }
96
97 private:
98 static int g_copy_count;
99 static int g_parse_count;
100 static int g_delete_count;
101
102 std::unique_ptr<IntValue> value_;
103 bool is_default_;
104
105 DISALLOW_COPY_AND_ASSIGN(TestValue);
106 };
107
108 // Static initializers.
109 int TestValue::g_copy_count = 0;
110 int TestValue::g_parse_count = 0;
111 int TestValue::g_delete_count = 0;
112
113 } // namespace
114
115 typedef ProtoValuePtr<TestValue> TestPtr;
116
117 class ProtoValuePtrTest : public testing::Test {
118 public:
119 void SetUp() override { TestValue::ResetCounters(); }
120
121 static bool WrappedValuesAreShared(const TestPtr& ptr1, const TestPtr& ptr2) {
122 const TestValue& wrapped_value_1 = ptr1.value();
123 const TestValue& wrapped_value_2 = ptr2.value();
124 // Compare addresses.
125 return &wrapped_value_1 == &wrapped_value_2;
126 }
127 };
128
129 TEST_F(ProtoValuePtrTest, ValueAssignment) {
130 // Basic assignment and default value.
131 TestValue t1(1);
132 {
133 TestPtr ptr1;
134 EXPECT_TRUE(ptr1->is_default());
135
136 ptr1.set_value(t1);
137 EXPECT_FALSE(ptr1->is_default());
138 EXPECT_EQ(1, ptr1->value());
139 }
140
141 EXPECT_EQ(1, TestValue::copy_count());
142 EXPECT_EQ(1, TestValue::delete_count());
143 }
144
145 TEST_F(ProtoValuePtrTest, ValueSwap) {
146 TestValue t2(2);
147 {
148 TestPtr ptr2;
149 EXPECT_TRUE(ptr2->is_default());
150
151 IntValue* inner_ptr = t2.value_ptr();
152
153 ptr2.swap_value(&t2);
154 EXPECT_FALSE(ptr2->is_default());
155 EXPECT_EQ(2, ptr2->value());
156 EXPECT_EQ(inner_ptr, ptr2->value_ptr());
157 }
158
159 EXPECT_EQ(0, TestValue::copy_count());
160 EXPECT_EQ(1, TestValue::delete_count());
161 }
162
163 TEST_F(ProtoValuePtrTest, SharingTest) {
164 // Sharing between two pointers.
165 TestValue empty;
166 TestValue t2(2);
167 TestValue t3(3);
168 {
169 TestPtr ptr2;
170 TestPtr ptr3;
171
172 EXPECT_TRUE(ptr2->is_default());
173 EXPECT_TRUE(ptr3->is_default());
174 EXPECT_EQ(0, TestValue::copy_count());
175 EXPECT_EQ(0, TestValue::delete_count());
176
177 ptr2.set_value(t2);
178 EXPECT_EQ(1, TestValue::copy_count());
179 EXPECT_EQ(0, TestValue::delete_count());
180
181 ptr3 = ptr2;
182 // Both |ptr2| and |ptr3| now share the same value "2".
183 // No additional copies expected.
184 EXPECT_EQ(1, TestValue::copy_count());
185 EXPECT_EQ(0, TestValue::delete_count());
186 EXPECT_FALSE(ptr3->is_default());
187 EXPECT_EQ(2, ptr3->value());
188 EXPECT_TRUE(WrappedValuesAreShared(ptr2, ptr3));
189
190 // Stop sharing - |ptr2| is "3" and |ptr3| is still "2".
191 ptr2.set_value(t3);
192 EXPECT_FALSE(WrappedValuesAreShared(ptr2, ptr3));
193 EXPECT_EQ(3, ptr2->value());
194 EXPECT_EQ(2, ptr3->value());
195 // No extra copies or deletions expected.
196 EXPECT_EQ(2, TestValue::copy_count());
197 EXPECT_EQ(0, TestValue::delete_count());
198
199 // |ptr3| still has the old value.
200 EXPECT_EQ(2, ptr3->value());
201
202 // Share again. Both values are "3".
203 ptr3 = ptr2;
204 EXPECT_EQ(3, ptr3->value());
205 // This should have resulted in deleting the wrapper for the value "2".
206 EXPECT_EQ(1, TestValue::delete_count());
207 // No extra copies expected.
208 EXPECT_EQ(2, TestValue::copy_count());
209
210 // Set default value to one of the pointers.
211 ptr2.set_value(empty);
212 EXPECT_TRUE(ptr2->is_default());
213 // The other one is still intact.
214 EXPECT_FALSE(ptr3->is_default());
215 EXPECT_EQ(3, ptr3->value());
216 // No extra copies or deletions expected.
217 EXPECT_EQ(1, TestValue::delete_count());
218 EXPECT_EQ(2, TestValue::copy_count());
219
220 // Copy the default value between the pointers.
221 ptr3 = ptr2;
222 EXPECT_TRUE(ptr3->is_default());
223 // The wrapper for "3" is now deleted.
224 EXPECT_EQ(2, TestValue::delete_count());
225 }
226
227 // No extra deletions expected upon leaving the scope.
228 EXPECT_EQ(2, TestValue::delete_count());
229 }
230
231 TEST_F(ProtoValuePtrTest, ParsingTest) {
232 int v1 = 21;
233
234 {
235 TestPtr ptr1;
236
237 ptr1.load(&v1, sizeof(int));
238
239 EXPECT_EQ(1, TestValue::parse_count());
240 EXPECT_EQ(0, TestValue::copy_count());
241
242 EXPECT_EQ(v1, ptr1->value());
243 }
244
245 EXPECT_EQ(1, TestValue::delete_count());
246 }
247
248 } // namespace syncer
OLDNEW
« no previous file with comments | « sync/internal_api/public/util/proto_value_ptr.h ('k') | sync/internal_api/public/util/sync_db_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698