Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / media / chrome_webrtc_browsertest.cc
index 3aae51b..7127c09 100644 (file)
@@ -5,6 +5,7 @@
 #include "base/command_line.h"
 #include "base/file_util.h"
 #include "base/json/json_reader.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/path_service.h"
 #include "base/process/launch.h"
 #include "base/process/process_metrics.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/test/test_timeouts.h"
 #include "base/time/time.h"
-#include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/media/webrtc_browsertest_base.h"
 #include "chrome/browser/media/webrtc_browsertest_common.h"
+#include "chrome/browser/media/webrtc_browsertest_perf.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "chrome/test/ui/ui_test.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/test/browser_test_utils.h"
+#include "media/base/media_switches.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "testing/perf/perf_test.h"
 
+// For fine-grained suppression.
+#if defined(OS_WIN)
+#include "base/win/windows_version.h"
+#endif
+
 static const char kMainWebrtcTestHtmlPage[] =
     "/webrtc/webrtc_jsep01_test.html";
 
-// Top-level integration test for WebRTC. Requires a real webcam and microphone
-// on the running system. This test is not meant to run in the main browser
-// test suite since normal tester machines do not have webcams.
-class WebrtcBrowserTest : public WebRtcTestBase {
+// Top-level integration test for WebRTC. The test methods here must run
+// sequentially since they use a server binary on the system (hence they are
+// tagged as MANUAL). In addition, they need the reference videos which require
+// the webrtc.DEPS solution, which is not generally available on Chromium bots.
+class WebRtcBrowserTest : public WebRtcTestBase,
+                          public testing::WithParamInterface<bool> {
  public:
+  WebRtcBrowserTest() {}
   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
-    PeerConnectionServerRunner::KillAllPeerConnectionServersOnCurrentSystem();
+    DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
   }
 
   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
-    // This test expects real device handling and requires a real webcam / audio
-    // device; it will not work with fake devices.
-    EXPECT_FALSE(command_line->HasSwitch(
-        switches::kUseFakeDeviceForMediaStream));
-    EXPECT_FALSE(command_line->HasSwitch(
-        switches::kUseFakeUIForMediaStream));
-
-    // The video playback will not work without a GPU, so force its use here.
-    command_line->AppendSwitch(switches::kUseGpuInTests);
-  }
-
-  // Ensures we didn't get any errors asynchronously (e.g. while no javascript
-  // call from this test was outstanding).
-  void AssertNoAsynchronousErrors(content::WebContents* tab_contents) {
-    EXPECT_EQ("ok-no-errors",
-              ExecuteJavascript("getAnyTestFailures()", tab_contents));
-  }
-
-  void EstablishCall(content::WebContents* from_tab,
-                     content::WebContents* to_tab) {
-    ConnectToPeerConnectionServer("peer 1", from_tab);
-    ConnectToPeerConnectionServer("peer 2", to_tab);
-
-    EXPECT_EQ("ok-peerconnection-created",
-              ExecuteJavascript("preparePeerConnection()", from_tab));
-    EXPECT_EQ("ok-added",
-              ExecuteJavascript("addLocalStream()", from_tab));
-    EXPECT_EQ("ok-negotiating",
-              ExecuteJavascript("negotiateCall()", from_tab));
-
-    // Ensure the call gets up on both sides.
-    EXPECT_TRUE(PollingWaitUntil("getPeerConnectionReadyState()",
-                                 "active", from_tab));
-    EXPECT_TRUE(PollingWaitUntil("getPeerConnectionReadyState()",
-                                 "active", to_tab));
-
-    AssertNoAsynchronousErrors(from_tab);
-    AssertNoAsynchronousErrors(to_tab);
-  }
-
-  void StartDetectingVideo(content::WebContents* tab_contents,
-                           const std::string& video_element) {
-    std::string javascript = base::StringPrintf(
-        "startDetection('%s', 'frame-buffer', 320, 240)",
-        video_element.c_str());
-    EXPECT_EQ("ok-started", ExecuteJavascript(javascript, tab_contents));
-  }
-
-  void WaitForVideoToPlay(content::WebContents* tab_contents) {
-    EXPECT_TRUE(PollingWaitUntil("isVideoPlaying()", "video-playing",
-                                 tab_contents));
-  }
-
-  void WaitForVideoToStopPlaying(content::WebContents* tab_contents) {
-    EXPECT_TRUE(PollingWaitUntil("isVideoPlaying()", "video-not-playing",
-                                 tab_contents));
-  }
-
-  void HangUp(content::WebContents* from_tab) {
-    EXPECT_EQ("ok-call-hung-up", ExecuteJavascript("hangUp()", from_tab));
-  }
-
-  void WaitUntilHangupVerified(content::WebContents* tab_contents) {
-    EXPECT_TRUE(PollingWaitUntil("getPeerConnectionReadyState()",
-                                 "no-peer-connection", tab_contents));
-  }
-
-  std::string ToggleLocalVideoTrack(content::WebContents* tab_contents) {
-    // Toggle the only video track in the page (e.g. video track 0).
-    return ExecuteJavascript("toggleLocalStream("
-        "function(local) { return local.getVideoTracks()[0]; }, "
-        "'video');", tab_contents);
-  }
-
-  std::string ToggleRemoteVideoTrack(content::WebContents* tab_contents) {
-    // Toggle the only video track in the page (e.g. video track 0).
-    return ExecuteJavascript("toggleRemoteStream("
-        "function(local) { return local.getVideoTracks()[0]; }, "
-        "'video');", tab_contents);
+    // Ensure the infobar is enabled, since we expect that in this test.
+    EXPECT_FALSE(command_line->HasSwitch(switches::kUseFakeUIForMediaStream));
+
+    // Play a suitable, somewhat realistic video file.
+    base::FilePath input_video = test::GetReferenceFilesDir()
+        .Append(test::kReferenceFileName360p)
+        .AddExtension(test::kY4mFileExtension);
+    command_line->AppendSwitchPath(switches::kUseFileForFakeVideoCapture,
+                                   input_video);
+    command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
+
+    // Flag used by TestWebAudioMediaStream to force garbage collection.
+    command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose-gc");
+
+    bool enable_audio_track_processing = GetParam();
+    if (enable_audio_track_processing)
+      command_line->AppendSwitch(switches::kEnableAudioTrackProcessing);
   }
 
   void PrintProcessMetrics(base::ProcessMetrics* process_metrics,
@@ -146,73 +93,64 @@ class WebrtcBrowserTest : public WebRtcTestBase {
     }
   }
 
