summaryrefslogtreecommitdiffstats
path: root/chrome_frame
diff options
context:
space:
mode:
authorgrt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 20:34:25 +0000
committergrt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 20:34:25 +0000
commita77ac74a0e89dd8ae256c4de754919d2b253ef6c (patch)
treee6dcc5ae72549c5d2437479c5f1e36120143c89e /chrome_frame
parenteb4e077ad36be4a7ba5f961de1a5ec98fda90064 (diff)
downloadchromium_src-a77ac74a0e89dd8ae256c4de754919d2b253ef6c.zip
chromium_src-a77ac74a0e89dd8ae256c4de754919d2b253ef6c.tar.gz
chromium_src-a77ac74a0e89dd8ae256c4de754919d2b253ef6c.tar.bz2
Attempt to fix ChromeFrameTestWithWebServer tests.
- Use a single MockWebServer (HTTPTestServer) instance for the whole test case rather than one per instance. - Run pending tasks and the end of each test. - Try even harder to keep the browser from caching. - Re-enable all previously disabled tests. - Save a snapshot of the screen to the desktop (ChromiumSnapshotYYYYMMDDHHMMSS.png) when tests timeout. - Use a local IPv4 address assigned to a NIC rather than the loopback address. - Retry tests that timeout a single time. BUG=112599,96449,37088,32321,111074 TEST=chrome_frame_tests.exe --gtest_filter=ChromeFrameTestWithWebServer.* becomes less flaky Review URL: http://codereview.chromium.org/10007043 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132637 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r--chrome_frame/chrome_frame.gyp2
-rw-r--r--chrome_frame/test/chrome_frame_test_utils.cc36
-rw-r--r--chrome_frame/test/chrome_frame_test_utils.h48
-rw-r--r--chrome_frame/test/mock_ie_event_sink_test.cc2
-rw-r--r--chrome_frame/test/net/fake_external_tab.cc29
-rw-r--r--chrome_frame/test/test_with_web_server.cc136
-rw-r--r--chrome_frame/test/test_with_web_server.h63
7 files changed, 227 insertions, 89 deletions
diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp
index 921b0a1..a8f4f1d 100644
--- a/chrome_frame/chrome_frame.gyp
+++ b/chrome_frame/chrome_frame.gyp
@@ -79,6 +79,7 @@
'dependencies': [
'../base/base.gyp:test_support_base',
'../chrome/app/policy/cloud_policy_codegen.gyp:policy',
+ '../chrome/chrome.gyp:test_support_common',
'../net/net.gyp:net',
'../testing/gmock.gyp:gmock',
'../testing/gtest.gyp:gtest',
@@ -306,6 +307,7 @@
'../chrome/chrome.gyp:browser',
'../chrome/chrome.gyp:debugger',
'../chrome/chrome.gyp:image_pre_reader',
+ '../chrome/chrome.gyp:test_support_common',
'../chrome/chrome.gyp:test_support_ui',
'../chrome/chrome.gyp:utility',
'../content/content.gyp:content_gpu',
diff --git a/chrome_frame/test/chrome_frame_test_utils.cc b/chrome_frame/test/chrome_frame_test_utils.cc
index fa504b8..1348b1a 100644
--- a/chrome_frame/test/chrome_frame_test_utils.cc
+++ b/chrome_frame/test/chrome_frame_test_utils.cc
@@ -9,6 +9,7 @@
#include <iepmapi.h>
#include <sddl.h>
#include <shlobj.h>
+#include <winsock2.h>
#include "base/command_line.h"
#include "base/file_path.h"
@@ -28,6 +29,7 @@
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome_frame/utils.h"
+#include "net/base/net_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
@@ -677,4 +679,38 @@ void ClearIESessionHistory() {
file_util::Delete(session_history_path, true);
}
+std::string GetLocalIPv4Address() {
+ std::string address;
+ net::NetworkInterfaceList nic_list;
+
+ if (!net::GetNetworkList(&nic_list)) {
+ LOG(ERROR) << "GetNetworkList failed to look up non-loopback adapters. "
+ << "Tests will be run over the loopback adapter, which may "
+ << "result in hangs.";
+ } else {
+ // GetNetworkList only returns 'Up' non-loopback adapters. Select the first
+ // IPv4 address found - we should be able to bind/connect over it.
+ for (size_t i = 0; i < nic_list.size(); ++i) {
+ if (nic_list[i].address.size() != net::kIPv4AddressSize)
+ continue;
+ char* address_string =
+ inet_ntoa(*reinterpret_cast<in_addr*>(&nic_list[i].address[0]));
+ DCHECK(address_string != NULL);
+ if (address_string != NULL) {
+ LOG(INFO) << "HTTP tests will run over " << address_string << ".";
+ address.assign(address_string);
+ break;
+ }
+ }
+ }
+
+ if (address.empty()) {
+ LOG(ERROR) << "Failed to find a non-loopback IP_V4 address. Tests will be "
+ << "run over the loopback adapter, which may result in hangs.";
+ address.assign("127.0.0.1");
+ }
+
+ return address;
+}
+
} // namespace chrome_frame_test
diff --git a/chrome_frame/test/chrome_frame_test_utils.h b/chrome_frame/test/chrome_frame_test_utils.h
index 8911188..2b7466b 100644
--- a/chrome_frame/test/chrome_frame_test_utils.h
+++ b/chrome_frame/test/chrome_frame_test_utils.h
@@ -13,14 +13,18 @@
#include <string>
#include "base/basictypes.h"
+#include "base/cancelable_callback.h"
#include "base/compiler_specific.h"
+#include "base/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/process_util.h"
#include "base/time.h"
#include "base/test/test_reg_util_win.h"
+#include "base/time.h"
#include "base/win/registry.h"
#include "base/win/scoped_comptr.h"
+#include "chrome/test/base/ui_test_utils.h"
#include "chrome_frame/chrome_tab.h"
#include "chrome_frame/test/simulate_input.h"
#include "chrome_frame/test_utils.h"
@@ -189,13 +193,22 @@ class HungCOMCallDetector
// We need a UI message loop in the main thread.
class TimedMsgLoop {
public:
- TimedMsgLoop() : quit_loop_invoked_(false) {
+ TimedMsgLoop() : snapshot_on_timeout_(false), quit_loop_invoked_(false) {
+ }
+
+ void set_snapshot_on_timeout(bool value) {
+ snapshot_on_timeout_ = value;
}
void RunFor(base::TimeDelta duration) {
- QuitAfter(duration);
quit_loop_invoked_ = false;
+ if (snapshot_on_timeout_)
+ timeout_closure_.Reset(base::Bind(&TimedMsgLoop::SnapshotAndQuit));
+ else
+ timeout_closure_.Reset(MessageLoop::QuitClosure());
+ loop_.PostDelayedTask(FROM_HERE, timeout_closure_.callback(), duration);
loop_.MessageLoop::Run();
+ timeout_closure_.Cancel();
}
void PostTask(const tracked_objects::Location& from_here,
@@ -209,10 +222,12 @@ class TimedMsgLoop {
}
void Quit() {
+ // Quit after no delay.
QuitAfter(base::TimeDelta());
}
void QuitAfter(base::TimeDelta delay) {
+ timeout_closure_.Cancel();
quit_loop_invoked_ = true;
loop_.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), delay);
}
@@ -221,8 +236,33 @@ class TimedMsgLoop {
return !quit_loop_invoked_;
}
+ void RunAllPending() {
+ loop_.RunAllPending();
+ }
+
private:
+ static void SnapshotAndQuit() {
+ FilePath snapshot;
+ if (ui_test_utils::SaveScreenSnapshotToDesktop(&snapshot)) {
+ testing::UnitTest* unit_test = testing::UnitTest::GetInstance();
+ const testing::TestInfo* test_info = unit_test->current_test_info();
+ std::string name;
+ if (test_info != NULL) {
+ name.append(test_info->test_case_name())
+ .append(1, '.')
+ .append(test_info->name());
+ } else {
+ name = "unknown test";
+ }
+ LOG(ERROR) << name << " timed out. Screen snapshot saved to "
+ << snapshot.value();
+ }
+ MessageLoop::current()->Quit();
+ }
+
MessageLoopForUI loop_;
+ base::CancelableClosure timeout_closure_;
+ bool snapshot_on_timeout_;
bool quit_loop_invoked_;
};
@@ -328,6 +368,10 @@ ScopedChromeFrameRegistrar::RegistrationType GetTestBedType();
// Clears IE8 session restore history.
void ClearIESessionHistory();
+// Returns a local IPv4 address for the current machine. The address
+// corresponding to a NIC is preferred over the loopback address.
+std::string GetLocalIPv4Address();
+
} // namespace chrome_frame_test
// TODO(tommi): This is a temporary workaround while we're getting our
diff --git a/chrome_frame/test/mock_ie_event_sink_test.cc b/chrome_frame/test/mock_ie_event_sink_test.cc
index 11a7dbd..49d6840 100644
--- a/chrome_frame/test/mock_ie_event_sink_test.cc
+++ b/chrome_frame/test/mock_ie_event_sink_test.cc
@@ -180,6 +180,7 @@ void MockIEEventSink::ExpectDocumentReadystate(int ready_state) {
// MockIEEventSinkTest methods
MockIEEventSinkTest::MockIEEventSinkTest() : server_mock_(1337, L"127.0.0.1",
GetTestDataFolder()) {
+ loop_.set_snapshot_on_timeout(true);
EXPECT_CALL(server_mock_, Get(_, StrCaseEq(L"/favicon.ico"), _))
.WillRepeatedly(SendFast("HTTP/1.1 404 Not Found", ""));
}
@@ -187,6 +188,7 @@ MockIEEventSinkTest::MockIEEventSinkTest() : server_mock_(1337, L"127.0.0.1",
MockIEEventSinkTest::MockIEEventSinkTest(int port, const std::wstring& address,
const FilePath& root_dir)
: server_mock_(port, address, root_dir) {
+ loop_.set_snapshot_on_timeout(true);
EXPECT_CALL(server_mock_, Get(_, StrCaseEq(L"/favicon.ico"), _))
.WillRepeatedly(SendFast("HTTP/1.1 404 Not Found", ""));
}
diff --git a/chrome_frame/test/net/fake_external_tab.cc b/chrome_frame/test/net/fake_external_tab.cc
index aa88758..0655ede 100644
--- a/chrome_frame/test/net/fake_external_tab.cc
+++ b/chrome_frame/test/net/fake_external_tab.cc
@@ -720,32 +720,9 @@ void CFUrlRequestUnittestRunner::OnInitializationTimeout() {
}
void CFUrlRequestUnittestRunner::OverrideHttpHost() {
- net::NetworkInterfaceList nic_list;
- if (!net::GetNetworkList(&nic_list)) {
- LOG(ERROR) << "GetNetworkList failed to look up non-loopback adapters. "
- << "Tests will be run over the loopback adapter, which may "
- << "result in hangs.";
- return;
- }
-
- // GetNetworkList only returns 'Up' non-loopback adapters. Select the first
- // IPV4 address found - we should be able to bind/connect over it.
- for (size_t i = 0; i < nic_list.size(); ++i) {
- if (nic_list[i].address.size() != net::kIPv4AddressSize)
- continue;
- char* address_string =
- inet_ntoa(*reinterpret_cast<in_addr*>(&nic_list[i].address[0]));
- DCHECK(address_string != NULL);
- if (address_string == NULL)
- continue;
- LOG(INFO) << "HTTP tests will run over " << address_string << ".";
- override_http_host_.reset(
- new ScopedCustomUrlRequestTestHttpHost(address_string));
- return;
- }
-
- LOG(ERROR) << "Failed to find a non-loopback IP_V4 address. Tests will be "
- << "run over the loopback adapter, which may result in hangs.";
+ override_http_host_.reset(
+ new ScopedCustomUrlRequestTestHttpHost(
+ chrome_frame_test::GetLocalIPv4Address()));
}
void CFUrlRequestUnittestRunner::PreEarlyInitialization() {
diff --git a/chrome_frame/test/test_with_web_server.cc b/chrome_frame/test/test_with_web_server.cc
index 1c87f7b..ca84ec6 100644
--- a/chrome_frame/test/test_with_web_server.cc
+++ b/chrome_frame/test/test_with_web_server.cc
@@ -44,8 +44,10 @@ std::string CreateHttpHeaders(CFInvocation invocation,
<< "Content-Type: " << content_type << "\r\n";
if (invocation.type() == CFInvocation::HTTP_HEADER)
ss << "X-UA-Compatible: chrome=1\r\n";
- if (add_no_cache_header)
+ if (add_no_cache_header) {
ss << "Cache-Control: no-cache\r\n";
+ ss << "Expires: Tue, 15 Nov 1994 08:12:31 GMT\r\n";
+ }
return ss.str();
}
@@ -74,11 +76,12 @@ FilePath ChromeFrameTestWithWebServer::CFInstall_path_;
FilePath ChromeFrameTestWithWebServer::CFInstance_path_;
ScopedTempDir ChromeFrameTestWithWebServer::temp_dir_;
FilePath ChromeFrameTestWithWebServer::chrome_user_data_dir_;
+chrome_frame_test::TimedMsgLoop* ChromeFrameTestWithWebServer::loop_;
+testing::StrictMock<MockWebServerListener>*
+ ChromeFrameTestWithWebServer::listener_mock_;
+testing::StrictMock<MockWebServer>* ChromeFrameTestWithWebServer::server_mock_;
-ChromeFrameTestWithWebServer::ChromeFrameTestWithWebServer()
- : loop_(),
- server_mock_(1337, L"127.0.0.1",
- chrome_frame_test::GetTestDataFolder()) {
+ChromeFrameTestWithWebServer::ChromeFrameTestWithWebServer() {
}
// static
@@ -108,13 +111,28 @@ void ChromeFrameTestWithWebServer::SetUpTestCase() {
CFInstall_path_ = test_file_path_.AppendASCII("CFInstall.js");
ASSERT_TRUE(file_util::CopyFile(CFInstall_src_path, CFInstall_path_));
+
+ loop_ = new chrome_frame_test::TimedMsgLoop();
+ loop_->set_snapshot_on_timeout(true);
+ listener_mock_ = new testing::StrictMock<MockWebServerListener>();
+ server_mock_ = new testing::StrictMock<MockWebServer>(
+ 1337, ASCIIToWide(chrome_frame_test::GetLocalIPv4Address()),
+ chrome_frame_test::GetTestDataFolder());
+ server_mock_->set_listener(listener_mock_);
}
// static
void ChromeFrameTestWithWebServer::TearDownTestCase() {
+ delete server_mock_;
+ server_mock_ = NULL;
+ delete listener_mock_;
+ listener_mock_ = NULL;
+ delete loop_;
+ loop_ = NULL;
file_util::Delete(CFInstall_path_, false);
file_util::Delete(CFInstance_path_, false);
- EXPECT_TRUE(temp_dir_.Delete());
+ if (temp_dir_.IsValid())
+ EXPECT_TRUE(temp_dir_.Delete());
}
// static
@@ -130,12 +148,16 @@ void ChromeFrameTestWithWebServer::SetUp() {
// Make sure that we are not accidentally enabling gcf protocol.
SetConfigBool(kAllowUnsafeURLs, false);
- server_mock_.ExpectAndServeAnyRequests(CFInvocation(CFInvocation::NONE));
- server_mock_.set_expected_result("OK");
+ server_mock().ClearResults();
+ server_mock().ExpectAndServeAnyRequests(CFInvocation(CFInvocation::NONE));
+ server_mock().set_expected_result("OK");
}
void ChromeFrameTestWithWebServer::TearDown() {
CloseBrowser();
+ loop().RunAllPending();
+ testing::Mock::VerifyAndClear(listener_mock_);
+ testing::Mock::VerifyAndClear(server_mock_);
}
bool ChromeFrameTestWithWebServer::LaunchBrowser(BrowserKind browser,
@@ -145,7 +167,7 @@ bool ChromeFrameTestWithWebServer::LaunchBrowser(BrowserKind browser,
// We should resolve the URL only if it is a relative url.
GURL parsed_url(WideToUTF8(page));
if (!parsed_url.has_scheme()) {
- url = server_mock_.Resolve(page);
+ url = server_mock().Resolve(page);
}
browser_ = browser;
@@ -203,8 +225,8 @@ bool ChromeFrameTestWithWebServer::BringBrowserToTop() {
bool ChromeFrameTestWithWebServer::WaitForTestToComplete(
base::TimeDelta duration) {
- loop_.RunFor(duration);
- return true;
+ loop().RunFor(duration);
+ return !loop().WasTimedOut();
}
bool ChromeFrameTestWithWebServer::WaitForOnLoad(int milliseconds) {
@@ -215,11 +237,28 @@ const wchar_t kPostedResultSubstring[] = L"/writefile/";
void ChromeFrameTestWithWebServer::SimpleBrowserTestExpectedResult(
BrowserKind browser, const wchar_t* page, const char* result) {
- server_mock_.ExpectAndHandlePostedResult(CFInvocation(CFInvocation::NONE),
- kPostedResultSubstring);
- ASSERT_TRUE(LaunchBrowser(browser, page));
- WaitForTestToComplete(TestTimeouts::action_max_timeout());
- ASSERT_EQ(result, server_mock_.posted_result());
+ int tries = 0;
+ ExpectAndHandlePostedResult();
+ // Retry tests that timeout once; see http://crbug.com/96449.
+ do {
+ // NOTE: Failed ASSERTs cause this function to exit immediately.
+ // Don't take a snapshot on the first try.
+ loop().set_snapshot_on_timeout(tries != 0);
+ ASSERT_TRUE(LaunchBrowser(browser, page));
+ if (WaitForTestToComplete(TestTimeouts::action_max_timeout())) {
+ // The test exited without timing out. Confirm that the expected response
+ // was posted and return.
+ ASSERT_EQ(result, server_mock().posted_result());
+ break;
+ }
+ ASSERT_EQ(std::string(), server_mock().posted_result())
+ << "Test timed out yet provided a result.";
+ ASSERT_EQ(0, tries++) << "Failing test due to two timeouts.";
+ // Close the browser and try a second time.
+ CloseBrowser();
+ LOG(ERROR) << "Retrying test once since it timed out.";
+ } while (true);
+ loop().set_snapshot_on_timeout(true);
}
void ChromeFrameTestWithWebServer::SimpleBrowserTest(BrowserKind browser,
@@ -227,6 +266,14 @@ void ChromeFrameTestWithWebServer::SimpleBrowserTest(BrowserKind browser,
SimpleBrowserTestExpectedResult(browser, page, "OK");
}
+void ChromeFrameTestWithWebServer::ExpectAndHandlePostedResult() {
+ EXPECT_CALL(listener_mock(), OnExpectedResponse())
+ .WillRepeatedly(QUIT_LOOP_SOON(loop(),
+ base::TimeDelta::FromMilliseconds(100)));
+ server_mock().ExpectAndHandlePostedResult(CFInvocation(CFInvocation::NONE),
+ kPostedResultSubstring);
+}
+
void ChromeFrameTestWithWebServer::VersionTest(BrowserKind browser,
const wchar_t* page) {
FilePath plugin_path;
@@ -258,15 +305,12 @@ void ChromeFrameTestWithWebServer::VersionTest(BrowserKind browser,
version = version_info->product_version();
}
- server_mock_.set_expected_result(WideToUTF8(version));
+ server_mock().set_expected_result(WideToUTF8(version));
EXPECT_TRUE(version_info);
EXPECT_FALSE(version.empty());
- server_mock_.ExpectAndHandlePostedResult(CFInvocation(CFInvocation::NONE),
- kPostedResultSubstring);
- EXPECT_TRUE(LaunchBrowser(browser, page));
- WaitForTestToComplete(TestTimeouts::action_max_timeout());
- ASSERT_EQ(version, UTF8ToWide(server_mock_.posted_result()));
+
+ SimpleBrowserTestExpectedResult(browser, page, WideToASCII(version).c_str());
}
// MockWebServer methods
@@ -305,11 +349,8 @@ void MockWebServer::HandlePostedResponse(
test_server::ConfigurableConnection* connection,
const test_server::Request& request) {
posted_result_ = request.content();
- if (posted_result_ == expected_result_) {
- MessageLoop::current()->PostDelayedTask(FROM_HERE,
- MessageLoop::QuitClosure(),
- 100);
- }
+ if (listener_ && posted_result_ == expected_result_)
+ listener_->OnExpectedResponse();
connection->Send("HTTP/1.1 200 OK\r\n", "");
}
@@ -426,7 +467,7 @@ TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_iframeBasic) {
const wchar_t kSrcPropertyTestPage[] = L"src_property_host.html";
-TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_SrcProperty) {
+TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_SrcProperty) {
SimpleBrowserTest(IE, kSrcPropertyTestPage);
}
@@ -444,14 +485,13 @@ TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceSingleton) {
const wchar_t kCFIDelayPage[] = L"CFInstance_delay_host.html";
-TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_CFInstanceDelay) {
+TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceDelay) {
SimpleBrowserTest(IE, kCFIDelayPage);
}
const wchar_t kCFIFallbackPage[] = L"CFInstance_fallback_host.html";
-// http://crbug.com/37088
-TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_CFInstanceFallback) {
+TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceFallback) {
SimpleBrowserTest(IE, kCFIFallbackPage);
}
@@ -477,8 +517,7 @@ TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceZeroSize) {
const wchar_t kCFIIfrPostPage[] = L"CFInstance_iframe_post_host.html";
-// http://crbug.com/32321
-TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_CFInstanceIfrPost) {
+TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceIfrPost) {
SimpleBrowserTest(IE, kCFIIfrPostPage);
}
@@ -503,14 +542,7 @@ TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstancePost) {
const wchar_t kCFIRPCPage[] = L"CFInstance_rpc_host.html";
-// This test consistently times out in debug builds; see http://crbug.com/112599
-#ifndef NDEBUG
-#define MAYBE_WidgetModeIE_CFInstanceRPC DISABLED_WidgetModeIE_CFInstanceRPC
-#else
-#define MAYBE_WidgetModeIE_CFInstanceRPC WidgetModeIE_CFInstanceRPC
-#endif
-
-TEST_F(ChromeFrameTestWithWebServer, MAYBE_WidgetModeIE_CFInstanceRPC) {
+TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceRPC) {
if (chrome_frame_test::GetInstalledIEVersion() == IE_9) {
LOG(INFO) << "Not running test on Vista/Windows 7 with IE9";
return;
@@ -670,18 +702,17 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_InstallFlowTest) {
ASSERT_TRUE(LaunchBrowser(IE, kInstallFlowTestUrl));
- loop_.RunFor(kChromeFrameLongNavigationTimeout);
+ loop().RunFor(kChromeFrameLongNavigationTimeout);
ScopedChromeFrameRegistrar::RegisterAtPath(
GetChromeFrameBuildPath().value(),
chrome_frame_test::GetTestBedType());
- server_mock_.ExpectAndHandlePostedResult(CFInvocation(CFInvocation::NONE),
- kPostedResultSubstring);
- loop_.RunFor(kChromeFrameLongNavigationTimeout);
+ ExpectAndHandlePostedResult();
+ loop().RunFor(kChromeFrameLongNavigationTimeout);
chrome_frame_test::CloseAllIEWindows();
- ASSERT_EQ("OK", server_mock_.posted_result());
+ ASSERT_EQ("OK", server_mock().posted_result());
}
}
@@ -729,7 +760,7 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_TestPostReissue) {
ASSERT_TRUE(LaunchBrowser(IE, server.FormatHttpPath(kPages[0]).c_str()));
- loop_.RunFor(kChromeFrameLongNavigationTimeout);
+ loop().RunFor(kChromeFrameLongNavigationTimeout);
const test_server::Request* request = NULL;
server.FindRequest("/quit?OK", &request);
@@ -761,7 +792,7 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_TestMultipleGet) {
ASSERT_TRUE(LaunchBrowser(IE, server.FormatHttpPath(kPages[0]).c_str()));
- loop_.RunFor(kChromeFrameVeryLongNavigationTimeout);
+ loop().RunFor(kChromeFrameVeryLongNavigationTimeout);
const test_server::Request* request = NULL;
server.FindRequest("/quit?OK", &request);
@@ -793,8 +824,7 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_XHRConditionalHeaderTest) {
const wchar_t kWindowCloseTestUrl[] =
L"window_close.html";
-// http://code.google.com/p/chromium/issues/detail?id=111074
-TEST_F(ChromeFrameTestWithWebServer, DISABLED_FullTabModeIE_WindowClose) {
+TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_WindowClose) {
SimpleBrowserTest(IE, kWindowCloseTestUrl);
}
@@ -879,7 +909,7 @@ TEST_F(ChromeFrameTestWithWebServer, FAILS_FullTabModeIE_RefreshMshtmlTest) {
ASSERT_TRUE(LaunchBrowser(IE, server.FormatHttpPath(kPages[0]).c_str()));
- loop_.RunFor(kChromeFrameLongNavigationTimeout);
+ loop().RunFor(kChromeFrameLongNavigationTimeout);
test_server::SimpleWebServer* ws = server.web_server();
const test_server::ConnectionList& connections = ws->connections();
@@ -1011,7 +1041,7 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_TestDownloadFromForm) {
EXPECT_CALL(win_observer_mock, OnWindowClose(_))
.Times(testing::AtMost(1))
- .WillOnce(QUIT_LOOP(loop_));
+ .WillOnce(QUIT_LOOP(loop()));
SimpleWebServerTest server(46664);
CustomResponse* response = new CustomResponse("/form.html");
@@ -1020,7 +1050,7 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_TestDownloadFromForm) {
std::wstring url(server.FormatHttpPath(L"form.html"));
ASSERT_TRUE(LaunchBrowser(IE, url.c_str()));
- loop_.RunFor(kChromeFrameLongNavigationTimeout);
+ loop().RunFor(kChromeFrameLongNavigationTimeout);
EXPECT_EQ(1, response->get_request_count());
EXPECT_EQ(1, response->post_request_count());
diff --git a/chrome_frame/test/test_with_web_server.h b/chrome_frame/test/test_with_web_server.h
index 78c3166..f080ed3 100644
--- a/chrome_frame/test/test_with_web_server.h
+++ b/chrome_frame/test/test_with_web_server.h
@@ -48,6 +48,16 @@ class CFInvocation {
Type method_;
};
+// An interface for listeners of interesting events on a MockWebServer.
+class WebServerListener {
+ public:
+ virtual ~WebServerListener() {}
+
+ // Invoked when a MockWebServer receives an expected response; see
+ // MockWebServer::ExpectAndHandlePostedResult.
+ virtual void OnExpectedResponse() = 0;
+};
+
// Simple Gmock friendly web server. Sample usage:
// MockWebServer mock(9999, "0.0.0.0");
// EXPECT_CALL(mock, Get(_, StrEq("/favicon.ico"), _)).WillRepeatedly(SendFast(
@@ -70,15 +80,15 @@ class CFInvocation {
class MockWebServer : public test_server::HTTPTestServer {
public:
MockWebServer(int port, const std::wstring& address, FilePath root_dir)
- : test_server::HTTPTestServer(port, address, root_dir) {}
+ : test_server::HTTPTestServer(port, address, root_dir), listener_(NULL) {}
// Overriden from test_server::HTTPTestServer.
MOCK_METHOD3(Get, void(test_server::ConfigurableConnection* connection,
const std::wstring& path,
- const test_server::Request&r));
+ const test_server::Request& r));
MOCK_METHOD3(Post, void(test_server::ConfigurableConnection* connection,
const std::wstring& path,
- const test_server::Request&r));
+ const test_server::Request& r));
// Expect a GET request for |url|. Respond with the file appropriate for
// the given |url|. Modify the file to follow the given CFInvocation method.
@@ -102,6 +112,12 @@ class MockWebServer : public test_server::HTTPTestServer {
void ExpectAndServeRequestAnyNumberTimes(CFInvocation invocation,
const std::wstring& path_prefix);
+ void set_listener(WebServerListener* listener) { listener_ = listener; }
+
+ // Expect a POST to an URL containing |post_suffix|, saving the response
+ // contents for retrieval by posted_result(). Invokes the listener's
+ // OnExpectedResponse method if the posted response matches the expected
+ // result.
void ExpectAndHandlePostedResult(CFInvocation invocation,
const std::wstring& post_suffix);
@@ -123,6 +139,11 @@ class MockWebServer : public test_server::HTTPTestServer {
void HandlePostedResponse(test_server::ConfigurableConnection* connection,
const test_server::Request& request);
+ void ClearResults() {
+ posted_result_.clear();
+ expected_result_.clear();
+ }
+
void set_expected_result(const std::string& expected_result) {
expected_result_ = expected_result;
}
@@ -132,11 +153,17 @@ class MockWebServer : public test_server::HTTPTestServer {
}
private:
+ WebServerListener* listener_;
// Holds the results of tests which post success/failure.
std::string posted_result_;
std::string expected_result_;
};
+class MockWebServerListener : public WebServerListener {
+ public:
+ MOCK_METHOD0(OnExpectedResponse, void());
+};
+
// Class that:
// 1) Starts the local webserver,
// 2) Supports launching browsers - Internet Explorer with local url
@@ -152,21 +179,26 @@ class ChromeFrameTestWithWebServer : public testing::Test {
enum BrowserKind { INVALID, IE, CHROME };
bool LaunchBrowser(BrowserKind browser, const wchar_t* url);
+
+ // Returns true if the test completed in time, or false if it timed out.
bool WaitForTestToComplete(base::TimeDelta duration);
// Waits for the page to notify us of the window.onload event firing.
// Note that the milliseconds value is only approximate.
bool WaitForOnLoad(int milliseconds);
- // Launches the specified browser and waits for the test to complete
- // (see WaitForTestToComplete). Then checks that the outcome is equal
- // to the expected result.
+ // Launches the specified browser and waits for the test to complete (see
+ // WaitForTestToComplete). Then checks that the outcome is equal to the
+ // expected result. The test is repeated once if it fails due to a timeout.
// This function uses EXPECT_TRUE and ASSERT_TRUE for all steps performed
// hence no return value.
void SimpleBrowserTestExpectedResult(BrowserKind browser,
const wchar_t* page, const char* result);
void SimpleBrowserTest(BrowserKind browser, const wchar_t* page);
+ // Sets up expectations for a page to post back a result.
+ void ExpectAndHandlePostedResult();
+
// Test if chrome frame correctly reports its version.
void VersionTest(BrowserKind browser, const wchar_t* page);
@@ -179,6 +211,18 @@ class ChromeFrameTestWithWebServer : public testing::Test {
return test_file_path_;
}
+ static chrome_frame_test::TimedMsgLoop& loop() {
+ return *loop_;
+ }
+
+ static testing::StrictMock<MockWebServerListener>& listener_mock() {
+ return *listener_mock_;
+ }
+
+ static testing::StrictMock<MockWebServer>& server_mock() {
+ return *server_mock_;
+ }
+
static void SetUpTestCase();
static void TearDownTestCase();
@@ -197,10 +241,13 @@ class ChromeFrameTestWithWebServer : public testing::Test {
// The user data directory used for Chrome instances.
static ScopedTempDir temp_dir_;
+ // The web server from which we serve the web!
+ static chrome_frame_test::TimedMsgLoop* loop_;
+ static testing::StrictMock<MockWebServerListener>* listener_mock_;
+ static testing::StrictMock<MockWebServer>* server_mock_;
+
BrowserKind browser_;
base::win::ScopedHandle browser_handle_;
- chrome_frame_test::TimedMsgLoop loop_;
- testing::StrictMock<MockWebServer> server_mock_;
};
// A helper class for doing some bookkeeping when using the