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
3 // found in the LICENSE file.
4 
5 #include <memory>
6 
7 #include "base/macros.h"
8 #include "base/run_loop.h"
9 #include "base/strings/string_util.h"
10 #include "base/test/bind.h"
11 #include "base/test/metrics/histogram_tester.h"
12 #include "base/values.h"
13 #include "build/build_config.h"
14 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
15 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
16 #include "chrome/browser/sync/test/integration/sync_test.h"
17 #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h"
18 #include "components/bookmarks/browser/bookmark_model.h"
19 #include "components/sync/base/model_type.h"
20 #include "components/sync/base/user_selectable_type.h"
21 #include "components/sync/driver/profile_sync_service.h"
22 #include "components/sync/driver/sync_user_settings_impl.h"
23 #include "components/sync/test/fake_server/bookmark_entity_builder.h"
24 #include "components/sync/test/fake_server/entity_builder_factory.h"
25 #include "content/public/test/browser_test.h"
26 
27 namespace {
28 
29 using syncer::ModelType;
30 using syncer::ModelTypeFromString;
31 using syncer::ModelTypeSet;
32 using syncer::ModelTypeToString;
33 using syncer::ProxyTypes;
34 using syncer::SyncPrefs;
35 using syncer::SyncUserSettings;
36 using syncer::UserSelectableType;
37 using syncer::UserSelectableTypeSet;
38 
39 const char kSyncedBookmarkURL[] = "http://www.mybookmark.com";
40 // Non-utf8 string to make sure it gets handled well.
41 const char kTestServerChips[] = "\xed\xa0\x80\xed\xbf\xbf";
42 
43 // Some types show up in multiple groups. This means that there are at least two
44 // user selectable groups that will cause these types to become enabled. This
45 // affects our tests because we cannot assume that before enabling a multi type
46 // it will be disabled, because the other selectable type(s) could already be
47 // enabling it. And vice versa for disabling.
MultiGroupTypes(const ModelTypeSet & registered_types)48 ModelTypeSet MultiGroupTypes(const ModelTypeSet& registered_types) {
49   ModelTypeSet seen;
50   ModelTypeSet multi;
51   for (UserSelectableType type : UserSelectableTypeSet::All()) {
52     const ModelTypeSet grouped_types =
53         syncer::SyncUserSettingsImpl::ResolvePreferredTypesForTesting({type});
54     for (ModelType grouped_type : grouped_types) {
55       if (seen.Has(grouped_type)) {
56         multi.Put(grouped_type);
57       } else {
58         seen.Put(grouped_type);
59       }
60     }
61   }
62   multi.RetainAll(registered_types);
63   return multi;
64 }
65 
66 // This test enables and disables types and verifies the type is sufficiently
67 // affected by checking for existence of a root node.
68 class EnableDisableSingleClientTest : public SyncTest {
69  public:
EnableDisableSingleClientTest()70   EnableDisableSingleClientTest() : SyncTest(SINGLE_CLIENT) {}
71   ~EnableDisableSingleClientTest() override = default;
72 
73   // Don't use self-notifications as they can trigger additional sync cycles.
TestUsesSelfNotifications()74   bool TestUsesSelfNotifications() override { return false; }
75 
ModelTypeExists(ModelType type)76   bool ModelTypeExists(ModelType type) {
77     base::RunLoop loop;
78     std::unique_ptr<base::ListValue> all_nodes;
79     GetSyncService(0)->GetAllNodesForDebugging(
80         base::BindLambdaForTesting([&](std::unique_ptr<base::ListValue> nodes) {
81           all_nodes = std::move(nodes);
82           loop.Quit();
83         }));
84     loop.Run();
85     // Look for the root node corresponding to |type|.
86     for (const base::Value& value : all_nodes->GetList()) {
87       DCHECK(value.is_dict());
88       const base::Value* nodes = value.FindKey("nodes");
89       DCHECK(nodes);
90       DCHECK(nodes->is_list());
91       // Ignore types that are empty, because we expect the root node.
92       if (nodes->GetList().empty()) {
93         continue;
94       }
95       const base::Value* model_type = value.FindKey("type");
96       DCHECK(model_type);
97       DCHECK(model_type->is_string());
98       if (type == ModelTypeFromString(model_type->GetString())) {
99         return true;
100       }
101     }
102     return false;
103   }
104 
InjectSyncedBookmark()105   void InjectSyncedBookmark() {
106     fake_server::BookmarkEntityBuilder bookmark_builder =
107         entity_builder_factory_.NewBookmarkEntityBuilder("My Bookmark");
108     GetFakeServer()->InjectEntity(
109         bookmark_builder.BuildBookmark(GURL(kSyncedBookmarkURL)));
110   }
111 
GetNumUpdatesDownloadedInLastCycle()112   int GetNumUpdatesDownloadedInLastCycle() {
113     return GetSyncService(0)
114         ->GetLastCycleSnapshotForDebugging()
115         .model_neutral_state()
116         .num_updates_downloaded_total;
117   }
118 
119  protected:
SetupTest(bool all_types_enabled)120   void SetupTest(bool all_types_enabled) {
121     ASSERT_TRUE(SetupClients());
122     if (all_types_enabled) {
123       ASSERT_TRUE(GetClient(0)->SetupSync());
124     } else {
125       ASSERT_TRUE(
126           GetClient(0)->SetupSyncNoWaitForCompletion(UserSelectableTypeSet()));
127       ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion());
128     }
129 
130     registered_data_types_ = GetSyncService(0)->GetRegisteredDataTypesForTest();
131     multi_grouped_types_ = MultiGroupTypes(registered_data_types_);
132     registered_selectable_types_ = GetRegisteredSelectableTypes(0);
133   }
134 
ResolveGroup(UserSelectableType type)135   ModelTypeSet ResolveGroup(UserSelectableType type) {
136     ModelTypeSet grouped_types =
137         syncer::SyncUserSettingsImpl::ResolvePreferredTypesForTesting({type});
138     grouped_types.RetainAll(registered_data_types_);
139     grouped_types.RemoveAll(ProxyTypes());
140     return grouped_types;
141   }
142 
WithoutMultiTypes(const ModelTypeSet & input)143   ModelTypeSet WithoutMultiTypes(const ModelTypeSet& input) {
144     return Difference(input, multi_grouped_types_);
145   }
146 
147   ModelTypeSet registered_data_types_;
148   ModelTypeSet multi_grouped_types_;
149   UserSelectableTypeSet registered_selectable_types_;
150 
151  private:
152   fake_server::EntityBuilderFactory entity_builder_factory_;
153 
154   DISALLOW_COPY_AND_ASSIGN(EnableDisableSingleClientTest);
155 };
156 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,EnableOneAtATime)157 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, EnableOneAtATime) {
158   // Setup sync with no enabled types.
159   SetupTest(/*all_types_enabled=*/false);
160 
161   for (UserSelectableType type : registered_selectable_types_) {
162     const ModelTypeSet grouped_types = ResolveGroup(type);
163     for (ModelType single_grouped_type : WithoutMultiTypes(grouped_types)) {
164       ASSERT_FALSE(ModelTypeExists(single_grouped_type))
165           << " for " << GetUserSelectableTypeName(type);
166     }
167 
168     base::HistogramTester histogram_tester;
169     EXPECT_TRUE(GetClient(0)->EnableSyncForType(type));
170 
171     for (ModelType grouped_type : grouped_types) {
172       EXPECT_TRUE(ModelTypeExists(grouped_type))
173           << " for " << GetUserSelectableTypeName(type);
174 
175       if (syncer::CommitOnlyTypes().Has(grouped_type)) {
176         EXPECT_EQ(0,
177                   histogram_tester.GetBucketCount(
178                       "Sync.PostedDataTypeGetUpdatesRequest",
179                       static_cast<int>(ModelTypeHistogramValue(grouped_type))))
180             << " for " << ModelTypeToString(grouped_type);
181       } else {
182         EXPECT_NE(0,
183                   histogram_tester.GetBucketCount(
184                       "Sync.PostedDataTypeGetUpdatesRequest",
185                       static_cast<int>(ModelTypeHistogramValue(grouped_type))))
186             << " for " << ModelTypeToString(grouped_type);
187       }
188     }
189   }
190 }
191 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,DisableOneAtATime)192 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, DisableOneAtATime) {
193   // Setup sync with no disabled types.
194   SetupTest(/*all_types_enabled=*/true);
195 
196   for (UserSelectableType type : registered_selectable_types_) {
197     const ModelTypeSet grouped_types = ResolveGroup(type);
198     for (ModelType grouped_type : grouped_types) {
199       ASSERT_TRUE(ModelTypeExists(grouped_type))
200           << " for " << GetUserSelectableTypeName(type);
201     }
202 
203     EXPECT_TRUE(GetClient(0)->DisableSyncForType(type));
204 
205     for (ModelType single_grouped_type : WithoutMultiTypes(grouped_types)) {
206       EXPECT_FALSE(ModelTypeExists(single_grouped_type))
207           << " for " << GetUserSelectableTypeName(type);
208     }
209   }
210 
211   // Lastly make sure that all the multi grouped times are all gone, since we
212   // did not check these after disabling inside the above loop.
213   for (ModelType multi_grouped_type : multi_grouped_types_) {
214     EXPECT_FALSE(ModelTypeExists(multi_grouped_type))
215         << " for " << ModelTypeToString(multi_grouped_type);
216   }
217 }
218 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,FastEnableDisableOneAtATime)219 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,
220                        FastEnableDisableOneAtATime) {
221   // Setup sync with no enabled types.
222   SetupTest(/*all_types_enabled=*/false);
223 
224   for (UserSelectableType type : registered_selectable_types_) {
225     const ModelTypeSet grouped_types = ResolveGroup(type);
226     const ModelTypeSet single_grouped_types = WithoutMultiTypes(grouped_types);
227     for (ModelType single_grouped_type : single_grouped_types) {
228       ASSERT_FALSE(ModelTypeExists(single_grouped_type))
229           << " for " << GetUserSelectableTypeName(type);
230     }
231 
232     // Enable and then disable immediately afterwards, before the datatype has
233     // had the chance to finish startup (which usually involves task posting).
234     EXPECT_TRUE(GetClient(0)->EnableSyncForType(type));
235     EXPECT_TRUE(GetClient(0)->DisableSyncForType(type));
236 
237     for (ModelType single_grouped_type : single_grouped_types) {
238       EXPECT_FALSE(ModelTypeExists(single_grouped_type))
239           << " for " << GetUserSelectableTypeName(type);
240     }
241   }
242 
243   // Lastly make sure that all the multi grouped times are all gone, since we
244   // did not check these after disabling inside the above loop.
245   for (ModelType multi_grouped_type : multi_grouped_types_) {
246     EXPECT_FALSE(ModelTypeExists(multi_grouped_type))
247         << " for " << ModelTypeToString(multi_grouped_type);
248   }
249 }
250 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,FastDisableEnableOneAtATime)251 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,
252                        FastDisableEnableOneAtATime) {
253   // Setup sync with no disabled types.
254   SetupTest(/*all_types_enabled=*/true);
255 
256   for (UserSelectableType type : registered_selectable_types_) {
257     const ModelTypeSet grouped_types = ResolveGroup(type);
258     for (ModelType grouped_type : grouped_types) {
259       ASSERT_TRUE(ModelTypeExists(grouped_type))
260           << " for " << GetUserSelectableTypeName(type);
261     }
262 
263     // Disable and then reenable immediately afterwards, before the datatype has
264     // had the chance to stop fully (which usually involves task posting).
265     EXPECT_TRUE(GetClient(0)->DisableSyncForType(type));
266     EXPECT_TRUE(GetClient(0)->EnableSyncForType(type));
267 
268     for (ModelType grouped_type : grouped_types) {
269       EXPECT_TRUE(ModelTypeExists(grouped_type))
270           << " for " << GetUserSelectableTypeName(type);
271     }
272   }
273 }
274 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,FastEnableDisableEnableOneAtATime)275 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,
276                        FastEnableDisableEnableOneAtATime) {
277   // Setup sync with no enabled types.
278   SetupTest(/*all_types_enabled=*/false);
279 
280   for (UserSelectableType type : registered_selectable_types_) {
281     const ModelTypeSet single_grouped_types =
282         WithoutMultiTypes(ResolveGroup(type));
283     for (ModelType single_grouped_type : single_grouped_types) {
284       ASSERT_FALSE(ModelTypeExists(single_grouped_type))
285           << " for " << GetUserSelectableTypeName(type);
286     }
287 
288     // Fast enable-disable-enable sequence, before the datatype has had the
289     // chance to transition fully across states (usually involves task posting).
290     EXPECT_TRUE(GetClient(0)->EnableSyncForType(type));
291     EXPECT_TRUE(GetClient(0)->DisableSyncForType(type));
292     EXPECT_TRUE(GetClient(0)->EnableSyncForType(type));
293 
294     for (ModelType single_grouped_type : single_grouped_types) {
295       EXPECT_TRUE(ModelTypeExists(single_grouped_type))
296           << " for " << GetUserSelectableTypeName(type);
297     }
298   }
299 }
300 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,EnableDisable)301 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, EnableDisable) {
302   SetupTest(/*all_types_enabled=*/false);
303 
304   // Enable all, and then disable immediately afterwards, before datatypes
305   // have had the chance to finish startup (which usually involves task
306   // posting).
307   GetClient(0)->EnableSyncForRegisteredDatatypes();
308   GetClient(0)->DisableSyncForAllDatatypes();
309 
310   for (UserSelectableType type : UserSelectableTypeSet::All()) {
311     for (ModelType grouped_type : ResolveGroup(type)) {
312       EXPECT_FALSE(ModelTypeExists(grouped_type))
313           << " for " << GetUserSelectableTypeName(type);
314     }
315   }
316 }
317 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,PRE_EnableAndRestart)318 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, PRE_EnableAndRestart) {
319   SetupTest(/*all_types_enabled=*/true);
320 }
321 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,EnableAndRestart)322 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, EnableAndRestart) {
323   ASSERT_TRUE(SetupClients());
324 
325   EXPECT_TRUE(GetClient(0)->AwaitEngineInitialization());
326 
327   for (UserSelectableType type : UserSelectableTypeSet::All()) {
328     for (ModelType model_type : ResolveGroup(type)) {
329       EXPECT_TRUE(ModelTypeExists(model_type))
330           << " for " << ModelTypeToString(model_type);
331     }
332   }
333 }
334 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,FastEnableDisableEnable)335 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, FastEnableDisableEnable) {
336   SetupTest(/*all_types_enabled=*/false);
337 
338   // Enable all, and then disable+reenable immediately afterwards, before
339   // datatypes have had the chance to finish startup (which usually involves
340   // task posting).
341   GetClient(0)->EnableSyncForRegisteredDatatypes();
342   GetClient(0)->DisableSyncForAllDatatypes();
343   GetClient(0)->EnableSyncForRegisteredDatatypes();
344 
345   for (UserSelectableType type : UserSelectableTypeSet::All()) {
346     for (ModelType model_type : ResolveGroup(type)) {
347       EXPECT_TRUE(ModelTypeExists(model_type))
348           << " for " << ModelTypeToString(model_type);
349     }
350   }
351 }
352 
353 // This test makes sure that after a StopAndClear(), Sync data gets redownloaded
354 // when Sync is started again. This does not actually verify that the data is
355 // gone from disk (which seems infeasible); it's mostly here as a baseline for
356 // the following tests.
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,RedownloadsAfterClearData)357 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,
358                        RedownloadsAfterClearData) {
359   ASSERT_TRUE(SetupClients());
360   ASSERT_FALSE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
361       GURL(kSyncedBookmarkURL)));
362 
363   // Create a bookmark on the server, then turn on Sync on the client.
364   InjectSyncedBookmark();
365   ASSERT_TRUE(GetClient(0)->SetupSync());
366   ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());
367 
368   // Make sure the bookmark got synced down.
369   ASSERT_TRUE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
370       GURL(kSyncedBookmarkURL)));
371   // Note: The response may also contain permanent nodes, so we can't check the
372   // exact count.
373   const int initial_updates_downloaded = GetNumUpdatesDownloadedInLastCycle();
374   ASSERT_GT(initial_updates_downloaded, 0);
375 
376   // Stop and restart Sync.
377   GetClient(0)->StopSyncServiceAndClearData();
378   GetClient(0)->StartSyncService();
379   ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());
380 
381   // Everything should have been redownloaded.
382   ASSERT_TRUE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
383       GURL(kSyncedBookmarkURL)));
384   EXPECT_EQ(GetNumUpdatesDownloadedInLastCycle(), initial_updates_downloaded);
385 }
386 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,DoesNotRedownloadAfterKeepData)387 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,
388                        DoesNotRedownloadAfterKeepData) {
389   ASSERT_TRUE(SetupClients());
390   ASSERT_FALSE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
391       GURL(kSyncedBookmarkURL)));
392 
393   // Create a bookmark on the server, then turn on Sync on the client.
394   InjectSyncedBookmark();
395   ASSERT_TRUE(GetClient(0)->SetupSync());
396   ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());
397 
398   // Make sure the bookmark got synced down.
399   ASSERT_TRUE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
400       GURL(kSyncedBookmarkURL)));
401   // Note: The response may also contain permanent nodes, so we can't check the
402   // exact count.
403   ASSERT_GT(GetNumUpdatesDownloadedInLastCycle(), 0);
404 
405   // Stop Sync and let it start up again in standalone transport mode.
406   GetClient(0)->StopSyncServiceWithoutClearingData();
407   ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive());
408   ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
409             GetSyncService(0)->GetTransportState());
410   ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureActive());
411 
412   // Now start full Sync again.
413   base::HistogramTester histogram_tester;
414   GetClient(0)->StartSyncService();
415   ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());
416 
417   // The bookmark should still be there, *without* having been redownloaded.
418   ASSERT_TRUE(SetupSync());
419   ASSERT_TRUE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
420       GURL(kSyncedBookmarkURL)));
421   EXPECT_EQ(
422       0, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange3.BOOKMARK",
423                                          /*REMOTE_NON_INITIAL_UPDATE=*/4));
424   EXPECT_EQ(
425       0, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange3.BOOKMARK",
426                                          /*REMOTE_INITIAL_UPDATE=*/5));
427 }
428 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,ClearsPrefsIfClearData)429 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, ClearsPrefsIfClearData) {
430   SetupTest(/*all_types_enabled=*/true);
431 
432   SyncPrefs prefs(GetProfile(0)->GetPrefs());
433   ASSERT_NE("", prefs.GetCacheGuid());
434 
435   GetClient(0)->StopSyncServiceAndClearData();
436   EXPECT_EQ("", prefs.GetCacheGuid());
437 }
438 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,DoesNotClearPrefsWithKeepData)439 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,
440                        DoesNotClearPrefsWithKeepData) {
441   SetupTest(/*all_types_enabled=*/true);
442 
443   SyncPrefs prefs(GetProfile(0)->GetPrefs());
444   const std::string cache_guid = prefs.GetCacheGuid();
445   ASSERT_NE("", cache_guid);
446 
447   GetClient(0)->StopSyncServiceWithoutClearingData();
448   EXPECT_EQ(cache_guid, prefs.GetCacheGuid());
449 }
450 
451 class EnableDisableSingleClientSelfNotifyTest
452     : public EnableDisableSingleClientTest {
453  public:
454   // UpdatedProgressMarkerChecker relies on the 'self-notify' feature.
TestUsesSelfNotifications()455   bool TestUsesSelfNotifications() override { return true; }
456 
TriggerGetUpdatesCycleAndWait()457   sync_pb::ClientToServerMessage TriggerGetUpdatesCycleAndWait() {
458     TriggerSyncForModelTypes(0, {syncer::BOOKMARKS});
459     EXPECT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait());
460 
461     sync_pb::ClientToServerMessage message;
462     EXPECT_TRUE(GetFakeServer()->GetLastGetUpdatesMessage(&message));
463     return message;
464   }
465 };
466 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientSelfNotifyTest,PRE_ResendsBagOfChips)467 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientSelfNotifyTest,
468                        PRE_ResendsBagOfChips) {
469   sync_pb::ChipBag bag_of_chips;
470   bag_of_chips.set_server_chips(kTestServerChips);
471   ASSERT_FALSE(base::IsStringUTF8(bag_of_chips.SerializeAsString()));
472   GetFakeServer()->SetBagOfChips(bag_of_chips);
473 
474   SetupTest(/*all_types_enabled=*/true);
475 
476   SyncPrefs prefs(GetProfile(0)->GetPrefs());
477   EXPECT_EQ(bag_of_chips.SerializeAsString(), prefs.GetBagOfChips());
478 
479   sync_pb::ClientToServerMessage message = TriggerGetUpdatesCycleAndWait();
480   EXPECT_TRUE(message.has_bag_of_chips());
481   EXPECT_EQ(kTestServerChips, message.bag_of_chips().server_chips());
482 }
483 
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientSelfNotifyTest,ResendsBagOfChips)484 IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientSelfNotifyTest,
485                        ResendsBagOfChips) {
486   ASSERT_TRUE(SetupClients());
487   SyncPrefs prefs(GetProfile(0)->GetPrefs());
488   ASSERT_NE("", prefs.GetBagOfChips());
489   ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion());
490 
491   sync_pb::ClientToServerMessage message = TriggerGetUpdatesCycleAndWait();
492   EXPECT_TRUE(message.has_bag_of_chips());
493   EXPECT_EQ(kTestServerChips, message.bag_of_chips().server_chips());
494 }
495 
496 }  // namespace
497