OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2010 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 "base/message_loop.h" | |
6 #include "base/platform_thread.h" | |
7 #include "media/audio/audio_output_dispatcher.h" | |
8 #include "media/audio/audio_output_proxy.h" | |
9 #include "media/audio/audio_manager.h" | |
10 #include "testing/gmock/include/gmock/gmock.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 | |
13 using ::testing::_; | |
14 using ::testing::Mock; | |
15 using ::testing::Return; | |
16 | |
17 namespace { | |
18 const int kTestCloseDelayMs = 100; | |
19 | |
20 // Used in the test where we don't want a stream to be closed unexpectedly. | |
21 const int kTestBigCloseDelayMs = 1000 * 1000; | |
scherkus (not reviewing)
2010/11/24 02:01:59
this worries me a lot w.r.t. flaky tests
any chan
Sergey Ulanov
2010/11/24 03:49:54
1000 seconds should be more than any reasonable ti
| |
22 } // namespace | |
23 | |
24 class MockAudioOutputStream : public AudioOutputStream { | |
25 public: | |
26 MockAudioOutputStream() {} | |
27 | |
28 MOCK_METHOD0(Open, bool()); | |
29 MOCK_METHOD1(Start, void(AudioSourceCallback* callback)); | |
30 MOCK_METHOD0(Stop, void()); | |
31 MOCK_METHOD1(SetVolume, void(double volume)); | |
32 MOCK_METHOD1(GetVolume, void(double* volume)); | |
33 MOCK_METHOD0(Close, void()); | |
34 }; | |
35 | |
36 class MockAudioManager : public AudioManager { | |
37 public: | |
38 MockAudioManager() { }; | |
39 | |
40 MOCK_METHOD0(Init, void()); | |
41 MOCK_METHOD0(HasAudioOutputDevices, bool()); | |
42 MOCK_METHOD0(HasAudioInputDevices, bool()); | |
43 MOCK_METHOD0(GetAudioInputDeviceModel, string16()); | |
44 MOCK_METHOD1(MakeAudioOutputStream, AudioOutputStream*( | |
45 AudioParameters params)); | |
46 MOCK_METHOD1(MakeAudioOutputStreamProxy, AudioOutputStream*( | |
47 const AudioParameters& params)); | |
48 MOCK_METHOD1(MakeAudioInputStream, AudioInputStream*( | |
49 AudioParameters params)); | |
50 MOCK_METHOD0(MuteAll, void()); | |
51 MOCK_METHOD0(UnMuteAll, void()); | |
52 MOCK_METHOD0(GetMessageLoop, MessageLoop*()); | |
53 }; | |
54 | |
55 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { | |
56 public: | |
57 MOCK_METHOD4(OnMoreData, uint32(AudioOutputStream* stream, | |
58 uint8* dest, uint32 max_size, | |
59 AudioBuffersState buffers_state)); | |
60 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); | |
61 }; | |
62 | |
63 class AudioOutputProxyTest : public testing::Test { | |
64 protected: | |
65 virtual void SetUp() { | |
66 EXPECT_CALL(manager_, GetMessageLoop()) | |
67 .WillRepeatedly(Return(&message_loop_)); | |
68 InitDispatcher(kTestCloseDelayMs); | |
69 } | |
70 | |
71 void InitDispatcher(int close_delay_ms) { | |
72 AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, 2, 44100, | |
73 16, 1024); | |
74 dispatcher_ = new AudioOutputDispatcher(&manager_, params, close_delay_ms); | |
75 } | |
76 | |
77 virtual void TearDown() { | |
78 // All paused proxies should have been destroyed at this point. | |
79 EXPECT_EQ(0, dispatcher_->paused_proxies_); | |
80 } | |
81 | |
82 MessageLoop message_loop_; | |
83 scoped_refptr<AudioOutputDispatcher> dispatcher_; | |
84 MockAudioManager manager_; | |
85 MockAudioSourceCallback callback_; | |
86 }; | |
87 | |
88 TEST_F(AudioOutputProxyTest, CreateAndClose) { | |
89 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
90 proxy->Close(); | |
91 } | |
92 | |
93 TEST_F(AudioOutputProxyTest, OpenAndClose) { | |
94 MockAudioOutputStream stream; | |
95 | |
96 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
97 .WillOnce(Return(&stream)); | |
98 EXPECT_CALL(stream, Open()) | |
99 .WillOnce(Return(true)); | |
100 EXPECT_CALL(stream, Close()) | |
101 .Times(1); | |
102 | |
103 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
104 EXPECT_TRUE(proxy->Open()); | |
105 proxy->Close(); | |
106 } | |
107 | |
108 // Create a stream, and verify that it is closed after kTestCloseDelayMs. | |
109 // if it doesn't start playing. | |
110 TEST_F(AudioOutputProxyTest, CreateAndWait) { | |
111 MockAudioOutputStream stream; | |
112 | |
113 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
114 .WillOnce(Return(&stream)); | |
115 EXPECT_CALL(stream, Open()) | |
116 .WillOnce(Return(true)); | |
117 EXPECT_CALL(stream, Close()) | |
118 .Times(1); | |
119 | |
120 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
121 EXPECT_TRUE(proxy->Open()); | |
122 | |
123 // Simulate a delay. | |
124 PlatformThread::Sleep(kTestCloseDelayMs * 2); | |
scherkus (not reviewing)
2010/11/24 02:01:59
this could also be flaky (although rare)
it'd be
Sergey Ulanov
2010/11/24 03:49:54
Sleep must guarantee that it sleeps the specified
| |
125 message_loop_.RunAllPending(); | |
126 | |
127 // Verify expectation before calling Close(). | |
128 Mock::VerifyAndClear(&stream); | |
129 | |
130 proxy->Close(); | |
131 } | |
132 | |
133 // Create a stream, and then calls Start() and Stop(). | |
134 TEST_F(AudioOutputProxyTest, StartAndStop) { | |
135 MockAudioOutputStream stream; | |
136 | |
137 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
138 .WillOnce(Return(&stream)); | |
139 EXPECT_CALL(stream, Open()) | |
140 .WillOnce(Return(true)); | |
141 EXPECT_CALL(stream, Start(_)) | |
142 .Times(1); | |
143 EXPECT_CALL(stream, SetVolume(_)) | |
144 .Times(1); | |
145 EXPECT_CALL(stream, Stop()) | |
146 .Times(1); | |
147 EXPECT_CALL(stream, Close()) | |
148 .Times(1); | |
149 | |
150 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
151 EXPECT_TRUE(proxy->Open()); | |
152 | |
153 proxy->Start(&callback_); | |
154 proxy->Stop(); | |
155 | |
156 proxy->Close(); | |
157 } | |
158 | |
159 // Verify that the stream is closed after Stop is called. | |
160 TEST_F(AudioOutputProxyTest, CloseAfterStop) { | |
161 MockAudioOutputStream stream; | |
162 | |
163 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
164 .WillOnce(Return(&stream)); | |
165 EXPECT_CALL(stream, Open()) | |
166 .WillOnce(Return(true)); | |
167 EXPECT_CALL(stream, Start(_)) | |
168 .Times(1); | |
169 EXPECT_CALL(stream, SetVolume(_)) | |
170 .Times(1); | |
171 EXPECT_CALL(stream, Stop()) | |
172 .Times(1); | |
173 EXPECT_CALL(stream, Close()) | |
174 .Times(1); | |
175 | |
176 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
177 EXPECT_TRUE(proxy->Open()); | |
178 | |
179 proxy->Start(&callback_); | |
180 proxy->Stop(); | |
181 | |
182 // Simulate a delay. | |
183 message_loop_.RunAllPending(); | |
184 PlatformThread::Sleep(kTestCloseDelayMs * 10); | |
scherkus (not reviewing)
2010/11/24 02:01:59
ditto
| |
185 message_loop_.RunAllPending(); | |
186 | |
187 // Verify expectation before calling Close(). | |
188 Mock::VerifyAndClear(&stream); | |
189 | |
190 proxy->Close(); | |
191 } | |
192 | |
193 // Create two streams, but don't start them. Only one device must be open. | |
194 TEST_F(AudioOutputProxyTest, TwoStreams) { | |
195 MockAudioOutputStream stream; | |
196 | |
197 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
198 .WillOnce(Return(&stream)); | |
199 EXPECT_CALL(stream, Open()) | |
200 .WillOnce(Return(true)); | |
201 EXPECT_CALL(stream, Close()) | |
202 .Times(1); | |
203 | |
204 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_); | |
205 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_); | |
206 EXPECT_TRUE(proxy1->Open()); | |
207 EXPECT_TRUE(proxy2->Open()); | |
208 proxy1->Close(); | |
209 proxy2->Close(); | |
210 } | |
211 | |
212 // Two streams: verify that second stream is allocated when the first | |
213 // starts playing. | |
214 TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying) { | |
215 MockAudioOutputStream stream1; | |
216 MockAudioOutputStream stream2; | |
217 | |
218 InitDispatcher(kTestBigCloseDelayMs); | |
219 | |
220 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
221 .WillOnce(Return(&stream1)) | |
222 .WillOnce(Return(&stream2)); | |
223 | |
224 EXPECT_CALL(stream1, Open()) | |
225 .WillOnce(Return(true)); | |
226 EXPECT_CALL(stream1, Start(_)) | |
227 .Times(1); | |
228 EXPECT_CALL(stream1, SetVolume(_)) | |
229 .Times(1); | |
230 EXPECT_CALL(stream1, Stop()) | |
231 .Times(1); | |
232 EXPECT_CALL(stream1, Close()) | |
233 .Times(1); | |
234 | |
235 EXPECT_CALL(stream2, Open()) | |
236 .WillOnce(Return(true)); | |
237 EXPECT_CALL(stream2, Close()) | |
238 .Times(1); | |
239 | |
240 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_); | |
241 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_); | |
242 EXPECT_TRUE(proxy1->Open()); | |
243 EXPECT_TRUE(proxy2->Open()); | |
244 | |
245 proxy1->Start(&callback_); | |
246 message_loop_.RunAllPending(); | |
247 proxy1->Stop(); | |
248 | |
249 proxy1->Close(); | |
250 proxy2->Close(); | |
251 } | |
252 | |
253 // Two streams, both are playing. Dispatcher should not open a third stream. | |
254 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) { | |
255 MockAudioOutputStream stream1; | |
256 MockAudioOutputStream stream2; | |
257 | |
258 InitDispatcher(kTestBigCloseDelayMs); | |
259 | |
260 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
261 .WillOnce(Return(&stream1)) | |
262 .WillOnce(Return(&stream2)); | |
263 | |
264 EXPECT_CALL(stream1, Open()) | |
265 .WillOnce(Return(true)); | |
266 EXPECT_CALL(stream1, Start(_)) | |
267 .Times(1); | |
268 EXPECT_CALL(stream1, SetVolume(_)) | |
269 .Times(1); | |
270 EXPECT_CALL(stream1, Stop()) | |
271 .Times(1); | |
272 EXPECT_CALL(stream1, Close()) | |
273 .Times(1); | |
274 | |
275 EXPECT_CALL(stream2, Open()) | |
276 .WillOnce(Return(true)); | |
277 EXPECT_CALL(stream2, Start(_)) | |
278 .Times(1); | |
279 EXPECT_CALL(stream2, SetVolume(_)) | |
280 .Times(1); | |
281 EXPECT_CALL(stream2, Stop()) | |
282 .Times(1); | |
283 EXPECT_CALL(stream2, Close()) | |
284 .Times(1); | |
285 | |
286 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_); | |
287 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_); | |
288 EXPECT_TRUE(proxy1->Open()); | |
289 EXPECT_TRUE(proxy2->Open()); | |
290 | |
291 proxy1->Start(&callback_); | |
292 proxy2->Start(&callback_); | |
293 proxy1->Stop(); | |
294 proxy2->Stop(); | |
295 | |
296 proxy1->Close(); | |
297 proxy2->Close(); | |
298 } | |
299 | |
300 // Open() method failed. | |
301 TEST_F(AudioOutputProxyTest, OpenFailed) { | |
302 MockAudioOutputStream stream; | |
303 | |
304 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
305 .WillOnce(Return(&stream)); | |
306 EXPECT_CALL(stream, Open()) | |
307 .WillOnce(Return(false)); | |
308 EXPECT_CALL(stream, Close()) | |
309 .Times(1); | |
310 | |
311 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
312 EXPECT_FALSE(proxy->Open()); | |
313 proxy->Close(); | |
314 } | |
315 | |
316 // Start() method failed. | |
317 TEST_F(AudioOutputProxyTest, StartFailed) { | |
318 MockAudioOutputStream stream; | |
319 | |
320 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
321 .WillOnce(Return(&stream)); | |
322 EXPECT_CALL(stream, Open()) | |
323 .WillOnce(Return(true)); | |
324 EXPECT_CALL(stream, Close()) | |
325 .Times(1); | |
326 | |
327 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
328 EXPECT_TRUE(proxy->Open()); | |
329 | |
330 // Simulate a delay. | |
331 PlatformThread::Sleep(kTestCloseDelayMs); | |
332 message_loop_.RunAllPending(); | |
333 | |
334 // Verify expectation before calling Close(). | |
335 Mock::VerifyAndClear(&stream); | |
336 | |
337 // |stream| is closed at this point. Start() should reopen it again. | |
338 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
339 .WillOnce(Return(reinterpret_cast<AudioOutputStream*>(NULL))); | |
340 | |
341 EXPECT_CALL(callback_, OnError(_, _)) | |
342 .Times(1); | |
343 | |
344 proxy->Start(&callback_); | |
345 | |
346 Mock::VerifyAndClear(&callback_); | |
347 | |
348 proxy->Close(); | |
349 } | |
OLD | NEW |