| Index: chrome/test/webdriver/session_manager.cc
|
| ===================================================================
|
| --- chrome/test/webdriver/session_manager.cc (revision 0)
|
| +++ chrome/test/webdriver/session_manager.cc (revision 0)
|
| @@ -0,0 +1,251 @@
|
| +// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/test/webdriver/session_manager.h"
|
| +
|
| +#ifdef OS_POSIX
|
| + #include <netdb.h>
|
| + #include <unistd.h>
|
| + #include <arpa/inet.h>
|
| + #include <net/if.h>
|
| + #include <sys/ioctl.h>
|
| + #include <sys/socket.h>
|
| + #include <sys/types.h>
|
| +#elif OS_WIN
|
| + #include <Shellapi.h>
|
| + #include <Winsock2.h>
|
| +#endif
|
| +
|
| +#include "base/command_line.h"
|
| +#include "base/lock.h"
|
| +#include "base/logging.h"
|
| +#include "base/process.h"
|
| +#include "base/process_util.h"
|
| +#include "base/ref_counted.h"
|
| +#include "base/scoped_ptr.h"
|
| +
|
| +#include "chrome/common/chrome_constants.h"
|
| +#include "chrome/common/chrome_switches.h"
|
| +
|
| +namespace webdriver {
|
| +
|
| +std::string SessionManager::GetIPAddress() {
|
| + return std::string(addr_) + std::string(":") + port_;
|
| +}
|
| +
|
| +std::string SessionManager::IPLookup(const std::string& nic) {
|
| +#ifdef OS_POSIX
|
| + int socket_conn;
|
| + struct ifreq ifr;
|
| + struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.ifr_addr;
|
| +
|
| + memset(&ifr, 0, sizeof(ifr));
|
| + snprintf(ifr.ifr_name, IFNAMSIZ, "%s", nic.c_str());
|
| + sin->sin_family = AF_INET;
|
| +
|
| + if (0 > (socket_conn = socket(AF_INET, SOCK_STREAM, 0))) {
|
| + return std::string("");
|
| + }
|
| +
|
| + if (0 == ioctl(socket_conn, SIOCGIFADDR, &ifr)) {
|
| + return std::string(inet_ntoa(sin->sin_addr));
|
| + }
|
| +#endif // cann't use else since a warning will be generated
|
| + return std::string("");
|
| +}
|
| +
|
| +bool SessionManager::SetIPAddress(const std::string& p) {
|
| + port_ = p;
|
| + std::string prefix("192.");
|
| +#ifdef OS_POSIX
|
| + char buff[32];
|
| +
|
| + for (int i = 0; i < 10; ++i) {
|
| +#ifdef OS_MACOSX
|
| + snprintf(buff, sizeof(buff), "%s%d", "en", i);
|
| +#elif OS_LINUX
|
| + snprintf(buff, sizeof(buff), "%s%d", "eth", i);
|
| +#endif
|
| + addr_ = IPLookup(std::string(buff));
|
| + if (addr_.length() > 0) {
|
| + if ((addr_.compare("127.0.0.1") != 0) &&
|
| + (addr_.compare("127.0.1.1") != 0) &&
|
| + (addr_.compare(0, prefix.size(), prefix) != 0)) {
|
| + return true;
|
| + }
|
| + }
|
| + }
|
| + return false;
|
| +#elif OS_WIN
|
| + hostent *h;
|
| + char host[1024];
|
| + WORD wVersionRequested;
|
| + WSADATA wsaData;
|
| +
|
| + memset(host, 0, sizeof host);
|
| + wVersionRequested = MAKEWORD(2, 0);
|
| + if (WSAStartup(wVersionRequested, &wsaData) != 0) {
|
| + LOG(ERROR) << "Could not initialize the Windows Sockets library";
|
| + LOG(ERROR) << std::endl;
|
| + return false;
|
| + }
|
| + if (gethostname(host, sizeof host) != 0) {
|
| + LOG(ERROR) << "Could not find the hostname of this machine" << std::endl;
|
| + WSACleanup();
|
| + return false;
|
| + }
|
| + h = gethostbyname(host);
|
| + for (int i = 0; ((h->h_addr_list[i]) && (i < h->h_length)); ++i) {
|
| + addr_ = std::string(inet_ntoa(*(struct in_addr *)h->h_addr_list[i]));
|
| + if ((addr_.compare("127.0.0.1") != 0) &&
|
| + (addr_.compare("127.0.1.1") != 0) &&
|
| + (addr_.compare(0, prefix.size(), prefix) != 0)) {
|
| + WSACleanup();
|
| + return true;
|
| + }
|
| + }
|
| +
|
| + WSACleanup();
|
| + return false;
|
| +#endif
|
| +}
|
| +
|
| +std::string SessionManager::GenerateSessionID() {
|
| + static const char text[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ"\
|
| + "RSTUVWXYZ0123456789";
|
| + session_generation_.Acquire();
|
| + std::string id = "";
|
| + count_++; // for every connection made increment the global count
|
| + for (int i = 0; i < 32; ++i) {
|
| +#ifdef OS_POSIX
|
| + id += text[random() % (sizeof text - 1)];
|
| +#else
|
| + id += text[rand() % (sizeof text - 1)];
|
| +#endif
|
| + id += count_; // append the global count to generate a unique id
|
| + }
|
| + session_generation_.Release();
|
| + return id;
|
| +}
|
| +
|
| +bool SessionManager::Create(std::string* id) {
|
| + FilePath browser_directory; // Path to the browser executable
|
| + MessageLoop loop;
|
| +
|
| + *id = GenerateSessionID();
|
| + if (map_.find(*id) != map_.end()) {
|
| + LOG(ERROR) << "Failed to generate a unique session ID";
|
| + return false;
|
| + }
|
| +
|
| + // Init the commandline singleton from the env
|
| + CommandLine::Init(0, NULL);
|
| +
|
| + // start chrome, if it doesn't startup in 8 seconds quit
|
| + scoped_ptr<Session> session(new Session(*id, new AutomationProxy(8000)));
|
| + if (session->proxy() == NULL) {
|
| + LOG(WARNING) << "Could not allocate automation proxy" << std::endl;
|
| + return false;
|
| + }
|
| +
|
| +#if defined(OS_POSIX)
|
| + char* user_data_dir = getenv("CHROME_UI_TESTS_USER_DATA_DIR");
|
| + if (user_data_dir) {
|
| + browser_directory.Append(user_data_dir);
|
| + }
|
| +#endif
|
| +
|
| + FilePath command =
|
| + browser_directory.Append(FilePath::FromWStringHack(
|
| + chrome::kBrowserProcessExecutablePath));
|
| + CommandLine command_line(command);
|
| +
|
| + // setup the automation port to communicate on
|
| + command_line.AppendSwitchASCII(switches::kAutomationClientChannelID,
|
| + session->proxy()->channel_id());
|
| +
|
| + // No first-run dialogs, please.
|
| + command_line.AppendSwitch(switches::kNoFirstRun);
|
| +
|
| + // No default browser check, it would create an info-bar (if we are
|
| + // not the default browser) that could conflicts with some tests
|
| + // expectations.
|
| + command_line.AppendSwitch(switches::kNoDefaultBrowserCheck);
|
| +
|
| + // We need cookies on file:// for things like the page cycler.
|
| + command_line.AppendSwitch(switches::kEnableFileCookies);
|
| + command_line.AppendSwitch(switches::kDomAutomationController);
|
| + command_line.AppendSwitch(switches::kFullMemoryCrashReport);
|
| +
|
| + // create a temp directory for the new profile
|
| + if (!session->CreateTemporaryProfileDirectory()) {
|
| + LOG(ERROR) << "Could not make a temp profile directory, "
|
| + << session->tmp_profile_dir() << std::endl;
|
| + LOG(ERROR) << "Need to quit, the issue must be fixed" << std::endl;
|
| + exit(-1);
|
| + }
|
| +
|
| + command_line.AppendSwitchASCII(switches::kUserDataDir,
|
| + session->tmp_profile_dir());
|
| +
|
| + base::ProcessHandle process_handle;
|
| +#if defined(OS_WIN)
|
| + base::LaunchApp(command_line, false, true, &process_handle);
|
| +#elif defined(OS_POSIX)
|
| + // Sometimes one needs to run the browser under a special environment
|
| + // (e.g. valgrind) without also running the test harness (e.g. python)
|
| + // under the special environment. Provide a way to wrap the browser
|
| + // commandline with a special prefix to invoke the special environment.
|
| + const char* browser_wrapper = getenv("BROWSER_WRAPPER");
|
| +
|
| + if (browser_wrapper) {
|
| + command_line.PrependWrapper(browser_wrapper);
|
| + LOG(INFO) << "BROWSER_WRAPPER was set, prefixing command_line with "
|
| + << browser_wrapper;
|
| + }
|
| +
|
| + base::LaunchApp(command_line.argv(), session->proxy()->fds_to_map(), false,
|
| + &process_handle);
|
| +#endif
|
| +
|
| + if (!session->Init(process_handle)) {
|
| + LOG(WARNING) << "Failed to initialize session";
|
| + return false;
|
| + }
|
| +
|
| + LOG(INFO) << "New session was created: " << id << std::endl;
|
| + map_[*id] = session.release();
|
| + return true;
|
| +}
|
| +
|
| +bool SessionManager::Has(const std::string& id) const {
|
| + return map_.find(id) != map_.end();
|
| +}
|
| +
|
| +bool SessionManager::Delete(const std::string& id) {
|
| + std::map<std::string, Session*>::iterator it;
|
| +
|
| + LOG(INFO) << "Deleting session with ID " << id;
|
| + it = map_.find(id);
|
| + if (it == map_.end()) {
|
| + LOG(INFO) << "No such session with ID " << id;
|
| + return false;
|
| + }
|
| +
|
| + it->second->Terminate();
|
| + map_.erase(it);
|
| + return true;
|
| +}
|
| +
|
| +Session* SessionManager::GetSession(const std::string& id) const {
|
| + std::map<std::string, Session*>::const_iterator it;
|
| + it = map_.find(id);
|
| + if (it == map_.end()) {
|
| + LOG(INFO) << "No such session with ID " << id;
|
| + return NULL;
|
| + }
|
| + return it->second;
|
| +}
|
| +} // namespace webdriver
|
| +
|
|
|
| Property changes on: chrome/test/webdriver/session_manager.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|