Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(598)

Side by Side Diff: chrome/browser/multi_process_notification_unittest.cc

Issue 5970015: Add multi-process notification class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed up bad tabs Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/multi_process_notification.h"
6
7 #include "base/basictypes.h"
8 #include "base/compiler_specific.h"
9 #include "base/environment.h"
10 #include "base/logging.h"
11 #include "base/message_loop.h"
12 #include "base/test/multiprocess_test.h"
13 #include "base/test/test_timeouts.h"
14 #include "base/time.h"
15 #include "chrome/browser/browser_thread.h"
16 #include "testing/multiprocess_func_list.h"
17
18 #if defined(OS_MACOSX)
19 // TODO(dmaclach): Remove defined(OS_MACOSX) once
20 // MultiProcessNotification is implemented on Win/Linux.
21
22 namespace {
23
24 const char kStartedNotificationName[] = "MultiProcessTestStartedNotification";
25 const char kQuitNotificationName[] = "MultiProcessTestQuitNotification";
26
27 void SpinRunLoop(int milliseconds) {
28 MessageLoop *loop = MessageLoop::current();
29
30 // Post a quit task so that this loop eventually ends and we don't hang
31 // in the case of a bad test. Usually, the run loop will quit sooner than
32 // that because all tests use a MultiProcessNotificationTestQuit which quits
33 // the current run loop when it gets a notification.
34 loop->PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask(), milliseconds);
35 loop->Run();
36 }
37
38 class SimpleDelegate
39 : public multi_process_notification::Listener::Delegate {
40 public:
41 SimpleDelegate()
42 : notification_received_(false), started_received_(false) { }
43 virtual ~SimpleDelegate();
44
45 virtual void OnNotificationReceived(
46 const std::string& name,
47 multi_process_notification::Domain domain) OVERRIDE;
48 virtual void OnListenerStarted(
49 const std::string& name, multi_process_notification::Domain domain,
50 bool success) OVERRIDE;
51
52 bool WasNotificationReceived() { return notification_received_; }
53 bool WasStartedReceived() { return started_received_; }
54
55 private:
56 bool notification_received_;
57 bool started_received_;
58 DISALLOW_COPY_AND_ASSIGN(SimpleDelegate);
59 };
60
61 SimpleDelegate::~SimpleDelegate() {
62 }
63
64 void SimpleDelegate::OnNotificationReceived(
65 const std::string& name, multi_process_notification::Domain domain) {
66 notification_received_ = true;
67 }
68
69 void SimpleDelegate::OnListenerStarted(
70 const std::string& name, multi_process_notification::Domain domain,
71 bool success) {
72 ASSERT_TRUE(success);
73 started_received_ = true;
74 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
75 }
76
77 class QuitterDelegate : public SimpleDelegate {
78 public:
79 QuitterDelegate() : SimpleDelegate() { }
80 virtual ~QuitterDelegate();
81
82 virtual void OnNotificationReceived(
83 const std::string& name,
84 multi_process_notification::Domain domain) OVERRIDE;
85
86 private:
87 DISALLOW_COPY_AND_ASSIGN(QuitterDelegate);
88 };
89
90 QuitterDelegate::~QuitterDelegate() {
91 }
92
93 void QuitterDelegate::OnNotificationReceived(
94 const std::string& name, multi_process_notification::Domain domain) {
95 SimpleDelegate::OnNotificationReceived(name, domain);
96 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
97 }
98
99 int MultiProcessNotificationMain(multi_process_notification::Domain domain) {
100 BrowserThread browser_thread(BrowserThread::IO);
101 base::Thread::Options options(MessageLoop::TYPE_IO, 0);
102 EXPECT_TRUE(browser_thread.StartWithOptions(options));
103 MessageLoop loop;
104 QuitterDelegate quitter;
105 multi_process_notification::Listener listener(
106 kQuitNotificationName, domain, &quitter);
107 EXPECT_TRUE(listener.Start());
108 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
109 EXPECT_TRUE(quitter.WasStartedReceived());
110 EXPECT_TRUE(multi_process_notification::Post(kStartedNotificationName,
111 domain));
112 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
113 EXPECT_TRUE(quitter.WasNotificationReceived());
114 return 0;
115 }
116
117 } // namespace
118
119 class MultiProcessNotificationTest : public base::MultiProcessTest {
120 public:
121 MultiProcessNotificationTest();
122
123 void PostNotificationTest(multi_process_notification::Domain domain);
124 void CrossPostNotificationTest(multi_process_notification::Domain domain);
125
126 static void SetUpTestCase();
127 static void TearDownTestCase();
128
129 private:
130 MessageLoop loop_;
131 static BrowserThread* g_io_thread;
132 };
133
134 MultiProcessNotificationTest::MultiProcessNotificationTest() {
135 }
136
137 BrowserThread* MultiProcessNotificationTest::g_io_thread = NULL;
138
139 void MultiProcessNotificationTest::SetUpTestCase() {
140 g_io_thread = new BrowserThread(BrowserThread::IO);
141 base::Thread::Options options(MessageLoop::TYPE_IO, 0);
142 ASSERT_TRUE(g_io_thread->StartWithOptions(options));
143 }
144
145 void MultiProcessNotificationTest::TearDownTestCase() {
146 delete g_io_thread;
147 }
148
149 void MultiProcessNotificationTest::PostNotificationTest(
150 multi_process_notification::Domain domain) {
151 QuitterDelegate process_started;
152 multi_process_notification::Listener listener(
153 kStartedNotificationName, domain, &process_started);
154 ASSERT_TRUE(listener.Start());
155 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
156 ASSERT_TRUE(process_started.WasStartedReceived());
157 std::string process_name;
158 switch (domain) {
159 case multi_process_notification::ProfileDomain:
160 process_name = "MultiProcessProfileNotificationMain";
161 break;
162
163 case multi_process_notification::UserDomain:
164 process_name = "MultiProcessUserNotificationMain";
165 break;
166
167 case multi_process_notification::SystemDomain:
168 process_name = "MultiProcessSystemNotificationMain";
169 break;
170 }
171 base::ProcessHandle handle = SpawnChild(process_name, false);
172 ASSERT_TRUE(handle);
173 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
174 ASSERT_TRUE(process_started.WasNotificationReceived());
175 ASSERT_TRUE(multi_process_notification::Post(kQuitNotificationName, domain));
176 int exit_code = 0;
177 EXPECT_TRUE(base::WaitForExitCodeWithTimeout(
178 handle, &exit_code, TestTimeouts::action_max_timeout_ms()));
179 }
180
181 void MultiProcessNotificationTest::CrossPostNotificationTest(
182 multi_process_notification::Domain domain) {
183 // Check to make sure notifications sent to user domain aren't picked up
184 // by system domain listeners and vice versa.
185 std::string local_notification("QuitLocalNotification");
186 std::string final_notification("FinalQuitLocalNotification");
187 QuitterDelegate profile_quitter;
188 QuitterDelegate user_quitter;
189 QuitterDelegate system_quitter;
190 QuitterDelegate final_quitter;
191 multi_process_notification::Listener profile_listener(
192 local_notification, multi_process_notification::ProfileDomain,
193 &profile_quitter);
194 multi_process_notification::Listener user_listener(
195 local_notification, multi_process_notification::UserDomain,
196 &user_quitter);
197 multi_process_notification::Listener system_listener(
198 local_notification, multi_process_notification::SystemDomain,
199 &system_quitter);
200 multi_process_notification::Listener final_listener(
201 final_notification, multi_process_notification::UserDomain,
202 &final_quitter);
203
204 ASSERT_TRUE(profile_listener.Start());
205 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
206 ASSERT_TRUE(profile_quitter.WasStartedReceived());
207 ASSERT_TRUE(user_listener.Start());
208 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
209 ASSERT_TRUE(user_quitter.WasStartedReceived());
210 ASSERT_TRUE(system_listener.Start());
211 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
212 ASSERT_TRUE(system_quitter.WasStartedReceived());
213
214 ASSERT_TRUE(multi_process_notification::Post(local_notification, domain));
215 SpinRunLoop(TestTimeouts::action_timeout_ms());
216
217 // Now send out a final_notification to queue up a notification
218 // after the local_notification and make sure that all listeners have had a
219 // chance to process local_notification before we check to see if they
220 // were called.
221 ASSERT_TRUE(final_listener.Start());
222 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
223 EXPECT_TRUE(final_quitter.WasStartedReceived());
224 ASSERT_TRUE(multi_process_notification::Post(
225 final_notification, multi_process_notification::UserDomain));
226 SpinRunLoop(TestTimeouts::action_timeout_ms());
227 ASSERT_TRUE(final_quitter.WasNotificationReceived());
228 switch (domain) {
229 case multi_process_notification::ProfileDomain:
230 ASSERT_TRUE(profile_quitter.WasNotificationReceived());
231 ASSERT_FALSE(user_quitter.WasNotificationReceived());
232 ASSERT_FALSE(system_quitter.WasNotificationReceived());
233 break;
234
235 case multi_process_notification::UserDomain:
236 ASSERT_FALSE(profile_quitter.WasNotificationReceived());
237 ASSERT_TRUE(user_quitter.WasNotificationReceived());
238 ASSERT_FALSE(system_quitter.WasNotificationReceived());
239 break;
240
241 case multi_process_notification::SystemDomain:
242 ASSERT_FALSE(profile_quitter.WasNotificationReceived());
243 ASSERT_FALSE(user_quitter.WasNotificationReceived());
244 ASSERT_TRUE(system_quitter.WasNotificationReceived());
245 break;
246 }
247 }
248
249 TEST_F(MultiProcessNotificationTest, BasicCreationTest) {
250 QuitterDelegate quitter;
251 multi_process_notification::Listener local_listener(
252 "BasicCreationTest", multi_process_notification::UserDomain, &quitter);
253 ASSERT_TRUE(local_listener.Start());
254 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
255 ASSERT_TRUE(quitter.WasStartedReceived());
256 multi_process_notification::Listener system_listener(
257 "BasicCreationTest", multi_process_notification::SystemDomain, &quitter);
258 ASSERT_TRUE(system_listener.Start());
259 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
260 ASSERT_TRUE(quitter.WasStartedReceived());
261 }
262
263 TEST_F(MultiProcessNotificationTest, PostInProcessNotification) {
264 std::string local_notification("QuitLocalNotification");
265 QuitterDelegate quitter;
266 multi_process_notification::Listener listener(
267 local_notification, multi_process_notification::UserDomain, &quitter);
268
269 ASSERT_TRUE(listener.Start());
270 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
271 ASSERT_TRUE(quitter.WasStartedReceived());
272 ASSERT_TRUE(multi_process_notification::Post(
273 local_notification, multi_process_notification::UserDomain));
274 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
275 ASSERT_TRUE(quitter.WasNotificationReceived());
276 }
277
278 TEST_F(MultiProcessNotificationTest, MultiListener) {
279 std::string local_notification("LocalNotification");
280 std::string quit_local_notification("QuitLocalNotification");
281
282 SimpleDelegate delegate1;
283 SimpleDelegate delegate2;
284 multi_process_notification::Listener local_listener1(
285 local_notification, multi_process_notification::UserDomain,
286 &delegate1);
287 multi_process_notification::Listener local_listener2(
288 local_notification, multi_process_notification::UserDomain,
289 &delegate2);
290
291 QuitterDelegate quitter;
292
293 multi_process_notification::Listener quit_listener(quit_local_notification,
294 multi_process_notification::UserDomain, &quitter);
295
296 ASSERT_TRUE(local_listener1.Start());
297 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
298 ASSERT_TRUE(delegate1.WasStartedReceived());
299 ASSERT_TRUE(local_listener2.Start());
300 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
301 ASSERT_TRUE(delegate2.WasStartedReceived());
302 ASSERT_TRUE(quit_listener.Start());
303 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
304 ASSERT_TRUE(quitter.WasStartedReceived());
305 ASSERT_TRUE(multi_process_notification::Post(
306 local_notification, multi_process_notification::UserDomain));
307 ASSERT_TRUE(multi_process_notification::Post(
308 quit_local_notification, multi_process_notification::UserDomain));
309 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
310 ASSERT_TRUE(delegate1.WasNotificationReceived());
311 ASSERT_TRUE(delegate2.WasNotificationReceived());
312 ASSERT_TRUE(quitter.WasNotificationReceived());
313 }
314
315 TEST_F(MultiProcessNotificationTest, PostProfileNotification) {
316 PostNotificationTest(multi_process_notification::ProfileDomain);
317 }
318
319 TEST_F(MultiProcessNotificationTest, PostUserNotification) {
320 PostNotificationTest(multi_process_notification::UserDomain);
321 }
322
323 TEST_F(MultiProcessNotificationTest, PostSystemNotification) {
324 PostNotificationTest(multi_process_notification::SystemDomain);
325 }
326
327 TEST_F(MultiProcessNotificationTest, ProfileCrossDomainPosting) {
328 CrossPostNotificationTest(multi_process_notification::ProfileDomain);
329 }
330
331 TEST_F(MultiProcessNotificationTest, UserCrossDomainPosting) {
332 CrossPostNotificationTest(multi_process_notification::UserDomain);
333 }
334
335 TEST_F(MultiProcessNotificationTest, SystemCrossDomainPosting) {
336 CrossPostNotificationTest(multi_process_notification::SystemDomain);
337 }
338
339 MULTIPROCESS_TEST_MAIN(MultiProcessProfileNotificationMain) {
340 return MultiProcessNotificationMain(
341 multi_process_notification::ProfileDomain);
342 }
343
344 MULTIPROCESS_TEST_MAIN(MultiProcessUserNotificationMain) {
345 return MultiProcessNotificationMain(multi_process_notification::UserDomain);
346 }
347
348 MULTIPROCESS_TEST_MAIN(MultiProcessSystemNotificationMain) {
349 return MultiProcessNotificationMain(multi_process_notification::SystemDomain);
350 }
351
352 #endif // defined(OS_MACOSX)
OLDNEW
« no previous file with comments | « chrome/browser/multi_process_notification_mac.mm ('k') | chrome/browser/multi_process_notification_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698