1// Copyright (c) 2009 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/sessions/sync_session.h"
6#include "chrome/test/sync/engine/test_id_factory.h"
7#include "testing/gtest/include/gtest/gtest.h"
8
9namespace browser_sync {
10namespace sessions {
11
12class StatusControllerTest : public testing::Test {
13 public:
14  virtual void SetUp() {
15    routes_[syncable::BOOKMARKS] = GROUP_UI;
16  }
17 protected:
18  ModelSafeRoutingInfo routes_;
19};
20
21TEST_F(StatusControllerTest, GetsDirty) {
22  StatusController status(routes_);
23  status.increment_num_conflicting_commits_by(1);
24  EXPECT_TRUE(status.TestAndClearIsDirty());
25  EXPECT_FALSE(status.TestAndClearIsDirty());  // Test that it actually resets.
26  status.increment_num_conflicting_commits_by(0);
27  EXPECT_FALSE(status.TestAndClearIsDirty());
28  status.increment_num_conflicting_commits_by(1);
29  EXPECT_TRUE(status.TestAndClearIsDirty());
30
31  status.set_num_consecutive_transient_error_commits(1);
32  EXPECT_TRUE(status.TestAndClearIsDirty());
33
34  status.increment_num_consecutive_transient_error_commits_by(1);
35  EXPECT_TRUE(status.TestAndClearIsDirty());
36  status.increment_num_consecutive_transient_error_commits_by(0);
37  EXPECT_FALSE(status.TestAndClearIsDirty());
38
39  status.set_num_consecutive_errors(10);
40  EXPECT_TRUE(status.TestAndClearIsDirty());
41  status.set_num_consecutive_errors(10);
42  EXPECT_FALSE(status.TestAndClearIsDirty());  // Only dirty if value changed.
43  status.increment_num_consecutive_errors();
44  EXPECT_TRUE(status.TestAndClearIsDirty());
45  status.increment_num_consecutive_errors_by(1);
46  EXPECT_TRUE(status.TestAndClearIsDirty());
47  status.increment_num_consecutive_errors_by(0);
48  EXPECT_FALSE(status.TestAndClearIsDirty());
49
50  status.set_num_server_changes_remaining(30);
51  EXPECT_TRUE(status.TestAndClearIsDirty());
52
53  status.set_invalid_store(true);
54  EXPECT_TRUE(status.TestAndClearIsDirty());
55  status.set_invalid_store(false);
56  EXPECT_TRUE(status.TestAndClearIsDirty());
57
58  status.set_syncer_stuck(true);
59  EXPECT_TRUE(status.TestAndClearIsDirty());
60  status.set_syncer_stuck(false);
61  EXPECT_TRUE(status.TestAndClearIsDirty());
62
63  status.set_syncing(true);
64  EXPECT_TRUE(status.TestAndClearIsDirty());
65  status.set_syncing(false);
66  EXPECT_TRUE(status.TestAndClearIsDirty());
67
68  status.increment_num_successful_commits();
69  EXPECT_TRUE(status.TestAndClearIsDirty());
70  status.increment_num_successful_commits();
71  EXPECT_TRUE(status.TestAndClearIsDirty());
72
73  {
74    ScopedModelSafeGroupRestriction r(&status, GROUP_UI);
75    status.mutable_conflict_progress()->AddConflictingItemById(syncable::Id());
76  }
77  EXPECT_TRUE(status.TestAndClearIsDirty());
78
79  std::vector<int64> v;
80  v.push_back(1);
81  status.set_unsynced_handles(v);
82  EXPECT_TRUE(status.TestAndClearIsDirty());
83  std::vector<int64> v2;
84  v2.push_back(1);
85  status.set_unsynced_handles(v2);
86  EXPECT_FALSE(status.TestAndClearIsDirty());  // Test for deep comparison.
87}
88
89TEST_F(StatusControllerTest, StaysClean) {
90  StatusController status(routes_);
91  status.update_conflict_sets_built(true);
92  EXPECT_FALSE(status.TestAndClearIsDirty());
93  status.update_conflicts_resolved(true);
94  EXPECT_FALSE(status.TestAndClearIsDirty());
95
96  status.set_items_committed();
97  EXPECT_FALSE(status.TestAndClearIsDirty());
98
99  OrderedCommitSet commits(routes_);
100  commits.AddCommitItem(0, syncable::Id(), syncable::BOOKMARKS);
101  status.set_commit_set(commits);
102  EXPECT_FALSE(status.TestAndClearIsDirty());
103}
104
105// This test is useful, as simple as it sounds, due to the copy-paste prone
106// nature of status_controller.cc (we have had bugs in the past where a set_foo
107// method was actually setting |bar_| instead!).
108TEST_F(StatusControllerTest, ReadYourWrites) {
109  StatusController status(routes_);
110  status.increment_num_conflicting_commits_by(1);
111  EXPECT_EQ(1, status.error_counters().num_conflicting_commits);
112
113  status.set_num_consecutive_transient_error_commits(6);
114  EXPECT_EQ(6, status.error_counters().consecutive_transient_error_commits);
115  status.increment_num_consecutive_transient_error_commits_by(1);
116  EXPECT_EQ(7, status.error_counters().consecutive_transient_error_commits);
117  status.increment_num_consecutive_transient_error_commits_by(0);
118  EXPECT_EQ(7, status.error_counters().consecutive_transient_error_commits);
119
120  status.set_num_consecutive_errors(8);
121  EXPECT_EQ(8, status.error_counters().consecutive_errors);
122  status.increment_num_consecutive_errors();
123  EXPECT_EQ(9, status.error_counters().consecutive_errors);
124  status.increment_num_consecutive_errors_by(2);
125  EXPECT_EQ(11, status.error_counters().consecutive_errors);
126
127  status.set_num_server_changes_remaining(13);
128  EXPECT_EQ(13, status.num_server_changes_remaining());
129
130  EXPECT_FALSE(status.syncer_status().invalid_store);
131  status.set_invalid_store(true);
132  EXPECT_TRUE(status.syncer_status().invalid_store);
133
134  EXPECT_FALSE(status.syncer_status().syncer_stuck);
135  status.set_syncer_stuck(true);
136  EXPECT_TRUE(status.syncer_status().syncer_stuck);
137
138  EXPECT_FALSE(status.syncer_status().syncing);
139  status.set_syncing(true);
140  EXPECT_TRUE(status.syncer_status().syncing);
141
142  for (int i = 0; i < 14; i++)
143    status.increment_num_successful_commits();
144  EXPECT_EQ(14, status.syncer_status().num_successful_commits);
145
146  std::vector<int64> v;
147  v.push_back(16);
148  status.set_unsynced_handles(v);
149  EXPECT_EQ(16, v[0]);
150}
151
152TEST_F(StatusControllerTest, HasConflictingUpdates) {
153  StatusController status(routes_);
154  EXPECT_FALSE(status.HasConflictingUpdates());
155  {
156    ScopedModelSafeGroupRestriction r(&status, GROUP_UI);
157    EXPECT_FALSE(status.update_progress().HasConflictingUpdates());
158    status.mutable_update_progress()->AddAppliedUpdate(SUCCESS,
159        syncable::Id());
160    status.mutable_update_progress()->AddAppliedUpdate(CONFLICT,
161        syncable::Id());
162    EXPECT_TRUE(status.update_progress().HasConflictingUpdates());
163  }
164
165  EXPECT_TRUE(status.HasConflictingUpdates());
166
167  {
168    ScopedModelSafeGroupRestriction r(&status, GROUP_PASSIVE);
169    EXPECT_FALSE(status.update_progress().HasConflictingUpdates());
170  }
171}
172
173TEST_F(StatusControllerTest, CountUpdates) {
174  StatusController status(routes_);
175  EXPECT_EQ(0, status.CountUpdates());
176  ClientToServerResponse* response(status.mutable_updates_response());
177  sync_pb::SyncEntity* entity1 = response->mutable_get_updates()->add_entries();
178  sync_pb::SyncEntity* entity2 = response->mutable_get_updates()->add_entries();
179  ASSERT_TRUE(entity1 != NULL && entity2 != NULL);
180  EXPECT_EQ(2, status.CountUpdates());
181}
182
183// Test TotalNumConflictingItems
184TEST_F(StatusControllerTest, TotalNumConflictingItems) {
185  StatusController status(routes_);
186  TestIdFactory f;
187  {
188    ScopedModelSafeGroupRestriction r(&status, GROUP_UI);
189    status.mutable_conflict_progress()->AddConflictingItemById(f.NewLocalId());
190    status.mutable_conflict_progress()->AddConflictingItemById(f.NewLocalId());
191    EXPECT_EQ(2, status.conflict_progress().ConflictingItemsSize());
192  }
193  EXPECT_EQ(2, status.TotalNumConflictingItems());
194  {
195    ScopedModelSafeGroupRestriction r(&status, GROUP_DB);
196    EXPECT_EQ(0, status.conflict_progress().ConflictingItemsSize());
197    status.mutable_conflict_progress()->AddConflictingItemById(f.NewLocalId());
198    status.mutable_conflict_progress()->AddConflictingItemById(f.NewLocalId());
199    EXPECT_EQ(2, status.conflict_progress().ConflictingItemsSize());
200  }
201  EXPECT_EQ(4, status.TotalNumConflictingItems());
202}
203
204// Basic test that non group-restricted state accessors don't cause violations.
205TEST_F(StatusControllerTest, Unrestricted) {
206  StatusController status(routes_);
207  status.GetUnrestrictedUpdateProgress(
208      GROUP_UI)->SuccessfullyAppliedUpdateCount();
209  status.mutable_commit_message();
210  status.commit_response();
211  status.mutable_commit_response();
212  status.updates_response();
213  status.mutable_updates_response();
214  status.error_counters();
215  status.syncer_status();
216  status.num_server_changes_remaining();
217  status.commit_ids();
218  status.HasBookmarkCommitActivity();
219  status.download_updates_succeeded();
220  status.ServerSaysNothingMoreToDownload();
221  status.group_restriction();
222}
223
224}  // namespace sessions
225}  // namespace browser_sync
226