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
3 // found in the LICENSE file.
6 #include "base/files/file_util.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/location.h"
9 #include "base/macros.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/run_loop.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "chrome/browser/media/webrtc_rtp_dump_handler.h"
15 #include "chrome/browser/media/webrtc_rtp_dump_writer.h"
16 #include "content/public/test/test_browser_thread_bundle.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 class FakeDumpWriter
: public WebRtcRtpDumpWriter
{
22 FakeDumpWriter(size_t max_dump_size
,
23 const base::Closure
& max_size_reached_callback
,
24 bool end_dump_success
)
25 : WebRtcRtpDumpWriter(base::FilePath(),
29 max_dump_size_(max_dump_size
),
30 current_dump_size_(0),
31 max_size_reached_callback_(max_size_reached_callback
),
32 end_dump_success_(end_dump_success
) {}
34 void WriteRtpPacket(const uint8
* packet_header
,
37 bool incoming
) override
{
38 current_dump_size_
+= header_length
;
39 if (current_dump_size_
> max_dump_size_
)
40 max_size_reached_callback_
.Run();
43 void EndDump(RtpDumpType type
,
44 const EndDumpCallback
& finished_callback
) override
{
45 bool incoming_sucess
= end_dump_success_
;
46 bool outgoing_success
= end_dump_success_
;
48 if (type
== RTP_DUMP_INCOMING
)
49 outgoing_success
= false;
50 else if (type
== RTP_DUMP_OUTGOING
)
51 incoming_sucess
= false;
53 base::ThreadTaskRunnerHandle::Get()->PostTask(
55 base::Bind(finished_callback
, incoming_sucess
, outgoing_success
));
59 size_t max_dump_size_
;
60 size_t current_dump_size_
;
61 base::Closure max_size_reached_callback_
;
62 bool end_dump_success_
;
65 class WebRtcRtpDumpHandlerTest
: public testing::Test
{
67 WebRtcRtpDumpHandlerTest()
68 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
) {
69 ResetDumpHandler(base::FilePath(), true);
72 void ResetDumpHandler(const base::FilePath
& dir
, bool end_dump_success
) {
73 handler_
.reset(new WebRtcRtpDumpHandler(
74 dir
.empty() ? base::FilePath(FILE_PATH_LITERAL("dummy")) : dir
));
76 scoped_ptr
<WebRtcRtpDumpWriter
> writer(new FakeDumpWriter(
78 base::Bind(&WebRtcRtpDumpHandler::OnMaxDumpSizeReached
,
79 base::Unretained(handler_
.get())),
82 handler_
->SetDumpWriterForTesting(writer
.Pass());
85 void DeleteDumpHandler() { handler_
.reset(); }
87 void WriteFakeDumpFiles(const base::FilePath
& dir
,
88 base::FilePath
* incoming_dump
,
89 base::FilePath
* outgoing_dump
) {
90 *incoming_dump
= dir
.AppendASCII("recv");
91 *outgoing_dump
= dir
.AppendASCII("send");
92 const char dummy
[] = "dummy";
93 EXPECT_GT(base::WriteFile(*incoming_dump
, dummy
, arraysize(dummy
)), 0);
94 EXPECT_GT(base::WriteFile(*outgoing_dump
, dummy
, arraysize(dummy
)), 0);
97 MOCK_METHOD2(OnStopDumpFinished
,
98 void(bool success
, const std::string
& error
));
100 MOCK_METHOD0(OnStopOngoingDumpsFinished
, void(void));
103 content::TestBrowserThreadBundle thread_bundle_
;
104 scoped_ptr
<WebRtcRtpDumpHandler
> handler_
;
107 TEST_F(WebRtcRtpDumpHandlerTest
, StateTransition
) {
110 RtpDumpType types
[3];
111 types
[0] = RTP_DUMP_INCOMING
;
112 types
[1] = RTP_DUMP_OUTGOING
;
113 types
[2] = RTP_DUMP_BOTH
;
115 for (size_t i
= 0; i
< arraysize(types
); ++i
) {
116 DVLOG(2) << "Verifying state transition: type = " << types
[i
];
118 // Only StartDump is allowed in STATE_NONE.
119 EXPECT_CALL(*this, OnStopDumpFinished(false, testing::_
));
120 handler_
->StopDump(types
[i
],
121 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
122 base::Unretained(this)));
124 WebRtcRtpDumpHandler::ReleasedDumps
empty_dumps(handler_
->ReleaseDumps());
125 EXPECT_TRUE(empty_dumps
.incoming_dump_path
.empty());
126 EXPECT_TRUE(empty_dumps
.outgoing_dump_path
.empty());
127 EXPECT_TRUE(handler_
->StartDump(types
[i
], &error
));
128 base::RunLoop().RunUntilIdle();
130 // Only StopDump is allowed in STATE_STARTED.
131 EXPECT_FALSE(handler_
->StartDump(types
[i
], &error
));
132 EXPECT_FALSE(handler_
->ReadyToRelease());
134 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_
));
135 handler_
->StopDump(types
[i
],
136 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
137 base::Unretained(this)));
138 base::RunLoop().RunUntilIdle();
140 // Only ReleaseDump is allowed in STATE_STOPPED.
141 EXPECT_FALSE(handler_
->StartDump(types
[i
], &error
));
143 EXPECT_CALL(*this, OnStopDumpFinished(false, testing::_
));
144 handler_
->StopDump(types
[i
],
145 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
146 base::Unretained(this)));
147 EXPECT_TRUE(handler_
->ReadyToRelease());
149 WebRtcRtpDumpHandler::ReleasedDumps
dumps(handler_
->ReleaseDumps());
150 if (types
[i
] == RTP_DUMP_INCOMING
|| types
[i
] == RTP_DUMP_BOTH
)
151 EXPECT_FALSE(dumps
.incoming_dump_path
.empty());
153 if (types
[i
] == RTP_DUMP_OUTGOING
|| types
[i
] == RTP_DUMP_BOTH
)
154 EXPECT_FALSE(dumps
.outgoing_dump_path
.empty());
156 base::RunLoop().RunUntilIdle();
157 ResetDumpHandler(base::FilePath(), true);
161 TEST_F(WebRtcRtpDumpHandlerTest
, StoppedWhenMaxSizeReached
) {
164 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_INCOMING
, &error
));
166 std::vector
<uint8
> buffer(100, 0);
167 handler_
->OnRtpPacket(&buffer
[0], buffer
.size(), buffer
.size(), true);
168 base::RunLoop().RunUntilIdle();
170 // Dumping should have been stopped, so ready to release.
171 WebRtcRtpDumpHandler::ReleasedDumps dumps
= handler_
->ReleaseDumps();
172 EXPECT_FALSE(dumps
.incoming_dump_path
.empty());
175 TEST_F(WebRtcRtpDumpHandlerTest
, PacketIgnoredIfDumpingNotStarted
) {
176 std::vector
<uint8
> buffer(100, 0);
177 handler_
->OnRtpPacket(&buffer
[0], buffer
.size(), buffer
.size(), true);
178 handler_
->OnRtpPacket(&buffer
[0], buffer
.size(), buffer
.size(), false);
179 base::RunLoop().RunUntilIdle();
182 TEST_F(WebRtcRtpDumpHandlerTest
, PacketIgnoredIfDumpingStopped
) {
185 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_INCOMING
, &error
));
187 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_
));
188 handler_
->StopDump(RTP_DUMP_INCOMING
,
189 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
190 base::Unretained(this)));
192 std::vector
<uint8
> buffer(100, 0);
193 handler_
->OnRtpPacket(&buffer
[0], buffer
.size(), buffer
.size(), true);
194 base::RunLoop().RunUntilIdle();
197 TEST_F(WebRtcRtpDumpHandlerTest
, CannotStartMoreThanFiveDumps
) {
202 scoped_ptr
<WebRtcRtpDumpHandler
> handlers
[6];
204 for (size_t i
= 0; i
< arraysize(handlers
); ++i
) {
205 handlers
[i
].reset(new WebRtcRtpDumpHandler(base::FilePath()));
207 if (i
< arraysize(handlers
) - 1) {
208 EXPECT_TRUE(handlers
[i
]->StartDump(RTP_DUMP_INCOMING
, &error
));
210 EXPECT_FALSE(handlers
[i
]->StartDump(RTP_DUMP_INCOMING
, &error
));
215 TEST_F(WebRtcRtpDumpHandlerTest
, StartStopIncomingThenStartStopOutgoing
) {
218 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_
)).Times(2);
220 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_INCOMING
, &error
));
221 handler_
->StopDump(RTP_DUMP_INCOMING
,
222 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
223 base::Unretained(this)));
225 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_OUTGOING
, &error
));
226 handler_
->StopDump(RTP_DUMP_OUTGOING
,
227 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
228 base::Unretained(this)));
230 base::RunLoop().RunUntilIdle();
233 TEST_F(WebRtcRtpDumpHandlerTest
, StartIncomingStartOutgoingThenStopBoth
) {
236 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_
));
238 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_INCOMING
, &error
));
239 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_OUTGOING
, &error
));
241 handler_
->StopDump(RTP_DUMP_INCOMING
,
242 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
243 base::Unretained(this)));
245 base::RunLoop().RunUntilIdle();
248 TEST_F(WebRtcRtpDumpHandlerTest
, StartBothThenStopIncomingStopOutgoing
) {
251 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_
)).Times(2);
253 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_BOTH
, &error
));
255 handler_
->StopDump(RTP_DUMP_INCOMING
,
256 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
257 base::Unretained(this)));
258 handler_
->StopDump(RTP_DUMP_OUTGOING
,
259 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
260 base::Unretained(this)));
262 base::RunLoop().RunUntilIdle();
265 TEST_F(WebRtcRtpDumpHandlerTest
, DumpsCleanedUpIfNotReleased
) {
266 base::ScopedTempDir temp_dir
;
267 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
268 ResetDumpHandler(temp_dir
.path(), true);
270 base::FilePath incoming_dump
, outgoing_dump
;
271 WriteFakeDumpFiles(temp_dir
.path(), &incoming_dump
, &outgoing_dump
);
274 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_BOTH
, &error
));
276 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_
));
277 handler_
->StopDump(RTP_DUMP_BOTH
,
278 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
279 base::Unretained(this)));
280 base::RunLoop().RunUntilIdle();
283 base::RunLoop().RunUntilIdle();
285 EXPECT_FALSE(base::PathExists(incoming_dump
));
286 EXPECT_FALSE(base::PathExists(outgoing_dump
));
289 TEST_F(WebRtcRtpDumpHandlerTest
, DumpDeletedIfEndDumpFailed
) {
290 base::ScopedTempDir temp_dir
;
291 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
293 // Make the writer return failure on EndStream.
294 ResetDumpHandler(temp_dir
.path(), false);
296 base::FilePath incoming_dump
, outgoing_dump
;
297 WriteFakeDumpFiles(temp_dir
.path(), &incoming_dump
, &outgoing_dump
);
300 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_BOTH
, &error
));
301 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_
)).Times(2);
303 handler_
->StopDump(RTP_DUMP_INCOMING
,
304 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
305 base::Unretained(this)));
306 base::RunLoop().RunUntilIdle();
308 EXPECT_FALSE(base::PathExists(incoming_dump
));
309 EXPECT_TRUE(base::PathExists(outgoing_dump
));
311 handler_
->StopDump(RTP_DUMP_OUTGOING
,
312 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
313 base::Unretained(this)));
314 base::RunLoop().RunUntilIdle();
315 EXPECT_FALSE(base::PathExists(outgoing_dump
));
318 TEST_F(WebRtcRtpDumpHandlerTest
, StopOngoingDumpsWhileStoppingDumps
) {
320 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_BOTH
, &error
));
322 testing::InSequence s
;
323 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_
));
324 EXPECT_CALL(*this, OnStopOngoingDumpsFinished());
326 handler_
->StopDump(RTP_DUMP_BOTH
,
327 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
328 base::Unretained(this)));
330 handler_
->StopOngoingDumps(
331 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopOngoingDumpsFinished
,
332 base::Unretained(this)));
334 base::RunLoop().RunUntilIdle();
336 WebRtcRtpDumpHandler::ReleasedDumps
dumps(handler_
->ReleaseDumps());
337 EXPECT_FALSE(dumps
.incoming_dump_path
.empty());
338 EXPECT_FALSE(dumps
.outgoing_dump_path
.empty());
341 TEST_F(WebRtcRtpDumpHandlerTest
, StopOngoingDumpsWhileDumping
) {
343 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_BOTH
, &error
));
345 EXPECT_CALL(*this, OnStopOngoingDumpsFinished());
347 handler_
->StopOngoingDumps(
348 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopOngoingDumpsFinished
,
349 base::Unretained(this)));
351 base::RunLoop().RunUntilIdle();
353 WebRtcRtpDumpHandler::ReleasedDumps
dumps(handler_
->ReleaseDumps());
354 EXPECT_FALSE(dumps
.incoming_dump_path
.empty());
355 EXPECT_FALSE(dumps
.outgoing_dump_path
.empty());
358 TEST_F(WebRtcRtpDumpHandlerTest
, StopOngoingDumpsWhenAlreadyStopped
) {
360 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_BOTH
, &error
));
363 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_
));
365 handler_
->StopDump(RTP_DUMP_BOTH
,
366 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
367 base::Unretained(this)));
368 base::RunLoop().RunUntilIdle();
371 EXPECT_CALL(*this, OnStopOngoingDumpsFinished());
372 handler_
->StopOngoingDumps(
373 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopOngoingDumpsFinished
,
374 base::Unretained(this)));
377 TEST_F(WebRtcRtpDumpHandlerTest
, StopOngoingDumpsWhileStoppingOneDump
) {
379 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_BOTH
, &error
));
381 testing::InSequence s
;
382 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_
));
383 EXPECT_CALL(*this, OnStopOngoingDumpsFinished());
385 handler_
->StopDump(RTP_DUMP_INCOMING
,
386 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished
,
387 base::Unretained(this)));
389 handler_
->StopOngoingDumps(
390 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopOngoingDumpsFinished
,
391 base::Unretained(this)));
393 base::RunLoop().RunUntilIdle();
395 WebRtcRtpDumpHandler::ReleasedDumps
dumps(handler_
->ReleaseDumps());
396 EXPECT_FALSE(dumps
.incoming_dump_path
.empty());
397 EXPECT_FALSE(dumps
.outgoing_dump_path
.empty());
400 TEST_F(WebRtcRtpDumpHandlerTest
, DeleteHandlerBeforeStopCallback
) {
403 EXPECT_CALL(*this, OnStopOngoingDumpsFinished())
404 .WillOnce(testing::InvokeWithoutArgs(
405 this, &WebRtcRtpDumpHandlerTest::DeleteDumpHandler
));
407 EXPECT_TRUE(handler_
->StartDump(RTP_DUMP_BOTH
, &error
));
409 handler_
->StopOngoingDumps(
410 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopOngoingDumpsFinished
,
411 base::Unretained(this)));
413 base::RunLoop().RunUntilIdle();