-  std::string GetWebrtcInternalsData(
+  // Tries to extract data from peerConnectionDataStore in the webrtc-internals
+  // tab. The caller owns the parsed data. Returns NULL on failure.
+  base::DictionaryValue* GetWebrtcInternalsData(
       content::WebContents* webrtc_internals_tab) {
-    return ExecuteJavascript(
+    std::string all_stats_json = ExecuteJavascript(
         "window.domAutomationController.send("
         "    JSON.stringify(peerConnectionDataStore));",
         webrtc_internals_tab);
-  }
 
-  void PrintInternalMetrics(const std::string& all_stats_json) {
     base::Value* parsed_json = base::JSONReader::Read(all_stats_json);
-    ASSERT_TRUE(parsed_json != NULL) <<
-        "Received bad JSON from webrtc-internals!";
-    const base::DictionaryValue* json_dict;
-    ASSERT_TRUE(parsed_json->GetAsDictionary(&json_dict));
-
-    base::DictionaryValue::Iterator iterator(*json_dict);
-    ASSERT_FALSE(iterator.IsAtEnd()) << "Didn't capture data about any peer "
-         "connections in webrtc-internals.";
-
-    const base::DictionaryValue* first_pc_dict;
-    ASSERT_TRUE(iterator.value().GetAsDictionary(&first_pc_dict));
-
-    std::string value;
-    ASSERT_TRUE(first_pc_dict->GetString(
-        "stats.bweforvideo-googAvailableSendBandwidth.values", &value));
-    perf_test::PrintResult("bwe_stats", "", "available_send_bw", value, "bytes",
-                           false);
-    ASSERT_TRUE(first_pc_dict->GetString(
-        "stats.bweforvideo-googAvailableReceiveBandwidth.values", &value));
-    perf_test::PrintResult("bwe_stats", "", "available_recv_bw", value, "bytes",
-                           false);
-    ASSERT_TRUE(first_pc_dict->GetString(
-        "stats.bweforvideo-googTargetEncBitrate.values", &value));
-    perf_test::PrintResult("bwe_stats", "", "target_enc_bitrate",
-                           value, "bytes", false);
-    ASSERT_TRUE(first_pc_dict->GetString(
-        "stats.bweforvideo-googActualEncBitrate.values", &value));
-    perf_test::PrintResult("bwe_stats", "", "actual_enc_bitrate",
-                           value, "bytes", false);
-    ASSERT_TRUE(first_pc_dict->GetString(
-        "stats.bweforvideo-googTransmitBitrate.values", &value));
-    perf_test::PrintResult("bwe_stats", "", "transmit_bitrate", value, "bytes",
-                           false);
+    base::DictionaryValue* result;
+    if (parsed_json && parsed_json->GetAsDictionary(&result))
+      return result;
+
+    return NULL;
   }
 
-  content::WebContents* OpenTestPageAndGetUserMediaInNewTab() {
-    chrome::AddBlankTabAt(browser(), -1, true);
-    ui_test_utils::NavigateToURL(
-        browser(), embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage));
-    content::WebContents* left_tab =
-        browser()->tab_strip_model()->GetActiveWebContents();
-    GetUserMediaAndAccept(left_tab);
-    return left_tab;
+  const base::DictionaryValue* GetDataOnFirstPeerConnection(
+      const base::DictionaryValue* all_data) {
+    base::DictionaryValue::Iterator iterator(*all_data);
+
+    const base::DictionaryValue* result;
+    if (!iterator.IsAtEnd() && iterator.value().GetAsDictionary(&result))
+      return result;
+
+    return NULL;
   }
 
-  PeerConnectionServerRunner peerconnection_server_;
+  bool OnWinXp() {
+#if defined(OS_WIN)
+    return base::win::GetVersion() <= base::win::VERSION_XP;
+#else
+    return false;
+#endif
+  }
 };
 
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
+static const bool kRunTestsWithFlag[] = { false, true };
+INSTANTIATE_TEST_CASE_P(WebRtcBrowserTests,
+                        WebRtcBrowserTest,
+                        testing::ValuesIn(kRunTestsWithFlag));
+
+IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest,
                        MANUAL_RunsAudioVideoWebRTCCallInTwoTabs) {
+  if (OnWinXp()) return;
+
+  ASSERT_TRUE(test::HasReferenceFilesInCheckout());
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-  ASSERT_TRUE(peerconnection_server_.Start());
 
-  content::WebContents* left_tab = OpenTestPageAndGetUserMediaInNewTab();
-  content::WebContents* right_tab = OpenTestPageAndGetUserMediaInNewTab();
+  content::WebContents* left_tab =
+      OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
+  content::WebContents* right_tab =
+      OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
+
+  SetupPeerconnectionWithLocalStream(left_tab);
+  SetupPeerconnectionWithLocalStream(right_tab);
 
-  EstablishCall(left_tab, right_tab);
+  NegotiateCall(left_tab, right_tab);
 
   StartDetectingVideo(left_tab, "remote-view");
   StartDetectingVideo(right_tab, "remote-view");
@@ -221,30 +159,26 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
   WaitForVideoToPlay(right_tab);
 
   HangUp(left_tab);
-  WaitUntilHangupVerified(left_tab);
-  WaitUntilHangupVerified(right_tab);
-
-  AssertNoAsynchronousErrors(left_tab);
-  AssertNoAsynchronousErrors(right_tab);
-
-  ASSERT_TRUE(peerconnection_server_.Stop());
 }
 
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MANUAL_CpuUsage15Seconds) {
+IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MANUAL_CpuUsage15Seconds) {
+  if (OnWinXp()) return;
+
+  ASSERT_TRUE(test::HasReferenceFilesInCheckout());
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-  ASSERT_TRUE(peerconnection_server_.Start());
 
   base::FilePath results_file;
-  ASSERT_TRUE(file_util::CreateTemporaryFile(&results_file));
+  ASSERT_TRUE(base::CreateTemporaryFile(&results_file));
 
-  content::WebContents* left_tab = OpenTestPageAndGetUserMediaInNewTab();
+  content::WebContents* left_tab =
+      OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
 
 #if defined(OS_MACOSX)
   // Don't measure renderer CPU on mac: requires a mach broker we don't have
   // access to from the browser test.
   scoped_ptr<base::ProcessMetrics> browser_process_metrics(
       base::ProcessMetrics::CreateProcessMetrics(
-      base::Process::Current().handle(), NULL));
+          base::Process::Current().handle(), NULL));
   browser_process_metrics->GetCPUUsage();
 #else
   // Measure rendering CPU on platforms that support it.
