diff options
Diffstat (limited to 'chrome_frame/test/test_server_test.cc')
-rw-r--r-- | chrome_frame/test/test_server_test.cc | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/chrome_frame/test/test_server_test.cc b/chrome_frame/test/test_server_test.cc new file mode 100644 index 0000000..4bd139e --- /dev/null +++ b/chrome_frame/test/test_server_test.cc @@ -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); + } +} |