multiple_client_dictionary_sync_test.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
1// Copyright (c) 2011 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 "base/strings/string_number_conversions.h" 6#include "chrome/browser/sync/test/integration/dictionary_helper.h" 7#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" 8#include "chrome/browser/sync/test/integration/sync_test.h" 9#include "chrome/common/spellcheck_common.h" 10 11using dictionary_helper::AwaitNumDictionaryEntries; 12using chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS; 13 14class MultipleClientDictionarySyncTest : public SyncTest { 15 public: 16 MultipleClientDictionarySyncTest() : SyncTest(MULTIPLE_CLIENT) {} 17 virtual ~MultipleClientDictionarySyncTest() {} 18 19 virtual bool TestUsesSelfNotifications() OVERRIDE { return false; } 20 21 private: 22 DISALLOW_COPY_AND_ASSIGN(MultipleClientDictionarySyncTest); 23}; 24 25IN_PROC_BROWSER_TEST_F(MultipleClientDictionarySyncTest, AddToOne) { 26 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; 27 dictionary_helper::LoadDictionaries(); 28 ASSERT_TRUE(dictionary_helper::AwaitDictionariesMatch()); 29 30 ASSERT_TRUE(dictionary_helper::AddWord(0, "foo")); 31 ASSERT_TRUE(dictionary_helper::AwaitDictionariesMatch()); 32} 33 34IN_PROC_BROWSER_TEST_F(MultipleClientDictionarySyncTest, AddSameToAll) { 35 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; 36 dictionary_helper::LoadDictionaries(); 37 ASSERT_TRUE(dictionary_helper::AwaitDictionariesMatch()); 38 39 for (int i = 0; i < num_clients(); ++i) 40 dictionary_helper::AddWord(i, "foo"); 41 ASSERT_TRUE(dictionary_helper::AwaitDictionariesMatch()); 42 ASSERT_EQ(1UL, dictionary_helper::GetDictionarySize(0)); 43} 44 45IN_PROC_BROWSER_TEST_F(MultipleClientDictionarySyncTest, AddDifferentToAll) { 46 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; 47 dictionary_helper::LoadDictionaries(); 48 ASSERT_TRUE(dictionary_helper::AwaitDictionariesMatch()); 49 50 for (int i = 0; i < num_clients(); ++i) 51 dictionary_helper::AddWord(i, "foo" + base::IntToString(i)); 52 ASSERT_TRUE(dictionary_helper::AwaitDictionariesMatch()); 53 ASSERT_EQ(num_clients(), 54 static_cast<int>(dictionary_helper::GetDictionarySize(0))); 55} 56 57// Tests the case where the Nth client pushes the server beyond its 58// MAX_SYNCABLE_DICTIONARY_WORDS limit. 59IN_PROC_BROWSER_TEST_F(MultipleClientDictionarySyncTest, Limit) { 60 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; 61 dictionary_helper::LoadDictionaries(); 62 ASSERT_TRUE(dictionary_helper::AwaitDictionariesMatch()); 63 64 const int n = num_clients(); 65 66 // Pick a number of initial words per client such that 67 // (num-clients()-1) * initial_words 68 // < MAX_SYNCABLE_DICTIONARY_WORDS 69 // < num_clients() * initial_words 70 size_t initial_words = 71 (MAX_SYNCABLE_DICTIONARY_WORDS + n) / n; 72 73 // Add |initial_words| words to each of the clients before sync. 74 for (int i = 0; i < n; ++i) { 75 GetClient(i)->DisableSyncForAllDatatypes(); 76 for (size_t j = 0; j < initial_words; ++j) { 77 ASSERT_TRUE(dictionary_helper::AddWord( 78 i, "foo-" + base::IntToString(i) + "-" + base::Uint64ToString(j))); 79 } 80 ASSERT_EQ(initial_words, dictionary_helper::GetDictionarySize(i)); 81 } 82 83 // As long as we don't get involved in any race conditions where two clients 84 // are committing at once, we should be able to guarantee that the server has 85 // at most MAX_SYNCABLE_DICTIONARY_WORDS words. Every client will be able to 86 // sync these items. Clients are allowed to have more words if they're 87 // available locally, but they won't be able to commit any words once the 88 // server is full. 89 // 90 // As we enable clients one-by-one, all but the (N-1)th client should be able 91 // to commit all of their items. The last one will have some local data left 92 // over. 93 94 // Open the floodgates. Allow N-1 clients to sync their items. 95 for (int i = 0; i < n-1; ++i) { 96 SCOPED_TRACE(i); 97 98 // Client #i has |initial_words| words before sync. 99 ASSERT_EQ(initial_words, dictionary_helper::GetDictionarySize(i)); 100 ASSERT_TRUE(GetClient(i)->EnableSyncForAllDatatypes()); 101 } 102 103 // Wait for clients to catch up. All should be in sync with the server 104 // and have exactly (initial_words * (N-1)) words in their dictionaries. 105 for (int i = 0; i < n-1; ++i) { 106 SCOPED_TRACE(i); 107 ASSERT_TRUE(AwaitNumDictionaryEntries(i, initial_words*(n-1))); 108 } 109 110 // Add the client that has engough new words to cause an overflow. 111 ASSERT_EQ(initial_words, dictionary_helper::GetDictionarySize(n-1)); 112 ASSERT_TRUE(GetClient(n-1)->EnableSyncForAllDatatypes()); 113 114 // The Nth client will receive the initial_words * (n-1) entries that were on 115 // the server. It will commit some of the entries it had locally. And it 116 // will have a few uncommittable items left over. 117 ASSERT_TRUE(AwaitNumDictionaryEntries(n-1, initial_words*n)); 118 119 // Everyone else should be at the limit. 120 for (int i = 0; i < n-1; ++i) { 121 SCOPED_TRACE(i); 122 ASSERT_TRUE(AwaitNumDictionaryEntries(i, MAX_SYNCABLE_DICTIONARY_WORDS)); 123 } 124} 125