@@ -260,70 +194,45 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MANUAL_CpuUsage15Seconds) {
   browser_process_metrics->GetCPUUsage();
 #endif
 
-  content::WebContents* right_tab = OpenTestPageAndGetUserMediaInNewTab();
+  content::WebContents* right_tab =
+      OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
 
-  EstablishCall(left_tab, right_tab);
+  SetupPeerconnectionWithLocalStream(left_tab);
+  SetupPeerconnectionWithLocalStream(right_tab);
 
-  SleepInJavascript(left_tab, 15000);
+  NegotiateCall(left_tab, right_tab);
+
+  test::SleepInJavascript(left_tab, 15000);
 
   HangUp(left_tab);
-  WaitUntilHangupVerified(left_tab);
-  WaitUntilHangupVerified(right_tab);
 
 #if !defined(OS_MACOSX)
   PrintProcessMetrics(renderer_process_metrics.get(), "_r");
 #endif
   PrintProcessMetrics(browser_process_metrics.get(), "_b");
-
-  AssertNoAsynchronousErrors(left_tab);
-  AssertNoAsynchronousErrors(right_tab);
-
-  ASSERT_TRUE(peerconnection_server_.Stop());
 }
 
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
-                       MANUAL_TestMediaStreamTrackEnableDisable) {
-  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-  ASSERT_TRUE(peerconnection_server_.Start());
-
-  content::WebContents* left_tab = OpenTestPageAndGetUserMediaInNewTab();
-  content::WebContents* right_tab = OpenTestPageAndGetUserMediaInNewTab();
-
-  EstablishCall(left_tab, right_tab);
-
-  StartDetectingVideo(left_tab, "remote-view");
-  StartDetectingVideo(right_tab, "remote-view");
-
-  WaitForVideoToPlay(left_tab);
-  WaitForVideoToPlay(right_tab);
-
-  EXPECT_EQ("ok-video-toggled-to-false", ToggleLocalVideoTrack(left_tab));
+// This is manual for its long execution time.
+IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest,
+                       MANUAL_RunsAudioVideoCall60SecsAndLogsInternalMetrics) {
+  if (OnWinXp()) return;
 
-  WaitForVideoToStopPlaying(right_tab);
-
-  EXPECT_EQ("ok-video-toggled-to-true", ToggleLocalVideoTrack(left_tab));
-
-  WaitForVideoToPlay(right_tab);
-
-  HangUp(left_tab);
-  WaitUntilHangupVerified(left_tab);
-  WaitUntilHangupVerified(right_tab);
+  ASSERT_TRUE(test::HasReferenceFilesInCheckout());
+  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
 
-  AssertNoAsynchronousErrors(left_tab);
-  AssertNoAsynchronousErrors(right_tab);
+  ASSERT_GE(TestTimeouts::action_max_timeout().InSeconds(), 100) <<
+      "This is a long-running test; you must specify "
+      "--ui-test-action-max-timeout to have a value of at least 100000.";
 
-  ASSERT_TRUE(peerconnection_server_.Stop());
-}
+  content::WebContents* left_tab =
+      OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
+  content::WebContents* right_tab =
+      OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
 
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
-                       MANUAL_RunsAudioVideoCall20SecsAndLogsInternalMetrics) {
-  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-  ASSERT_TRUE(peerconnection_server_.Start());
+  SetupPeerconnectionWithLocalStream(left_tab);
+  SetupPeerconnectionWithLocalStream(right_tab);
 
-  content::WebContents* left_tab = OpenTestPageAndGetUserMediaInNewTab();
-  content::WebContents* right_tab = OpenTestPageAndGetUserMediaInNewTab();
-
-  EstablishCall(left_tab, right_tab);
+  NegotiateCall(left_tab, right_tab);
 
   StartDetectingVideo(left_tab, "remote-view");
   StartDetectingVideo(right_tab, "remote-view");
@@ -332,25 +241,41 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
   WaitForVideoToPlay(right_tab);
 
   // Let values stabilize, bandwidth ramp up, etc.
-  SleepInJavascript(left_tab, 10000);
+  test::SleepInJavascript(left_tab, 60000);
 
   // Start measurements.
-  chrome::AddBlankTabAt(browser(), -1, true);
+  chrome::AddTabAt(browser(), GURL(), -1, true);
   ui_test_utils::NavigateToURL(browser(), GURL("chrome://webrtc-internals"));
   content::WebContents* webrtc_internals_tab =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-  SleepInJavascript(left_tab, 10000);
+  test::SleepInJavascript(left_tab, 10000);
+
+  scoped_ptr<base::DictionaryValue> all_data(
+      GetWebrtcInternalsData(webrtc_internals_tab));
+  ASSERT_TRUE(all_data.get() != NULL);
 
-  std::string all_stats_json = GetWebrtcInternalsData(webrtc_internals_tab);
-  PrintInternalMetrics(all_stats_json);
+  const base::DictionaryValue* first_pc_dict =
+      GetDataOnFirstPeerConnection(all_data.get());
+  ASSERT_TRUE(first_pc_dict != NULL);
+  test::PrintBweForVideoMetrics(*first_pc_dict);
+  test::PrintMetricsForAllStreams(*first_pc_dict);
 
   HangUp(left_tab);
-  WaitUntilHangupVerified(left_tab);
-  WaitUntilHangupVerified(right_tab);
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MANUAL_TestWebAudioMediaStream) {
+  if (OnWinXp()) return;
+
+  ASSERT_TRUE(test::HasReferenceFilesInCheckout());
+  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+  GURL url(embedded_test_server()->GetURL("/webrtc/webaudio_crash.html"));
+  ui_test_utils::NavigateToURL(browser(), url);
+  content::WebContents* tab =
+      browser()->tab_strip_model()->GetActiveWebContents();
 
-  AssertNoAsynchronousErrors(left_tab);
-  AssertNoAsynchronousErrors(right_tab);
+  // A sleep is necessary to be able to detect the crash.
+  test::SleepInJavascript(tab, 1000);
 
-  ASSERT_TRUE(peerconnection_server_.Stop());
+  ASSERT_FALSE(tab->IsCrashed());
 }