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

Side by Side Diff: chrome/browser/media/webrtc_rtp_dump_handler_unittest.cc

Issue 264793017: Implements RTP header dumping. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix threading Created 6 years, 7 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
OLDNEW
(Empty)
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.
4
5 #include "base/bind.h"
6 #include "base/file_util.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/macros.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/run_loop.h"
11 #include "chrome/browser/media/webrtc_rtp_dump_handler.h"
12 #include "chrome/browser/media/webrtc_rtp_dump_writer.h"
13 #include "content/public/test/test_browser_thread_bundle.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 class FakeDumpWriter : public WebRtcRtpDumpWriter {
18 public:
19 explicit FakeDumpWriter(size_t max_dump_size,
20 const base::Closure& max_size_reached_callback,
21 bool end_dump_success)
22 : WebRtcRtpDumpWriter(base::FilePath(),
23 base::FilePath(),
24 max_dump_size,
25 base::Closure()),
26 max_dump_size_(max_dump_size),
27 current_dump_size_(0),
28 max_size_reached_callback_(max_size_reached_callback),
29 end_dump_success_(end_dump_success) {}
30
31 virtual void WriteRtpPacket(const uint8* packet_header,
32 size_t header_length,
33 size_t packet_length,
34 bool incoming) OVERRIDE {
35 current_dump_size_ += header_length;
36 if (current_dump_size_ > max_dump_size_)
37 max_size_reached_callback_.Run();
38 }
39
40 virtual void EndDump(RtpDumpType type,
41 const EndDumpCallback& finished_callback) OVERRIDE {
42 bool incoming_sucess = end_dump_success_;
43 bool outgoing_success = end_dump_success_;
44
45 if (type == RTP_DUMP_INCOMING)
46 outgoing_success = false;
47 else if (type == RTP_DUMP_OUTGOING)
48 incoming_sucess = false;
49
50 base::MessageLoop::current()->PostTask(
51 FROM_HERE,
52 base::Bind(finished_callback, incoming_sucess, outgoing_success));
53 }
54
55 private:
56 size_t max_dump_size_;
57 size_t current_dump_size_;
58 base::Closure max_size_reached_callback_;
59 bool end_dump_success_;
60 };
61
62 class WebRtcRtpDumpHandlerTest : public testing::Test {
63 public:
64 WebRtcRtpDumpHandlerTest()
65 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
66 ResetDumpHandler(base::FilePath(), true);
67 }
68
69 void ResetDumpHandler(const base::FilePath& dir, bool end_dump_success) {
70 handler_.reset(new WebRtcRtpDumpHandler(
71 dir.empty() ? base::FilePath(FILE_PATH_LITERAL("dummy")) : dir));
72
73 scoped_ptr<WebRtcRtpDumpWriter> writer(new FakeDumpWriter(
74 10,
75 base::Bind(&WebRtcRtpDumpHandler::OnMaxDumpSizeReached,
76 base::Unretained(handler_.get())),
77 end_dump_success));
78
79 handler_->SetDumpWriterForTesting(writer.Pass());
80 }
81
82 void WriteFakeDumpFiles(const base::FilePath& dir,
83 base::FilePath* incoming_dump,
84 base::FilePath* outgoing_dump) {
85 *incoming_dump = dir.AppendASCII("recv");
86 *outgoing_dump = dir.AppendASCII("send");
87 const char dummy[] = "dummy";
88 EXPECT_GT(base::WriteFile(*incoming_dump, dummy, arraysize(dummy)), 0);
89 EXPECT_GT(base::WriteFile(*outgoing_dump, dummy, arraysize(dummy)), 0);
90 }
91
92 MOCK_METHOD2(OnStopDumpFinished,
93 void(bool success, const std::string& error));
94
95 MOCK_METHOD0(OnStopOngoingDumpsFinished, void(void));
96
97 protected:
98 content::TestBrowserThreadBundle thread_bundle_;
99 scoped_ptr<WebRtcRtpDumpHandler> handler_;
100 };
101
102 TEST_F(WebRtcRtpDumpHandlerTest, StateTransition) {
103 std::string error;
104
105 RtpDumpType types[3];
106 types[0] = RTP_DUMP_INCOMING;
107 types[1] = RTP_DUMP_OUTGOING;
108 types[2] = RTP_DUMP_BOTH;
109
110 for (size_t i = 0; i < arraysize(types); ++i) {
111 DVLOG(2) << "Verifying state transition: type = " << types[i];
112
113 // Only StartDump is allowed in STATE_NONE.
114 EXPECT_CALL(*this, OnStopDumpFinished(false, testing::_));
115 handler_->StopDump(types[i],
116 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
117 base::Unretained(this)));
118
119 WebRtcRtpDumpHandler::ReleasedDumps dumps_0(handler_->ReleaseDumps());
120 EXPECT_TRUE(dumps_0.incoming_dump_path.empty());
121 EXPECT_TRUE(dumps_0.outgoing_dump_path.empty());
122
123 EXPECT_TRUE(handler_->StartDump(types[i], &error));
124 base::RunLoop().RunUntilIdle();
125
126 // Only StopDump is allowed in STATE_STARTED.
127 EXPECT_FALSE(handler_->StartDump(types[i], &error));
128
129 WebRtcRtpDumpHandler::ReleasedDumps dumps_1(handler_->ReleaseDumps());
130 EXPECT_TRUE(dumps_1.incoming_dump_path.empty());
131 EXPECT_TRUE(dumps_1.outgoing_dump_path.empty());
132
133 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_));
134 handler_->StopDump(types[i],
135 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
136 base::Unretained(this)));
137 base::RunLoop().RunUntilIdle();
138
139 // Only ReleaseDump is allowed in STATE_STOPPED.
140 EXPECT_FALSE(handler_->StartDump(types[i], &error));
141
142 EXPECT_CALL(*this, OnStopDumpFinished(false, testing::_));
143 handler_->StopDump(types[i],
144 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
145 base::Unretained(this)));
146
147 WebRtcRtpDumpHandler::ReleasedDumps dumps_2(handler_->ReleaseDumps());
148 if (types[i] == RTP_DUMP_INCOMING || types[i] == RTP_DUMP_BOTH)
149 EXPECT_FALSE(dumps_2.incoming_dump_path.empty());
150
151 if (types[i] == RTP_DUMP_OUTGOING || types[i] == RTP_DUMP_BOTH)
152 EXPECT_FALSE(dumps_2.outgoing_dump_path.empty());
153
154 base::RunLoop().RunUntilIdle();
155 ResetDumpHandler(base::FilePath(), true);
156 }
157 }
158
159 TEST_F(WebRtcRtpDumpHandlerTest, StoppedWhenMaxSizeReached) {
160 std::string error;
161
162 EXPECT_TRUE(handler_->StartDump(RTP_DUMP_INCOMING, &error));
163
164 std::vector<uint8> buffer(100, 0);
165 handler_->OnRtpPacket(buffer.data(), buffer.size(), buffer.size(), true);
166 base::RunLoop().RunUntilIdle();
167
168 // Dumping should have been stopped, so ready to release.
169 WebRtcRtpDumpHandler::ReleasedDumps dumps = handler_->ReleaseDumps();
170 EXPECT_FALSE(dumps.incoming_dump_path.empty());
171 }
172
173 TEST_F(WebRtcRtpDumpHandlerTest, PacketIgnoredIfDumpingNotStarted) {
174 std::vector<uint8> buffer(100, 0);
175 handler_->OnRtpPacket(buffer.data(), buffer.size(), buffer.size(), true);
176 handler_->OnRtpPacket(buffer.data(), buffer.size(), buffer.size(), false);
177 base::RunLoop().RunUntilIdle();
178 }
179
180 TEST_F(WebRtcRtpDumpHandlerTest, PacketIgnoredIfDumpingStopped) {
181 std::string error;
182
183 EXPECT_TRUE(handler_->StartDump(RTP_DUMP_INCOMING, &error));
184
185 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_));
186 handler_->StopDump(RTP_DUMP_INCOMING,
187 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
188 base::Unretained(this)));
189
190 std::vector<uint8> buffer(100, 0);
191 handler_->OnRtpPacket(buffer.data(), buffer.size(), buffer.size(), true);
192 base::RunLoop().RunUntilIdle();
193 }
194
195 TEST_F(WebRtcRtpDumpHandlerTest, CannotStartMoreThanFiveDumps) {
196 std::string error;
197
198 handler_.reset();
199
200 scoped_ptr<WebRtcRtpDumpHandler> handlers[6];
201
202 for (size_t i = 0; i < arraysize(handlers); ++i) {
203 handlers[i].reset(new WebRtcRtpDumpHandler(base::FilePath()));
204
205 if (i < arraysize(handlers) - 1) {
206 EXPECT_TRUE(handlers[i]->StartDump(RTP_DUMP_INCOMING, &error));
207 } else {
208 EXPECT_FALSE(handlers[i]->StartDump(RTP_DUMP_INCOMING, &error));
209 }
210 }
211 }
212
213 TEST_F(WebRtcRtpDumpHandlerTest, StartStopIncomingThenStartStopOutgoing) {
214 std::string error;
215
216 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_)).Times(2);
217
218 EXPECT_TRUE(handler_->StartDump(RTP_DUMP_INCOMING, &error));
219 handler_->StopDump(RTP_DUMP_INCOMING,
220 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
221 base::Unretained(this)));
222
223 EXPECT_TRUE(handler_->StartDump(RTP_DUMP_OUTGOING, &error));
224 handler_->StopDump(RTP_DUMP_OUTGOING,
225 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
226 base::Unretained(this)));
227
228 base::RunLoop().RunUntilIdle();
229 }
230
231 TEST_F(WebRtcRtpDumpHandlerTest, StartIncomingStartOutgoingThenStopBoth) {
232 std::string error;
233
234 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_));
235
236 EXPECT_TRUE(handler_->StartDump(RTP_DUMP_INCOMING, &error));
237 EXPECT_TRUE(handler_->StartDump(RTP_DUMP_OUTGOING, &error));
238
239 handler_->StopDump(RTP_DUMP_INCOMING,
240 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
241 base::Unretained(this)));
242
243 base::RunLoop().RunUntilIdle();
244 }
245
246 TEST_F(WebRtcRtpDumpHandlerTest, StartBothThenStopIncomingStopOutgoing) {
247 std::string error;
248
249 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_)).Times(2);
250
251 EXPECT_TRUE(handler_->StartDump(RTP_DUMP_BOTH, &error));
252
253 handler_->StopDump(RTP_DUMP_INCOMING,
254 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
255 base::Unretained(this)));
256 handler_->StopDump(RTP_DUMP_OUTGOING,
257 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
258 base::Unretained(this)));
259
260 base::RunLoop().RunUntilIdle();
261 }
262
263 TEST_F(WebRtcRtpDumpHandlerTest, DumpsCleanedUpIfNotReleased) {
264 base::ScopedTempDir temp_dir;
265 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
266 ResetDumpHandler(temp_dir.path(), true);
267
268 base::FilePath incoming_dump, outgoing_dump;
269 WriteFakeDumpFiles(temp_dir.path(), &incoming_dump, &outgoing_dump);
270
271 std::string error;
272 EXPECT_TRUE(handler_->StartDump(RTP_DUMP_BOTH, &error));
273
274 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_));
275 handler_->StopDump(RTP_DUMP_BOTH,
276 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
277 base::Unretained(this)));
278 base::RunLoop().RunUntilIdle();
279
280 handler_.reset();
281 base::RunLoop().RunUntilIdle();
282
283 EXPECT_FALSE(base::PathExists(incoming_dump));
284 EXPECT_FALSE(base::PathExists(outgoing_dump));
285 }
286
287 TEST_F(WebRtcRtpDumpHandlerTest, DumpDeletedIfEndDumpFailed) {
288 base::ScopedTempDir temp_dir;
289 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
290
291 // Make the writer return failure on EndStream.
292 ResetDumpHandler(temp_dir.path(), false);
293
294 base::FilePath incoming_dump, outgoing_dump;
295 WriteFakeDumpFiles(temp_dir.path(), &incoming_dump, &outgoing_dump);
296
297 std::string error;
298 EXPECT_TRUE(handler_->StartDump(RTP_DUMP_BOTH, &error));
299 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_)).Times(2);
300
301 handler_->StopDump(RTP_DUMP_INCOMING,
302 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
303 base::Unretained(this)));
304 base::RunLoop().RunUntilIdle();
305
306 EXPECT_FALSE(base::PathExists(incoming_dump));
307 EXPECT_TRUE(base::PathExists(outgoing_dump));
308
309 handler_->StopDump(RTP_DUMP_OUTGOING,
310 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
311 base::Unretained(this)));
312 base::RunLoop().RunUntilIdle();
313 EXPECT_FALSE(base::PathExists(outgoing_dump));
314 }
315
316 TEST_F(WebRtcRtpDumpHandlerTest, StopOngoingDumpsWhileStoppingDumps) {
317 std::string error;
318 EXPECT_TRUE(handler_->StartDump(RTP_DUMP_BOTH, &error));
319
320 testing::InSequence s;
321 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_));
322 EXPECT_CALL(*this, OnStopOngoingDumpsFinished());
323
324 handler_->StopDump(RTP_DUMP_BOTH,
325 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
326 base::Unretained(this)));
327
328 handler_->StopOngoingDumps(
329 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopOngoingDumpsFinished,
330 base::Unretained(this)));
331
332 base::RunLoop().RunUntilIdle();
333
334 WebRtcRtpDumpHandler::ReleasedDumps dumps(handler_->ReleaseDumps());
335 EXPECT_FALSE(dumps.incoming_dump_path.empty());
336 EXPECT_FALSE(dumps.outgoing_dump_path.empty());
337 }
338
339 TEST_F(WebRtcRtpDumpHandlerTest, StopOngoingDumpsWhileDumping) {
340 std::string error;
341 EXPECT_TRUE(handler_->StartDump(RTP_DUMP_BOTH, &error));
342
343 EXPECT_CALL(*this, OnStopOngoingDumpsFinished());
344
345 handler_->StopOngoingDumps(
346 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopOngoingDumpsFinished,
347 base::Unretained(this)));
348
349 base::RunLoop().RunUntilIdle();
350
351 WebRtcRtpDumpHandler::ReleasedDumps dumps(handler_->ReleaseDumps());
352 EXPECT_FALSE(dumps.incoming_dump_path.empty());
353 EXPECT_FALSE(dumps.outgoing_dump_path.empty());
354 }
355
356 TEST_F(WebRtcRtpDumpHandlerTest, StopOngoingDumpsWhenAlreadyStopped) {
357 std::string error;
358 EXPECT_TRUE(handler_->StartDump(RTP_DUMP_BOTH, &error));
359
360 {
361 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_));
362
363 handler_->StopDump(RTP_DUMP_BOTH,
364 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
365 base::Unretained(this)));
366 base::RunLoop().RunUntilIdle();
367 }
368
369 EXPECT_CALL(*this, OnStopOngoingDumpsFinished());
370 handler_->StopOngoingDumps(
371 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopOngoingDumpsFinished,
372 base::Unretained(this)));
373 }
374
375 TEST_F(WebRtcRtpDumpHandlerTest, StopOngoingDumpsWhileStoppingOneDump) {
376 std::string error;
377 EXPECT_TRUE(handler_->StartDump(RTP_DUMP_BOTH, &error));
378
379 testing::InSequence s;
380 EXPECT_CALL(*this, OnStopDumpFinished(true, testing::_));
381 EXPECT_CALL(*this, OnStopOngoingDumpsFinished());
382
383 handler_->StopDump(RTP_DUMP_INCOMING,
384 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopDumpFinished,
385 base::Unretained(this)));
386
387 handler_->StopOngoingDumps(
388 base::Bind(&WebRtcRtpDumpHandlerTest::OnStopOngoingDumpsFinished,
389 base::Unretained(this)));
390
391 base::RunLoop().RunUntilIdle();
392
393 WebRtcRtpDumpHandler::ReleasedDumps dumps(handler_->ReleaseDumps());
394 EXPECT_FALSE(dumps.incoming_dump_path.empty());
395 EXPECT_FALSE(dumps.outgoing_dump_path.empty());
396 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698