preferences_helper.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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 "chrome/browser/sync/test/integration/preferences_helper.h"
6
7#include "base/prefs/pref_change_registrar.h"
8#include "base/prefs/pref_service.h"
9#include "base/prefs/scoped_user_pref_update.h"
10#include "base/strings/stringprintf.h"
11#include "chrome/browser/profiles/profile.h"
12#include "chrome/browser/sync/test/integration/multi_client_status_change_checker.h"
13#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
14#include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
15#include "chrome/browser/sync/test/integration/sync_test.h"
16
17using sync_datatype_helper::test;
18
19namespace preferences_helper {
20
21PrefService* GetPrefs(int index) {
22  return test()->GetProfile(index)->GetPrefs();
23}
24
25PrefService* GetVerifierPrefs() {
26  return test()->verifier()->GetPrefs();
27}
28
29void ChangeBooleanPref(int index, const char* pref_name) {
30  bool new_value = !GetPrefs(index)->GetBoolean(pref_name);
31  GetPrefs(index)->SetBoolean(pref_name, new_value);
32  if (test()->use_verifier())
33    GetVerifierPrefs()->SetBoolean(pref_name, new_value);
34}
35
36void ChangeIntegerPref(int index, const char* pref_name, int new_value) {
37  GetPrefs(index)->SetInteger(pref_name, new_value);
38  if (test()->use_verifier())
39    GetVerifierPrefs()->SetInteger(pref_name, new_value);
40}
41
42void ChangeInt64Pref(int index, const char* pref_name, int64 new_value) {
43  GetPrefs(index)->SetInt64(pref_name, new_value);
44  if (test()->use_verifier())
45    GetVerifierPrefs()->SetInt64(pref_name, new_value);
46}
47
48void ChangeDoublePref(int index, const char* pref_name, double new_value) {
49  GetPrefs(index)->SetDouble(pref_name, new_value);
50  if (test()->use_verifier())
51    GetVerifierPrefs()->SetDouble(pref_name, new_value);
52}
53
54void ChangeStringPref(int index,
55                      const char* pref_name,
56                      const std::string& new_value) {
57  GetPrefs(index)->SetString(pref_name, new_value);
58  if (test()->use_verifier())
59    GetVerifierPrefs()->SetString(pref_name, new_value);
60}
61
62void ChangeFilePathPref(int index,
63                        const char* pref_name,
64                        const base::FilePath& new_value) {
65  GetPrefs(index)->SetFilePath(pref_name, new_value);
66  if (test()->use_verifier())
67    GetVerifierPrefs()->SetFilePath(pref_name, new_value);
68}
69
70void ChangeListPref(int index,
71                    const char* pref_name,
72                    const base::ListValue& new_value) {
73  {
74    ListPrefUpdate update(GetPrefs(index), pref_name);
75    base::ListValue* list = update.Get();
76    for (base::ListValue::const_iterator it = new_value.begin();
77         it != new_value.end();
78         ++it) {
79      list->Append((*it)->DeepCopy());
80    }
81  }
82
83  if (test()->use_verifier()) {
84    ListPrefUpdate update_verifier(GetVerifierPrefs(), pref_name);
85    base::ListValue* list_verifier = update_verifier.Get();
86    for (base::ListValue::const_iterator it = new_value.begin();
87         it != new_value.end();
88         ++it) {
89      list_verifier->Append((*it)->DeepCopy());
90    }
91  }
92}
93
94bool BooleanPrefMatches(const char* pref_name) {
95  bool reference_value;
96  if (test()->use_verifier()) {
97    reference_value = GetVerifierPrefs()->GetBoolean(pref_name);
98  } else {
99    reference_value = GetPrefs(0)->GetBoolean(pref_name);
100  }
101  for (int i = 0; i < test()->num_clients(); ++i) {
102    if (reference_value != GetPrefs(i)->GetBoolean(pref_name)) {
103      DVLOG(1) << "Boolean preference " << pref_name << " mismatched in"
104               << " profile " << i << ".";
105      return false;
106    }
107  }
108  return true;
109}
110
111bool IntegerPrefMatches(const char* pref_name) {
112  int reference_value;
113  if (test()->use_verifier()) {
114    reference_value = GetVerifierPrefs()->GetInteger(pref_name);
115  } else {
116    reference_value = GetPrefs(0)->GetInteger(pref_name);
117  }
118  for (int i = 0; i < test()->num_clients(); ++i) {
119    if (reference_value != GetPrefs(i)->GetInteger(pref_name)) {
120      DVLOG(1) << "Integer preference " << pref_name << " mismatched in"
121               << " profile " << i << ".";
122      return false;
123    }
124  }
125  return true;
126}
127
128bool Int64PrefMatches(const char* pref_name) {
129  int64 reference_value;
130  if (test()->use_verifier()) {
131    reference_value = GetVerifierPrefs()->GetInt64(pref_name);
132  } else {
133    reference_value = GetPrefs(0)->GetInt64(pref_name);
134  }
135  for (int i = 0; i < test()->num_clients(); ++i) {
136    if (reference_value != GetPrefs(i)->GetInt64(pref_name)) {
137      DVLOG(1) << "Integer preference " << pref_name << " mismatched in"
138               << " profile " << i << ".";
139      return false;
140    }
141  }
142  return true;
143}
144
145bool DoublePrefMatches(const char* pref_name) {
146  double reference_value;
147  if (test()->use_verifier()) {
148    reference_value = GetVerifierPrefs()->GetDouble(pref_name);
149  } else {
150    reference_value = GetPrefs(0)->GetDouble(pref_name);
151  }
152  for (int i = 0; i < test()->num_clients(); ++i) {
153    if (reference_value != GetPrefs(i)->GetDouble(pref_name)) {
154      DVLOG(1) << "Double preference " << pref_name << " mismatched in"
155               << " profile " << i << ".";
156      return false;
157    }
158  }
159  return true;
160}
161
162bool StringPrefMatches(const char* pref_name) {
163  std::string reference_value;
164  if (test()->use_verifier()) {
165    reference_value = GetVerifierPrefs()->GetString(pref_name);
166  } else {
167    reference_value = GetPrefs(0)->GetString(pref_name);
168  }
169  for (int i = 0; i < test()->num_clients(); ++i) {
170    if (reference_value != GetPrefs(i)->GetString(pref_name)) {
171      DVLOG(1) << "String preference " << pref_name << " mismatched in"
172               << " profile " << i << ".";
173      return false;
174    }
175  }
176  return true;
177}
178
179bool FilePathPrefMatches(const char* pref_name) {
180  base::FilePath reference_value;
181  if (test()->use_verifier()) {
182    reference_value = GetVerifierPrefs()->GetFilePath(pref_name);
183  } else {
184    reference_value = GetPrefs(0)->GetFilePath(pref_name);
185  }
186  for (int i = 0; i < test()->num_clients(); ++i) {
187    if (reference_value != GetPrefs(i)->GetFilePath(pref_name)) {
188      DVLOG(1) << "base::FilePath preference " << pref_name << " mismatched in"
189               << " profile " << i << ".";
190      return false;
191    }
192  }
193  return true;
194}
195
196bool ListPrefMatches(const char* pref_name) {
197  const base::ListValue* reference_value;
198  if (test()->use_verifier()) {
199    reference_value = GetVerifierPrefs()->GetList(pref_name);
200  } else {
201    reference_value = GetPrefs(0)->GetList(pref_name);
202  }
203  for (int i = 0; i < test()->num_clients(); ++i) {
204    if (!reference_value->Equals(GetPrefs(i)->GetList(pref_name))) {
205      DVLOG(1) << "List preference " << pref_name << " mismatched in"
206               << " profile " << i << ".";
207      return false;
208    }
209  }
210  return true;
211}
212
213
214namespace {
215
216class PrefMatchChecker : public StatusChangeChecker {
217 public:
218  explicit PrefMatchChecker(const char* path);
219  virtual ~PrefMatchChecker();
220
221  // StatusChangeChecker implementation.
222  virtual bool IsExitConditionSatisfied() = 0;
223  virtual std::string GetDebugMessage() const OVERRIDE;
224
225  // Wait for condition to become true.
226  void Wait();
227
228 protected:
229  const char* GetPath() const;
230
231 private:
232  void RegisterPrefListener(PrefService* pref_service);
233
234  ScopedVector<PrefChangeRegistrar> pref_change_registrars_;
235  const char* path_;
236};
237
238PrefMatchChecker::PrefMatchChecker(const char* path) : path_(path) {
239}
240
241PrefMatchChecker::~PrefMatchChecker() {
242}
243
244std::string PrefMatchChecker::GetDebugMessage() const {
245  return base::StringPrintf("Waiting for pref '%s' to match", GetPath());
246}
247
248void PrefMatchChecker::Wait() {
249  if (test()->use_verifier()) {
250    RegisterPrefListener(GetVerifierPrefs());
251  }
252
253  for (int i = 0; i < test()->num_clients(); ++i) {
254    RegisterPrefListener(GetPrefs(i));
255  }
256
257  if (IsExitConditionSatisfied()) {
258    return;
259  }
260
261  StartBlockingWait();
262}
263
264const char* PrefMatchChecker::GetPath() const {
265  return path_;
266}
267
268void PrefMatchChecker::RegisterPrefListener(PrefService* pref_service) {
269  scoped_ptr<PrefChangeRegistrar> registrar(new PrefChangeRegistrar());
270  registrar->Init(pref_service);
271  registrar->Add(path_,
272                 base::Bind(&PrefMatchChecker::CheckExitCondition,
273                            base::Unretained(this)));
274  pref_change_registrars_.push_back(registrar.release());
275}
276
277// Helper class used in the implementation of AwaitListPrefMatches.
278class ListPrefMatchChecker : public PrefMatchChecker {
279 public:
280  explicit ListPrefMatchChecker(const char* path);
281  virtual ~ListPrefMatchChecker();
282
283  // Implementation of PrefMatchChecker.
284  virtual bool IsExitConditionSatisfied() OVERRIDE;
285};
286
287ListPrefMatchChecker::ListPrefMatchChecker(const char* path)
288    : PrefMatchChecker(path) {
289}
290
291ListPrefMatchChecker::~ListPrefMatchChecker() {
292}
293
294bool ListPrefMatchChecker::IsExitConditionSatisfied() {
295  return ListPrefMatches(GetPath());
296}
297
298// Helper class used in the implementation of AwaitBooleanPrefMatches.
299class BooleanPrefMatchChecker : public PrefMatchChecker {
300 public:
301  explicit BooleanPrefMatchChecker(const char* path);
302  virtual ~BooleanPrefMatchChecker();
303
304  // Implementation of PrefMatchChecker.
305  virtual bool IsExitConditionSatisfied() OVERRIDE;
306};
307
308BooleanPrefMatchChecker::BooleanPrefMatchChecker(const char* path)
309    : PrefMatchChecker(path) {
310}
311
312BooleanPrefMatchChecker::~BooleanPrefMatchChecker() {
313}
314
315bool BooleanPrefMatchChecker::IsExitConditionSatisfied() {
316  return BooleanPrefMatches(GetPath());
317}
318
319// Helper class used in the implementation of AwaitIntegerPrefMatches.
320class IntegerPrefMatchChecker : public PrefMatchChecker {
321 public:
322  explicit IntegerPrefMatchChecker(const char* path);
323  virtual ~IntegerPrefMatchChecker();
324
325  // Implementation of PrefMatchChecker.
326  virtual bool IsExitConditionSatisfied() OVERRIDE;
327};
328
329IntegerPrefMatchChecker::IntegerPrefMatchChecker(const char* path)
330    : PrefMatchChecker(path) {
331}
332
333IntegerPrefMatchChecker::~IntegerPrefMatchChecker() {
334}
335
336bool IntegerPrefMatchChecker::IsExitConditionSatisfied() {
337  return IntegerPrefMatches(GetPath());
338}
339
340// Helper class used in the implementation of AwaitStringPrefMatches.
341class StringPrefMatchChecker : public PrefMatchChecker {
342 public:
343  explicit StringPrefMatchChecker(const char* path);
344  virtual ~StringPrefMatchChecker();
345
346  // Implementation of PrefMatchChecker.
347  virtual bool IsExitConditionSatisfied() OVERRIDE;
348};
349
350StringPrefMatchChecker::StringPrefMatchChecker(const char* path)
351    : PrefMatchChecker(path) {
352}
353
354StringPrefMatchChecker::~StringPrefMatchChecker() {
355}
356
357bool StringPrefMatchChecker::IsExitConditionSatisfied() {
358  return StringPrefMatches(GetPath());
359}
360
361}  //  namespace
362
363bool AwaitListPrefMatches(const char* pref_name) {
364  ListPrefMatchChecker checker(pref_name);
365  checker.Wait();
366  return !checker.TimedOut();
367}
368
369bool AwaitBooleanPrefMatches(const char* pref_name) {
370  BooleanPrefMatchChecker checker(pref_name);
371  checker.Wait();
372  return !checker.TimedOut();
373}
374
375bool AwaitIntegerPrefMatches(const char* pref_name) {
376  IntegerPrefMatchChecker checker(pref_name);
377  checker.Wait();
378  return !checker.TimedOut();
379}
380
381bool AwaitStringPrefMatches(const char* pref_name) {
382  StringPrefMatchChecker checker(pref_name);
383  checker.Wait();
384  return !checker.TimedOut();
385}
386
387}  // namespace preferences_helper
388