1 // Copyright 2013 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 "chrome/browser/media/webrtc_browsertest_common.h" 6 7 #include "base/command_line.h" 8 #include "base/file_util.h" 9 #include "base/path_service.h" 10 #include "base/process/launch.h" 11 #include "base/strings/stringprintf.h" 12 #include "base/test/test_timeouts.h" 13 #include "base/time/time.h" 14 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/ui/browser_tabstrip.h" 16 #include "content/public/test/browser_test_utils.h" 17 18 const int kDefaultPollIntervalMsec = 250; 19 20 bool SleepInJavascript(content::WebContents* tab_contents, int timeout_msec) { 21 const std::string javascript = base::StringPrintf( 22 "setTimeout(function() {" 23 " window.domAutomationController.send('sleep-ok');" 24 "}, %d)", timeout_msec); 25 26 std::string result; 27 bool ok = content::ExecuteScriptAndExtractString( 28 tab_contents, javascript, &result); 29 return ok && result == "sleep-ok"; 30 } 31 32 bool PollingWaitUntil(const std::string& javascript, 33 const std::string& evaluates_to, 34 content::WebContents* tab_contents) { 35 return PollingWaitUntil(javascript, evaluates_to, tab_contents, 36 kDefaultPollIntervalMsec); 37 } 38 39 bool PollingWaitUntil(const std::string& javascript, 40 const std::string& evaluates_to, 41 content::WebContents* tab_contents, 42 int poll_interval_msec) { 43 base::Time start_time = base::Time::Now(); 44 base::TimeDelta timeout = TestTimeouts::action_max_timeout(); 45 std::string result; 46 47 while (base::Time::Now() - start_time < timeout) { 48 std::string result; 49 if (!content::ExecuteScriptAndExtractString(tab_contents, javascript, 50 &result)) { 51 LOG(ERROR) << "Failed to execute javascript " << javascript; 52 return false; 53 } 54 55 if (evaluates_to == result) 56 return true; 57 58 // Sleep a bit here to keep this loop from spinlocking too badly. 59 if (!SleepInJavascript(tab_contents, poll_interval_msec)) { 60 // TODO(phoglund): Figure out why this fails every now and then. 61 // It's not a huge deal if it does though. 62 LOG(ERROR) << "Failed to sleep."; 63 } 64 } 65 LOG(ERROR) << "Timed out while waiting for " << javascript << 66 " to evaluate to " << evaluates_to << "; last result was '" << result << 67 "'"; 68 return false; 69 } 70 71 static base::FilePath::CharType kServerExecutable[] = 72 #if defined(OS_WIN) 73 FILE_PATH_LITERAL("peerconnection_server.exe"); 74 #else 75 FILE_PATH_LITERAL("peerconnection_server"); 76 #endif 77 78 const char PeerConnectionServerRunner::kDefaultPort[] = "7778"; 79 80 bool PeerConnectionServerRunner::Start() { 81 base::FilePath peerconnection_server; 82 if (!PathService::Get(base::DIR_MODULE, &peerconnection_server)) { 83 LOG(ERROR) << "Failed retrieving base::DIR_MODULE!"; 84 return false; 85 } 86 peerconnection_server = peerconnection_server.Append(kServerExecutable); 87 88 if (!base::PathExists(peerconnection_server)) { 89 LOG(ERROR) << "Missing " << kServerExecutable << ". You must build " 90 "it so it ends up next to the browser test binary."; 91 return false; 92 } 93 94 CommandLine command_line(peerconnection_server); 95 command_line.AppendSwitchASCII("port", kDefaultPort); 96 VLOG(0) << "Running " << command_line.GetCommandLineString(); 97 return base::LaunchProcess(command_line, 98 base::LaunchOptions(), 99 &server_pid_); 100 } 101 102 bool PeerConnectionServerRunner::Stop() { 103 return base::KillProcess(server_pid_, 0, false); 104 } 105 106 void PeerConnectionServerRunner::KillAllPeerConnectionServersOnCurrentSystem() { 107 if (!base::KillProcesses(kServerExecutable, -1, NULL)) { 108 LOG(ERROR) << "Failed to kill instances of " << kServerExecutable << "."; 109 return; 110 } 111 base::WaitForProcessesToExit(kServerExecutable, 112 base::TimeDelta::FromSeconds(5), NULL); 113 } 114