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

Side by Side Diff: content/browser/media/webrtc_internals_browsertest.cc

Issue 13859011: Fixes webrtc-internals stats reporting for the new stats API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: sync Created 7 years, 8 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
« no previous file with comments | « no previous file | content/browser/resources/media/stats_graph_helper.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/command_line.h"
5 #include "base/time.h" 6 #include "base/time.h"
6 #include "base/utf_string_conversions.h" 7 #include "base/utf_string_conversions.h"
8 #include "content/public/common/content_switches.h"
7 #include "content/public/test/browser_test_utils.h" 9 #include "content/public/test/browser_test_utils.h"
8 #include "content/shell/shell.h" 10 #include "content/shell/shell.h"
9 #include "content/test/content_browser_test.h" 11 #include "content/test/content_browser_test.h"
10 #include "content/test/content_browser_test_utils.h" 12 #include "content/test/content_browser_test_utils.h"
13 #include "net/test/test_server.h"
11 14
12 using std::string; 15 using std::string;
13 namespace content { 16 namespace content {
14 17
15 struct EventEntry { 18 struct EventEntry {
16 string type; 19 string type;
17 string value; 20 string value;
18 }; 21 };
19 22
20 struct StatsUnit { 23 struct StatsUnit {
21 string GetString() const { 24 string GetString() const {
22 std::stringstream ss; 25 std::stringstream ss;
23 ss << "{timestamp:" << timestamp << ", values:["; 26 ss << "{timestamp:" << timestamp << ", values:[";
24 std::map<string, string>::const_iterator iter; 27 std::map<string, string>::const_iterator iter;
25 for (iter = values.begin(); iter != values.end(); iter++) { 28 for (iter = values.begin(); iter != values.end(); iter++) {
26 ss << "'" << iter->first << "','" << iter->second << "',"; 29 ss << "'" << iter->first << "','" << iter->second << "',";
27 } 30 }
28 ss << "]}"; 31 ss << "]}";
29 return ss.str(); 32 return ss.str();
30 } 33 }
31 34
32 int64 timestamp; 35 int64 timestamp;
33 std::map<string, string> values; 36 std::map<string, string> values;
34 }; 37 };
35 38
36 struct StatsEntry { 39 struct StatsEntry {
37 string type; 40 string type;
38 string id; 41 string id;
39 StatsUnit local; 42 StatsUnit stats;
40 StatsUnit remote;
41 }; 43 };
42 44
43 typedef std::map<string, std::vector<string> > StatsMap; 45 typedef std::map<string, std::vector<string> > StatsMap;
44 46
45 class PeerConnectionEntry { 47 class PeerConnectionEntry {
46 public: 48 public:
47 PeerConnectionEntry(int pid, int lid) : pid_(pid), lid_(lid) {} 49 PeerConnectionEntry(int pid, int lid) : pid_(pid), lid_(lid) {}
48 50
49 void AddEvent(const string& type, const string& value) { 51 void AddEvent(const string& type, const string& value) {
50 EventEntry entry = {type, value}; 52 EventEntry entry = {type, value};
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 std::map<string, StatsMap> stats_; 86 std::map<string, StatsMap> stats_;
85 }; 87 };
86 88
87 static const int64 FAKE_TIME_STAMP = 0; 89 static const int64 FAKE_TIME_STAMP = 0;
88 90
89 class WebRTCInternalsBrowserTest: public ContentBrowserTest { 91 class WebRTCInternalsBrowserTest: public ContentBrowserTest {
90 public: 92 public:
91 WebRTCInternalsBrowserTest() {} 93 WebRTCInternalsBrowserTest() {}
92 virtual ~WebRTCInternalsBrowserTest() {} 94 virtual ~WebRTCInternalsBrowserTest() {}
93 95
96 virtual void SetUpOnMainThread() OVERRIDE {
97 // We need fake devices in this test since we want to run on naked VMs. We
98 // assume this switch is set by default in content_browsertests.
99 ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
100 switches::kUseFakeDeviceForMediaStream));
101
102 ASSERT_TRUE(test_server()->Start());
103 }
104
94 protected: 105 protected:
95 bool ExecuteJavascript(const string& javascript) { 106 bool ExecuteJavascript(const string& javascript) {
96 return ExecuteScript(shell()->web_contents(), javascript); 107 return ExecuteScript(shell()->web_contents(), javascript);
97 } 108 }
98 109
110 void ExpectTitle(const std::string& expected_title) const {
111 string16 expected_title16(ASCIIToUTF16(expected_title));
112 TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
113 EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
114 }
115
99 // Execute the javascript of addPeerConnection. 116 // Execute the javascript of addPeerConnection.
100 void ExecuteAddPeerConnectionJs(const PeerConnectionEntry& pc) { 117 void ExecuteAddPeerConnectionJs(const PeerConnectionEntry& pc) {
101 std::stringstream ss; 118 std::stringstream ss;
102 ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ << ", " << 119 ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ << ", " <<
103 "url:'u', servers:'s', constraints:'c'}"; 120 "url:'u', servers:'s', constraints:'c'}";
104 ASSERT_TRUE(ExecuteJavascript("addPeerConnection(" + ss.str() + ");")); 121 ASSERT_TRUE(ExecuteJavascript("addPeerConnection(" + ss.str() + ");"));
105 } 122 }
106 123
107 // Execute the javascript of removePeerConnection. 124 // Execute the javascript of removePeerConnection.
108 void ExecuteRemovePeerConnectionJs(const PeerConnectionEntry& pc) { 125 void ExecuteRemovePeerConnectionJs(const PeerConnectionEntry& pc) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ << 180 ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ <<
164 ", type:'" << type << "', value:'" << value << "'}"; 181 ", type:'" << type << "', value:'" << value << "'}";
165 ASSERT_TRUE(ExecuteJavascript("updatePeerConnection(" + ss.str() + ")")); 182 ASSERT_TRUE(ExecuteJavascript("updatePeerConnection(" + ss.str() + ")"));
166 183
167 VerifyPeerConnectionEntry(pc); 184 VerifyPeerConnectionEntry(pc);
168 } 185 }
169 186
170 // Execute addStats and verifies that the stats table has the right content. 187 // Execute addStats and verifies that the stats table has the right content.
171 void ExecuteAndVerifyAddStats( 188 void ExecuteAndVerifyAddStats(
172 PeerConnectionEntry& pc, const string& type, const string& id, 189 PeerConnectionEntry& pc, const string& type, const string& id,
173 StatsUnit& local, StatsUnit& remote) { 190 StatsUnit& stats) {
174 StatsEntry entry = {type, id, local, remote}; 191 StatsEntry entry = {type, id, stats};
175 192
176 // Adds each new value to the map of stats history. 193 // Adds each new value to the map of stats history.
177 std::map<string, string>::iterator iter; 194 std::map<string, string>::iterator iter;
178 for (iter = local.values.begin(); iter != local.values.end(); iter++) { 195 for (iter = stats.values.begin(); iter != stats.values.end(); iter++) {
179 pc.stats_[type + "-" + id][iter->first].push_back(iter->second); 196 pc.stats_[type + "-" + id][iter->first].push_back(iter->second);
180 } 197 }
181 for (iter = remote.values.begin(); iter != remote.values.end(); iter++) {
182 pc.stats_[type + "-" + id][iter->first].push_back(iter->second);
183 }
184
185 std::stringstream ss; 198 std::stringstream ss;
186 ss << "{pid:" << pc.pid_ << ", lid:" << pc.lid_ << "," 199 ss << "{pid:" << pc.pid_ << ", lid:" << pc.lid_ << ","
187 "reports:[" << "{id:'" << id << "', type:'" << type << "', " 200 "reports:[" << "{id:'" << id << "', type:'" << type << "', "
188 "local:" << local.GetString() << ", " 201 "stats:" << stats.GetString() << "}]}";
189 "remote:" << remote.GetString() << "}]}";
190 202
191 ASSERT_TRUE(ExecuteJavascript("addStats(" + ss.str() + ")")); 203 ASSERT_TRUE(ExecuteJavascript("addStats(" + ss.str() + ")"));
192 VerifyStatsTable(pc, entry); 204 VerifyStatsTable(pc, entry);
193 } 205 }
194 206
195 207
196 // Verifies that the stats table has the right content. 208 // Verifies that the stats table has the right content.
197 void VerifyStatsTable(const PeerConnectionEntry& pc, 209 void VerifyStatsTable(const PeerConnectionEntry& pc,
198 const StatsEntry& report) { 210 const StatsEntry& report) {
199 string table_id = 211 string table_id =
200 pc.getIdString() + "-table-" + report.type + "-" + report.id; 212 pc.getIdString() + "-table-" + report.type + "-" + report.id;
201 VerifyElementWithId(table_id); 213 VerifyElementWithId(table_id);
202 214
203 std::map<string, string>::const_iterator iter; 215 std::map<string, string>::const_iterator iter;
204 for (iter = report.local.values.begin(); 216 for (iter = report.stats.values.begin();
205 iter != report.local.values.end(); iter++) { 217 iter != report.stats.values.end(); iter++) {
206 VerifyStatsTableRow(table_id, iter->first, iter->second);
207 }
208 for (iter = report.remote.values.begin();
209 iter != report.remote.values.end(); iter++) {
210 VerifyStatsTableRow(table_id, iter->first, iter->second); 218 VerifyStatsTableRow(table_id, iter->first, iter->second);
211 } 219 }
212 } 220 }
213 221
214 // Verifies that the row named as |name| of the stats table |table_id| has 222 // Verifies that the row named as |name| of the stats table |table_id| has
215 // the correct content as |name| : |value|. 223 // the correct content as |name| : |value|.
216 void VerifyStatsTableRow(const string& table_id, 224 void VerifyStatsTableRow(const string& table_id,
217 const string& name, 225 const string& name,
218 const string& value) { 226 const string& value) {
219 VerifyElementWithId(table_id + "-" + name); 227 VerifyElementWithId(table_id + "-" + name);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 // Tests that adding random named stats updates the dataSeries and graphs. 336 // Tests that adding random named stats updates the dataSeries and graphs.
329 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, AddStats) { 337 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, AddStats) {
330 GURL url("chrome://webrtc-internals"); 338 GURL url("chrome://webrtc-internals");
331 NavigateToURL(shell(), url); 339 NavigateToURL(shell(), url);
332 340
333 PeerConnectionEntry pc(1, 0); 341 PeerConnectionEntry pc(1, 0);
334 ExecuteAddPeerConnectionJs(pc); 342 ExecuteAddPeerConnectionJs(pc);
335 343
336 const string type = "ssrc"; 344 const string type = "ssrc";
337 const string id = "1234"; 345 const string id = "1234";
338 StatsUnit local = {FAKE_TIME_STAMP}; 346 StatsUnit stats = {FAKE_TIME_STAMP};
339 local.values["bitrate"] = "2000"; 347 stats.values["bitrate"] = "2000";
340 local.values["framerate"] = "30"; 348 stats.values["framerate"] = "30";
341 StatsUnit remote = {FAKE_TIME_STAMP};
342 remote.values["jitter"] = "1";
343 remote.values["rtt"] = "20";
344 349
345 // Add new stats and verify the stats table and graphs. 350 // Add new stats and verify the stats table and graphs.
346 ExecuteAndVerifyAddStats(pc, type, id, local, remote); 351 ExecuteAndVerifyAddStats(pc, type, id, stats);
347 VerifyStatsGraph(pc); 352 VerifyStatsGraph(pc);
348 353
349 // Update existing stats and verify the stats table and graphs. 354 // Update existing stats and verify the stats table and graphs.
350 local.values["bitrate"] = "2001"; 355 stats.values["bitrate"] = "2001";
351 local.values["framerate"] = "31"; 356 stats.values["framerate"] = "31";
352 ExecuteAndVerifyAddStats(pc, type, id, local, remote); 357 ExecuteAndVerifyAddStats(pc, type, id, stats);
353 VerifyStatsGraph(pc); 358 VerifyStatsGraph(pc);
354 } 359 }
355 360
356 // Tests that the bandwidth estimation values are drawn on a single graph. 361 // Tests that the bandwidth estimation values are drawn on a single graph.
357 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, BweCompoundGraph) { 362 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, BweCompoundGraph) {
358 GURL url("chrome://webrtc-internals"); 363 GURL url("chrome://webrtc-internals");
359 NavigateToURL(shell(), url); 364 NavigateToURL(shell(), url);
360 365
361 PeerConnectionEntry pc(1, 0); 366 PeerConnectionEntry pc(1, 0);
362 ExecuteAddPeerConnectionJs(pc); 367 ExecuteAddPeerConnectionJs(pc);
363 368
364 StatsUnit local = {FAKE_TIME_STAMP}; 369 StatsUnit stats = {FAKE_TIME_STAMP};
365 local.values["googAvailableSendBandwidth"] = "1000000"; 370 stats.values["googAvailableSendBandwidth"] = "1000000";
366 local.values["googTargetEncBitrate"] = "1000"; 371 stats.values["googTargetEncBitrate"] = "1000";
367 local.values["googActualEncBitrate"] = "1000000"; 372 stats.values["googActualEncBitrate"] = "1000000";
368 local.values["googRetransmitBitrate"] = "10"; 373 stats.values["googRetransmitBitrate"] = "10";
369 local.values["googTransmitBitrate"] = "1000000"; 374 stats.values["googTransmitBitrate"] = "1000000";
370 const string stats_type = "bwe"; 375 const string stats_type = "bwe";
371 const string stats_id = "videobwe"; 376 const string stats_id = "videobwe";
372 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, local, local); 377 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);
373 378
374 string graph_id = 379 string graph_id =
375 pc.getIdString() + "-" + stats_type + "-" + stats_id + "-bweCompound"; 380 pc.getIdString() + "-" + stats_type + "-" + stats_id + "-bweCompound";
376 bool result = false; 381 bool result = false;
377 // Verify that the bweCompound graph exists. 382 // Verify that the bweCompound graph exists.
378 ASSERT_TRUE(ExecuteScriptAndExtractBool( 383 ASSERT_TRUE(ExecuteScriptAndExtractBool(
379 shell()->web_contents(), 384 shell()->web_contents(),
380 "window.domAutomationController.send(" 385 "window.domAutomationController.send("
381 " graphViews['" + graph_id + "'] != null)", 386 " graphViews['" + graph_id + "'] != null)",
382 &result)); 387 &result));
383 EXPECT_TRUE(result); 388 EXPECT_TRUE(result);
384 389
385 // Verify that the bweCompound graph contains multiple dataSeries. 390 // Verify that the bweCompound graph contains multiple dataSeries.
386 int count = 0; 391 int count = 0;
387 ASSERT_TRUE(ExecuteScriptAndExtractInt( 392 ASSERT_TRUE(ExecuteScriptAndExtractInt(
388 shell()->web_contents(), 393 shell()->web_contents(),
389 "window.domAutomationController.send(" 394 "window.domAutomationController.send("
390 " graphViews['" + graph_id + "'].getDataSeriesCount())", 395 " graphViews['" + graph_id + "'].getDataSeriesCount())",
391 &count)); 396 &count));
392 EXPECT_EQ((int)local.values.size(), count); 397 EXPECT_EQ((int)stats.values.size(), count);
393 } 398 }
394 399
395 // Tests that the total packet/byte count is converted to count per second, 400 // Tests that the total packet/byte count is converted to count per second,
396 // and the converted data is drawn. 401 // and the converted data is drawn.
397 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, ConvertedGraphs) { 402 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, ConvertedGraphs) {
398 GURL url("chrome://webrtc-internals"); 403 GURL url("chrome://webrtc-internals");
399 NavigateToURL(shell(), url); 404 NavigateToURL(shell(), url);
400 405
401 PeerConnectionEntry pc(1, 0); 406 PeerConnectionEntry pc(1, 0);
402 ExecuteAddPeerConnectionJs(pc); 407 ExecuteAddPeerConnectionJs(pc);
403 408
404 const string stats_type = "s"; 409 const string stats_type = "s";
405 const string stats_id = "1"; 410 const string stats_id = "1";
406 const int num_converted_stats = 4; 411 const int num_converted_stats = 4;
407 const string stats_names[] = 412 const string stats_names[] =
408 {"packetsSent", "bytesSent", "packetsReceived", "bytesReceived"}; 413 {"packetsSent", "bytesSent", "packetsReceived", "bytesReceived"};
409 const string converted_names[] = 414 const string converted_names[] =
410 {"packetsSentPerSecond", "bitsSentPerSecond", 415 {"packetsSentPerSecond", "bitsSentPerSecond",
411 "packetsReceivedPerSecond", "bitsReceivedPerSecond"}; 416 "packetsReceivedPerSecond", "bitsReceivedPerSecond"};
412 const string first_value = "1000"; 417 const string first_value = "1000";
413 const string second_value = "2000"; 418 const string second_value = "2000";
414 const string converted_values[] = {"1000", "8000", "1000", "8000"}; 419 const string converted_values[] = {"1000", "8000", "1000", "8000"};
415 420
416 // Send the first data point. 421 // Send the first data point.
417 StatsUnit remote = {FAKE_TIME_STAMP}; 422 StatsUnit stats = {FAKE_TIME_STAMP};
418 StatsUnit local = {FAKE_TIME_STAMP};
419 for (int i = 0; i < num_converted_stats; ++i) 423 for (int i = 0; i < num_converted_stats; ++i)
420 local.values[stats_names[i]] = first_value; 424 stats.values[stats_names[i]] = first_value;
421 425
422 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, local, remote); 426 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);
423 427
424 // Send the second data point at 1000ms after the first data point. 428 // Send the second data point at 1000ms after the first data point.
425 local.timestamp += 1000; 429 stats.timestamp += 1000;
426 for (int i = 0; i < num_converted_stats; ++i) 430 for (int i = 0; i < num_converted_stats; ++i)
427 local.values[stats_names[i]] = second_value; 431 stats.values[stats_names[i]] = second_value;
428 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, local, remote); 432 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);
429 433
430 // Verifies the graph data matches converted_values. 434 // Verifies the graph data matches converted_values.
431 string graph_id_prefix = pc.getIdString() + "-" + stats_type + "-" + stats_id; 435 string graph_id_prefix = pc.getIdString() + "-" + stats_type + "-" + stats_id;
432 for (int i = 0; i < num_converted_stats; ++i) { 436 for (int i = 0; i < num_converted_stats; ++i) {
433 VerifyGraphDataPoint( 437 VerifyGraphDataPoint(
434 graph_id_prefix + "-" + converted_names[i], 1, converted_values[i]); 438 graph_id_prefix + "-" + converted_names[i], 1, converted_values[i]);
435 } 439 }
436 } 440 }
437 441
442 // Sanity check of the page content under a real PeerConnection call.
443 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, withRealPeerConnectionCall) {
444 // Start a peerconnection call in the first window.
445 GURL url(test_server()->GetURL("files/media/peerconnection-call.html"));
446 NavigateToURL(shell(), url);
447 ASSERT_TRUE(ExecuteJavascript("call({video:true});"));
448 ExpectTitle("OK");
449
450 // Open webrtc-internals in the second window.
451 GURL url2("chrome://webrtc-internals");
452 Shell* shell2 = CreateBrowser();
453 NavigateToURL(shell2, url2);
454
455 const int NUMBER_OF_PEER_CONNECTIONS = 2;
456
457 // Verifies the number of peerconnections.
458 int count = 0;
459 ASSERT_TRUE(ExecuteScriptAndExtractInt(
460 shell2->web_contents(),
461 "window.domAutomationController.send("
462 "$('peer-connections-list').getElementsByTagName('li').length);",
463 &count));
464 EXPECT_EQ(NUMBER_OF_PEER_CONNECTIONS, count);
465
466 // Verifies the the event tables.
467 ASSERT_TRUE(ExecuteScriptAndExtractInt(
468 shell2->web_contents(),
469 "window.domAutomationController.send("
470 "$('peer-connections-list').getElementsByClassName('log-table')[0]"
471 ".rows.length);",
472 &count));
473 EXPECT_GT(count, 1);
474
475 ASSERT_TRUE(ExecuteScriptAndExtractInt(
476 shell2->web_contents(),
477 "window.domAutomationController.send("
478 "$('peer-connections-list').getElementsByClassName('log-table')[1]"
479 ".rows.length);",
480 &count));
481 EXPECT_GT(count, 1);
482
483 // Wait until the stats table containers are created.
484 count = 0;
485 while (count != NUMBER_OF_PEER_CONNECTIONS) {
486 ASSERT_TRUE(ExecuteScriptAndExtractInt(
487 shell2->web_contents(),
488 "window.domAutomationController.send("
489 "$('peer-connections-list').getElementsByClassName("
490 "'stats-table-container').length);",
491 &count));
492 }
493
494 // Verifies each stats table having more than one rows.
495 bool result = false;
496 ASSERT_TRUE(ExecuteScriptAndExtractBool(
497 shell2->web_contents(),
498 "var tableContainers = $('peer-connections-list')"
499 ".getElementsByClassName('stats-table-container');"
500 "var result = true;"
501 "for (var i = 0; i < tableContainers.length && result; ++i) {"
502 "var tables = tableContainers[i].getElementsByTagName('table');"
503 "for (var j = 0; j < tables.length && result; ++j) {"
504 "result = (tables[j].rows.length > 1);"
505 "}"
506 "if (!result) {"
507 "console.log(tableContainers[i].innerHTML);"
508 "}"
509 "}"
510 "window.domAutomationController.send(result);",
511 &result));
512
513 EXPECT_TRUE(result);
514 }
515
438 } // namespace content 516 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/browser/resources/media/stats_graph_helper.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698