Index: chrome_frame/test/test_server_test.cc |
=================================================================== |
--- chrome_frame/test/test_server_test.cc (revision 0) |
+++ chrome_frame/test/test_server_test.cc (revision 0) |
@@ -0,0 +1,194 @@ |
+// Copyright (c) 2006-2008 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 <windows.h> |
+#include <wininet.h> |
+ |
+#include "base/basictypes.h" |
+#include "base/path_service.h" |
+#include "base/scoped_handle_win.h" |
+#include "chrome_frame/test/test_server.h" |
+#include "net/base/cookie_monster.h" |
+#include "net/base/host_resolver_proc.h" |
+#include "net/disk_cache/disk_cache.h" |
+#include "net/http/http_cache.h" |
+#include "net/proxy/proxy_service.h" |
+#include "net/url_request/url_request.h" |
+#include "net/url_request/url_request_unittest.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+class TestServerTest: public testing::Test { |
+ protected: |
+ virtual void SetUp() { |
+ PathService::Get(base::DIR_SOURCE_ROOT, &source_path_); |
+ source_path_ = source_path_.Append(FILE_PATH_LITERAL("chrome_frame")); |
+ } |
+ virtual void TearDown() { |
+ } |
+ |
+ public: |
+ const FilePath& source_path() const { |
+ return source_path_; |
+ } |
+ |
+ protected: |
+ FilePath source_path_; |
+}; |
+ |
+namespace { |
+ |
+class ScopedInternet { |
+ public: |
+ explicit ScopedInternet(HINTERNET handle) |
+ : h_(handle) { |
+ } |
+ ~ScopedInternet() { |
+ if (h_) { |
+ InternetCloseHandle(h_); |
+ } |
+ } |
+ |
+ operator HINTERNET() { |
+ return h_; |
+ } |
+ |
+ protected: |
+ HINTERNET h_; |
+}; |
+ |
+class URLRequestTestContext : public URLRequestContext { |
+ public: |
+ URLRequestTestContext() { |
+ host_resolver_ = net::CreateSystemHostResolver(); |
+ proxy_service_ = net::ProxyService::CreateNull(); |
+ ssl_config_service_ = new net::SSLConfigServiceDefaults; |
+ http_transaction_factory_ = |
+ new net::HttpCache( |
+ net::HttpNetworkLayer::CreateFactory(host_resolver_, proxy_service_, |
+ ssl_config_service_), |
+ disk_cache::CreateInMemoryCacheBackend(0)); |
+ // In-memory cookie store. |
+ cookie_store_ = new net::CookieMonster(); |
+ } |
+ |
+ virtual ~URLRequestTestContext() { |
+ delete http_transaction_factory_; |
+ } |
+}; |
+ |
+class TestURLRequest : public URLRequest { |
+ public: |
+ TestURLRequest(const GURL& url, Delegate* delegate) |
+ : URLRequest(url, delegate) { |
+ set_context(new URLRequestTestContext()); |
+ } |
+}; |
+ |
+class UrlTaskChain { |
+ public: |
+ UrlTaskChain(const char* url, UrlTaskChain* next) |
+ : url_(url), next_(next) { |
+ } |
+ |
+ void Run() { |
+ EXPECT_EQ(0, delegate_.response_started_count()); |
+ |
+ MessageLoopForIO loop; |
+ |
+ TestURLRequest r(GURL(url_), &delegate_); |
+ r.Start(); |
+ EXPECT_TRUE(r.is_pending()); |
+ |
+ MessageLoop::current()->Run(); |
+ |
+ EXPECT_EQ(1, delegate_.response_started_count()); |
+ EXPECT_FALSE(delegate_.received_data_before_response()); |
+ EXPECT_NE(0, delegate_.bytes_received()); |
+ } |
+ |
+ UrlTaskChain* next() const { |
+ return next_; |
+ } |
+ |
+ const std::string& response() const { |
+ return delegate_.data_received(); |
+ } |
+ |
+ protected: |
+ std::string url_; |
+ TestDelegate delegate_; |
+ UrlTaskChain* next_; |
+}; |
+ |
+DWORD WINAPI FetchUrl(void* param) { |
+ UrlTaskChain* task = reinterpret_cast<UrlTaskChain*>(param); |
+ while (task != NULL) { |
+ task->Run(); |
+ task = task->next(); |
+ } |
+ |
+ return 0; |
+} |
+ |
+struct QuitMessageHit { |
+ explicit QuitMessageHit(MessageLoopForUI* loop) : loop_(loop), hit_(false) { |
+ } |
+ |
+ MessageLoopForUI* loop_; |
+ bool hit_; |
+}; |
+ |
+void QuitMessageLoop(QuitMessageHit* msg) { |
+ msg->hit_ = true; |
+ msg->loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask); |
+} |
+ |
+} // end namespace |
+ |
+TEST_F(TestServerTest, DISABLED_TestServer) { |
+ // The web server needs a loop to exist on this thread during construction |
+ // the loop must be created before we construct the server. |
+ MessageLoopForUI loop; |
+ |
+ test_server::SimpleWebServer server(1337); |
+ test_server::SimpleResponse person("/person", "Guthrie Govan!"); |
+ server.AddResponse(&person); |
+ test_server::FileResponse file("/file", source_path().Append( |
+ FILE_PATH_LITERAL("CFInstance.js"))); |
+ server.AddResponse(&file); |
+ test_server::RedirectResponse redir("/goog", "http://www.google.com/"); |
+ server.AddResponse(&redir); |
+ |
+ // We should never hit this, but it's our way to break out of the test if |
+ // things start hanging. |
+ QuitMessageHit quit_msg(&loop); |
+ loop.PostDelayedTask(FROM_HERE, |
+ NewRunnableFunction(QuitMessageLoop, &quit_msg), |
+ 10 * 1000); |
+ |
+ UrlTaskChain quit_task("http://localhost:1337/quit", NULL); |
+ UrlTaskChain fnf_task("http://localhost:1337/404", &quit_task); |
+ UrlTaskChain person_task("http://localhost:1337/person", &fnf_task); |
+ UrlTaskChain file_task("http://localhost:1337/file", &person_task); |
+ UrlTaskChain goog_task("http://localhost:1337/goog", &file_task); |
+ |
+ DWORD tid = 0; |
+ ScopedHandle worker(::CreateThread(NULL, 0, FetchUrl, &goog_task, 0, &tid)); |
+ loop.MessageLoop::Run(); |
+ |
+ EXPECT_FALSE(quit_msg.hit_); |
+ if (!quit_msg.hit_) { |
+ EXPECT_EQ(::WaitForSingleObject(worker, 10 * 1000), WAIT_OBJECT_0); |
+ |
+ EXPECT_EQ(person.accessed(), 1); |
+ EXPECT_EQ(file.accessed(), 1); |
+ EXPECT_EQ(redir.accessed(), 1); |
+ |
+ EXPECT_TRUE(person_task.response().find("Guthrie") != std::string::npos); |
+ EXPECT_TRUE(file_task.response().find("function") != std::string::npos); |
+ EXPECT_TRUE(goog_task.response().find("<title>") != std::string::npos); |
+ } else { |
+ ::TerminateThread(worker, ~0); |
+ } |
+} |