OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <string> | 5 #include <string> |
6 #include <vector> | 6 #include <vector> |
7 | 7 |
| 8 #include "base/auto_reset.h" |
8 #include "base/bind.h" | 9 #include "base/bind.h" |
9 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
10 #include "base/memory/scoped_vector.h" | 11 #include "base/memory/scoped_vector.h" |
11 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
12 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
13 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
14 #include "mojo/common/common_type_converters.h" | 15 #include "mojo/common/common_type_converters.h" |
15 #include "mojo/public/cpp/application/application.h" | 16 #include "mojo/public/cpp/application/application.h" |
16 #include "mojo/public/cpp/application/connect.h" | 17 #include "mojo/public/cpp/application/connect.h" |
| 18 #include "mojo/public/cpp/bindings/lib/router.h" |
17 #include "mojo/public/cpp/environment/environment.h" | 19 #include "mojo/public/cpp/environment/environment.h" |
18 #include "mojo/service_manager/service_manager.h" | 20 #include "mojo/service_manager/service_manager.h" |
19 #include "mojo/services/public/cpp/geometry/geometry_type_converters.h" | 21 #include "mojo/services/public/cpp/geometry/geometry_type_converters.h" |
20 #include "mojo/services/public/cpp/view_manager/util.h" | 22 #include "mojo/services/public/cpp/view_manager/util.h" |
21 #include "mojo/services/public/cpp/view_manager/view_manager_types.h" | 23 #include "mojo/services/public/cpp/view_manager/view_manager_types.h" |
22 #include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h" | 24 #include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h" |
23 #include "mojo/services/view_manager/test_change_tracker.h" | 25 #include "mojo/services/view_manager/test_change_tracker.h" |
24 #include "mojo/shell/shell_test_helper.h" | 26 #include "mojo/shell/shell_test_helper.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
26 #include "ui/gfx/geometry/rect.h" | 28 #include "ui/gfx/geometry/rect.h" |
27 | 29 |
28 namespace mojo { | 30 namespace mojo { |
29 namespace view_manager { | 31 namespace view_manager { |
30 namespace service { | 32 namespace service { |
31 | 33 |
32 namespace { | 34 namespace { |
33 | 35 |
| 36 // TODO(sky): clean this up. Should be moved to the single place its used. |
34 base::RunLoop* current_run_loop = NULL; | 37 base::RunLoop* current_run_loop = NULL; |
35 | 38 |
36 const char kTestServiceURL[] = "mojo:test_url"; | 39 const char kTestServiceURL[] = "mojo:test_url"; |
37 | 40 |
38 void INodesToTestNodes(const Array<INodePtr>& data, | 41 void INodesToTestNodes(const Array<INodePtr>& data, |
39 std::vector<TestNode>* test_nodes) { | 42 std::vector<TestNode>* test_nodes) { |
40 for (size_t i = 0; i < data.size(); ++i) { | 43 for (size_t i = 0; i < data.size(); ++i) { |
41 TestNode node; | 44 TestNode node; |
42 node.parent_id = data[i]->parent_id; | 45 node.parent_id = data[i]->parent_id; |
43 node.node_id = data[i]->node_id; | 46 node.node_id = data[i]->node_id; |
44 node.view_id = data[i]->view_id; | 47 node.view_id = data[i]->view_id; |
45 test_nodes->push_back(node); | 48 test_nodes->push_back(node); |
46 } | 49 } |
47 } | 50 } |
48 | 51 |
49 // BackgroundConnection is used when a child ViewManagerConnection is created by | 52 // ViewManagerProxy is a proxy to an IViewManager. It handles invoking |
50 // way of Connect(). BackgroundConnection is created on a background thread (the | 53 // IViewManager functions on the right thread in a synchronous manner (each |
51 // thread where the shell lives). All public methods are to be invoked on the | 54 // IViewManager cover function blocks until the response from the IViewManager |
52 // main thread. They wait for a result (by spinning a nested message loop), | 55 // is returned). In addition it tracks the set of IViewManagerClient messages |
53 // calling through to background thread, then the underlying IViewManager* and | 56 // received by way of a vector of Changes. Use DoRunLoopUntilChangesCount() to |
54 // respond back to the calling thread to return control to the test. | 57 // wait for a certain number of messages to be received. |
55 class BackgroundConnection : public TestChangeTracker::Delegate { | 58 class ViewManagerProxy : public TestChangeTracker::Delegate { |
56 public: | 59 public: |
57 BackgroundConnection(TestChangeTracker* tracker, | 60 ViewManagerProxy(TestChangeTracker* tracker, base::MessageLoop* loop) |
58 base::MessageLoop* loop) | |
59 : tracker_(tracker), | 61 : tracker_(tracker), |
60 main_loop_(loop), | 62 main_loop_(loop), |
61 background_loop_(base::MessageLoop::current()), | 63 background_loop_(base::MessageLoop::current()), |
62 view_manager_(NULL), | 64 view_manager_(NULL), |
63 quit_count_(0) { | 65 quit_count_(0), |
| 66 router_(NULL) { |
64 main_loop_->PostTask(FROM_HERE, | 67 main_loop_->PostTask(FROM_HERE, |
65 base::Bind(&BackgroundConnection::SetInstance, this)); | 68 base::Bind(&ViewManagerProxy::SetInstance, this)); |
66 } | 69 } |
67 | 70 |
68 virtual ~BackgroundConnection() { | 71 virtual ~ViewManagerProxy() { |
69 instance_ = NULL; | |
70 } | |
71 | |
72 void set_view_manager(IViewManager* view_manager) { | |
73 view_manager_ = view_manager; | |
74 } | 72 } |
75 | 73 |
76 // Runs a message loop until the single instance has been created. | 74 // Runs a message loop until the single instance has been created. |
77 static BackgroundConnection* WaitForInstance() { | 75 static ViewManagerProxy* WaitForInstance() { |
78 if (!instance_) | 76 if (!instance_) |
79 RunMainLoop(); | 77 RunMainLoop(); |
80 return instance_; | 78 ViewManagerProxy* instance = instance_; |
| 79 instance_ = NULL; |
| 80 return instance; |
81 } | 81 } |
82 | 82 |
83 // Runs the main loop until |count| changes have been received. | 83 // Runs the main loop until |count| changes have been received. |
84 std::vector<Change> DoRunLoopUntilChangesCount(size_t count) { | 84 std::vector<Change> DoRunLoopUntilChangesCount(size_t count) { |
85 background_loop_->PostTask(FROM_HERE, | 85 background_loop_->PostTask(FROM_HERE, |
86 base::Bind(&BackgroundConnection::SetQuitCount, | 86 base::Bind(&ViewManagerProxy::SetQuitCount, |
87 base::Unretained(this), count)); | 87 base::Unretained(this), count)); |
88 // Run the current message loop. When the quit count is reached we'll quit. | 88 // Run the current message loop. When |count| Changes have been received, |
| 89 // we'll quit. |
89 RunMainLoop(); | 90 RunMainLoop(); |
90 return changes_; | 91 return changes_; |
91 } | 92 } |
92 | 93 |
| 94 const std::vector<Change>& changes() const { return changes_; } |
| 95 |
| 96 // Destroys the connection, blocking until done. |
| 97 void Destroy() { |
| 98 background_loop_->PostTask( |
| 99 FROM_HERE, |
| 100 base::Bind(&ViewManagerProxy::DestroyOnBackgroundThread, |
| 101 base::Unretained(this))); |
| 102 RunMainLoop(); |
| 103 } |
| 104 |
93 // The following functions mirror that of IViewManager. They bounce the | 105 // The following functions mirror that of IViewManager. They bounce the |
94 // function to the right thread and return the result. | 106 // function to the right thread and return the result. |
95 bool CreateNode(TransportNodeId node_id) { | 107 bool CreateNode(TransportNodeId node_id) { |
| 108 changes_.clear(); |
96 bool result = false; | 109 bool result = false; |
97 background_loop_->PostTask( | 110 background_loop_->PostTask( |
98 FROM_HERE, | 111 FROM_HERE, |
99 base::Bind(&BackgroundConnection::CreateNodeOnBackgroundThread, | 112 base::Bind(&ViewManagerProxy::CreateNodeOnBackgroundThread, |
100 base::Unretained(this), node_id, &result)); | 113 base::Unretained(this), node_id, &result)); |
101 RunMainLoop(); | 114 RunMainLoop(); |
102 return result; | 115 return result; |
103 } | 116 } |
104 bool AddNode(TransportNodeId parent, | 117 bool AddNode(TransportNodeId parent, |
105 TransportNodeId child, | 118 TransportNodeId child, |
106 TransportChangeId server_change_id) { | 119 TransportChangeId server_change_id) { |
| 120 changes_.clear(); |
107 bool result = false; | 121 bool result = false; |
108 background_loop_->PostTask( | 122 background_loop_->PostTask( |
109 FROM_HERE, | 123 FROM_HERE, |
110 base::Bind(&BackgroundConnection::AddNodeOnBackgroundThread, | 124 base::Bind(&ViewManagerProxy::AddNodeOnBackgroundThread, |
111 base::Unretained(this), parent, child, server_change_id, | 125 base::Unretained(this), parent, child, server_change_id, |
112 &result)); | 126 &result)); |
113 RunMainLoop(); | 127 RunMainLoop(); |
114 return result; | 128 return result; |
115 } | 129 } |
116 bool RemoveNodeFromParent(TransportNodeId node_id, | 130 bool RemoveNodeFromParent(TransportNodeId node_id, |
117 TransportChangeId server_change_id) { | 131 TransportChangeId server_change_id) { |
| 132 changes_.clear(); |
118 bool result = false; | 133 bool result = false; |
119 background_loop_->PostTask( | 134 background_loop_->PostTask( |
120 FROM_HERE, | 135 FROM_HERE, |
121 base::Bind( | 136 base::Bind(&ViewManagerProxy::RemoveNodeFromParentOnBackgroundThread, |
122 &BackgroundConnection::RemoveNodeFromParentOnBackgroundThread, | 137 base::Unretained(this), node_id, server_change_id, &result)); |
123 base::Unretained(this), node_id, server_change_id, &result)); | |
124 RunMainLoop(); | 138 RunMainLoop(); |
125 return result; | 139 return result; |
126 } | 140 } |
127 bool SetView(TransportNodeId node_id, TransportViewId view_id) { | 141 bool SetView(TransportNodeId node_id, TransportViewId view_id) { |
| 142 changes_.clear(); |
128 bool result = false; | 143 bool result = false; |
129 background_loop_->PostTask( | 144 background_loop_->PostTask( |
130 FROM_HERE, | 145 FROM_HERE, |
131 base::Bind( | 146 base::Bind(&ViewManagerProxy::SetViewOnBackgroundThread, |
132 &BackgroundConnection::SetViewOnBackgroundThread, | 147 base::Unretained(this), node_id, view_id, &result)); |
133 base::Unretained(this), node_id, view_id, &result)); | |
134 RunMainLoop(); | 148 RunMainLoop(); |
135 return result; | 149 return result; |
136 } | 150 } |
137 bool CreateView(TransportViewId view_id) { | 151 bool CreateView(TransportViewId view_id) { |
| 152 changes_.clear(); |
138 bool result = false; | 153 bool result = false; |
139 background_loop_->PostTask( | 154 background_loop_->PostTask( |
140 FROM_HERE, | 155 FROM_HERE, |
141 base::Bind( | 156 base::Bind(&ViewManagerProxy::CreateViewOnBackgroundThread, |
142 &BackgroundConnection::CreateViewOnBackgroundThread, | 157 base::Unretained(this), view_id, &result)); |
143 base::Unretained(this), view_id, &result)); | |
144 RunMainLoop(); | 158 RunMainLoop(); |
145 return result; | 159 return result; |
146 } | 160 } |
147 void GetNodeTree(TransportNodeId node_id, std::vector<TestNode>* nodes) { | 161 void GetNodeTree(TransportNodeId node_id, std::vector<TestNode>* nodes) { |
| 162 changes_.clear(); |
148 background_loop_->PostTask( | 163 background_loop_->PostTask( |
149 FROM_HERE, | 164 FROM_HERE, |
150 base::Bind( | 165 base::Bind(&ViewManagerProxy::GetNodeTreeOnBackgroundThread, |
151 &BackgroundConnection::GetNodeTreeOnBackgroundThread, | 166 base::Unretained(this), node_id, nodes)); |
152 base::Unretained(this), node_id, nodes)); | |
153 RunMainLoop(); | 167 RunMainLoop(); |
154 } | 168 } |
| 169 bool Connect(const std::vector<TransportNodeId>& nodes) { |
| 170 changes_.clear(); |
| 171 base::AutoReset<bool> auto_reset(&in_connect_, true); |
| 172 bool result = false; |
| 173 background_loop_->PostTask( |
| 174 FROM_HERE, |
| 175 base::Bind(&ViewManagerProxy::ConnectOnBackgroundThread, |
| 176 base::Unretained(this), nodes, &result)); |
| 177 RunMainLoop(); |
| 178 return result; |
| 179 } |
| 180 bool DeleteNode(TransportNodeId node_id) { |
| 181 changes_.clear(); |
| 182 bool result = false; |
| 183 background_loop_->PostTask( |
| 184 FROM_HERE, |
| 185 base::Bind(&ViewManagerProxy::DeleteNodeOnBackgroundThread, |
| 186 base::Unretained(this), node_id, &result)); |
| 187 RunMainLoop(); |
| 188 return result; |
| 189 } |
| 190 bool DeleteView(TransportViewId node_id) { |
| 191 changes_.clear(); |
| 192 bool result = false; |
| 193 background_loop_->PostTask( |
| 194 FROM_HERE, |
| 195 base::Bind(&ViewManagerProxy::DeleteViewOnBackgroundThread, |
| 196 base::Unretained(this), node_id, &result)); |
| 197 RunMainLoop(); |
| 198 return result; |
| 199 } |
| 200 bool SetNodeBounds(TransportNodeId node_id, const gfx::Rect& rect) { |
| 201 bool result = false; |
| 202 background_loop_->PostTask( |
| 203 FROM_HERE, |
| 204 base::Bind(&ViewManagerProxy::SetNodeBoundsOnBackgroundThread, |
| 205 base::Unretained(this), node_id, rect, &result)); |
| 206 RunMainLoop(); |
| 207 return result; |
| 208 } |
155 | 209 |
156 private: | 210 private: |
| 211 friend class TestViewManagerClientConnection; |
| 212 |
| 213 void set_router(mojo::internal::Router* router) { router_ = router; } |
| 214 |
| 215 void set_view_manager(IViewManager* view_manager) { |
| 216 view_manager_ = view_manager; |
| 217 } |
| 218 |
| 219 void DestroyOnBackgroundThread() { |
| 220 router_->CloseMessagePipe(); |
| 221 main_loop_->PostTask( |
| 222 FROM_HERE, |
| 223 base::Bind(&ViewManagerProxy::QuitOnMainThread, |
| 224 base::Unretained(this))); |
| 225 } |
| 226 |
157 void SetQuitCount(size_t count) { | 227 void SetQuitCount(size_t count) { |
158 DCHECK_EQ(background_loop_, base::MessageLoop::current()); | 228 DCHECK_EQ(background_loop_, base::MessageLoop::current()); |
159 if (tracker_->changes()->size() >= count) { | 229 if (tracker_->changes()->size() >= count) { |
160 QuitCountReached(); | 230 QuitCountReached(); |
161 return; | 231 return; |
162 } | 232 } |
163 quit_count_ = count - tracker_->changes()->size(); | 233 quit_count_ = count - tracker_->changes()->size(); |
164 } | 234 } |
165 | 235 |
166 static void RunMainLoop() { | 236 static void RunMainLoop() { |
167 DCHECK(!main_run_loop_); | 237 DCHECK(!main_run_loop_); |
168 main_run_loop_ = new base::RunLoop; | 238 main_run_loop_ = new base::RunLoop; |
169 main_run_loop_->Run(); | 239 main_run_loop_->Run(); |
170 delete main_run_loop_; | 240 delete main_run_loop_; |
171 main_run_loop_ = NULL; | 241 main_run_loop_ = NULL; |
172 } | 242 } |
173 | 243 |
174 void QuitCountReached() { | 244 void QuitCountReached() { |
175 std::vector<Change> changes; | 245 std::vector<Change> changes; |
176 tracker_->changes()->swap(changes); | 246 tracker_->changes()->swap(changes); |
177 main_loop_->PostTask( | 247 main_loop_->PostTask( |
178 FROM_HERE, | 248 FROM_HERE, |
179 base::Bind(&BackgroundConnection::QuitCountReachedOnMain, | 249 base::Bind(&ViewManagerProxy::QuitCountReachedOnMain, |
180 base::Unretained(this), changes)); | 250 base::Unretained(this), changes)); |
181 } | 251 } |
182 | 252 |
183 void QuitCountReachedOnMain(const std::vector<Change>& changes) { | 253 void QuitCountReachedOnMain(const std::vector<Change>& changes) { |
184 changes_ = changes; | 254 changes_ = changes; |
185 DCHECK(main_run_loop_); | 255 DCHECK(main_run_loop_); |
186 main_run_loop_->Quit(); | 256 main_run_loop_->Quit(); |
187 } | 257 } |
188 | 258 |
189 static void SetInstance(BackgroundConnection* instance) { | 259 static void SetInstance(ViewManagerProxy* instance) { |
190 DCHECK(!instance_); | 260 DCHECK(!instance_); |
191 instance_ = instance; | 261 instance_ = instance; |
192 if (main_run_loop_) | 262 // Connect() runs its own run loop that is quit when the result is |
| 263 // received. Connect() also results in a new instance. If we quit here while |
| 264 // waiting for a Connect() we would prematurely return before we got the |
| 265 // result from Connect(). |
| 266 if (!in_connect_ && main_run_loop_) |
193 main_run_loop_->Quit(); | 267 main_run_loop_->Quit(); |
194 } | 268 } |
195 | 269 |
196 // Callbacks from the various IViewManager functions. | 270 // Callbacks from the various IViewManager functions. |
197 void GotResultOnBackgroundThread(bool* result_cache, bool result) { | 271 void GotResultOnBackgroundThread(bool* result_cache, bool result) { |
198 *result_cache = result; | 272 *result_cache = result; |
199 main_loop_->PostTask( | 273 main_loop_->PostTask( |
200 FROM_HERE, | 274 FROM_HERE, |
201 base::Bind(&BackgroundConnection::QuitOnMainThread, | 275 base::Bind(&ViewManagerProxy::QuitOnMainThread, |
202 base::Unretained(this))); | 276 base::Unretained(this))); |
203 } | 277 } |
204 | 278 |
205 void GotNodeTreeOnBackgroundThread(std::vector<TestNode>* nodes, | 279 void GotNodeTreeOnBackgroundThread(std::vector<TestNode>* nodes, |
206 Array<INodePtr> results) { | 280 Array<INodePtr> results) { |
207 INodesToTestNodes(results, nodes); | 281 INodesToTestNodes(results, nodes); |
208 main_loop_->PostTask( | 282 main_loop_->PostTask( |
209 FROM_HERE, | 283 FROM_HERE, |
210 base::Bind(&BackgroundConnection::QuitOnMainThread, | 284 base::Bind(&ViewManagerProxy::QuitOnMainThread, |
211 base::Unretained(this))); | 285 base::Unretained(this))); |
212 } | 286 } |
213 | 287 |
214 void QuitOnMainThread() { | 288 void QuitOnMainThread() { |
215 DCHECK(main_run_loop_); | 289 DCHECK(main_run_loop_); |
216 main_run_loop_->Quit(); | 290 main_run_loop_->Quit(); |
217 } | 291 } |
218 | 292 |
219 // The following functions correspond to the IViewManager functions. These run | 293 // The following functions correspond to the IViewManager functions. These run |
220 // on the background thread. | 294 // on the background thread. |
221 void CreateNodeOnBackgroundThread(TransportNodeId node_id, bool* result) { | 295 void CreateNodeOnBackgroundThread(TransportNodeId node_id, bool* result) { |
222 view_manager_->CreateNode( | 296 view_manager_->CreateNode( |
223 node_id, | 297 node_id, |
224 base::Bind(&BackgroundConnection::GotResultOnBackgroundThread, | 298 base::Bind(&ViewManagerProxy::GotResultOnBackgroundThread, |
225 base::Unretained(this), result)); | 299 base::Unretained(this), result)); |
226 } | 300 } |
227 void AddNodeOnBackgroundThread(TransportNodeId parent, | 301 void AddNodeOnBackgroundThread(TransportNodeId parent, |
228 TransportNodeId child, | 302 TransportNodeId child, |
229 TransportChangeId server_change_id, | 303 TransportChangeId server_change_id, |
230 bool* result) { | 304 bool* result) { |
231 view_manager_->AddNode( | 305 view_manager_->AddNode( |
232 parent, child, server_change_id, | 306 parent, child, server_change_id, |
233 base::Bind(&BackgroundConnection::GotResultOnBackgroundThread, | 307 base::Bind(&ViewManagerProxy::GotResultOnBackgroundThread, |
234 base::Unretained(this), result)); | 308 base::Unretained(this), result)); |
235 } | 309 } |
236 void RemoveNodeFromParentOnBackgroundThread( | 310 void RemoveNodeFromParentOnBackgroundThread( |
237 TransportNodeId node_id, | 311 TransportNodeId node_id, |
238 TransportChangeId server_change_id, | 312 TransportChangeId server_change_id, |
239 bool* result) { | 313 bool* result) { |
240 view_manager_->RemoveNodeFromParent(node_id, server_change_id, | 314 view_manager_->RemoveNodeFromParent(node_id, server_change_id, |
241 base::Bind(&BackgroundConnection::GotResultOnBackgroundThread, | 315 base::Bind(&ViewManagerProxy::GotResultOnBackgroundThread, |
242 base::Unretained(this), result)); | 316 base::Unretained(this), result)); |
243 } | 317 } |
244 void SetViewOnBackgroundThread(TransportNodeId node_id, | 318 void SetViewOnBackgroundThread(TransportNodeId node_id, |
245 TransportViewId view_id, | 319 TransportViewId view_id, |
246 bool* result) { | 320 bool* result) { |
247 view_manager_->SetView(node_id, view_id, | 321 view_manager_->SetView(node_id, view_id, |
248 base::Bind(&BackgroundConnection::GotResultOnBackgroundThread, | 322 base::Bind(&ViewManagerProxy::GotResultOnBackgroundThread, |
249 base::Unretained(this), result)); | 323 base::Unretained(this), result)); |
250 } | 324 } |
251 void CreateViewOnBackgroundThread(TransportViewId view_id, bool* result) { | 325 void CreateViewOnBackgroundThread(TransportViewId view_id, bool* result) { |
252 view_manager_->CreateView(view_id, | 326 view_manager_->CreateView(view_id, |
253 base::Bind(&BackgroundConnection::GotResultOnBackgroundThread, | 327 base::Bind(&ViewManagerProxy::GotResultOnBackgroundThread, |
254 base::Unretained(this), result)); | 328 base::Unretained(this), result)); |
255 } | 329 } |
256 void GetNodeTreeOnBackgroundThread(TransportNodeId node_id, | 330 void GetNodeTreeOnBackgroundThread(TransportNodeId node_id, |
257 std::vector<TestNode>* nodes) { | 331 std::vector<TestNode>* nodes) { |
258 view_manager_->GetNodeTree(node_id, | 332 view_manager_->GetNodeTree(node_id, |
259 base::Bind(&BackgroundConnection::GotNodeTreeOnBackgroundThread, | 333 base::Bind(&ViewManagerProxy::GotNodeTreeOnBackgroundThread, |
260 base::Unretained(this), nodes)); | 334 base::Unretained(this), nodes)); |
261 } | 335 } |
| 336 void ConnectOnBackgroundThread(const std::vector<TransportNodeId>& ids, |
| 337 bool* result) { |
| 338 view_manager_->Connect(kTestServiceURL, |
| 339 Array<TransportNodeId>::From(ids), |
| 340 base::Bind(&ViewManagerProxy::GotResultOnBackgroundThread, |
| 341 base::Unretained(this), result)); |
| 342 } |
| 343 void DeleteNodeOnBackgroundThread(TransportNodeId node_id, bool* result) { |
| 344 view_manager_->DeleteNode(node_id, |
| 345 base::Bind(&ViewManagerProxy::GotResultOnBackgroundThread, |
| 346 base::Unretained(this), result)); |
| 347 } |
| 348 void DeleteViewOnBackgroundThread(TransportViewId view_id, bool* result) { |
| 349 view_manager_->DeleteView(view_id, |
| 350 base::Bind(&ViewManagerProxy::GotResultOnBackgroundThread, |
| 351 base::Unretained(this), result)); |
| 352 } |
| 353 void SetNodeBoundsOnBackgroundThread(TransportNodeId node_id, |
| 354 const gfx::Rect& bounds, |
| 355 bool* result) { |
| 356 view_manager_->SetNodeBounds(node_id, Rect::From(bounds), |
| 357 base::Bind(&ViewManagerProxy::GotResultOnBackgroundThread, |
| 358 base::Unretained(this), result)); |
| 359 } |
262 | 360 |
263 // TestChangeTracker::Delegate: | 361 // TestChangeTracker::Delegate: |
264 virtual void OnChangeAdded() OVERRIDE { | 362 virtual void OnChangeAdded() OVERRIDE { |
265 if (quit_count_ > 0 && --quit_count_ == 0) | 363 if (quit_count_ > 0 && --quit_count_ == 0) |
266 QuitCountReached(); | 364 QuitCountReached(); |
267 } | 365 } |
268 | 366 |
269 static BackgroundConnection* instance_; | 367 static ViewManagerProxy* instance_; |
270 static base::RunLoop* main_run_loop_; | 368 static base::RunLoop* main_run_loop_; |
| 369 static bool in_connect_; |
271 | 370 |
272 TestChangeTracker* tracker_; | 371 TestChangeTracker* tracker_; |
273 | 372 |
274 // MessageLoop of the test. | 373 // MessageLoop of the test. |
275 base::MessageLoop* main_loop_; | 374 base::MessageLoop* main_loop_; |
276 | 375 |
277 // MessageLoop BackgroundConnection lives on. | 376 // MessageLoop ViewManagerProxy lives on. |
278 base::MessageLoop* background_loop_; | 377 base::MessageLoop* background_loop_; |
279 | 378 |
280 IViewManager* view_manager_; | 379 IViewManager* view_manager_; |
281 | 380 |
282 // Number of changes we're waiting on until we quit the current loop. | 381 // Number of changes we're waiting on until we quit the current loop. |
283 size_t quit_count_; | 382 size_t quit_count_; |
284 | 383 |
285 std::vector<Change> changes_; | 384 std::vector<Change> changes_; |
286 | 385 |
287 DISALLOW_COPY_AND_ASSIGN(BackgroundConnection); | 386 mojo::internal::Router* router_; |
| 387 |
| 388 DISALLOW_COPY_AND_ASSIGN(ViewManagerProxy); |
288 }; | 389 }; |
289 | 390 |
290 // static | 391 // static |
291 BackgroundConnection* BackgroundConnection::instance_ = NULL; | 392 ViewManagerProxy* ViewManagerProxy::instance_ = NULL; |
292 | 393 |
293 // static | 394 // static |
294 base::RunLoop* BackgroundConnection::main_run_loop_ = NULL; | 395 base::RunLoop* ViewManagerProxy::main_run_loop_ = NULL; |
| 396 |
| 397 // static |
| 398 bool ViewManagerProxy::in_connect_ = false; |
295 | 399 |
296 class TestViewManagerClientConnection | 400 class TestViewManagerClientConnection |
297 : public InterfaceImpl<IViewManagerClient> { | 401 : public InterfaceImpl<IViewManagerClient> { |
298 public: | 402 public: |
299 explicit TestViewManagerClientConnection(base::MessageLoop* loop) | 403 explicit TestViewManagerClientConnection(base::MessageLoop* loop) |
300 : connection_(&tracker_, loop) { | 404 : connection_(&tracker_, loop) { |
301 tracker_.set_delegate(&connection_); | 405 tracker_.set_delegate(&connection_); |
302 } | 406 } |
303 | 407 |
304 // InterfaceImp: | 408 // InterfaceImp: |
305 virtual void OnConnectionEstablished() OVERRIDE { | 409 virtual void OnConnectionEstablished() OVERRIDE { |
| 410 connection_.set_router(internal_state()->router()); |
306 connection_.set_view_manager(client()); | 411 connection_.set_view_manager(client()); |
307 } | 412 } |
308 | 413 |
309 // IViewMangerClient: | 414 // IViewMangerClient: |
310 virtual void OnViewManagerConnectionEstablished( | 415 virtual void OnViewManagerConnectionEstablished( |
311 TransportConnectionId connection_id, | 416 TransportConnectionId connection_id, |
312 TransportChangeId next_server_change_id, | 417 TransportChangeId next_server_change_id, |
313 Array<INodePtr> nodes) OVERRIDE { | 418 Array<INodePtr> nodes) OVERRIDE { |
314 tracker_.OnViewManagerConnectionEstablished( | 419 tracker_.OnViewManagerConnectionEstablished( |
315 connection_id, next_server_change_id, nodes.Pass()); | 420 connection_id, next_server_change_id, nodes.Pass()); |
316 } | 421 } |
317 virtual void OnServerChangeIdAdvanced( | 422 virtual void OnServerChangeIdAdvanced( |
318 TransportChangeId next_server_change_id) OVERRIDE { | 423 TransportChangeId next_server_change_id) OVERRIDE { |
319 tracker_.OnServerChangeIdAdvanced(next_server_change_id); | 424 tracker_.OnServerChangeIdAdvanced(next_server_change_id); |
320 } | 425 } |
321 virtual void OnNodeBoundsChanged(TransportNodeId node_id, | 426 virtual void OnNodeBoundsChanged(TransportNodeId node_id, |
322 RectPtr old_bounds, | 427 RectPtr old_bounds, |
323 RectPtr new_bounds) OVERRIDE { | 428 RectPtr new_bounds) OVERRIDE { |
324 tracker_.OnNodeBoundsChanged(node_id, old_bounds.Pass(), new_bounds.Pass()); | 429 tracker_.OnNodeBoundsChanged(node_id, old_bounds.Pass(), new_bounds.Pass()); |
325 } | 430 } |
326 virtual void OnNodeHierarchyChanged( | 431 virtual void OnNodeHierarchyChanged( |
327 TransportNodeId node, | 432 TransportNodeId node, |
328 TransportNodeId new_parent, | 433 TransportNodeId new_parent, |
329 TransportNodeId old_parent, | 434 TransportNodeId old_parent, |
330 TransportChangeId server_change_id, | 435 TransportChangeId server_change_id, |
331 Array<INodePtr> nodes) OVERRIDE { | 436 Array<INodePtr> nodes) OVERRIDE { |
332 tracker_.OnNodeHierarchyChanged(node, new_parent, old_parent, | 437 tracker_.OnNodeHierarchyChanged(node, new_parent, old_parent, |
333 server_change_id, nodes.Pass()); | 438 server_change_id, nodes.Pass()); |
334 } | 439 } |
335 virtual void OnNodeDeleted(TransportNodeId node, | 440 virtual void OnNodeDeleted(TransportNodeId node, |
336 TransportChangeId server_change_id) OVERRIDE { | 441 TransportChangeId server_change_id) OVERRIDE { |
337 tracker_.OnNodeDeleted(node, server_change_id); | 442 tracker_.OnNodeDeleted(node, server_change_id); |
338 } | 443 } |
339 virtual void OnViewDeleted(TransportViewId view) OVERRIDE { | 444 virtual void OnViewDeleted(TransportViewId view) OVERRIDE { |
340 tracker_.OnViewDeleted(view); | 445 tracker_.OnViewDeleted(view); |
341 } | 446 } |
342 virtual void OnNodeViewReplaced(TransportNodeId node, | 447 virtual void OnNodeViewReplaced(TransportNodeId node, |
343 TransportViewId new_view_id, | 448 TransportViewId new_view_id, |
344 TransportViewId old_view_id) OVERRIDE { | 449 TransportViewId old_view_id) OVERRIDE { |
345 tracker_.OnNodeViewReplaced(node, new_view_id, old_view_id); | 450 tracker_.OnNodeViewReplaced(node, new_view_id, old_view_id); |
346 } | 451 } |
347 | 452 |
348 private: | 453 private: |
349 TestChangeTracker tracker_; | 454 TestChangeTracker tracker_; |
350 BackgroundConnection connection_; | 455 ViewManagerProxy connection_; |
351 | 456 |
352 DISALLOW_COPY_AND_ASSIGN(TestViewManagerClientConnection); | 457 DISALLOW_COPY_AND_ASSIGN(TestViewManagerClientConnection); |
353 }; | 458 }; |
354 | 459 |
355 // Used with IViewManager::Connect(). Creates a TestViewManagerClientConnection, | 460 // Used with IViewManager::Connect(). Creates a TestViewManagerClientConnection, |
356 // which creates and owns the BackgroundConnection. | 461 // which creates and owns the ViewManagerProxy. |
357 class ConnectServiceLoader : public ServiceLoader { | 462 class ConnectServiceLoader : public ServiceLoader { |
358 public: | 463 public: |
359 ConnectServiceLoader() : initial_loop_(base::MessageLoop::current()) { | 464 ConnectServiceLoader() : initial_loop_(base::MessageLoop::current()) { |
360 } | 465 } |
361 virtual ~ConnectServiceLoader() { | 466 virtual ~ConnectServiceLoader() { |
362 } | 467 } |
363 | 468 |
364 // ServiceLoader: | 469 // ServiceLoader: |
365 virtual void LoadService(ServiceManager* manager, | 470 virtual void LoadService(ServiceManager* manager, |
366 const GURL& url, | 471 const GURL& url, |
(...skipping 24 matching lines...) Expand all Loading... |
391 current_run_loop = NULL; | 496 current_run_loop = NULL; |
392 } | 497 } |
393 | 498 |
394 // Boolean callback. Sets |result_cache| to the value of |result| and quits | 499 // Boolean callback. Sets |result_cache| to the value of |result| and quits |
395 // the run loop. | 500 // the run loop. |
396 void BooleanCallback(bool* result_cache, bool result) { | 501 void BooleanCallback(bool* result_cache, bool result) { |
397 *result_cache = result; | 502 *result_cache = result; |
398 current_run_loop->Quit(); | 503 current_run_loop->Quit(); |
399 } | 504 } |
400 | 505 |
401 // Callback that results in a vector of INodes. The INodes are converted to | |
402 // TestNodes. | |
403 void INodesCallback(std::vector<TestNode>* test_nodes, | |
404 Array<INodePtr> data) { | |
405 INodesToTestNodes(data, test_nodes); | |
406 current_run_loop->Quit(); | |
407 } | |
408 | |
409 // Creates an id used for transport from the specified parameters. | 506 // Creates an id used for transport from the specified parameters. |
410 TransportNodeId CreateNodeId(TransportConnectionId connection_id, | 507 TransportNodeId BuildNodeId(TransportConnectionId connection_id, |
411 TransportConnectionSpecificNodeId node_id) { | 508 TransportConnectionSpecificNodeId node_id) { |
412 return (connection_id << 16) | node_id; | 509 return (connection_id << 16) | node_id; |
413 } | 510 } |
414 | 511 |
415 // Creates an id used for transport from the specified parameters. | 512 // Creates an id used for transport from the specified parameters. |
416 TransportViewId CreateViewId(TransportConnectionId connection_id, | 513 TransportViewId BuildViewId(TransportConnectionId connection_id, |
417 TransportConnectionSpecificViewId view_id) { | 514 TransportConnectionSpecificViewId view_id) { |
418 return (connection_id << 16) | view_id; | 515 return (connection_id << 16) | view_id; |
419 } | 516 } |
420 | 517 |
421 // Creates a node with the specified id. Returns true on success. Blocks until | 518 // Resposible for establishing connection to the viewmanager. Blocks until get |
422 // we get back result from server. | 519 // back result. |
423 bool CreateNode(IViewManager* view_manager, | 520 bool ViewManagerInitConnect(IViewManagerInit* view_manager_init, |
424 TransportConnectionId connection_id, | 521 const std::string& url) { |
425 TransportConnectionSpecificNodeId node_id) { | |
426 bool result = false; | 522 bool result = false; |
427 view_manager->CreateNode(CreateNodeId(connection_id, node_id), | 523 view_manager_init->Connect(url, base::Bind(&BooleanCallback, &result)); |
428 base::Bind(&BooleanCallback, &result)); | |
429 DoRunLoop(); | 524 DoRunLoop(); |
430 return result; | 525 return result; |
431 } | 526 } |
432 | |
433 // Deletes a view, blocking until done. | |
434 bool DeleteNode(IViewManager* view_manager, TransportNodeId node_id) { | |
435 bool result = false; | |
436 view_manager->DeleteNode(node_id, base::Bind(&BooleanCallback, &result)); | |
437 DoRunLoop(); | |
438 return result; | |
439 } | |
440 | |
441 // Deletes a node, blocking until done. | |
442 bool DeleteView(IViewManager* view_manager, TransportViewId view_id) { | |
443 bool result = false; | |
444 view_manager->DeleteView(view_id, base::Bind(&BooleanCallback, &result)); | |
445 DoRunLoop(); | |
446 return result; | |
447 } | |
448 | |
449 bool SetNodeBounds(IViewManager* view_manager, | |
450 TransportNodeId node_id, | |
451 const gfx::Rect& bounds) { | |
452 bool result = false; | |
453 view_manager->SetNodeBounds(node_id, Rect::From(bounds), | |
454 base::Bind(&BooleanCallback, &result)); | |
455 DoRunLoop(); | |
456 return result; | |
457 } | |
458 | |
459 // Adds a node, blocking until done. | |
460 bool AddNode(IViewManager* view_manager, | |
461 TransportNodeId parent, | |
462 TransportNodeId child, | |
463 TransportChangeId server_change_id) { | |
464 bool result = false; | |
465 view_manager->AddNode(parent, child, server_change_id, | |
466 base::Bind(&BooleanCallback, &result)); | |
467 DoRunLoop(); | |
468 return result; | |
469 } | |
470 | |
471 // Removes a node, blocking until done. | |
472 bool RemoveNodeFromParent(IViewManager* view_manager, | |
473 TransportNodeId node_id, | |
474 TransportChangeId server_change_id) { | |
475 bool result = false; | |
476 view_manager->RemoveNodeFromParent( | |
477 node_id, server_change_id, base::Bind(&BooleanCallback, &result)); | |
478 DoRunLoop(); | |
479 return result; | |
480 } | |
481 | |
482 void GetNodeTree(IViewManager* view_manager, | |
483 TransportNodeId node_id, | |
484 std::vector<TestNode>* nodes) { | |
485 view_manager->GetNodeTree(node_id, base::Bind(&INodesCallback, nodes)); | |
486 DoRunLoop(); | |
487 } | |
488 | |
489 // Creates a view with the specified id. Returns true on success. Blocks until | |
490 // we get back result from server. | |
491 bool CreateView(IViewManager* view_manager, | |
492 TransportConnectionId connection_id, | |
493 TransportConnectionSpecificViewId id) { | |
494 bool result = false; | |
495 view_manager->CreateView(CreateViewId(connection_id, id), | |
496 base::Bind(&BooleanCallback, &result)); | |
497 DoRunLoop(); | |
498 return result; | |
499 } | |
500 | |
501 // Sets a view on the specified node. Returns true on success. Blocks until we | |
502 // get back result from server. | |
503 bool SetView(IViewManager* view_manager, | |
504 TransportNodeId node_id, | |
505 TransportViewId view_id) { | |
506 bool result = false; | |
507 view_manager->SetView(node_id, view_id, | |
508 base::Bind(&BooleanCallback, &result)); | |
509 DoRunLoop(); | |
510 return result; | |
511 } | |
512 | |
513 bool Connect(IViewManager* view_manager, | |
514 const std::string& url, | |
515 TransportNodeId id, | |
516 TransportNodeId id2) { | |
517 bool result = false; | |
518 std::vector<TransportNodeId> node_ids; | |
519 node_ids.push_back(id); | |
520 if (id2 != 0) | |
521 node_ids.push_back(id2); | |
522 view_manager->Connect(url, Array<uint32_t>::From(node_ids), | |
523 base::Bind(&BooleanCallback, &result)); | |
524 DoRunLoop(); | |
525 return result; | |
526 } | |
527 | 527 |
528 } // namespace | 528 } // namespace |
529 | 529 |
530 typedef std::vector<std::string> Changes; | 530 typedef std::vector<std::string> Changes; |
531 | 531 |
532 class MainLoopTrackerDelegate : public TestChangeTracker::Delegate { | |
533 public: | |
534 explicit MainLoopTrackerDelegate(TestChangeTracker* tracker) | |
535 : tracker_(tracker), | |
536 quit_count_(0) {} | |
537 | |
538 void DoRunLoopUntilChangesCount(size_t count) { | |
539 if (tracker_->changes()->size() >= count) | |
540 return; | |
541 quit_count_ = count - tracker_->changes()->size(); | |
542 DoRunLoop(); | |
543 } | |
544 | |
545 // TestChangeTracker::Delegate: | |
546 virtual void OnChangeAdded() OVERRIDE { | |
547 if (quit_count_ > 0 && --quit_count_ == 0) | |
548 current_run_loop->Quit(); | |
549 } | |
550 | |
551 private: | |
552 TestChangeTracker* tracker_; | |
553 size_t quit_count_; | |
554 | |
555 DISALLOW_COPY_AND_ASSIGN(MainLoopTrackerDelegate); | |
556 }; | |
557 | |
558 class ViewManagerClientImpl : public IViewManagerClient { | |
559 public: | |
560 ViewManagerClientImpl() | |
561 : id_(0), | |
562 next_server_change_id_(0), | |
563 main_loop_tracker_delegate_(&tracker_) { | |
564 tracker_.set_delegate(&main_loop_tracker_delegate_); | |
565 } | |
566 | |
567 TransportConnectionId id() const { return id_; } | |
568 | |
569 TransportChangeId next_server_change_id() const { | |
570 return next_server_change_id_; | |
571 } | |
572 const std::vector<TestNode>& initial_nodes() const { | |
573 return initial_nodes_; | |
574 } | |
575 const std::vector<TestNode>& hierarchy_changed_nodes() const { | |
576 return hierarchy_changed_nodes_; | |
577 } | |
578 | |
579 Changes GetAndClearChanges() { | |
580 Changes changes = ChangesToDescription1(*tracker_.changes()); | |
581 tracker_.changes()->clear(); | |
582 return changes; | |
583 } | |
584 | |
585 void ClearId() { | |
586 id_ = 0; | |
587 } | |
588 | |
589 void WaitForId() { | |
590 DCHECK_EQ(0, id_); | |
591 DoRunLoopUntilChangesCount(1); | |
592 } | |
593 | |
594 void DoRunLoopUntilChangesCount(size_t count) { | |
595 main_loop_tracker_delegate_.DoRunLoopUntilChangesCount(count); | |
596 } | |
597 | |
598 private: | |
599 // IViewManagerClient overrides: | |
600 virtual void OnViewManagerConnectionEstablished( | |
601 TransportConnectionId connection_id, | |
602 TransportChangeId next_server_change_id, | |
603 mojo::Array<INodePtr> nodes) OVERRIDE { | |
604 id_ = connection_id; | |
605 next_server_change_id_ = next_server_change_id; | |
606 initial_nodes_.clear(); | |
607 INodesToTestNodes(nodes, &initial_nodes_); | |
608 tracker_.OnViewManagerConnectionEstablished( | |
609 connection_id, next_server_change_id, nodes.Pass()); | |
610 } | |
611 virtual void OnServerChangeIdAdvanced( | |
612 TransportChangeId next_server_change_id) OVERRIDE { | |
613 tracker_.OnServerChangeIdAdvanced(next_server_change_id); | |
614 } | |
615 virtual void OnNodeBoundsChanged(TransportNodeId node_id, | |
616 RectPtr old_bounds, | |
617 RectPtr new_bounds) OVERRIDE { | |
618 tracker_.OnNodeBoundsChanged(node_id, old_bounds.Pass(), new_bounds.Pass()); | |
619 } | |
620 virtual void OnNodeHierarchyChanged( | |
621 TransportNodeId node, | |
622 TransportNodeId new_parent, | |
623 TransportNodeId old_parent, | |
624 TransportChangeId server_change_id, | |
625 mojo::Array<INodePtr> nodes) OVERRIDE { | |
626 hierarchy_changed_nodes_.clear(); | |
627 INodesToTestNodes(nodes, &hierarchy_changed_nodes_); | |
628 tracker_.OnNodeHierarchyChanged(node, new_parent, old_parent, | |
629 server_change_id, nodes.Pass()); | |
630 } | |
631 virtual void OnNodeDeleted(TransportNodeId node, | |
632 TransportChangeId server_change_id) OVERRIDE { | |
633 tracker_.OnNodeDeleted(node, server_change_id); | |
634 } | |
635 virtual void OnViewDeleted(TransportViewId view) OVERRIDE { | |
636 tracker_.OnViewDeleted(view); | |
637 } | |
638 virtual void OnNodeViewReplaced(TransportNodeId node, | |
639 TransportViewId new_view_id, | |
640 TransportViewId old_view_id) OVERRIDE { | |
641 tracker_.OnNodeViewReplaced(node, new_view_id, old_view_id); | |
642 } | |
643 | |
644 TransportConnectionId id_; | |
645 TransportChangeId next_server_change_id_; | |
646 | |
647 // Set of nodes sent when connection created. | |
648 std::vector<TestNode> initial_nodes_; | |
649 | |
650 // Nodes sent from last OnNodeHierarchyChanged. | |
651 std::vector<TestNode> hierarchy_changed_nodes_; | |
652 | |
653 TestChangeTracker tracker_; | |
654 MainLoopTrackerDelegate main_loop_tracker_delegate_; | |
655 | |
656 DISALLOW_COPY_AND_ASSIGN(ViewManagerClientImpl); | |
657 }; | |
658 | |
659 class ViewManagerConnectionTest : public testing::Test { | 532 class ViewManagerConnectionTest : public testing::Test { |
660 public: | 533 public: |
661 ViewManagerConnectionTest() : background_connection_(NULL) {} | 534 ViewManagerConnectionTest() : connection_(NULL), connection2_(NULL) {} |
662 | 535 |
663 virtual void SetUp() OVERRIDE { | 536 virtual void SetUp() OVERRIDE { |
664 test_helper_.Init(); | 537 test_helper_.Init(); |
665 | 538 |
666 ConnectToService(test_helper_.service_provider(), | |
667 "mojo:mojo_view_manager", | |
668 &view_manager_); | |
669 view_manager_.set_client(&client_); | |
670 | |
671 client_.WaitForId(); | |
672 client_.GetAndClearChanges(); | |
673 | |
674 test_helper_.SetLoaderForURL( | 539 test_helper_.SetLoaderForURL( |
675 scoped_ptr<ServiceLoader>(new ConnectServiceLoader()), | 540 scoped_ptr<ServiceLoader>(new ConnectServiceLoader()), |
676 GURL(kTestServiceURL)); | 541 GURL(kTestServiceURL)); |
| 542 |
| 543 ConnectToService(test_helper_.service_provider(), |
| 544 "mojo:mojo_view_manager", |
| 545 &view_manager_init_); |
| 546 ASSERT_TRUE(ViewManagerInitConnect(view_manager_init_.get(), |
| 547 kTestServiceURL)); |
| 548 |
| 549 connection_ = ViewManagerProxy::WaitForInstance(); |
| 550 ASSERT_TRUE(connection_ != NULL); |
| 551 connection_->DoRunLoopUntilChangesCount(1); |
| 552 } |
| 553 |
| 554 virtual void TearDown() OVERRIDE { |
| 555 if (connection2_) |
| 556 connection2_->Destroy(); |
| 557 if (connection_) |
| 558 connection_->Destroy(); |
677 } | 559 } |
678 | 560 |
679 protected: | 561 protected: |
680 // Creates a second connection to the viewmanager. | 562 void EstablishSecondConnectionWithRoots( |
681 void EstablishSecondConnection() { | 563 TransportNodeId id1, |
682 ConnectToService(test_helper_.service_provider(), | 564 TransportNodeId id2) { |
683 "mojo:mojo_view_manager", | 565 std::vector<TransportNodeId> node_ids; |
684 &view_manager2_); | 566 node_ids.push_back(id1); |
685 view_manager2_.set_client(&client2_); | 567 if (id2 != 0) |
686 | 568 node_ids.push_back(id2); |
687 client2_.WaitForId(); | 569 ASSERT_TRUE(connection_->Connect(node_ids)); |
688 client2_.GetAndClearChanges(); | 570 connection2_ = ViewManagerProxy::WaitForInstance(); |
| 571 ASSERT_TRUE(connection2_ != NULL); |
| 572 connection2_->DoRunLoopUntilChangesCount(1); |
| 573 ASSERT_EQ(1u, connection2_->changes().size()); |
689 } | 574 } |
690 | 575 |
691 std::vector<Change> EstablishBackgroundConnectionWithRoots( | 576 // Creates a second connection to the viewmanager. |
692 TransportNodeId id1, | 577 void EstablishSecondConnection(bool create_initial_node) { |
693 TransportNodeId id2) { | 578 if (create_initial_node) |
694 Connect(view_manager_.get(), kTestServiceURL, id1, id2); | 579 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
695 background_connection_ = BackgroundConnection::WaitForInstance(); | 580 ASSERT_NO_FATAL_FAILURE( |
696 return background_connection_->DoRunLoopUntilChangesCount(1); | 581 EstablishSecondConnectionWithRoots(BuildNodeId(1, 1), 0)); |
697 } | 582 const std::vector<Change>& changes(connection2_->changes()); |
698 | |
699 void EstablishBackgroundConnectionWithRoot1() { | |
700 std::vector<Change> changes( | |
701 EstablishBackgroundConnectionWithRoots(CreateNodeId(1, 1), 0)); | |
702 if (HasFatalFailure()) | |
703 return; | |
704 ASSERT_EQ(1u, changes.size()); | 583 ASSERT_EQ(1u, changes.size()); |
705 EXPECT_EQ("OnConnectionEstablished", ChangesToDescription1(changes)[0]); | 584 EXPECT_EQ("OnConnectionEstablished", ChangesToDescription1(changes)[0]); |
706 EXPECT_EQ("[node=1,1 parent=null view=null]", | 585 if (create_initial_node) { |
707 ChangeNodeDescription(changes)); | 586 EXPECT_EQ("[node=1,1 parent=null view=null]", |
| 587 ChangeNodeDescription(changes)); |
| 588 } |
708 } | 589 } |
709 | 590 |
710 void DestroySecondConnection() { | 591 void DestroySecondConnection() { |
711 view_manager2_.reset(); | 592 connection2_->Destroy(); |
| 593 connection2_ = NULL; |
712 } | 594 } |
713 | 595 |
714 base::MessageLoop loop_; | 596 base::MessageLoop loop_; |
715 shell::ShellTestHelper test_helper_; | 597 shell::ShellTestHelper test_helper_; |
716 | 598 |
717 ViewManagerClientImpl client_; | 599 IViewManagerInitPtr view_manager_init_; |
718 IViewManagerPtr view_manager_; | |
719 | 600 |
720 ViewManagerClientImpl client2_; | 601 ViewManagerProxy* connection_; |
721 IViewManagerPtr view_manager2_; | 602 ViewManagerProxy* connection2_; |
722 | |
723 BackgroundConnection* background_connection_; | |
724 | 603 |
725 DISALLOW_COPY_AND_ASSIGN(ViewManagerConnectionTest); | 604 DISALLOW_COPY_AND_ASSIGN(ViewManagerConnectionTest); |
726 }; | 605 }; |
727 | 606 |
728 // Verifies client gets a valid id. | 607 // Verifies client gets a valid id. |
729 TEST_F(ViewManagerConnectionTest, ValidId) { | 608 TEST_F(ViewManagerConnectionTest, ValidId) { |
| 609 EXPECT_EQ("OnConnectionEstablished", |
| 610 ChangesToDescription1(connection_->changes())[0]); |
| 611 |
730 // All these tests assume 1 for the client id. The only real assertion here is | 612 // All these tests assume 1 for the client id. The only real assertion here is |
731 // the client id is not zero, but adding this as rest of code here assumes 1. | 613 // the client id is not zero, but adding this as rest of code here assumes 1. |
732 EXPECT_EQ(1, client_.id()); | 614 EXPECT_EQ(1, connection_->changes()[0].connection_id); |
733 | 615 |
734 // Change ids start at 1 as well. | 616 // Change ids start at 1 as well. |
735 EXPECT_EQ(static_cast<TransportChangeId>(1), client_.next_server_change_id()); | 617 EXPECT_EQ(static_cast<TransportChangeId>(1), |
| 618 connection_->changes()[0].change_id); |
736 } | 619 } |
737 | 620 |
738 // Verifies two clients/connections get different ids. | 621 // Verifies two clients/connections get different ids. |
739 TEST_F(ViewManagerConnectionTest, TwoClientsGetDifferentConnectionIds) { | 622 TEST_F(ViewManagerConnectionTest, TwoClientsGetDifferentConnectionIds) { |
740 EstablishSecondConnection(); | 623 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); |
741 EXPECT_NE(0, client2_.id()); | 624 EXPECT_EQ("OnConnectionEstablished", |
742 EXPECT_NE(client_.id(), client2_.id()); | 625 ChangesToDescription1(connection2_->changes())[0]); |
| 626 |
| 627 // It isn't strickly necessary that the second connection gets 2, but these |
| 628 // tests are written assuming that is the case. The key thing is the |
| 629 // connection ids of |connection_| and |connection2_| differ. |
| 630 EXPECT_EQ(2, connection2_->changes()[0].connection_id); |
| 631 |
| 632 // Change ids start at 1 as well. |
| 633 EXPECT_EQ(static_cast<TransportChangeId>(1), |
| 634 connection2_->changes()[0].change_id); |
743 } | 635 } |
744 | 636 |
745 // Verifies client gets a valid id. | 637 // Verifies client gets a valid id. |
746 TEST_F(ViewManagerConnectionTest, CreateNode) { | 638 TEST_F(ViewManagerConnectionTest, CreateNode) { |
747 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 639 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
| 640 EXPECT_TRUE(connection_->changes().empty()); |
748 | 641 |
749 // Can't create a node with the same id. | 642 // Can't create a node with the same id. |
750 ASSERT_FALSE(CreateNode(view_manager_.get(), 1, 1)); | 643 ASSERT_FALSE(connection_->CreateNode(BuildNodeId(1, 1))); |
751 } | 644 EXPECT_TRUE(connection_->changes().empty()); |
752 | 645 |
753 TEST_F(ViewManagerConnectionTest, CreateNodeFailsWithBogusConnectionId) { | 646 // Can't create a node with a bogus connection id. |
754 EXPECT_FALSE(CreateNode(view_manager_.get(), 2, 1)); | 647 EXPECT_FALSE(connection_->CreateNode(BuildNodeId(2, 1))); |
| 648 EXPECT_TRUE(connection_->changes().empty()); |
755 } | 649 } |
756 | 650 |
757 TEST_F(ViewManagerConnectionTest, CreateViewFailsWithBogusConnectionId) { | 651 TEST_F(ViewManagerConnectionTest, CreateViewFailsWithBogusConnectionId) { |
758 EXPECT_FALSE(CreateView(view_manager_.get(), 2, 1)); | 652 EXPECT_FALSE(connection_->CreateView(BuildViewId(2, 1))); |
| 653 EXPECT_TRUE(connection_->changes().empty()); |
759 } | 654 } |
760 | 655 |
761 // Verifies hierarchy changes. | 656 // Verifies hierarchy changes. |
762 TEST_F(ViewManagerConnectionTest, AddRemoveNotify) { | 657 TEST_F(ViewManagerConnectionTest, AddRemoveNotify) { |
763 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 658 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
764 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | 659 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3))); |
765 | 660 |
766 EXPECT_TRUE(client_.GetAndClearChanges().empty()); | 661 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); |
767 | 662 |
768 EstablishSecondConnection(); | 663 // Make 3 a child of 2. |
769 EXPECT_TRUE(client2_.GetAndClearChanges().empty()); | 664 { |
| 665 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3), 1)); |
| 666 EXPECT_TRUE(connection_->changes().empty()); |
770 | 667 |
771 // Make 2 a child of 1. | 668 connection2_->DoRunLoopUntilChangesCount(1); |
772 { | 669 const Changes changes(ChangesToDescription1(connection2_->changes())); |
773 ASSERT_TRUE(AddNode(view_manager_.get(), | |
774 CreateNodeId(client_.id(), 1), | |
775 CreateNodeId(client_.id(), 2), | |
776 1)); | |
777 Changes changes(client_.GetAndClearChanges()); | |
778 ASSERT_TRUE(changes.empty()); | |
779 | |
780 client2_.DoRunLoopUntilChangesCount(1); | |
781 changes = client2_.GetAndClearChanges(); | |
782 ASSERT_EQ(1u, changes.size()); | 670 ASSERT_EQ(1u, changes.size()); |
783 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]); | 671 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]); |
784 } | 672 } |
785 | 673 |
786 // Remove 2 from its parent. | 674 // Remove 3 from its parent. |
787 { | 675 { |
788 ASSERT_TRUE(RemoveNodeFromParent(view_manager_.get(), | 676 ASSERT_TRUE(connection_->RemoveNodeFromParent(BuildNodeId(1, 3), 2)); |
789 CreateNodeId(client_.id(), 2), | 677 EXPECT_TRUE(connection_->changes().empty()); |
790 2)); | |
791 Changes changes(client_.GetAndClearChanges()); | |
792 ASSERT_TRUE(changes.empty()); | |
793 | 678 |
794 client2_.DoRunLoopUntilChangesCount(1); | 679 connection2_->DoRunLoopUntilChangesCount(1); |
795 changes = client2_.GetAndClearChanges(); | 680 const Changes changes(ChangesToDescription1(connection2_->changes())); |
796 ASSERT_EQ(1u, changes.size()); | 681 ASSERT_EQ(1u, changes.size()); |
797 EXPECT_EQ("ServerChangeIdAdvanced 3", changes[0]); | 682 EXPECT_EQ("ServerChangeIdAdvanced 3", changes[0]); |
798 } | 683 } |
799 } | 684 } |
800 | 685 |
801 // Verifies AddNode fails when node is already in position. | 686 // Verifies AddNode fails when node is already in position. |
802 TEST_F(ViewManagerConnectionTest, AddNodeWithNoChange) { | 687 TEST_F(ViewManagerConnectionTest, AddNodeWithNoChange) { |
803 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 688 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
804 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | 689 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3))); |
805 | 690 |
806 EXPECT_TRUE(client_.GetAndClearChanges().empty()); | 691 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); |
807 | 692 |
808 EstablishSecondConnection(); | 693 // Make 3 a child of 2. |
809 EXPECT_TRUE(client2_.GetAndClearChanges().empty()); | 694 { |
810 | 695 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3), 1)); |
811 // Make 2 a child of 1. | 696 |
812 { | 697 connection2_->DoRunLoopUntilChangesCount(1); |
813 ASSERT_TRUE(AddNode(view_manager_.get(), | 698 const Changes changes(ChangesToDescription1(connection2_->changes())); |
814 CreateNodeId(client_.id(), 1), | |
815 CreateNodeId(client_.id(), 2), | |
816 1)); | |
817 Changes changes(client_.GetAndClearChanges()); | |
818 ASSERT_TRUE(changes.empty()); | |
819 | |
820 client2_.DoRunLoopUntilChangesCount(1); | |
821 changes = client2_.GetAndClearChanges(); | |
822 ASSERT_EQ(1u, changes.size()); | 699 ASSERT_EQ(1u, changes.size()); |
823 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]); | 700 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]); |
824 } | 701 } |
825 | 702 |
826 // Try again, this should fail. | 703 // Try again, this should fail. |
827 { | 704 { |
828 EXPECT_FALSE(AddNode(view_manager_.get(), | 705 EXPECT_FALSE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3), 2)); |
829 CreateNodeId(client_.id(), 1), | |
830 CreateNodeId(client_.id(), 2), | |
831 2)); | |
832 Changes changes(client_.GetAndClearChanges()); | |
833 EXPECT_TRUE(changes.empty()); | |
834 } | 706 } |
835 } | 707 } |
836 | 708 |
837 // Verifies AddNode fails when node is already in position. | 709 // Verifies AddNode fails when node is already in position. |
838 TEST_F(ViewManagerConnectionTest, AddAncestorFails) { | 710 TEST_F(ViewManagerConnectionTest, AddAncestorFails) { |
839 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 711 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
840 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | 712 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3))); |
841 | 713 |
842 EXPECT_TRUE(client_.GetAndClearChanges().empty()); | 714 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); |
843 | 715 |
844 EstablishSecondConnection(); | 716 // Make 3 a child of 2. |
845 EXPECT_TRUE(client2_.GetAndClearChanges().empty()); | 717 { |
846 | 718 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3), 1)); |
847 // Make 2 a child of 1. | 719 connection2_->DoRunLoopUntilChangesCount(1); |
848 { | 720 const Changes changes(ChangesToDescription1(connection2_->changes())); |
849 ASSERT_TRUE(AddNode(view_manager_.get(), | |
850 CreateNodeId(client_.id(), 1), | |
851 CreateNodeId(client_.id(), 2), | |
852 1)); | |
853 Changes changes(client_.GetAndClearChanges()); | |
854 ASSERT_TRUE(changes.empty()); | |
855 | |
856 client2_.DoRunLoopUntilChangesCount(1); | |
857 changes = client2_.GetAndClearChanges(); | |
858 ASSERT_EQ(1u, changes.size()); | 721 ASSERT_EQ(1u, changes.size()); |
859 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]); | 722 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]); |
860 } | 723 } |
861 | 724 |
862 // Try to make 1 a child of 2, this should fail since 1 is an ancestor of 2. | 725 // Try to make 2 a child of 3, this should fail since 2 is an ancestor of 3. |
863 { | 726 { |
864 EXPECT_FALSE(AddNode(view_manager_.get(), | 727 EXPECT_FALSE(connection_->AddNode(BuildNodeId(1, 3), BuildNodeId(1, 2), 2)); |
865 CreateNodeId(client_.id(), 2), | |
866 CreateNodeId(client_.id(), 1), | |
867 2)); | |
868 Changes changes(client_.GetAndClearChanges()); | |
869 EXPECT_TRUE(changes.empty()); | |
870 } | 728 } |
871 } | 729 } |
872 | 730 |
873 // Verifies adding with an invalid id fails. | 731 // Verifies adding with an invalid id fails. |
874 TEST_F(ViewManagerConnectionTest, AddWithInvalidServerId) { | 732 TEST_F(ViewManagerConnectionTest, AddWithInvalidServerId) { |
875 // Create two nodes. | 733 // Create two nodes. |
876 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 734 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
877 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | 735 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
878 | 736 |
879 // Make 2 a child of 1. Supply an invalid change id, which should fail. | 737 // Make 2 a child of 1. Supply an invalid change id, which should fail. |
880 { | 738 ASSERT_FALSE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 0)); |
881 ASSERT_FALSE(AddNode(view_manager_.get(), | |
882 CreateNodeId(client_.id(), 1), | |
883 CreateNodeId(client_.id(), 2), | |
884 0)); | |
885 Changes changes(client_.GetAndClearChanges()); | |
886 EXPECT_TRUE(changes.empty()); | |
887 } | |
888 } | 739 } |
889 | 740 |
890 // Verifies adding to root sends right notifications. | 741 // Verifies adding to root sends right notifications. |
891 TEST_F(ViewManagerConnectionTest, AddToRoot) { | 742 TEST_F(ViewManagerConnectionTest, AddToRoot) { |
892 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 21)); | 743 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 21))); |
893 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 3)); | 744 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3))); |
894 EXPECT_TRUE(client_.GetAndClearChanges().empty()); | 745 |
895 | 746 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); |
896 EstablishSecondConnection(); | |
897 EXPECT_TRUE(client2_.GetAndClearChanges().empty()); | |
898 | 747 |
899 // Make 3 a child of 21. | 748 // Make 3 a child of 21. |
900 { | 749 { |
901 ASSERT_TRUE(AddNode(view_manager_.get(), | 750 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 21), BuildNodeId(1, 3), 1)); |
902 CreateNodeId(client_.id(), 21), | 751 |
903 CreateNodeId(client_.id(), 3), | 752 connection2_->DoRunLoopUntilChangesCount(1); |
904 1)); | 753 const Changes changes(ChangesToDescription1(connection2_->changes())); |
905 Changes changes(client_.GetAndClearChanges()); | |
906 ASSERT_TRUE(changes.empty()); | |
907 | |
908 client2_.DoRunLoopUntilChangesCount(1); | |
909 changes = client2_.GetAndClearChanges(); | |
910 ASSERT_EQ(1u, changes.size()); | 754 ASSERT_EQ(1u, changes.size()); |
911 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]); | 755 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]); |
912 } | 756 } |
913 | 757 |
914 // Make 21 a child of the root. | 758 // Make 21 a child of 1. |
915 { | 759 { |
916 ASSERT_TRUE(AddNode(view_manager_.get(), | 760 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 21), 2)); |
917 CreateNodeId(0, 1), | 761 |
918 CreateNodeId(client_.id(), 21), | 762 connection2_->DoRunLoopUntilChangesCount(1); |
919 2)); | 763 const Changes changes(ChangesToDescription1(connection2_->changes())); |
920 Changes changes(client_.GetAndClearChanges()); | 764 ASSERT_EQ(1u, changes.size()); |
921 ASSERT_TRUE(changes.empty()); | 765 EXPECT_EQ( |
922 | 766 "HierarchyChanged change_id=2 node=1,21 new_parent=1,1 old_parent=null", |
923 client2_.DoRunLoopUntilChangesCount(1); | 767 changes[0]); |
924 changes = client2_.GetAndClearChanges(); | 768 } |
925 ASSERT_EQ(1u, changes.size()); | 769 } |
926 EXPECT_EQ( | 770 |
927 "HierarchyChanged change_id=2 node=1,21 new_parent=0,1 old_parent=null", | 771 // Verifies HierarchyChanged is correctly sent for various adds/removes. |
928 changes[0]); | |
929 } | |
930 } | |
931 | |
932 // Verifies adding to root sends right notifications. | |
933 TEST_F(ViewManagerConnectionTest, NodeHierarchyChangedNodes) { | 772 TEST_F(ViewManagerConnectionTest, NodeHierarchyChangedNodes) { |
934 // Create nodes 1 and 11 with 1 parented to the root and 11 a child of 1. | 773 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
935 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 774 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 11))); |
936 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 11)); | 775 // Make 11 a child of 2. |
937 | 776 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 11), 1)); |
938 // Make 11 a child of 1. | 777 |
939 { | 778 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); |
940 ASSERT_TRUE(AddNode(view_manager_.get(), | 779 |
941 CreateNodeId(client_.id(), 1), | 780 // Make 2 a child of 1. |
942 CreateNodeId(client_.id(), 11), | 781 { |
943 1)); | 782 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 2)); |
944 ASSERT_TRUE(client_.GetAndClearChanges().empty()); | |
945 } | |
946 | |
947 EstablishSecondConnection(); | |
948 | |
949 // Make 1 a child of the root. | |
950 { | |
951 ASSERT_TRUE(AddNode(view_manager_.get(), | |
952 CreateNodeId(0, 1), | |
953 CreateNodeId(client_.id(), 1), | |
954 2)); | |
955 ASSERT_TRUE(client_.GetAndClearChanges().empty()); | |
956 | 783 |
957 // Client 2 should get a hierarchy change that includes the new nodes as it | 784 // Client 2 should get a hierarchy change that includes the new nodes as it |
958 // has not yet seen them. | 785 // has not yet seen them. |
959 client2_.DoRunLoopUntilChangesCount(1); | 786 connection2_->DoRunLoopUntilChangesCount(1); |
960 Changes changes(client2_.GetAndClearChanges()); | 787 const Changes changes(ChangesToDescription1(connection2_->changes())); |
961 ASSERT_EQ(1u, changes.size()); | 788 ASSERT_EQ(1u, changes.size()); |
962 EXPECT_EQ( | 789 EXPECT_EQ( |
963 "HierarchyChanged change_id=2 node=1,1 new_parent=0,1 old_parent=null", | 790 "HierarchyChanged change_id=2 node=1,2 new_parent=1,1 old_parent=null", |
964 changes[0]); | 791 changes[0]); |
965 const std::vector<TestNode>& nodes(client2_.hierarchy_changed_nodes()); | 792 EXPECT_EQ("[node=1,2 parent=1,1 view=null]," |
966 ASSERT_EQ(2u, nodes.size()); | 793 "[node=1,11 parent=1,2 view=null]", |
967 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[0].ToString()); | 794 ChangeNodeDescription(connection2_->changes())); |
968 EXPECT_EQ("node=1,11 parent=1,1 view=null", nodes[1].ToString()); | 795 } |
969 } | 796 |
970 | 797 // Add 1 to the root. |
971 // Remove 1 from the root. | 798 { |
972 { | 799 ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 3)); |
973 ASSERT_TRUE(RemoveNodeFromParent(view_manager_.get(), | 800 |
974 CreateNodeId(client_.id(), 1), | 801 // Client 2 should get a hierarchy change that includes the new nodes as it |
975 3)); | 802 // has not yet seen them. |
976 ASSERT_TRUE(client_.GetAndClearChanges().empty()); | 803 connection2_->DoRunLoopUntilChangesCount(1); |
977 | 804 const Changes changes(ChangesToDescription1(connection2_->changes())); |
978 client2_.DoRunLoopUntilChangesCount(1); | 805 ASSERT_EQ(1u, changes.size()); |
979 Changes changes(client2_.GetAndClearChanges()); | 806 EXPECT_EQ( |
980 ASSERT_EQ(1u, changes.size()); | 807 "HierarchyChanged change_id=3 node=1,1 new_parent=null old_parent=null", |
981 EXPECT_EQ( | 808 changes[0]); |
982 "HierarchyChanged change_id=3 node=1,1 new_parent=null old_parent=0,1", | 809 EXPECT_EQ(std::string(), ChangeNodeDescription(connection2_->changes())); |
| 810 } |
| 811 |
| 812 // Remove 1 from its parent. |
| 813 { |
| 814 ASSERT_TRUE(connection_->RemoveNodeFromParent(BuildNodeId(1, 1), 4)); |
| 815 EXPECT_TRUE(connection_->changes().empty()); |
| 816 |
| 817 connection2_->DoRunLoopUntilChangesCount(1); |
| 818 const Changes changes(ChangesToDescription1(connection2_->changes())); |
| 819 ASSERT_EQ(1u, changes.size()); |
| 820 EXPECT_EQ( |
| 821 "HierarchyChanged change_id=4 node=1,1 new_parent=null old_parent=null", |
983 changes[0]); | 822 changes[0]); |
984 } | 823 } |
985 | 824 |
986 // Create another node, 111, parent it to 11. | 825 // Create another node, 111, parent it to 11. |
987 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 111)); | 826 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 111))); |
988 { | 827 { |
989 ASSERT_TRUE(AddNode(view_manager_.get(), | 828 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 11), BuildNodeId(1, 111), |
990 CreateNodeId(client_.id(), 11), | 829 5)); |
991 CreateNodeId(client_.id(), 111), | 830 |
992 4)); | 831 connection2_->DoRunLoopUntilChangesCount(1); |
993 ASSERT_TRUE(client_.GetAndClearChanges().empty()); | 832 const Changes changes(ChangesToDescription1(connection2_->changes())); |
994 | 833 ASSERT_EQ(1u, changes.size()); |
995 client2_.DoRunLoopUntilChangesCount(1); | 834 EXPECT_EQ( |
996 Changes changes(client2_.GetAndClearChanges()); | 835 "HierarchyChanged change_id=5 node=1,111 new_parent=1,11 " |
997 ASSERT_EQ(1u, changes.size()); | |
998 // Even though 11 isn't attached to the root client 2 is still notified of | |
999 // the change because it was told about 11. | |
1000 EXPECT_EQ( | |
1001 "HierarchyChanged change_id=4 node=1,111 new_parent=1,11 " | |
1002 "old_parent=null", changes[0]); | 836 "old_parent=null", changes[0]); |
1003 const std::vector<TestNode>& nodes(client2_.hierarchy_changed_nodes()); | 837 EXPECT_EQ("[node=1,111 parent=1,11 view=null]", |
1004 ASSERT_EQ(1u, nodes.size()); | 838 ChangeNodeDescription(connection2_->changes())); |
1005 EXPECT_EQ("node=1,111 parent=1,11 view=null", nodes[0].ToString()); | |
1006 } | 839 } |
1007 | 840 |
1008 // Reattach 1 to the root. | 841 // Reattach 1 to the root. |
1009 { | 842 { |
1010 ASSERT_TRUE(AddNode(view_manager_.get(), | 843 ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 6)); |
1011 CreateNodeId(0, 1), | 844 |
1012 CreateNodeId(client_.id(), 1), | 845 connection2_->DoRunLoopUntilChangesCount(1); |
1013 5)); | 846 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1014 ASSERT_TRUE(client_.GetAndClearChanges().empty()); | 847 ASSERT_EQ(1u, changes.size()); |
1015 | 848 EXPECT_EQ( |
1016 client2_.DoRunLoopUntilChangesCount(1); | 849 "HierarchyChanged change_id=6 node=1,1 new_parent=null old_parent=null", |
1017 Changes changes = client2_.GetAndClearChanges(); | 850 changes[0]); |
1018 ASSERT_EQ(1u, changes.size()); | 851 EXPECT_EQ(std::string(), ChangeNodeDescription(connection2_->changes())); |
1019 EXPECT_EQ( | |
1020 "HierarchyChanged change_id=5 node=1,1 new_parent=0,1 old_parent=null", | |
1021 changes[0]); | |
1022 ASSERT_TRUE(client2_.hierarchy_changed_nodes().empty()); | |
1023 } | 852 } |
1024 } | 853 } |
1025 | 854 |
1026 TEST_F(ViewManagerConnectionTest, NodeHierarchyChangedAddingKnownToUnknown) { | 855 TEST_F(ViewManagerConnectionTest, NodeHierarchyChangedAddingKnownToUnknown) { |
1027 // Create the following structure: root -> 1 -> 11 and 2->21 (2 has no | 856 // Create the following structure: root -> 1 -> 11 and 2->21 (2 has no |
1028 // parent). | 857 // parent). |
1029 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 858 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
1030 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 11)); | 859 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 11))); |
1031 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | 860 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
1032 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 21)); | 861 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 21))); |
1033 | 862 |
1034 // Set up the hierarchy. | 863 // Set up the hierarchy. |
1035 { | 864 ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1)); |
1036 ASSERT_TRUE(AddNode(view_manager_.get(), | 865 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 11), 2)); |
1037 CreateNodeId(0, 1), | 866 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 21), 3)); |
1038 CreateNodeId(client_.id(), 1), | 867 |
1039 1)); | 868 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); |
1040 ASSERT_TRUE(AddNode(view_manager_.get(), | 869 { |
1041 CreateNodeId(client_.id(), 1), | 870 EXPECT_EQ("[node=1,1 parent=null view=null]," |
1042 CreateNodeId(client_.id(), 11), | 871 "[node=1,11 parent=1,1 view=null]", |
1043 2)); | 872 ChangeNodeDescription(connection2_->changes())); |
1044 ASSERT_TRUE(AddNode(view_manager_.get(), | 873 } |
1045 CreateNodeId(client_.id(), 2), | 874 |
1046 CreateNodeId(client_.id(), 21), | 875 // Remove 11, should result in a delete (since 11 is no longer in connection |
1047 3)); | 876 // 2's root). |
1048 } | 877 { |
1049 | 878 ASSERT_TRUE(connection_->RemoveNodeFromParent(BuildNodeId(1, 11), 4)); |
1050 EstablishSecondConnection(); | 879 |
1051 | 880 connection2_->DoRunLoopUntilChangesCount(1); |
1052 // Remove 11. | 881 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1053 { | 882 ASSERT_EQ(1u, changes.size()); |
1054 ASSERT_TRUE(RemoveNodeFromParent(view_manager_.get(), | 883 EXPECT_EQ("NodeDeleted change_id=4 node=1,11", changes[0]); |
1055 CreateNodeId(client_.id(), 11), | 884 } |
1056 4)); | 885 |
1057 ASSERT_TRUE(client_.GetAndClearChanges().empty()); | 886 // Add 2 to 1. |
1058 | 887 { |
1059 client2_.DoRunLoopUntilChangesCount(1); | 888 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 5)); |
1060 Changes changes(client2_.GetAndClearChanges()); | 889 |
1061 ASSERT_EQ(1u, changes.size()); | 890 connection2_->DoRunLoopUntilChangesCount(1); |
1062 EXPECT_EQ( | 891 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1063 "HierarchyChanged change_id=4 node=1,11 new_parent=null old_parent=1,1", | 892 ASSERT_EQ(1u, changes.size()); |
1064 changes[0]); | 893 EXPECT_EQ( |
1065 EXPECT_TRUE(client2_.hierarchy_changed_nodes().empty()); | 894 "HierarchyChanged change_id=5 node=1,2 new_parent=1,1 old_parent=null", |
1066 } | 895 changes[0]); |
1067 | 896 EXPECT_EQ("[node=1,2 parent=1,1 view=null]," |
1068 // Add 11 to 21. As client2 knows about 11 it should receive the new | 897 "[node=1,21 parent=1,2 view=null]", |
1069 // hierarchy. | 898 ChangeNodeDescription(connection2_->changes())); |
1070 { | 899 } |
1071 ASSERT_TRUE(AddNode(view_manager_.get(), | |
1072 CreateNodeId(client_.id(), 21), | |
1073 CreateNodeId(client_.id(), 11), | |
1074 5)); | |
1075 ASSERT_TRUE(client_.GetAndClearChanges().empty()); | |
1076 | |
1077 client2_.DoRunLoopUntilChangesCount(1); | |
1078 Changes changes(client2_.GetAndClearChanges()); | |
1079 ASSERT_EQ(1u, changes.size()); | |
1080 EXPECT_EQ( | |
1081 "HierarchyChanged change_id=5 node=1,11 new_parent=1,21 " | |
1082 "old_parent=null", changes[0]); | |
1083 const std::vector<TestNode>& nodes(client2_.hierarchy_changed_nodes()); | |
1084 ASSERT_EQ(2u, nodes.size()); | |
1085 EXPECT_EQ("node=1,2 parent=null view=null", nodes[0].ToString()); | |
1086 EXPECT_EQ("node=1,21 parent=1,2 view=null", nodes[1].ToString()); | |
1087 } | |
1088 } | |
1089 | |
1090 // Verifies connection on told descendants of the root when connecting. | |
1091 TEST_F(ViewManagerConnectionTest, GetInitialNodesOnInit) { | |
1092 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 21)); | |
1093 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 3)); | |
1094 EXPECT_TRUE(client_.GetAndClearChanges().empty()); | |
1095 | |
1096 // Make 3 a child of 21. | |
1097 { | |
1098 ASSERT_TRUE(AddNode(view_manager_.get(), | |
1099 CreateNodeId(client_.id(), 21), | |
1100 CreateNodeId(client_.id(), 3), | |
1101 1)); | |
1102 ASSERT_TRUE(client_.GetAndClearChanges().empty()); | |
1103 } | |
1104 | |
1105 // Make 21 a child of the root. | |
1106 { | |
1107 ASSERT_TRUE(AddNode(view_manager_.get(), | |
1108 CreateNodeId(0, 1), | |
1109 CreateNodeId(client_.id(), 21), | |
1110 2)); | |
1111 ASSERT_TRUE(client_.GetAndClearChanges().empty()); | |
1112 } | |
1113 | |
1114 EstablishSecondConnection(); | |
1115 // Should get notification of children of the root. | |
1116 const std::vector<TestNode>& nodes(client2_.initial_nodes()); | |
1117 ASSERT_EQ(3u, nodes.size()); | |
1118 EXPECT_EQ("node=0,1 parent=null view=null", nodes[0].ToString()); | |
1119 EXPECT_EQ("node=1,21 parent=0,1 view=null", nodes[1].ToString()); | |
1120 EXPECT_EQ("node=1,3 parent=1,21 view=null", nodes[2].ToString()); | |
1121 } | 900 } |
1122 | 901 |
1123 // Verifies DeleteNode works. | 902 // Verifies DeleteNode works. |
1124 TEST_F(ViewManagerConnectionTest, DeleteNode) { | 903 TEST_F(ViewManagerConnectionTest, DeleteNode) { |
1125 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 904 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
1126 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | 905 |
1127 EXPECT_TRUE(client_.GetAndClearChanges().empty()); | 906 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); |
1128 | |
1129 EstablishSecondConnection(); | |
1130 EXPECT_TRUE(client2_.GetAndClearChanges().empty()); | |
1131 | 907 |
1132 // Make 2 a child of 1. | 908 // Make 2 a child of 1. |
1133 { | 909 { |
1134 ASSERT_TRUE(AddNode(view_manager_.get(), | 910 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1)); |
1135 CreateNodeId(client_.id(), 1), | 911 connection2_->DoRunLoopUntilChangesCount(1); |
1136 CreateNodeId(client_.id(), 2), | 912 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1137 1)); | 913 ASSERT_EQ(1u, changes.size()); |
1138 Changes changes(client_.GetAndClearChanges()); | 914 EXPECT_EQ("HierarchyChanged change_id=1 node=1,2 new_parent=1,1 " |
1139 ASSERT_TRUE(changes.empty()); | 915 "old_parent=null", changes[0]); |
1140 | 916 } |
1141 client2_.DoRunLoopUntilChangesCount(1); | 917 |
1142 changes = client2_.GetAndClearChanges(); | 918 // Delete 2. |
1143 ASSERT_EQ(1u, changes.size()); | 919 { |
1144 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]); | 920 ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 2))); |
1145 } | 921 EXPECT_TRUE(connection_->changes().empty()); |
1146 | 922 |
1147 // Add 1 to the root | 923 // TODO(sky): fix this, client should not get ServerChangeIdAdvanced. |
1148 { | 924 connection2_->DoRunLoopUntilChangesCount(2); |
1149 ASSERT_TRUE(AddNode(view_manager_.get(), | 925 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1150 CreateNodeId(0, 1), | 926 ASSERT_EQ(2u, changes.size()); |
1151 CreateNodeId(client_.id(), 1), | 927 EXPECT_EQ("NodeDeleted change_id=2 node=1,2", changes[0]); |
1152 2)); | 928 EXPECT_EQ("ServerChangeIdAdvanced 3", changes[1]); |
1153 Changes changes(client_.GetAndClearChanges()); | |
1154 ASSERT_TRUE(changes.empty()); | |
1155 | |
1156 client2_.DoRunLoopUntilChangesCount(1); | |
1157 changes = client2_.GetAndClearChanges(); | |
1158 ASSERT_EQ(1u, changes.size()); | |
1159 EXPECT_EQ( | |
1160 "HierarchyChanged change_id=2 node=1,1 new_parent=0,1 old_parent=null", | |
1161 changes[0]); | |
1162 } | |
1163 | |
1164 // Delete 1. | |
1165 { | |
1166 ASSERT_TRUE(DeleteNode(view_manager_.get(), CreateNodeId(client_.id(), 1))); | |
1167 Changes changes(client_.GetAndClearChanges()); | |
1168 ASSERT_TRUE(changes.empty()); | |
1169 | |
1170 client2_.DoRunLoopUntilChangesCount(1); | |
1171 changes = client2_.GetAndClearChanges(); | |
1172 ASSERT_EQ(1u, changes.size()); | |
1173 EXPECT_EQ("NodeDeleted change_id=3 node=1,1", changes[0]); | |
1174 } | 929 } |
1175 } | 930 } |
1176 | 931 |
1177 // Verifies DeleteNode isn't allowed from a separate connection. | 932 // Verifies DeleteNode isn't allowed from a separate connection. |
1178 TEST_F(ViewManagerConnectionTest, DeleteNodeFromAnotherConnectionDisallowed) { | 933 TEST_F(ViewManagerConnectionTest, DeleteNodeFromAnotherConnectionDisallowed) { |
1179 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 934 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); |
1180 EstablishSecondConnection(); | 935 EXPECT_FALSE(connection2_->DeleteNode(BuildNodeId(1, 1))); |
1181 EXPECT_FALSE(DeleteNode(view_manager2_.get(), CreateNodeId(client_.id(), 1))); | |
1182 } | 936 } |
1183 | 937 |
1184 // Verifies DeleteView isn't allowed from a separate connection. | 938 // Verifies DeleteView isn't allowed from a separate connection. |
1185 TEST_F(ViewManagerConnectionTest, DeleteViewFromAnotherConnectionDisallowed) { | 939 TEST_F(ViewManagerConnectionTest, DeleteViewFromAnotherConnectionDisallowed) { |
1186 ASSERT_TRUE(CreateView(view_manager_.get(), 1, 1)); | 940 ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1))); |
1187 EstablishSecondConnection(); | 941 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); |
1188 EXPECT_FALSE(DeleteView(view_manager2_.get(), CreateViewId(client_.id(), 1))); | 942 EXPECT_FALSE(connection2_->DeleteView(BuildViewId(1, 1))); |
1189 } | 943 } |
1190 | 944 |
1191 // Verifies if a node was deleted and then reused that other clients are | 945 // Verifies if a node was deleted and then reused that other clients are |
1192 // properly notified. | 946 // properly notified. |
1193 TEST_F(ViewManagerConnectionTest, ReusedDeletedId) { | 947 TEST_F(ViewManagerConnectionTest, ReuseDeletedNodeId) { |
1194 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 948 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); |
1195 EXPECT_TRUE(client_.GetAndClearChanges().empty()); | 949 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
1196 | 950 |
1197 EstablishSecondConnection(); | 951 // Add 2 to 1. |
1198 | 952 { |
1199 // Make 1 a child of the root. | 953 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1)); |
1200 { | 954 |
1201 ASSERT_TRUE(AddNode(view_manager_.get(), | 955 connection2_->DoRunLoopUntilChangesCount(1); |
1202 CreateNodeId(0, 1), | 956 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1203 CreateNodeId(client_.id(), 1), | 957 EXPECT_EQ( |
1204 1)); | 958 "HierarchyChanged change_id=1 node=1,2 new_parent=1,1 old_parent=null", |
1205 EXPECT_TRUE(client_.GetAndClearChanges().empty()); | 959 changes[0]); |
1206 | 960 EXPECT_EQ("[node=1,2 parent=1,1 view=null]", |
1207 client2_.DoRunLoopUntilChangesCount(1); | 961 ChangeNodeDescription(connection2_->changes())); |
1208 Changes changes = client2_.GetAndClearChanges(); | 962 } |
1209 EXPECT_EQ( | 963 |
1210 "HierarchyChanged change_id=1 node=1,1 new_parent=0,1 old_parent=null", | 964 // Delete 2. |
1211 changes[0]); | 965 { |
1212 const std::vector<TestNode>& nodes(client2_.hierarchy_changed_nodes()); | 966 ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 2))); |
1213 ASSERT_EQ(1u, nodes.size()); | 967 |
1214 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[0].ToString()); | 968 // TODO(sky): fix this, shouldn't get ServerChangeIdAdvanced. |
1215 } | 969 connection2_->DoRunLoopUntilChangesCount(2); |
1216 | 970 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1217 // Delete 1. | 971 ASSERT_EQ(2u, changes.size()); |
1218 { | 972 EXPECT_EQ("NodeDeleted change_id=2 node=1,2", changes[0]); |
1219 ASSERT_TRUE(DeleteNode(view_manager_.get(), CreateNodeId(client_.id(), 1))); | 973 EXPECT_EQ("ServerChangeIdAdvanced 3", changes[1]); |
1220 EXPECT_TRUE(client_.GetAndClearChanges().empty()); | 974 } |
1221 | 975 |
1222 client2_.DoRunLoopUntilChangesCount(1); | 976 // Create 2 again, and add it back to 1. Should get the same notification. |
1223 Changes changes = client2_.GetAndClearChanges(); | 977 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
1224 ASSERT_EQ(1u, changes.size()); | 978 { |
1225 EXPECT_EQ("NodeDeleted change_id=2 node=1,1", changes[0]); | 979 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 3)); |
1226 } | 980 |
1227 | 981 connection2_->DoRunLoopUntilChangesCount(1); |
1228 // Create 1 again, and add it back to the root. Should get the same | 982 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1229 // notification. | 983 EXPECT_EQ( |
1230 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 984 "HierarchyChanged change_id=3 node=1,2 new_parent=1,1 old_parent=null", |
1231 { | 985 changes[0]); |
1232 ASSERT_TRUE(AddNode(view_manager_.get(), | 986 EXPECT_EQ("[node=1,2 parent=1,1 view=null]", |
1233 CreateNodeId(0, 1), | 987 ChangeNodeDescription(connection2_->changes())); |
1234 CreateNodeId(client_.id(), 1), | |
1235 3)); | |
1236 EXPECT_TRUE(client_.GetAndClearChanges().empty()); | |
1237 | |
1238 client2_.DoRunLoopUntilChangesCount(1); | |
1239 Changes changes = client2_.GetAndClearChanges(); | |
1240 EXPECT_EQ( | |
1241 "HierarchyChanged change_id=3 node=1,1 new_parent=0,1 old_parent=null", | |
1242 changes[0]); | |
1243 const std::vector<TestNode>& nodes(client2_.hierarchy_changed_nodes()); | |
1244 ASSERT_EQ(1u, nodes.size()); | |
1245 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[0].ToString()); | |
1246 } | 988 } |
1247 } | 989 } |
1248 | 990 |
1249 // Assertions around setting a view. | 991 // Assertions around setting a view. |
1250 TEST_F(ViewManagerConnectionTest, SetView) { | 992 TEST_F(ViewManagerConnectionTest, SetView) { |
1251 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 993 // Create nodes 1, 2 and 3 and the view 11. Nodes 2 and 3 are parented to 1. |
1252 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | 994 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
1253 ASSERT_TRUE(CreateView(view_manager_.get(), 1, 11)); | 995 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
1254 ASSERT_TRUE(AddNode(view_manager_.get(), 1, CreateNodeId(1, 1), 1)); | 996 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3))); |
1255 ASSERT_TRUE(AddNode(view_manager_.get(), 1, CreateNodeId(1, 2), 2)); | 997 ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 11))); |
1256 EXPECT_TRUE(client_.GetAndClearChanges().empty()); | 998 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1)); |
1257 | 999 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 3), 2)); |
1258 EstablishSecondConnection(); | 1000 |
1259 EXPECT_TRUE(client2_.GetAndClearChanges().empty()); | 1001 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); |
1260 | 1002 |
1261 // Set view 11 on node 1. | 1003 // Set view 11 on node 1. |
1262 { | 1004 { |
1263 ASSERT_TRUE(SetView(view_manager_.get(), | 1005 ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 1), |
1264 CreateNodeId(client_.id(), 1), | 1006 BuildViewId(1, 11))); |
1265 CreateViewId(client_.id(), 11))); | 1007 |
1266 Changes changes(client_.GetAndClearChanges()); | 1008 connection2_->DoRunLoopUntilChangesCount(1); |
1267 ASSERT_TRUE(changes.empty()); | 1009 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1268 | 1010 ASSERT_EQ(1u, changes.size()); |
1269 client2_.DoRunLoopUntilChangesCount(1); | 1011 EXPECT_EQ("ViewReplaced node=1,1 new_view=1,11 old_view=null", |
1270 changes = client2_.GetAndClearChanges(); | 1012 changes[0]); |
1271 ASSERT_EQ(1u, changes.size()); | |
1272 EXPECT_EQ( | |
1273 "ViewReplaced node=1,1 new_view=1,11 old_view=null", | |
1274 changes[0]); | |
1275 } | 1013 } |
1276 | 1014 |
1277 // Set view 11 on node 2. | 1015 // Set view 11 on node 2. |
1278 { | 1016 { |
1279 ASSERT_TRUE(SetView(view_manager_.get(), | 1017 ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 2), BuildViewId(1, 11))); |
1280 CreateNodeId(client_.id(), 2), | 1018 |
1281 CreateViewId(client_.id(), 11))); | 1019 connection2_->DoRunLoopUntilChangesCount(2); |
1282 Changes changes(client_.GetAndClearChanges()); | 1020 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1283 ASSERT_TRUE(changes.empty()); | |
1284 | |
1285 client2_.DoRunLoopUntilChangesCount(2); | |
1286 changes = client2_.GetAndClearChanges(); | |
1287 ASSERT_EQ(2u, changes.size()); | 1021 ASSERT_EQ(2u, changes.size()); |
1288 EXPECT_EQ("ViewReplaced node=1,1 new_view=null old_view=1,11", | 1022 EXPECT_EQ("ViewReplaced node=1,1 new_view=null old_view=1,11", |
1289 changes[0]); | 1023 changes[0]); |
1290 EXPECT_EQ("ViewReplaced node=1,2 new_view=1,11 old_view=null", | 1024 EXPECT_EQ("ViewReplaced node=1,2 new_view=1,11 old_view=null", |
1291 changes[1]); | 1025 changes[1]); |
1292 } | 1026 } |
1293 } | 1027 } |
1294 | 1028 |
1295 // Verifies deleting a node with a view sends correct notifications. | 1029 // Verifies deleting a node with a view sends correct notifications. |
1296 TEST_F(ViewManagerConnectionTest, DeleteNodeWithView) { | 1030 TEST_F(ViewManagerConnectionTest, DeleteNodeWithView) { |
1297 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 1031 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
1298 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | 1032 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
1299 ASSERT_TRUE(CreateView(view_manager_.get(), 1, 11)); | 1033 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3))); |
1300 EXPECT_TRUE(client_.GetAndClearChanges().empty()); | 1034 ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 11))); |
1301 | 1035 |
1302 // Set view 11 on node 1. | 1036 // Set view 11 on node 2. |
1303 ASSERT_TRUE(SetView(view_manager_.get(), | 1037 ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 2), BuildViewId(1, 11))); |
1304 CreateNodeId(client_.id(), 1), | |
1305 CreateViewId(client_.id(), 11))); | |
1306 client_.GetAndClearChanges(); | |
1307 | 1038 |
1308 EstablishSecondConnection(); | 1039 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); |
1309 EXPECT_TRUE(client2_.GetAndClearChanges().empty()); | |
1310 | 1040 |
1311 // Delete node 1. The second connection should not see this because the node | 1041 // Delete node 2. The second connection should not see this because the node |
1312 // was not known to it. | 1042 // was not known to it. |
1313 { | 1043 { |
1314 ASSERT_TRUE(DeleteNode(view_manager_.get(), CreateNodeId(client_.id(), 1))); | 1044 ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 2))); |
1315 Changes changes(client_.GetAndClearChanges()); | |
1316 ASSERT_TRUE(changes.empty()); | |
1317 | 1045 |
1318 client2_.DoRunLoopUntilChangesCount(1); | 1046 connection2_->DoRunLoopUntilChangesCount(1); |
1319 changes = client2_.GetAndClearChanges(); | 1047 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1320 ASSERT_EQ(1u, changes.size()); | 1048 ASSERT_EQ(1u, changes.size()); |
1321 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]); | 1049 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]); |
1322 } | 1050 } |
1323 | 1051 |
1324 // Parent 2 to the root. | 1052 // Parent 3 to 1. |
1325 ASSERT_TRUE(AddNode(view_manager_.get(), | 1053 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 3), 2)); |
1326 CreateNodeId(0, 1), | 1054 connection2_->DoRunLoopUntilChangesCount(1); |
1327 CreateNodeId(client_.id(), 2), | |
1328 2)); | |
1329 client2_.DoRunLoopUntilChangesCount(1); | |
1330 client2_.GetAndClearChanges(); | |
1331 | 1055 |
1332 // Set view 11 on node 2. | 1056 // Set view 11 on node 3. |
1333 { | 1057 { |
1334 ASSERT_TRUE(SetView(view_manager_.get(), | 1058 ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 3), BuildViewId(1, 11))); |
1335 CreateNodeId(client_.id(), 2), | |
1336 CreateViewId(client_.id(), 11))); | |
1337 Changes changes(client_.GetAndClearChanges()); | |
1338 ASSERT_TRUE(changes.empty()); | |
1339 | 1059 |
1340 client2_.DoRunLoopUntilChangesCount(1); | 1060 connection2_->DoRunLoopUntilChangesCount(1); |
1341 changes = client2_.GetAndClearChanges(); | 1061 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1342 ASSERT_EQ(1u, changes.size()); | 1062 ASSERT_EQ(1u, changes.size()); |
1343 EXPECT_EQ("ViewReplaced node=1,2 new_view=1,11 old_view=null", changes[0]); | 1063 EXPECT_EQ("ViewReplaced node=1,3 new_view=1,11 old_view=null", changes[0]); |
1344 } | 1064 } |
1345 | 1065 |
1346 // Delete node. | 1066 // Delete 3. |
1347 { | 1067 { |
1348 ASSERT_TRUE(DeleteNode(view_manager_.get(), CreateNodeId(client_.id(), 2))); | 1068 ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 3))); |
1349 Changes changes(client_.GetAndClearChanges()); | |
1350 ASSERT_TRUE(changes.empty()); | |
1351 | 1069 |
1352 client2_.DoRunLoopUntilChangesCount(2); | 1070 // TODO(sky): shouldn't get ServerChangeIdAdvanced here. |
1353 changes = client2_.GetAndClearChanges(); | 1071 connection2_->DoRunLoopUntilChangesCount(2); |
| 1072 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1354 ASSERT_EQ(2u, changes.size()); | 1073 ASSERT_EQ(2u, changes.size()); |
1355 EXPECT_EQ("ViewReplaced node=1,2 new_view=null old_view=1,11", changes[0]); | 1074 EXPECT_EQ("NodeDeleted change_id=3 node=1,3", changes[0]); |
1356 EXPECT_EQ("NodeDeleted change_id=3 node=1,2", changes[1]); | 1075 EXPECT_EQ("ServerChangeIdAdvanced 4", changes[1]); |
1357 } | 1076 } |
1358 } | 1077 } |
1359 | 1078 |
1360 // Sets view from one connection on another. | 1079 // Sets view from one connection on another. |
1361 TEST_F(ViewManagerConnectionTest, SetViewFromSecondConnection) { | 1080 TEST_F(ViewManagerConnectionTest, SetViewFromSecondConnection) { |
1362 EstablishSecondConnection(); | 1081 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); |
1363 | 1082 |
1364 // Create two nodes in first connection. | 1083 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
1365 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | |
1366 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | |
1367 | |
1368 EXPECT_TRUE(client_.GetAndClearChanges().empty()); | |
1369 EXPECT_TRUE(client2_.GetAndClearChanges().empty()); | |
1370 | 1084 |
1371 // Create a view in the second connection. | 1085 // Create a view in the second connection. |
1372 ASSERT_TRUE(CreateView(view_manager2_.get(), 2, 51)); | 1086 ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 51))); |
1373 | 1087 |
1374 // Attach view to node 1 in the first connectoin. | 1088 // Attach view to node 1 in the first connection. |
1375 { | 1089 { |
1376 ASSERT_TRUE(SetView(view_manager2_.get(), | 1090 ASSERT_TRUE(connection2_->SetView(BuildNodeId(1, 1), BuildViewId(2, 51))); |
1377 CreateNodeId(client_.id(), 1), | 1091 connection_->DoRunLoopUntilChangesCount(1); |
1378 CreateViewId(client2_.id(), 51))); | 1092 const Changes changes(ChangesToDescription1(connection_->changes())); |
1379 client_.DoRunLoopUntilChangesCount(1); | |
1380 Changes changes(client_.GetAndClearChanges()); | |
1381 ASSERT_EQ(1u, changes.size()); | 1093 ASSERT_EQ(1u, changes.size()); |
1382 EXPECT_EQ("ViewReplaced node=1,1 new_view=2,51 old_view=null", changes[0]); | 1094 EXPECT_EQ("ViewReplaced node=1,1 new_view=2,51 old_view=null", changes[0]); |
1383 } | 1095 } |
1384 | 1096 |
1385 // Shutdown the second connection and verify view is removed. | 1097 // Shutdown the second connection and verify view is removed. |
1386 { | 1098 { |
1387 DestroySecondConnection(); | 1099 DestroySecondConnection(); |
1388 client_.DoRunLoopUntilChangesCount(2); | 1100 connection_->DoRunLoopUntilChangesCount(2); |
1389 | 1101 const Changes changes(ChangesToDescription1(connection_->changes())); |
1390 Changes changes(client_.GetAndClearChanges()); | |
1391 ASSERT_EQ(2u, changes.size()); | 1102 ASSERT_EQ(2u, changes.size()); |
1392 EXPECT_EQ("ViewReplaced node=1,1 new_view=null old_view=2,51", changes[0]); | 1103 EXPECT_EQ("ViewReplaced node=1,1 new_view=null old_view=2,51", changes[0]); |
1393 EXPECT_EQ("ViewDeleted view=2,51", changes[1]); | 1104 EXPECT_EQ("ViewDeleted view=2,51", changes[1]); |
1394 } | 1105 } |
1395 } | 1106 } |
1396 | 1107 |
1397 // Assertions for GetNodeTree. | 1108 // Assertions for GetNodeTree. |
1398 TEST_F(ViewManagerConnectionTest, GetNodeTree) { | 1109 TEST_F(ViewManagerConnectionTest, GetNodeTree) { |
1399 EstablishSecondConnection(); | 1110 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); |
1400 | 1111 |
1401 // Create two nodes in first connection, 1 and 11 (11 is a child of 1). | 1112 // Create 11 in first connection and make it a child of 1. |
1402 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 1113 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 11))); |
1403 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 11)); | 1114 ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1)); |
1404 ASSERT_TRUE(AddNode(view_manager_.get(), | 1115 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 11), 2)); |
1405 CreateNodeId(0, 1), | |
1406 CreateNodeId(client_.id(), 1), | |
1407 1)); | |
1408 ASSERT_TRUE(AddNode(view_manager_.get(), | |
1409 CreateNodeId(client_.id(), 1), | |
1410 CreateNodeId(client_.id(), 11), | |
1411 2)); | |
1412 | 1116 |
1413 // Create two nodes in second connection, 2 and 3, both children of the root. | 1117 // Create two nodes in second connection, 2 and 3, both children of 1. |
1414 ASSERT_TRUE(CreateNode(view_manager2_.get(), 2, 2)); | 1118 ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 2))); |
1415 ASSERT_TRUE(CreateNode(view_manager2_.get(), 2, 3)); | 1119 ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 3))); |
1416 ASSERT_TRUE(AddNode(view_manager2_.get(), | 1120 ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 2), 3)); |
1417 CreateNodeId(0, 1), | 1121 ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 3), 4)); |
1418 CreateNodeId(client2_.id(), 2), | |
1419 3)); | |
1420 ASSERT_TRUE(AddNode(view_manager2_.get(), | |
1421 CreateNodeId(0, 1), | |
1422 CreateNodeId(client2_.id(), 3), | |
1423 4)); | |
1424 | 1122 |
1425 // Attach view to node 11 in the first connection. | 1123 // Attach view to node 11 in the first connection. |
1426 ASSERT_TRUE(CreateView(view_manager_.get(), 1, 51)); | 1124 ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 51))); |
1427 ASSERT_TRUE(SetView(view_manager_.get(), | 1125 ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 11), BuildViewId(1, 51))); |
1428 CreateNodeId(client_.id(), 11), | |
1429 CreateViewId(client_.id(), 51))); | |
1430 | 1126 |
1431 // Verifies GetNodeTree() on the root. | 1127 // Verifies GetNodeTree() on the root. |
1432 { | 1128 { |
1433 std::vector<TestNode> nodes; | 1129 std::vector<TestNode> nodes; |
1434 GetNodeTree(view_manager2_.get(), CreateNodeId(0, 1), &nodes); | 1130 connection_->GetNodeTree(BuildNodeId(0, 1), &nodes); |
1435 ASSERT_EQ(5u, nodes.size()); | 1131 ASSERT_EQ(5u, nodes.size()); |
1436 EXPECT_EQ("node=0,1 parent=null view=null", nodes[0].ToString()); | 1132 EXPECT_EQ("node=0,1 parent=null view=null", nodes[0].ToString()); |
1437 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[1].ToString()); | 1133 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[1].ToString()); |
1438 EXPECT_EQ("node=1,11 parent=1,1 view=1,51", nodes[2].ToString()); | 1134 EXPECT_EQ("node=1,11 parent=1,1 view=1,51", nodes[2].ToString()); |
1439 EXPECT_EQ("node=2,2 parent=0,1 view=null", nodes[3].ToString()); | 1135 EXPECT_EQ("node=2,2 parent=1,1 view=null", nodes[3].ToString()); |
1440 EXPECT_EQ("node=2,3 parent=0,1 view=null", nodes[4].ToString()); | 1136 EXPECT_EQ("node=2,3 parent=1,1 view=null", nodes[4].ToString()); |
1441 } | 1137 } |
1442 | 1138 |
1443 // Verifies GetNodeTree() on the node 1,1. | 1139 // Verifies GetNodeTree() on the node 1,1. |
1444 { | 1140 { |
1445 std::vector<TestNode> nodes; | 1141 std::vector<TestNode> nodes; |
1446 GetNodeTree(view_manager2_.get(), CreateNodeId(1, 1), &nodes); | 1142 connection2_->GetNodeTree(BuildNodeId(1, 1), &nodes); |
1447 ASSERT_EQ(2u, nodes.size()); | 1143 ASSERT_EQ(4u, nodes.size()); |
1448 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[0].ToString()); | 1144 EXPECT_EQ("node=1,1 parent=null view=null", nodes[0].ToString()); |
1449 EXPECT_EQ("node=1,11 parent=1,1 view=1,51", nodes[1].ToString()); | 1145 EXPECT_EQ("node=1,11 parent=1,1 view=1,51", nodes[1].ToString()); |
| 1146 EXPECT_EQ("node=2,2 parent=1,1 view=null", nodes[2].ToString()); |
| 1147 EXPECT_EQ("node=2,3 parent=1,1 view=null", nodes[3].ToString()); |
| 1148 } |
| 1149 |
| 1150 // Connection 2 shouldn't be able to get the root tree. |
| 1151 { |
| 1152 std::vector<TestNode> nodes; |
| 1153 connection2_->GetNodeTree(BuildNodeId(0, 1), &nodes); |
| 1154 ASSERT_EQ(0u, nodes.size()); |
1450 } | 1155 } |
1451 } | 1156 } |
1452 | 1157 |
1453 TEST_F(ViewManagerConnectionTest, SetNodeBounds) { | 1158 TEST_F(ViewManagerConnectionTest, SetNodeBounds) { |
1454 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 1159 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
1455 ASSERT_TRUE(AddNode(view_manager_.get(), | 1160 ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1)); |
1456 CreateNodeId(0, 1), | |
1457 CreateNodeId(1, 1), | |
1458 1)); | |
1459 EstablishSecondConnection(); | |
1460 | 1161 |
1461 ASSERT_TRUE(SetNodeBounds(view_manager_.get(), | 1162 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); |
1462 CreateNodeId(1, 1), | |
1463 gfx::Rect(0, 0, 100, 100))); | |
1464 | 1163 |
1465 client2_.DoRunLoopUntilChangesCount(1); | 1164 ASSERT_TRUE(connection_->SetNodeBounds(BuildNodeId(1, 1), |
1466 Changes changes(client2_.GetAndClearChanges()); | 1165 gfx::Rect(0, 0, 100, 100))); |
| 1166 |
| 1167 connection2_->DoRunLoopUntilChangesCount(1); |
| 1168 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1467 ASSERT_EQ(1u, changes.size()); | 1169 ASSERT_EQ(1u, changes.size()); |
1468 EXPECT_EQ("BoundsChanged node=1,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100", | 1170 EXPECT_EQ("BoundsChanged node=1,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100", |
1469 changes[0]); | 1171 changes[0]); |
1470 | 1172 |
1471 // Should not be possible to change the bounds of a node created by another | 1173 // Should not be possible to change the bounds of a node created by another |
1472 // connection. | 1174 // connection. |
1473 ASSERT_FALSE(SetNodeBounds(view_manager2_.get(), | 1175 ASSERT_FALSE(connection2_->SetNodeBounds(BuildNodeId(1, 1), |
1474 CreateNodeId(1, 1), | 1176 gfx::Rect(0, 0, 0, 0))); |
1475 gfx::Rect(0, 0, 0, 0))); | |
1476 } | 1177 } |
1477 | 1178 |
1478 // Various assertions around SetRoots. | 1179 // Various assertions around SetRoots. |
1479 TEST_F(ViewManagerConnectionTest, SetRoots) { | 1180 TEST_F(ViewManagerConnectionTest, SetRoots) { |
1480 // Create 1, 2, and 3 in the first connection. | 1181 // Create 1, 2, and 3 in the first connection. |
1481 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 1182 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
1482 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | 1183 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
1483 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 3)); | 1184 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3))); |
1484 | 1185 |
1485 // Parent 1 to the root. | 1186 // Parent 1 to the root. |
1486 ASSERT_TRUE(AddNode(view_manager_.get(), | 1187 ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1)); |
1487 CreateNodeId(0, 1), | |
1488 CreateNodeId(client_.id(), 1), | |
1489 1)); | |
1490 | 1188 |
1491 // Establish the second connection and give it the roots 1 and 3. | 1189 // Establish the second connection and give it the roots 1 and 3. |
1492 { | 1190 { |
1493 std::vector<Change> changes(EstablishBackgroundConnectionWithRoots( | 1191 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnectionWithRoots( |
1494 CreateNodeId(1, 1), CreateNodeId(1, 3))); | 1192 BuildNodeId(1, 1), BuildNodeId(1, 3))); |
1495 if (HasFatalFailure()) | 1193 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1496 return; | |
1497 ASSERT_EQ(1u, changes.size()); | 1194 ASSERT_EQ(1u, changes.size()); |
1498 EXPECT_EQ("OnConnectionEstablished", ChangesToDescription1(changes)[0]); | 1195 EXPECT_EQ("OnConnectionEstablished", changes[0]); |
1499 EXPECT_EQ("[node=1,1 parent=null view=null]," | 1196 EXPECT_EQ("[node=1,1 parent=null view=null]," |
1500 "[node=1,3 parent=null view=null]", | 1197 "[node=1,3 parent=null view=null]", |
1501 ChangeNodeDescription(changes)); | 1198 ChangeNodeDescription(connection2_->changes())); |
1502 } | 1199 } |
1503 | 1200 |
1504 // Create 4 and add it to the root, connection 2 should only get id advanced. | 1201 // Create 4 and add it to the root, connection 2 should only get id advanced. |
1505 { | 1202 { |
1506 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 4)); | 1203 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 4))); |
1507 ASSERT_TRUE(AddNode(view_manager_.get(), | 1204 ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 4), 2)); |
1508 CreateNodeId(0, 1), | 1205 |
1509 CreateNodeId(client_.id(), 4), | 1206 connection2_->DoRunLoopUntilChangesCount(1); |
1510 2)); | 1207 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1511 Changes changes = ChangesToDescription1( | |
1512 background_connection_->DoRunLoopUntilChangesCount(1)); | |
1513 ASSERT_EQ(1u, changes.size()); | 1208 ASSERT_EQ(1u, changes.size()); |
1514 EXPECT_EQ("ServerChangeIdAdvanced 3", changes[0]); | 1209 EXPECT_EQ("ServerChangeIdAdvanced 3", changes[0]); |
1515 } | 1210 } |
1516 | 1211 |
1517 // Move 4 under 3, this should expose 4 to the client. | 1212 // Move 4 under 3, this should expose 4 to the client. |
1518 { | 1213 { |
1519 ASSERT_TRUE(AddNode(view_manager_.get(), | 1214 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 3), BuildNodeId(1, 4), 3)); |
1520 CreateNodeId(1, 3), | 1215 connection2_->DoRunLoopUntilChangesCount(1); |
1521 CreateNodeId(1, 4), | 1216 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1522 3)); | 1217 ASSERT_EQ(1u, changes.size()); |
1523 std::vector<Change> changes = | |
1524 background_connection_->DoRunLoopUntilChangesCount(1); | |
1525 Changes change_strings(ChangesToDescription1(changes)); | |
1526 ASSERT_EQ(1u, change_strings.size()); | |
1527 EXPECT_EQ( | 1218 EXPECT_EQ( |
1528 "HierarchyChanged change_id=3 node=1,4 new_parent=1,3 " | 1219 "HierarchyChanged change_id=3 node=1,4 new_parent=1,3 " |
1529 "old_parent=null", change_strings[0]); | 1220 "old_parent=null", changes[0]); |
1530 EXPECT_EQ("[node=1,4 parent=1,3 view=null]", | 1221 EXPECT_EQ("[node=1,4 parent=1,3 view=null]", |
1531 ChangeNodeDescription(changes)); | 1222 ChangeNodeDescription(connection2_->changes())); |
1532 } | 1223 } |
1533 | 1224 |
1534 // Move 4 under 2, since 2 isn't a root client should get a delete. | 1225 // Move 4 under 2, since 2 isn't a root client should get a delete. |
1535 { | 1226 { |
1536 ASSERT_TRUE(AddNode(view_manager_.get(), | 1227 ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 4), 4)); |
1537 CreateNodeId(1, 2), | 1228 connection2_->DoRunLoopUntilChangesCount(1); |
1538 CreateNodeId(1, 4), | 1229 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1539 4)); | |
1540 Changes changes = ChangesToDescription1( | |
1541 background_connection_->DoRunLoopUntilChangesCount(1)); | |
1542 ASSERT_EQ(1u, changes.size()); | 1230 ASSERT_EQ(1u, changes.size()); |
1543 EXPECT_EQ("NodeDeleted change_id=4 node=1,4", changes[0]); | 1231 EXPECT_EQ("NodeDeleted change_id=4 node=1,4", changes[0]); |
1544 } | 1232 } |
1545 | 1233 |
1546 // Delete 4, client shouldn't receive a delete since it should no longer know | 1234 // Delete 4, client shouldn't receive a delete since it should no longer know |
1547 // about 4. | 1235 // about 4. |
1548 { | 1236 { |
1549 ASSERT_TRUE(DeleteNode(view_manager_.get(), CreateNodeId(client_.id(), 4))); | 1237 ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 4))); |
1550 ASSERT_TRUE(client_.GetAndClearChanges().empty()); | |
1551 | 1238 |
1552 Changes changes = ChangesToDescription1( | 1239 connection2_->DoRunLoopUntilChangesCount(1); |
1553 background_connection_->DoRunLoopUntilChangesCount(1)); | 1240 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1554 ASSERT_EQ(1u, changes.size()); | 1241 ASSERT_EQ(1u, changes.size()); |
1555 EXPECT_EQ("ServerChangeIdAdvanced 6", changes[0]); | 1242 EXPECT_EQ("ServerChangeIdAdvanced 6", changes[0]); |
1556 } | 1243 } |
1557 } | 1244 } |
1558 | 1245 |
1559 // Verify AddNode fails when trying to manipulate nodes in other roots. | 1246 // Verify AddNode fails when trying to manipulate nodes in other roots. |
1560 TEST_F(ViewManagerConnectionTest, CantMoveNodesFromOtherRoot) { | 1247 TEST_F(ViewManagerConnectionTest, CantMoveNodesFromOtherRoot) { |
1561 // Create 1 and 2 in the first connection. | 1248 // Create 1 and 2 in the first connection. |
1562 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 1249 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
1563 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | 1250 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
1564 | 1251 |
1565 ASSERT_NO_FATAL_FAILURE(EstablishBackgroundConnectionWithRoot1()); | 1252 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); |
1566 | 1253 |
1567 // Try to move 2 to be a child of 1 from connection 2. This should fail as 2 | 1254 // Try to move 2 to be a child of 1 from connection 2. This should fail as 2 |
1568 // should not be able to access 1. | 1255 // should not be able to access 1. |
1569 ASSERT_FALSE(background_connection_->AddNode( | 1256 ASSERT_FALSE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1)); |
1570 CreateNodeId(1, 1), CreateNodeId(1, 2), 1)); | |
1571 | 1257 |
1572 // Try to reparent 1 to the root. A connection is not allowed to reparent its | 1258 // Try to reparent 1 to the root. A connection is not allowed to reparent its |
1573 // roots. | 1259 // roots. |
1574 ASSERT_FALSE(background_connection_->AddNode(CreateNodeId(0, 1), | 1260 ASSERT_FALSE(connection2_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1)); |
1575 CreateNodeId(1, 1), 1)); | |
1576 } | 1261 } |
1577 | 1262 |
1578 // Verify RemoveNodeFromParent fails for nodes that are descendants of the | 1263 // Verify RemoveNodeFromParent fails for nodes that are descendants of the |
1579 // roots. | 1264 // roots. |
1580 TEST_F(ViewManagerConnectionTest, CantRemoveNodesInOtherRoots) { | 1265 TEST_F(ViewManagerConnectionTest, CantRemoveNodesInOtherRoots) { |
1581 // Create 1 and 2 in the first connection and parent both to the root. | 1266 // Create 1 and 2 in the first connection and parent both to the root. |
1582 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 1267 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
1583 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | 1268 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
1584 | 1269 |
1585 ASSERT_TRUE(AddNode(view_manager_.get(), | 1270 ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1)); |
1586 CreateNodeId(0, 1), | 1271 ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 2), 2)); |
1587 CreateNodeId(client_.id(), 1), | |
1588 1)); | |
1589 ASSERT_TRUE(AddNode(view_manager_.get(), | |
1590 CreateNodeId(0, 1), | |
1591 CreateNodeId(client_.id(), 2), | |
1592 2)); | |
1593 | 1272 |
1594 // Establish the second connection and give it the root 1. | 1273 // Establish the second connection and give it the root 1. |
1595 ASSERT_NO_FATAL_FAILURE(EstablishBackgroundConnectionWithRoot1()); | 1274 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); |
1596 | 1275 |
1597 // Connection 2 should not be able to remove node 2 or 1 from its parent. | 1276 // Connection 2 should not be able to remove node 2 or 1 from its parent. |
1598 ASSERT_FALSE(background_connection_->RemoveNodeFromParent( | 1277 ASSERT_FALSE(connection2_->RemoveNodeFromParent(BuildNodeId(1, 2), 3)); |
1599 CreateNodeId(1, 2), 3)); | 1278 ASSERT_FALSE(connection2_->RemoveNodeFromParent(BuildNodeId(1, 1), 3)); |
1600 ASSERT_FALSE(background_connection_->RemoveNodeFromParent(CreateNodeId(1, 1), | |
1601 3)); | |
1602 | 1279 |
1603 // Create nodes 10 and 11 in 2. | 1280 // Create nodes 10 and 11 in 2. |
1604 ASSERT_TRUE(background_connection_->CreateNode(CreateNodeId(2, 10))); | 1281 ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 10))); |
1605 ASSERT_TRUE(background_connection_->CreateNode(CreateNodeId(2, 11))); | 1282 ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 11))); |
1606 | 1283 |
1607 // Parent 11 to 10. | 1284 // Parent 11 to 10. |
1608 ASSERT_TRUE(background_connection_->AddNode(CreateNodeId(2, 10), | 1285 ASSERT_TRUE(connection2_->AddNode(BuildNodeId(2, 10), BuildNodeId(2, 11), 3)); |
1609 CreateNodeId(2, 11), 3)); | |
1610 // Remove 11 from 10. | 1286 // Remove 11 from 10. |
1611 ASSERT_TRUE(background_connection_->RemoveNodeFromParent( | 1287 ASSERT_TRUE(connection2_->RemoveNodeFromParent( BuildNodeId(2, 11), 4)); |
1612 CreateNodeId(2, 11), 4)); | |
1613 | 1288 |
1614 // Verify nothing was actually removed. | 1289 // Verify nothing was actually removed. |
1615 { | 1290 { |
1616 std::vector<TestNode> nodes; | 1291 std::vector<TestNode> nodes; |
1617 GetNodeTree(view_manager_.get(), CreateNodeId(0, 1), &nodes); | 1292 connection_->GetNodeTree(BuildNodeId(0, 1), &nodes); |
1618 ASSERT_EQ(3u, nodes.size()); | 1293 ASSERT_EQ(3u, nodes.size()); |
1619 EXPECT_EQ("node=0,1 parent=null view=null", nodes[0].ToString()); | 1294 EXPECT_EQ("node=0,1 parent=null view=null", nodes[0].ToString()); |
1620 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[1].ToString()); | 1295 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[1].ToString()); |
1621 EXPECT_EQ("node=1,2 parent=0,1 view=null", nodes[2].ToString()); | 1296 EXPECT_EQ("node=1,2 parent=0,1 view=null", nodes[2].ToString()); |
1622 } | 1297 } |
1623 } | 1298 } |
1624 | 1299 |
1625 // Verify SetView fails for nodes that are not descendants of the roots. | 1300 // Verify SetView fails for nodes that are not descendants of the roots. |
1626 TEST_F(ViewManagerConnectionTest, CantRemoveSetViewInOtherRoots) { | 1301 TEST_F(ViewManagerConnectionTest, CantRemoveSetViewInOtherRoots) { |
1627 // Create 1 and 2 in the first connection and parent both to the root. | 1302 // Create 1 and 2 in the first connection and parent both to the root. |
1628 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 1303 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
1629 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | 1304 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
1630 | 1305 |
1631 ASSERT_TRUE(AddNode(view_manager_.get(), | 1306 ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1)); |
1632 CreateNodeId(0, 1), | 1307 ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 2), 2)); |
1633 CreateNodeId(client_.id(), 1), | |
1634 1)); | |
1635 ASSERT_TRUE(AddNode(view_manager_.get(), | |
1636 CreateNodeId(0, 1), | |
1637 CreateNodeId(client_.id(), 2), | |
1638 2)); | |
1639 | 1308 |
1640 ASSERT_NO_FATAL_FAILURE(EstablishBackgroundConnectionWithRoot1()); | 1309 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); |
1641 | 1310 |
1642 // Create a view in the second connection. | 1311 // Create a view in the second connection. |
1643 ASSERT_TRUE(background_connection_->CreateView(CreateViewId(2, 51))); | 1312 ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 51))); |
1644 | 1313 |
1645 // Connection 2 should be able to set the view on node 1 (it's root), but not | 1314 // Connection 2 should be able to set the view on node 1 (it's root), but not |
1646 // on 2. | 1315 // on 2. |
1647 ASSERT_TRUE(background_connection_->SetView(CreateNodeId(client_.id(), 1), | 1316 ASSERT_TRUE(connection2_->SetView(BuildNodeId(1, 1), BuildViewId(2, 51))); |
1648 CreateViewId(2, 51))); | 1317 ASSERT_FALSE(connection2_->SetView(BuildNodeId(1, 2), BuildViewId(2, 51))); |
1649 ASSERT_FALSE(background_connection_->SetView(CreateNodeId(client_.id(), 2), | |
1650 CreateViewId(2, 51))); | |
1651 } | 1318 } |
1652 | 1319 |
1653 // Verify GetNodeTree fails for nodes that are not descendants of the roots. | 1320 // Verify GetNodeTree fails for nodes that are not descendants of the roots. |
1654 TEST_F(ViewManagerConnectionTest, CantGetNodeTreeOfOtherRoots) { | 1321 TEST_F(ViewManagerConnectionTest, CantGetNodeTreeOfOtherRoots) { |
1655 // Create 1 and 2 in the first connection and parent both to the root. | 1322 // Create 1 and 2 in the first connection and parent both to the root. |
1656 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | 1323 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
1657 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); | 1324 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
1658 | 1325 |
1659 ASSERT_TRUE(AddNode(view_manager_.get(), | 1326 ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1)); |
1660 CreateNodeId(0, 1), | 1327 ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 2), 2)); |
1661 CreateNodeId(client_.id(), 1), | |
1662 1)); | |
1663 ASSERT_TRUE(AddNode(view_manager_.get(), | |
1664 CreateNodeId(0, 1), | |
1665 CreateNodeId(client_.id(), 2), | |
1666 2)); | |
1667 | 1328 |
1668 ASSERT_NO_FATAL_FAILURE(EstablishBackgroundConnectionWithRoot1()); | 1329 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); |
1669 | 1330 |
1670 std::vector<TestNode> nodes; | 1331 std::vector<TestNode> nodes; |
1671 | 1332 |
1672 // Should get nothing for the root. | 1333 // Should get nothing for the root. |
1673 background_connection_->GetNodeTree(CreateNodeId(0, 1), &nodes); | 1334 connection2_->GetNodeTree(BuildNodeId(0, 1), &nodes); |
1674 ASSERT_TRUE(nodes.empty()); | 1335 ASSERT_TRUE(nodes.empty()); |
1675 | 1336 |
1676 // Should get nothing for node 2. | 1337 // Should get nothing for node 2. |
1677 background_connection_->GetNodeTree(CreateNodeId(1, 2), &nodes); | 1338 connection2_->GetNodeTree(BuildNodeId(1, 2), &nodes); |
1678 ASSERT_TRUE(nodes.empty()); | 1339 ASSERT_TRUE(nodes.empty()); |
1679 | 1340 |
1680 // Should get node 1 if asked for. | 1341 // Should get node 1 if asked for. |
1681 background_connection_->GetNodeTree(CreateNodeId(1, 1), &nodes); | 1342 connection2_->GetNodeTree(BuildNodeId(1, 1), &nodes); |
1682 ASSERT_EQ(1u, nodes.size()); | 1343 ASSERT_EQ(1u, nodes.size()); |
1683 EXPECT_EQ("node=1,1 parent=null view=null", nodes[0].ToString()); | 1344 EXPECT_EQ("node=1,1 parent=null view=null", nodes[0].ToString()); |
1684 } | 1345 } |
1685 | 1346 |
1686 // Verify GetNodeTree fails for nodes that are not descendants of the roots. | |
1687 TEST_F(ViewManagerConnectionTest, Connect) { | |
1688 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); | |
1689 ASSERT_TRUE(Connect(view_manager_.get(), kTestServiceURL, CreateNodeId(1, 1), | |
1690 0)); | |
1691 BackgroundConnection* instance = BackgroundConnection::WaitForInstance(); | |
1692 ASSERT_TRUE(instance != NULL); | |
1693 Changes changes( | |
1694 ChangesToDescription1(instance->DoRunLoopUntilChangesCount(1)));; | |
1695 ASSERT_EQ(1u, changes.size()); | |
1696 EXPECT_EQ("OnConnectionEstablished", changes[0]); | |
1697 } | |
1698 | |
1699 // TODO(sky): add coverage of test that destroys connections and ensures other | 1347 // TODO(sky): add coverage of test that destroys connections and ensures other |
1700 // connections get deletion notification (or advanced server id). | 1348 // connections get deletion notification (or advanced server id). |
1701 | 1349 |
| 1350 // TODO(sky): need to better track changes to initial connection. For example, |
| 1351 // that SetBounsdNodes/AddNode and the like don't result in messages to the |
| 1352 // originating connection. |
| 1353 |
1702 } // namespace service | 1354 } // namespace service |
1703 } // namespace view_manager | 1355 } // namespace view_manager |
1704 } // namespace mojo | 1356 } // namespace mojo |
OLD | NEW |