Chromium Code Reviews

Side by Side Diff: chrome/common/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 mac side so that it works on 10.5 as well. Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | 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/common/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 "testing/multiprocess_func_list.h"
16
17 #if defined(OS_MACOSX)
18 // TODO(dmaclach): Remove defined(OS_MACOSX) once
19 // MultiProcessNotification is implemented on Win/Linux.
20
21 namespace {
22
23 const char kStartedNotificationName[] = "MultiProcessTestStartedNotification";
24 const char kQuitNotificationName[] = "MultiProcessTestQuitNotification";
25
26 void SpinRunLoop(int milliseconds) {
27 MessageLoopForIO *loop = MessageLoopForIO::current();
28
29 // Post a quit task so that this loop eventually ends and we don't hang
30 // in the case of a bad test. Usually, the run loop will quit sooner than
31 // that because all tests use a MultiProcessNotificationTestQuit which quits
32 // the current run loop when it gets a notification.
33 loop->PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask(), milliseconds);
34 loop->Run();
35 }
36
37 int MultiProcessNotificationMain(multi_process_notification::Domain domain) {
38 MessageLoop io_loop(MessageLoop::TYPE_IO);
39 multi_process_notification::PerformTaskOnNotification quitter(
40 new MessageLoop::QuitTask());
41 multi_process_notification::Listener listener(
42 kQuitNotificationName, domain, &quitter);
43 EXPECT_TRUE(listener.Start());
44 EXPECT_TRUE(multi_process_notification::Post(kStartedNotificationName,
45 domain));
46 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
47 EXPECT_TRUE(quitter.WasNotificationReceived());
48 return 0;
49 }
50
51 } // namespace
52
53 class SimpleNotification
54 : public multi_process_notification::Listener::Delegate {
55 public:
56 SimpleNotification() : notification_received_(false) { }
57 virtual ~SimpleNotification();
58
59 virtual void OnNotificationReceived(
60 const std::string& name,
61 multi_process_notification::Domain domain) OVERRIDE;
62 bool WasNotificationReceived() { return notification_received_; }
63
64 private:
65 bool notification_received_;
66
67 DISALLOW_COPY_AND_ASSIGN(SimpleNotification);
68 };
69
70 SimpleNotification::~SimpleNotification() {
71 }
72
73 void SimpleNotification::OnNotificationReceived(
74 const std::string& name, multi_process_notification::Domain domain) {
75 notification_received_ = true;
76 }
77
78 class MultiProcessNotificationTest : public base::MultiProcessTest {
79 public:
80 MultiProcessNotificationTest();
81
82 void PostNotificationTest(multi_process_notification::Domain domain);
83 void CrossPostNotificationTest(multi_process_notification::Domain domain);
84
85 private:
86 MessageLoop io_loop_;
87 };
88
89 MultiProcessNotificationTest::MultiProcessNotificationTest()
90 : io_loop_(MessageLoop::TYPE_IO) {
91 }
92
93 void MultiProcessNotificationTest::PostNotificationTest(
94 multi_process_notification::Domain domain) {
95 multi_process_notification::PerformTaskOnNotification process_started(
96 new MessageLoop::QuitTask());
97 multi_process_notification::Listener listener(kStartedNotificationName,
98 domain,
99 &process_started);
100 ASSERT_TRUE(listener.Start());
101 std::string process_name;
102 switch (domain) {
103 case multi_process_notification::ProfileDomain:
104 process_name = "MultiProcessProfileNotificationMain";
105 break;
106
107 case multi_process_notification::UserDomain:
108 process_name = "MultiProcessUserNotificationMain";
109 break;
110
111 case multi_process_notification::SystemDomain:
112 process_name = "MultiProcessSystemNotificationMain";
113 break;
114 }
115 base::ProcessHandle handle = SpawnChild(process_name, false);
116 ASSERT_TRUE(handle);
117 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
118 ASSERT_TRUE(process_started.WasNotificationReceived());
119 ASSERT_TRUE(multi_process_notification::Post(kQuitNotificationName, domain));
120 int exit_code = 0;
121 EXPECT_TRUE(base::WaitForExitCodeWithTimeout(
122 handle, &exit_code, TestTimeouts::action_max_timeout_ms()));
123 }
124
125 void MultiProcessNotificationTest::CrossPostNotificationTest(
126 multi_process_notification::Domain domain) {
127 // Check to make sure notifications sent to user domain aren't picked up
128 // by system domain listeners and vice versa.
129 std::string local_notification("QuitLocalNotification");
130 std::string final_notification("FinalQuitLocalNotification");
131 multi_process_notification::PerformTaskOnNotification profile_quitter(
132 new MessageLoop::QuitTask());
133 multi_process_notification::PerformTaskOnNotification user_quitter(
134 new MessageLoop::QuitTask());
135 multi_process_notification::PerformTaskOnNotification system_quitter(
136 new MessageLoop::QuitTask());
137 multi_process_notification::PerformTaskOnNotification final_quitter(
138 new MessageLoop::QuitTask());
139 multi_process_notification::Listener profile_listener(
140 local_notification, multi_process_notification::ProfileDomain,
141 &profile_quitter);
142 multi_process_notification::Listener user_listener(
143 local_notification, multi_process_notification::UserDomain,
144 &user_quitter);
145 multi_process_notification::Listener system_listener(
146 local_notification, multi_process_notification::SystemDomain,
147 &system_quitter);
148 multi_process_notification::Listener final_listener(
149 final_notification, multi_process_notification::UserDomain,
150 &final_quitter);
151
152 ASSERT_TRUE(profile_listener.Start());
153 ASSERT_TRUE(user_listener.Start());
154 ASSERT_TRUE(system_listener.Start());
155 ASSERT_TRUE(multi_process_notification::Post(local_notification, domain));
156 SpinRunLoop(TestTimeouts::action_timeout_ms());
157
158 // Now send out a final_notification to queue up a notification
159 // after the local_notification and make sure that all listeners have had a
160 // chance to process local_notification before we check to see if they
161 // were called.
162 ASSERT_TRUE(final_listener.Start());
163 ASSERT_TRUE(multi_process_notification::Post(
164 final_notification, multi_process_notification::UserDomain));
165 SpinRunLoop(TestTimeouts::action_timeout_ms());
166 ASSERT_TRUE(final_quitter.WasNotificationReceived());
167 switch (domain) {
168 case multi_process_notification::ProfileDomain:
169 ASSERT_TRUE(profile_quitter.WasNotificationReceived());
170 ASSERT_FALSE(user_quitter.WasNotificationReceived());
171 ASSERT_FALSE(system_quitter.WasNotificationReceived());
172 break;
173
174 case multi_process_notification::UserDomain:
175 ASSERT_FALSE(profile_quitter.WasNotificationReceived());
176 ASSERT_TRUE(user_quitter.WasNotificationReceived());
177 ASSERT_FALSE(system_quitter.WasNotificationReceived());
178 break;
179
180 case multi_process_notification::SystemDomain:
181 ASSERT_FALSE(profile_quitter.WasNotificationReceived());
182 ASSERT_FALSE(user_quitter.WasNotificationReceived());
183 ASSERT_TRUE(system_quitter.WasNotificationReceived());
184 break;
185 }
186 }
187
188 TEST_F(MultiProcessNotificationTest, BasicCreationTest) {
189 multi_process_notification::Listener local_listener(
190 "BasicCreationTest", multi_process_notification::UserDomain, NULL);
191 ASSERT_TRUE(local_listener.Start());
192 multi_process_notification::Listener system_listener(
193 "BasicCreationTest", multi_process_notification::SystemDomain, NULL);
194 ASSERT_TRUE(system_listener.Start());
195 }
196
197 TEST_F(MultiProcessNotificationTest, PostInProcessNotification) {
198 std::string local_notification("QuitLocalNotification");
199 multi_process_notification::PerformTaskOnNotification quitter(
200 new MessageLoop::QuitTask());
201 multi_process_notification::Listener listener(
202 local_notification, multi_process_notification::UserDomain, &quitter);
203
204 ASSERT_TRUE(listener.Start());
205 ASSERT_TRUE(multi_process_notification::Post(
206 local_notification, multi_process_notification::UserDomain));
207 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
208 ASSERT_TRUE(quitter.WasNotificationReceived());
209 }
210
211 TEST_F(MultiProcessNotificationTest, MultiListener) {
212 std::string local_notification("LocalNotification");
213 std::string quit_local_notification("QuitLocalNotification");
214
215 SimpleNotification notification1;
216 SimpleNotification notification2;
217 multi_process_notification::Listener local_listener1(
218 local_notification, multi_process_notification::UserDomain,
219 &notification1);
220 multi_process_notification::Listener local_listener2(
221 local_notification, multi_process_notification::UserDomain,
222 &notification2);
223
224 multi_process_notification::PerformTaskOnNotification quitter(
225 new MessageLoop::QuitTask());
226
227 multi_process_notification::Listener quit_listener(quit_local_notification,
228 multi_process_notification::UserDomain, &quitter);
229
230 ASSERT_TRUE(local_listener1.Start());
231 ASSERT_TRUE(local_listener2.Start());
232 ASSERT_TRUE(quit_listener.Start());
233 ASSERT_TRUE(multi_process_notification::Post(
234 local_notification, multi_process_notification::UserDomain));
235 ASSERT_TRUE(multi_process_notification::Post(
236 quit_local_notification, multi_process_notification::UserDomain));
237 SpinRunLoop(TestTimeouts::action_max_timeout_ms());
238 ASSERT_TRUE(notification1.WasNotificationReceived());
239 ASSERT_TRUE(notification2.WasNotificationReceived());
240 ASSERT_TRUE(quitter.WasNotificationReceived());
241 }
242
243 TEST_F(MultiProcessNotificationTest, PostProfileNotification) {
244 PostNotificationTest(multi_process_notification::ProfileDomain);
245 }
246
247 TEST_F(MultiProcessNotificationTest, PostUserNotification) {
248 PostNotificationTest(multi_process_notification::UserDomain);
249 }
250
251 TEST_F(MultiProcessNotificationTest, PostSystemNotification) {
252 PostNotificationTest(multi_process_notification::SystemDomain);
253 }
254
255 TEST_F(MultiProcessNotificationTest, ProfileCrossDomainPosting) {
256 CrossPostNotificationTest(multi_process_notification::ProfileDomain);
257 }
258
259 TEST_F(MultiProcessNotificationTest, UserCrossDomainPosting) {
260 CrossPostNotificationTest(multi_process_notification::UserDomain);
261 }
262
263 TEST_F(MultiProcessNotificationTest, SystemCrossDomainPosting) {
264 CrossPostNotificationTest(multi_process_notification::SystemDomain);
265 }
266
267 MULTIPROCESS_TEST_MAIN(MultiProcessProfileNotificationMain) {
268 return MultiProcessNotificationMain(
269 multi_process_notification::ProfileDomain);
270 }
271
272 MULTIPROCESS_TEST_MAIN(MultiProcessUserNotificationMain) {
273 return MultiProcessNotificationMain(multi_process_notification::UserDomain);
274 }
275
276 MULTIPROCESS_TEST_MAIN(MultiProcessSystemNotificationMain) {
277 return MultiProcessNotificationMain(multi_process_notification::SystemDomain);
278 }
279
280 #endif // defined(OS_MACOSX)
OLDNEW

Powered by Google App Engine