ceftests: Add shared test_request and test_server implementations
To reduce text execution time and flakyness this change also introduces a global test server that is initialized when needed and torn down after all tests have completed.
This commit is contained in:
parent
d63e5bbd8a
commit
b09cd1a197
|
@ -520,6 +520,11 @@
|
||||||
'tests/ceftests/task_unittest.cc',
|
'tests/ceftests/task_unittest.cc',
|
||||||
'tests/ceftests/test_handler.cc',
|
'tests/ceftests/test_handler.cc',
|
||||||
'tests/ceftests/test_handler.h',
|
'tests/ceftests/test_handler.h',
|
||||||
|
'tests/ceftests/test_request.cc',
|
||||||
|
'tests/ceftests/test_request.h',
|
||||||
|
'tests/ceftests/test_server.cc',
|
||||||
|
'tests/ceftests/test_server.h',
|
||||||
|
'tests/ceftests/test_server_unittest.cc',
|
||||||
'tests/ceftests/test_suite.cc',
|
'tests/ceftests/test_suite.cc',
|
||||||
'tests/ceftests/test_suite.h',
|
'tests/ceftests/test_suite.h',
|
||||||
'tests/ceftests/test_util.cc',
|
'tests/ceftests/test_util.cc',
|
||||||
|
@ -588,6 +593,10 @@
|
||||||
'tests/ceftests/urlrequest_unittest.cc',
|
'tests/ceftests/urlrequest_unittest.cc',
|
||||||
'tests/ceftests/test_handler.cc',
|
'tests/ceftests/test_handler.cc',
|
||||||
'tests/ceftests/test_handler.h',
|
'tests/ceftests/test_handler.h',
|
||||||
|
'tests/ceftests/test_request.cc',
|
||||||
|
'tests/ceftests/test_request.h',
|
||||||
|
'tests/ceftests/test_server.cc',
|
||||||
|
'tests/ceftests/test_server.h',
|
||||||
'tests/ceftests/test_suite.cc',
|
'tests/ceftests/test_suite.cc',
|
||||||
'tests/ceftests/test_suite.h',
|
'tests/ceftests/test_suite.h',
|
||||||
'tests/ceftests/test_util.cc',
|
'tests/ceftests/test_util.cc',
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "include/wrapper/cef_closure_task.h"
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
#include "tests/ceftests/routing_test_handler.h"
|
#include "tests/ceftests/routing_test_handler.h"
|
||||||
#include "tests/ceftests/test_handler.h"
|
#include "tests/ceftests/test_handler.h"
|
||||||
|
#include "tests/ceftests/test_server.h"
|
||||||
#include "tests/ceftests/test_suite.h"
|
#include "tests/ceftests/test_suite.h"
|
||||||
#include "tests/ceftests/test_util.h"
|
#include "tests/ceftests/test_util.h"
|
||||||
#include "tests/gtest/include/gtest/gtest.h"
|
#include "tests/gtest/include/gtest/gtest.h"
|
||||||
|
@ -1050,30 +1051,29 @@ namespace {
|
||||||
|
|
||||||
const char kCookieAccessScheme[] = "http";
|
const char kCookieAccessScheme[] = "http";
|
||||||
const char kCookieAccessDomain[] = "test-cookies.com";
|
const char kCookieAccessDomain[] = "test-cookies.com";
|
||||||
const char kCookieAccessServerIP[] = "127.0.0.1";
|
const char* kCookieAccessServerAddress = test_server::kServerAddress;
|
||||||
const uint16 kCookieAccessServerPort = 8099;
|
const uint16 kCookieAccessServerPort = test_server::kServerPort;
|
||||||
|
|
||||||
std::string GetCookieAccessOrigin(const std::string& scheme,
|
std::string GetCookieAccessOrigin(const std::string& scheme,
|
||||||
bool server_backend) {
|
bool server_backend) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
if (server_backend) {
|
if (server_backend) {
|
||||||
ss << scheme << "://" << kCookieAccessServerIP << ":"
|
ss << scheme << "://" << kCookieAccessServerAddress << ":"
|
||||||
<< kCookieAccessServerPort;
|
<< kCookieAccessServerPort;
|
||||||
} else {
|
} else {
|
||||||
ss << scheme << "://" << kCookieAccessDomain;
|
ss << scheme << "://" << kCookieAccessDomain;
|
||||||
}
|
}
|
||||||
ss << "/";
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetCookieAccessUrl1(const std::string& scheme,
|
std::string GetCookieAccessUrl1(const std::string& scheme,
|
||||||
bool server_backend) {
|
bool server_backend) {
|
||||||
return GetCookieAccessOrigin(scheme, server_backend) + "cookie1.html";
|
return GetCookieAccessOrigin(scheme, server_backend) + "/cookie1.html";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetCookieAccessUrl2(const std::string& scheme,
|
std::string GetCookieAccessUrl2(const std::string& scheme,
|
||||||
bool server_backend) {
|
bool server_backend) {
|
||||||
return GetCookieAccessOrigin(scheme, server_backend) + "cookie2.html";
|
return GetCookieAccessOrigin(scheme, server_backend) + "/cookie2.html";
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCookieString(const std::string& cookie_str,
|
void TestCookieString(const std::string& cookie_str,
|
||||||
|
@ -1248,7 +1248,7 @@ class CookieAccessSchemeHandlerFactory : public CefSchemeHandlerFactory,
|
||||||
};
|
};
|
||||||
|
|
||||||
// HTTP server handler.
|
// HTTP server handler.
|
||||||
class CookieAccessServerHandler : public CefServerHandler,
|
class CookieAccessServerHandler : public test_server::ObserverHelper,
|
||||||
public CookieAccessResponseHandler {
|
public CookieAccessResponseHandler {
|
||||||
public:
|
public:
|
||||||
CookieAccessServerHandler()
|
CookieAccessServerHandler()
|
||||||
|
@ -1288,8 +1288,7 @@ class CookieAccessServerHandler : public CefServerHandler,
|
||||||
EXPECT_TRUE(complete_callback_.is_null());
|
EXPECT_TRUE(complete_callback_.is_null());
|
||||||
complete_callback_ = complete_callback;
|
complete_callback_ = complete_callback;
|
||||||
|
|
||||||
CefServer::CreateServer(kCookieAccessServerIP, kCookieAccessServerPort, 10,
|
Initialize();
|
||||||
this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Results in a call to VerifyResults() and eventual execution of the
|
// Results in a call to VerifyResults() and eventual execution of the
|
||||||
|
@ -1301,73 +1300,60 @@ class CookieAccessServerHandler : public CefServerHandler,
|
||||||
EXPECT_TRUE(complete_callback_.is_null());
|
EXPECT_TRUE(complete_callback_.is_null());
|
||||||
complete_callback_ = complete_callback;
|
complete_callback_ = complete_callback;
|
||||||
|
|
||||||
EXPECT_TRUE(server_);
|
Shutdown();
|
||||||
if (server_)
|
|
||||||
server_->Shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnServerCreated(CefRefPtr<CefServer> server) override {
|
void OnInitialized(const std::string& server_origin) override {
|
||||||
EXPECT_TRUE(server);
|
EXPECT_UI_THREAD();
|
||||||
EXPECT_TRUE(server->IsRunning());
|
EXPECT_STREQ(server_origin.c_str(),
|
||||||
EXPECT_FALSE(server->HasConnection());
|
GetCookieAccessOrigin(kCookieAccessScheme, true).c_str());
|
||||||
|
|
||||||
EXPECT_FALSE(got_server_created_);
|
EXPECT_FALSE(got_server_created_);
|
||||||
got_server_created_.yes();
|
got_server_created_.yes();
|
||||||
|
|
||||||
EXPECT_FALSE(server_);
|
RunCompleteCallback();
|
||||||
server_ = server;
|
|
||||||
|
|
||||||
EXPECT_FALSE(server_runner_);
|
|
||||||
server_runner_ = server_->GetTaskRunner();
|
|
||||||
EXPECT_TRUE(server_runner_);
|
|
||||||
EXPECT_TRUE(server_runner_->BelongsToCurrentThread());
|
|
||||||
|
|
||||||
CefPostTask(
|
|
||||||
TID_UI,
|
|
||||||
base::Bind(&CookieAccessServerHandler::RunCompleteCallback, this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnServerDestroyed(CefRefPtr<CefServer> server) override {
|
void OnShutdown() override {
|
||||||
EXPECT_TRUE(VerifyServer(server));
|
EXPECT_UI_THREAD();
|
||||||
EXPECT_FALSE(server->IsRunning());
|
|
||||||
EXPECT_FALSE(server->HasConnection());
|
|
||||||
|
|
||||||
EXPECT_FALSE(got_server_destroyed_);
|
EXPECT_FALSE(got_server_destroyed_);
|
||||||
got_server_destroyed_.yes();
|
got_server_destroyed_.yes();
|
||||||
|
|
||||||
server_ = nullptr;
|
|
||||||
|
|
||||||
VerifyResults();
|
VerifyResults();
|
||||||
|
|
||||||
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnClientConnected(CefRefPtr<CefServer> server,
|
bool OnClientConnected(CefRefPtr<CefServer> server,
|
||||||
int connection_id) override {
|
int connection_id) override {
|
||||||
EXPECT_TRUE(VerifyServer(server));
|
EXPECT_UI_THREAD();
|
||||||
EXPECT_TRUE(server->HasConnection());
|
|
||||||
EXPECT_TRUE(server->IsValidConnection(connection_id));
|
|
||||||
|
|
||||||
EXPECT_TRUE(connection_id_set_.find(connection_id) ==
|
EXPECT_TRUE(connection_id_set_.find(connection_id) ==
|
||||||
connection_id_set_.end());
|
connection_id_set_.end());
|
||||||
connection_id_set_.insert(connection_id);
|
connection_id_set_.insert(connection_id);
|
||||||
|
|
||||||
actual_connection_ct_++;
|
actual_connection_ct_++;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnClientDisconnected(CefRefPtr<CefServer> server,
|
bool OnClientDisconnected(CefRefPtr<CefServer> server,
|
||||||
int connection_id) override {
|
int connection_id) override {
|
||||||
EXPECT_TRUE(VerifyServer(server));
|
EXPECT_UI_THREAD();
|
||||||
EXPECT_FALSE(server->IsValidConnection(connection_id));
|
|
||||||
|
|
||||||
ConnectionIdSet::iterator it = connection_id_set_.find(connection_id);
|
ConnectionIdSet::iterator it = connection_id_set_.find(connection_id);
|
||||||
EXPECT_TRUE(it != connection_id_set_.end());
|
EXPECT_TRUE(it != connection_id_set_.end());
|
||||||
connection_id_set_.erase(it);
|
connection_id_set_.erase(it);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnHttpRequest(CefRefPtr<CefServer> server,
|
bool OnHttpRequest(CefRefPtr<CefServer> server,
|
||||||
int connection_id,
|
int connection_id,
|
||||||
const CefString& client_address,
|
const CefString& client_address,
|
||||||
CefRefPtr<CefRequest> request) override {
|
CefRefPtr<CefRequest> request) override {
|
||||||
EXPECT_TRUE(VerifyServer(server));
|
EXPECT_UI_THREAD();
|
||||||
EXPECT_TRUE(VerifyConnection(connection_id));
|
EXPECT_TRUE(VerifyConnection(connection_id));
|
||||||
EXPECT_FALSE(client_address.empty());
|
EXPECT_FALSE(client_address.empty());
|
||||||
|
|
||||||
|
@ -1378,50 +1364,16 @@ class CookieAccessServerHandler : public CefServerHandler,
|
||||||
HandleRequest(server, connection_id, request);
|
HandleRequest(server, connection_id, request);
|
||||||
|
|
||||||
actual_http_request_ct_++;
|
actual_http_request_ct_++;
|
||||||
}
|
|
||||||
|
|
||||||
void OnWebSocketRequest(CefRefPtr<CefServer> server,
|
return true;
|
||||||
int connection_id,
|
|
||||||
const CefString& client_address,
|
|
||||||
CefRefPtr<CefRequest> request,
|
|
||||||
CefRefPtr<CefCallback> callback) override {
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnWebSocketConnected(CefRefPtr<CefServer> server,
|
|
||||||
int connection_id) override {
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnWebSocketMessage(CefRefPtr<CefServer> server,
|
|
||||||
int connection_id,
|
|
||||||
const void* data,
|
|
||||||
size_t data_size) override {
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool RunningOnServerThread() {
|
|
||||||
return server_runner_ && server_runner_->BelongsToCurrentThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VerifyServer(CefRefPtr<CefServer> server) {
|
|
||||||
V_DECLARE();
|
|
||||||
V_EXPECT_TRUE(RunningOnServerThread());
|
|
||||||
V_EXPECT_TRUE(server);
|
|
||||||
V_EXPECT_TRUE(server_);
|
|
||||||
V_EXPECT_TRUE(server->GetAddress().ToString() ==
|
|
||||||
server_->GetAddress().ToString());
|
|
||||||
V_RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VerifyConnection(int connection_id) {
|
bool VerifyConnection(int connection_id) {
|
||||||
return connection_id_set_.find(connection_id) != connection_id_set_.end();
|
return connection_id_set_.find(connection_id) != connection_id_set_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerifyResults() {
|
void VerifyResults() {
|
||||||
EXPECT_TRUE(RunningOnServerThread());
|
|
||||||
|
|
||||||
EXPECT_TRUE(got_server_created_);
|
EXPECT_TRUE(got_server_created_);
|
||||||
EXPECT_TRUE(got_server_destroyed_);
|
EXPECT_TRUE(got_server_destroyed_);
|
||||||
EXPECT_TRUE(connection_id_set_.empty());
|
EXPECT_TRUE(connection_id_set_.empty());
|
||||||
|
@ -1453,10 +1405,19 @@ class CookieAccessServerHandler : public CefServerHandler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendResponse(CefRefPtr<CefServer> server,
|
static void SendResponse(CefRefPtr<CefServer> server,
|
||||||
int connection_id,
|
int connection_id,
|
||||||
CefRefPtr<CefResponse> response,
|
CefRefPtr<CefResponse> response,
|
||||||
const std::string& response_data) {
|
const std::string& response_data) {
|
||||||
|
// Execute on the server thread because some methods require it.
|
||||||
|
CefRefPtr<CefTaskRunner> task_runner = server->GetTaskRunner();
|
||||||
|
if (!task_runner->BelongsToCurrentThread()) {
|
||||||
|
task_runner->PostTask(CefCreateClosureTask(
|
||||||
|
base::Bind(CookieAccessServerHandler::SendResponse, server,
|
||||||
|
connection_id, response, response_data)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int response_code = response->GetStatus();
|
int response_code = response->GetStatus();
|
||||||
const CefString& content_type = response->GetMimeType();
|
const CefString& content_type = response->GetMimeType();
|
||||||
int64 content_length = static_cast<int64>(response_data.size());
|
int64 content_length = static_cast<int64>(response_data.size());
|
||||||
|
@ -1489,8 +1450,6 @@ class CookieAccessServerHandler : public CefServerHandler,
|
||||||
typedef std::map<std::string, CookieAccessData*> ResponseDataMap;
|
typedef std::map<std::string, CookieAccessData*> ResponseDataMap;
|
||||||
ResponseDataMap data_map_;
|
ResponseDataMap data_map_;
|
||||||
|
|
||||||
CefRefPtr<CefServer> server_;
|
|
||||||
CefRefPtr<CefTaskRunner> server_runner_;
|
|
||||||
bool initialized_;
|
bool initialized_;
|
||||||
|
|
||||||
// Only accessed on the UI thread.
|
// Only accessed on the UI thread.
|
||||||
|
@ -1512,7 +1471,6 @@ class CookieAccessServerHandler : public CefServerHandler,
|
||||||
|
|
||||||
std::string request_log_;
|
std::string request_log_;
|
||||||
|
|
||||||
IMPLEMENT_REFCOUNTING(CookieAccessServerHandler);
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(CookieAccessServerHandler);
|
DISALLOW_COPY_AND_ASSIGN(CookieAccessServerHandler);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1833,7 +1791,7 @@ class CookieAccessTestHandler : public RoutingTestHandler,
|
||||||
EXPECT_FALSE(server_handler_);
|
EXPECT_FALSE(server_handler_);
|
||||||
|
|
||||||
server_handler_ = new CookieAccessServerHandler();
|
server_handler_ = new CookieAccessServerHandler();
|
||||||
AddResponses(server_handler_.get());
|
AddResponses(server_handler_);
|
||||||
server_handler_->CreateServer(complete_callback);
|
server_handler_->CreateServer(complete_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1911,6 +1869,7 @@ class CookieAccessTestHandler : public RoutingTestHandler,
|
||||||
void ShutdownServer(const base::Closure& complete_callback) {
|
void ShutdownServer(const base::Closure& complete_callback) {
|
||||||
EXPECT_TRUE(server_handler_);
|
EXPECT_TRUE(server_handler_);
|
||||||
|
|
||||||
|
// |server_handler_| will delete itself after shutdown.
|
||||||
server_handler_->ShutdownServer(complete_callback);
|
server_handler_->ShutdownServer(complete_callback);
|
||||||
server_handler_ = nullptr;
|
server_handler_ = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -1933,7 +1892,7 @@ class CookieAccessTestHandler : public RoutingTestHandler,
|
||||||
CefRefPtr<CefRequestContext> context_;
|
CefRefPtr<CefRequestContext> context_;
|
||||||
CefRefPtr<CefCookieManager> cookie_manager_;
|
CefRefPtr<CefCookieManager> cookie_manager_;
|
||||||
|
|
||||||
CefRefPtr<CookieAccessServerHandler> server_handler_;
|
CookieAccessServerHandler* server_handler_ = nullptr;
|
||||||
CefRefPtr<CookieAccessSchemeHandlerFactory> scheme_factory_;
|
CefRefPtr<CookieAccessSchemeHandlerFactory> scheme_factory_;
|
||||||
|
|
||||||
CookieAccessData data1_;
|
CookieAccessData data1_;
|
||||||
|
@ -2292,7 +2251,7 @@ class CookieRestartTestHandler : public RoutingTestHandler,
|
||||||
EXPECT_FALSE(server_handler_);
|
EXPECT_FALSE(server_handler_);
|
||||||
|
|
||||||
server_handler_ = new CookieAccessServerHandler();
|
server_handler_ = new CookieAccessServerHandler();
|
||||||
AddResponses(server_handler_.get());
|
AddResponses(server_handler_);
|
||||||
// 2 requests for each URL.
|
// 2 requests for each URL.
|
||||||
server_handler_->SetExpectedRequestCount(4);
|
server_handler_->SetExpectedRequestCount(4);
|
||||||
server_handler_->CreateServer(complete_callback);
|
server_handler_->CreateServer(complete_callback);
|
||||||
|
@ -2351,6 +2310,7 @@ class CookieRestartTestHandler : public RoutingTestHandler,
|
||||||
void ShutdownServer(const base::Closure& complete_callback) {
|
void ShutdownServer(const base::Closure& complete_callback) {
|
||||||
EXPECT_TRUE(server_handler_);
|
EXPECT_TRUE(server_handler_);
|
||||||
|
|
||||||
|
// |server_handler_| will delete itself after shutdown.
|
||||||
server_handler_->ShutdownServer(complete_callback);
|
server_handler_->ShutdownServer(complete_callback);
|
||||||
server_handler_ = nullptr;
|
server_handler_ = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -2360,7 +2320,7 @@ class CookieRestartTestHandler : public RoutingTestHandler,
|
||||||
CefRefPtr<CefRequestContext> context_;
|
CefRefPtr<CefRequestContext> context_;
|
||||||
CefRefPtr<CefCookieManager> cookie_manager_;
|
CefRefPtr<CefCookieManager> cookie_manager_;
|
||||||
|
|
||||||
CefRefPtr<CookieAccessServerHandler> server_handler_;
|
CookieAccessServerHandler* server_handler_ = nullptr;
|
||||||
|
|
||||||
CookieAccessData data1_;
|
CookieAccessData data1_;
|
||||||
CookieAccessData data2_;
|
CookieAccessData data2_;
|
||||||
|
|
|
@ -20,9 +20,11 @@
|
||||||
#include "include/cef_app.h"
|
#include "include/cef_app.h"
|
||||||
#include "include/cef_task.h"
|
#include "include/cef_task.h"
|
||||||
#include "include/cef_thread.h"
|
#include "include/cef_thread.h"
|
||||||
|
#include "include/cef_waitable_event.h"
|
||||||
#include "include/wrapper/cef_closure_task.h"
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
#include "include/wrapper/cef_helpers.h"
|
#include "include/wrapper/cef_helpers.h"
|
||||||
#include "tests/ceftests/test_handler.h"
|
#include "tests/ceftests/test_handler.h"
|
||||||
|
#include "tests/ceftests/test_server.h"
|
||||||
#include "tests/ceftests/test_suite.h"
|
#include "tests/ceftests/test_suite.h"
|
||||||
#include "tests/shared/browser/client_app_browser.h"
|
#include "tests/shared/browser/client_app_browser.h"
|
||||||
#include "tests/shared/browser/main_message_loop_external_pump.h"
|
#include "tests/shared/browser/main_message_loop_external_pump.h"
|
||||||
|
@ -48,6 +50,7 @@
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void QuitMessageLoop() {
|
void QuitMessageLoop() {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
client::MainMessageLoop* message_loop = client::MainMessageLoop::Get();
|
client::MainMessageLoop* message_loop = client::MainMessageLoop::Get();
|
||||||
if (message_loop)
|
if (message_loop)
|
||||||
message_loop->Quit();
|
message_loop->Quit();
|
||||||
|
@ -74,8 +77,8 @@ void RunTestsOnTestThread() {
|
||||||
while (TestHandler::HasBrowser())
|
while (TestHandler::HasBrowser())
|
||||||
sleep(100);
|
sleep(100);
|
||||||
|
|
||||||
// Quit the CEF message loop.
|
// Wait for the test server to stop, and then quit the CEF message loop.
|
||||||
CefPostTask(TID_UI, base::Bind(&QuitMessageLoop));
|
test_server::Stop(base::Bind(QuitMessageLoop));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called on the UI thread.
|
// Called on the UI thread.
|
||||||
|
@ -201,6 +204,12 @@ int main(int argc, char* argv[]) {
|
||||||
if (settings.multi_threaded_message_loop) {
|
if (settings.multi_threaded_message_loop) {
|
||||||
// Run the test suite on the main thread.
|
// Run the test suite on the main thread.
|
||||||
retval = test_suite.Run();
|
retval = test_suite.Run();
|
||||||
|
|
||||||
|
// Wait for the test server to stop.
|
||||||
|
CefRefPtr<CefWaitableEvent> event =
|
||||||
|
CefWaitableEvent::CreateWaitableEvent(true, false);
|
||||||
|
test_server::Stop(base::Bind(&CefWaitableEvent::Signal, event));
|
||||||
|
event->Wait();
|
||||||
} else {
|
} else {
|
||||||
// Create and start the test thread.
|
// Create and start the test thread.
|
||||||
CefRefPtr<CefThread> thread = CefThread::CreateThread("test_thread");
|
CefRefPtr<CefThread> thread = CefThread::CreateThread("test_thread");
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
// Must use a different port than test_server.cc.
|
||||||
const char kTestServerAddress[] = "127.0.0.1";
|
const char kTestServerAddress[] = "127.0.0.1";
|
||||||
const uint16 kTestServerPort = 8099;
|
const uint16 kTestServerPort = 8099;
|
||||||
const int kTestTimeout = 5000;
|
const int kTestTimeout = 5000;
|
||||||
|
@ -27,7 +28,7 @@ const int kTestTimeout = 5000;
|
||||||
std::string GetTestServerOrigin(bool is_websocket) {
|
std::string GetTestServerOrigin(bool is_websocket) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << (is_websocket ? "ws://" : "http://") << kTestServerAddress << ":"
|
ss << (is_websocket ? "ws://" : "http://") << kTestServerAddress << ":"
|
||||||
<< kTestServerPort << "/";
|
<< kTestServerPort;
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,7 +794,7 @@ CefRefPtr<CefRequest> CreateTestServerRequest(
|
||||||
const std::string& content_type = std::string(),
|
const std::string& content_type = std::string(),
|
||||||
const CefRequest::HeaderMap& extra_headers = CefRequest::HeaderMap()) {
|
const CefRequest::HeaderMap& extra_headers = CefRequest::HeaderMap()) {
|
||||||
CefRefPtr<CefRequest> request = CefRequest::Create();
|
CefRefPtr<CefRequest> request = CefRequest::Create();
|
||||||
request->SetURL(GetTestServerOrigin(false) + path);
|
request->SetURL(GetTestServerOrigin(false) + "/" + path);
|
||||||
request->SetMethod(method);
|
request->SetMethod(method);
|
||||||
|
|
||||||
CefRequest::HeaderMap header_map;
|
CefRequest::HeaderMap header_map;
|
||||||
|
@ -1277,7 +1278,7 @@ class EchoWebSocketRequestHandler : public TestServerHandler::WsRequestHandler {
|
||||||
explicit EchoWebSocketRequestHandler(int expected_message_ct)
|
explicit EchoWebSocketRequestHandler(int expected_message_ct)
|
||||||
: expected_message_ct_(expected_message_ct), actual_message_ct_(0) {}
|
: expected_message_ct_(expected_message_ct), actual_message_ct_(0) {}
|
||||||
|
|
||||||
std::string GetWebSocketUrl() { return GetTestServerOrigin(true) + "echo"; }
|
std::string GetWebSocketUrl() { return GetTestServerOrigin(true) + "/echo"; }
|
||||||
|
|
||||||
bool HandleRequest(CefRefPtr<CefServer> server,
|
bool HandleRequest(CefRefPtr<CefServer> server,
|
||||||
int connection_id,
|
int connection_id,
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
// Copyright (c) 2020 The Chromium Embedded Framework 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 "tests/ceftests/test_request.h"
|
||||||
|
|
||||||
|
#include "include/cef_urlrequest.h"
|
||||||
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
|
#include "include/wrapper/cef_helpers.h"
|
||||||
|
|
||||||
|
namespace test_request {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Implementation of CefURLRequestClient that stores response information.
|
||||||
|
class RequestClient : public CefURLRequestClient, public State {
|
||||||
|
public:
|
||||||
|
RequestClient(const bool has_credentials,
|
||||||
|
const std::string& username,
|
||||||
|
const std::string& password,
|
||||||
|
const RequestDoneCallback& done_callback)
|
||||||
|
: has_credentials_(has_credentials),
|
||||||
|
username_(username),
|
||||||
|
password_(password),
|
||||||
|
done_callback_(done_callback) {
|
||||||
|
DCHECK(!done_callback_.is_null());
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUploadProgress(CefRefPtr<CefURLRequest> request,
|
||||||
|
int64 current,
|
||||||
|
int64 total) override {
|
||||||
|
upload_progress_ct_++;
|
||||||
|
upload_total_ = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDownloadProgress(CefRefPtr<CefURLRequest> request,
|
||||||
|
int64 current,
|
||||||
|
int64 total) override {
|
||||||
|
response_ = request->GetResponse();
|
||||||
|
DCHECK(response_.get());
|
||||||
|
DCHECK(response_->IsReadOnly());
|
||||||
|
download_progress_ct_++;
|
||||||
|
download_total_ = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDownloadData(CefRefPtr<CefURLRequest> request,
|
||||||
|
const void* data,
|
||||||
|
size_t data_length) override {
|
||||||
|
response_ = request->GetResponse();
|
||||||
|
DCHECK(response_.get());
|
||||||
|
DCHECK(response_->IsReadOnly());
|
||||||
|
download_data_ct_++;
|
||||||
|
download_data_ += std::string(static_cast<const char*>(data), data_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetAuthCredentials(bool isProxy,
|
||||||
|
const CefString& host,
|
||||||
|
int port,
|
||||||
|
const CefString& realm,
|
||||||
|
const CefString& scheme,
|
||||||
|
CefRefPtr<CefAuthCallback> callback) override {
|
||||||
|
auth_credentials_ct_++;
|
||||||
|
if (has_credentials_) {
|
||||||
|
callback->Continue(username_, password_);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnRequestComplete(CefRefPtr<CefURLRequest> request) override {
|
||||||
|
request_complete_ct_++;
|
||||||
|
|
||||||
|
request_ = request->GetRequest();
|
||||||
|
DCHECK(request_->IsReadOnly());
|
||||||
|
status_ = request->GetRequestStatus();
|
||||||
|
error_code_ = request->GetRequestError();
|
||||||
|
response_was_cached_ = request->ResponseWasCached();
|
||||||
|
response_ = request->GetResponse();
|
||||||
|
if (response_) {
|
||||||
|
DCHECK(response_->IsReadOnly());
|
||||||
|
}
|
||||||
|
|
||||||
|
done_callback_.Run(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const bool has_credentials_;
|
||||||
|
const std::string username_;
|
||||||
|
const std::string password_;
|
||||||
|
const RequestDoneCallback done_callback_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(RequestClient);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void Send(const SendConfig& config, const RequestDoneCallback& callback) {
|
||||||
|
DCHECK(config.request_);
|
||||||
|
CefRefPtr<RequestClient> client = new RequestClient(
|
||||||
|
config.has_credentials_, config.username_, config.password_, callback);
|
||||||
|
if (config.frame_) {
|
||||||
|
config.frame_->CreateURLRequest(config.request_, client.get());
|
||||||
|
} else {
|
||||||
|
CefURLRequest::Create(config.request_, client.get(),
|
||||||
|
config.request_context_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace test_request
|
|
@ -0,0 +1,69 @@
|
||||||
|
// Copyright (c) 2020 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef CEF_TESTS_CEFTESTS_TEST_REQUEST_H_
|
||||||
|
#define CEF_TESTS_CEFTESTS_TEST_REQUEST_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "include/base/cef_bind.h"
|
||||||
|
#include "include/cef_frame.h"
|
||||||
|
#include "include/cef_request.h"
|
||||||
|
#include "include/cef_request_context.h"
|
||||||
|
#include "include/cef_response.h"
|
||||||
|
|
||||||
|
namespace test_request {
|
||||||
|
|
||||||
|
// Stores all state passed to CefURLRequestClient.
|
||||||
|
struct State {
|
||||||
|
public:
|
||||||
|
// Number of times each callback is executed.
|
||||||
|
int upload_progress_ct_ = 0;
|
||||||
|
int download_progress_ct_ = 0;
|
||||||
|
int download_data_ct_ = 0;
|
||||||
|
int auth_credentials_ct_ = 0;
|
||||||
|
int request_complete_ct_ = 0;
|
||||||
|
|
||||||
|
// From OnUploadProgress.
|
||||||
|
int64 upload_total_ = 0;
|
||||||
|
|
||||||
|
// From OnDownloadProgress.
|
||||||
|
int64 download_total_ = 0;
|
||||||
|
|
||||||
|
// From OnDownloadData.
|
||||||
|
std::string download_data_;
|
||||||
|
|
||||||
|
// From OnRequestComplete.
|
||||||
|
CefRefPtr<CefRequest> request_;
|
||||||
|
cef_urlrequest_status_t status_ = UR_UNKNOWN;
|
||||||
|
cef_errorcode_t error_code_ = ERR_NONE;
|
||||||
|
CefRefPtr<CefResponse> response_;
|
||||||
|
bool response_was_cached_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef base::Callback<void(const State& state)> RequestDoneCallback;
|
||||||
|
|
||||||
|
struct SendConfig {
|
||||||
|
// Send using |frame_| or |request_context_| if non-nullptr.
|
||||||
|
// Sends using the global request context if both are nullptr.
|
||||||
|
CefRefPtr<CefFrame> frame_;
|
||||||
|
CefRefPtr<CefRequestContext> request_context_;
|
||||||
|
|
||||||
|
// The request to send.
|
||||||
|
CefRefPtr<CefRequest> request_;
|
||||||
|
|
||||||
|
// Returned via GetAuthCredentials if |has_credentials_| is true.
|
||||||
|
bool has_credentials_ = false;
|
||||||
|
std::string username_;
|
||||||
|
std::string password_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send a request. |callback| will be executed on the calling thread after the
|
||||||
|
// request completes.
|
||||||
|
void Send(const SendConfig& config, const RequestDoneCallback& callback);
|
||||||
|
|
||||||
|
} // namespace test_request
|
||||||
|
|
||||||
|
#endif // CEF_TESTS_CEFTESTS_TEST_REQUEST_H_
|
|
@ -0,0 +1,492 @@
|
||||||
|
// Copyright (c) 2020 The Chromium Embedded Framework 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 "tests/ceftests/test_server.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
|
#include "include/wrapper/cef_helpers.h"
|
||||||
|
|
||||||
|
namespace test_server {
|
||||||
|
|
||||||
|
// Must use a different port than server_unittest.cc.
|
||||||
|
const char kServerAddress[] = "127.0.0.1";
|
||||||
|
const uint16 kServerPort = 8098;
|
||||||
|
const char kServerScheme[] = "http";
|
||||||
|
const char kServerOrigin[] = "http://127.0.0.1:8098";
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class ServerManager;
|
||||||
|
ServerManager* g_manager = nullptr;
|
||||||
|
|
||||||
|
// True if Stop() has been called.
|
||||||
|
bool g_stopping = false;
|
||||||
|
|
||||||
|
// Created on the UI thread and called on the dedicated server thread.
|
||||||
|
class ServerHandler : public CefServerHandler {
|
||||||
|
public:
|
||||||
|
ServerHandler() {
|
||||||
|
CefServer::CreateServer(kServerAddress, kServerPort, 10, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ServerHandler() override {
|
||||||
|
DCHECK(!server_);
|
||||||
|
NotifyServerHandlerDeleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shutdown() { server_->Shutdown(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// CefServerHandler methods:
|
||||||
|
void OnServerCreated(CefRefPtr<CefServer> server) override {
|
||||||
|
server_ = server;
|
||||||
|
NotifyServerCreated(kServerOrigin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnServerDestroyed(CefRefPtr<CefServer> server) override {
|
||||||
|
server_ = nullptr;
|
||||||
|
NotifyServerDestroyed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClientConnected(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id) override {
|
||||||
|
DCHECK(server->HasConnection());
|
||||||
|
DCHECK(server->IsValidConnection(connection_id));
|
||||||
|
NotifyClientConnected(server, connection_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClientDisconnected(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id) override {
|
||||||
|
DCHECK(!server->IsValidConnection(connection_id));
|
||||||
|
NotifyClientDisconnected(server, connection_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnHttpRequest(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id,
|
||||||
|
const CefString& client_address,
|
||||||
|
CefRefPtr<CefRequest> request) override {
|
||||||
|
NotifyHttpRequest(server, connection_id, client_address, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnWebSocketRequest(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id,
|
||||||
|
const CefString& client_address,
|
||||||
|
CefRefPtr<CefRequest> request,
|
||||||
|
CefRefPtr<CefCallback> callback) override {}
|
||||||
|
void OnWebSocketConnected(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id) override {}
|
||||||
|
void OnWebSocketMessage(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id,
|
||||||
|
const void* data,
|
||||||
|
size_t data_size) override {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void NotifyServerCreated(const std::string& server_origin);
|
||||||
|
static void NotifyServerDestroyed();
|
||||||
|
static void NotifyServerHandlerDeleted();
|
||||||
|
static void NotifyClientConnected(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id);
|
||||||
|
static void NotifyClientDisconnected(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id);
|
||||||
|
static void NotifyHttpRequest(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id,
|
||||||
|
const CefString& client_address,
|
||||||
|
CefRefPtr<CefRequest> request);
|
||||||
|
|
||||||
|
CefRefPtr<CefServer> server_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(ServerHandler);
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ServerHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only accessed on the UI thread. Deletes itself after the server is stopped.
|
||||||
|
class ServerManager {
|
||||||
|
public:
|
||||||
|
ServerManager() {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
DCHECK(!g_manager);
|
||||||
|
g_manager = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ServerManager() {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
DCHECK(observer_list_.empty());
|
||||||
|
DCHECK(start_callback_list_.empty());
|
||||||
|
DCHECK(stop_callback_.is_null());
|
||||||
|
|
||||||
|
g_manager = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Start(const StartDoneCallback& callback) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
if (!origin_.empty()) {
|
||||||
|
// The server is already running.
|
||||||
|
callback.Run(origin_);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If tests run in parallel, and the server is starting, then there may be
|
||||||
|
// multiple pending callbacks.
|
||||||
|
start_callback_list_.push_back(callback);
|
||||||
|
|
||||||
|
// Only create the handler a single time.
|
||||||
|
if (!handler_) {
|
||||||
|
handler_ = new ServerHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stop(const DoneCallback& callback) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
if (!handler_) {
|
||||||
|
// The server is not currently running.
|
||||||
|
callback.Run();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only 1 stop callback supported.
|
||||||
|
DCHECK(stop_callback_.is_null());
|
||||||
|
stop_callback_ = callback;
|
||||||
|
|
||||||
|
handler_->Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddObserver(Observer* observer) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
observer_list_.push_back(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveObserver(Observer* observer) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
bool found = false;
|
||||||
|
ObserverList::iterator it = observer_list_.begin();
|
||||||
|
for (; it != observer_list_.end(); ++it) {
|
||||||
|
if (*it == observer) {
|
||||||
|
observer_list_.erase(it);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DCHECK(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotifyServerCreated(const std::string& server_origin) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
DCHECK(origin_.empty());
|
||||||
|
origin_ = server_origin;
|
||||||
|
|
||||||
|
StartDoneCallbackList::const_iterator it = start_callback_list_.begin();
|
||||||
|
for (; it != start_callback_list_.end(); ++it) {
|
||||||
|
(*it).Run(origin_);
|
||||||
|
}
|
||||||
|
start_callback_list_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotifyServerDestroyed() {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
origin_.clear();
|
||||||
|
handler_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All server-related objects have been torn down.
|
||||||
|
void NotifyServerHandlerDeleted() {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
DCHECK(!stop_callback_.is_null());
|
||||||
|
stop_callback_.Run();
|
||||||
|
stop_callback_.Reset();
|
||||||
|
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotifyClientConnected(CefRefPtr<CefServer> server, int connection_id) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
DCHECK(!observer_list_.empty());
|
||||||
|
|
||||||
|
// Use a copy in case |observer_list_| is modified during iteration.
|
||||||
|
ObserverList list = observer_list_;
|
||||||
|
|
||||||
|
ObserverList::const_iterator it = list.begin();
|
||||||
|
for (; it != list.end(); ++it) {
|
||||||
|
if ((*it)->OnClientConnected(server, connection_id)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotifyClientDisconnected(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
DCHECK(!observer_list_.empty());
|
||||||
|
|
||||||
|
// Use a copy in case |observer_list_| is modified during iteration.
|
||||||
|
ObserverList list = observer_list_;
|
||||||
|
|
||||||
|
ObserverList::const_iterator it = list.begin();
|
||||||
|
for (; it != list.end(); ++it) {
|
||||||
|
if ((*it)->OnClientDisconnected(server, connection_id)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotifyHttpRequest(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id,
|
||||||
|
const CefString& client_address,
|
||||||
|
CefRefPtr<CefRequest> request) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
DCHECK(!observer_list_.empty());
|
||||||
|
|
||||||
|
// Use a copy in case |observer_list_| is modified during iteration.
|
||||||
|
ObserverList list = observer_list_;
|
||||||
|
|
||||||
|
ObserverList::const_iterator it = list.begin();
|
||||||
|
for (; it != list.end(); ++it) {
|
||||||
|
if ((*it)->OnHttpRequest(server, connection_id, client_address,
|
||||||
|
request)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CefRefPtr<ServerHandler> handler_;
|
||||||
|
std::string origin_;
|
||||||
|
|
||||||
|
typedef std::vector<StartDoneCallback> StartDoneCallbackList;
|
||||||
|
StartDoneCallbackList start_callback_list_;
|
||||||
|
|
||||||
|
DoneCallback stop_callback_;
|
||||||
|
|
||||||
|
typedef std::vector<Observer*> ObserverList;
|
||||||
|
ObserverList observer_list_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ServerManager);
|
||||||
|
};
|
||||||
|
|
||||||
|
ServerManager* GetServerManager() {
|
||||||
|
return g_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerManager* GetOrCreateServerManager() {
|
||||||
|
if (!g_manager) {
|
||||||
|
new ServerManager();
|
||||||
|
DCHECK(g_manager);
|
||||||
|
}
|
||||||
|
return g_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void ServerHandler::NotifyServerCreated(const std::string& server_origin) {
|
||||||
|
if (!CefCurrentlyOn(TID_UI)) {
|
||||||
|
CefPostTask(TID_UI,
|
||||||
|
base::Bind(ServerHandler::NotifyServerCreated, server_origin));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetServerManager()->NotifyServerCreated(server_origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void ServerHandler::NotifyServerDestroyed() {
|
||||||
|
if (!CefCurrentlyOn(TID_UI)) {
|
||||||
|
CefPostTask(TID_UI, base::Bind(ServerHandler::NotifyServerDestroyed));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetServerManager()->NotifyServerDestroyed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void ServerHandler::NotifyServerHandlerDeleted() {
|
||||||
|
if (!CefCurrentlyOn(TID_UI)) {
|
||||||
|
CefPostTask(TID_UI, base::Bind(ServerHandler::NotifyServerHandlerDeleted));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetServerManager()->NotifyServerHandlerDeleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void ServerHandler::NotifyClientConnected(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id) {
|
||||||
|
if (!CefCurrentlyOn(TID_UI)) {
|
||||||
|
CefPostTask(TID_UI, base::Bind(ServerHandler::NotifyClientConnected, server,
|
||||||
|
connection_id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetServerManager()->NotifyClientConnected(server, connection_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void ServerHandler::NotifyClientDisconnected(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id) {
|
||||||
|
if (!CefCurrentlyOn(TID_UI)) {
|
||||||
|
CefPostTask(TID_UI, base::Bind(ServerHandler::NotifyClientDisconnected,
|
||||||
|
server, connection_id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetServerManager()->NotifyClientDisconnected(server, connection_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void ServerHandler::NotifyHttpRequest(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id,
|
||||||
|
const CefString& client_address,
|
||||||
|
CefRefPtr<CefRequest> request) {
|
||||||
|
if (!CefCurrentlyOn(TID_UI)) {
|
||||||
|
CefPostTask(TID_UI, base::Bind(ServerHandler::NotifyHttpRequest, server,
|
||||||
|
connection_id, client_address, request));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetServerManager()->NotifyHttpRequest(server, connection_id, client_address,
|
||||||
|
request);
|
||||||
|
}
|
||||||
|
|
||||||
|
// May be created on any thread but will be destroyed on the UI thread.
|
||||||
|
class ObserverRegistration : public CefRegistration {
|
||||||
|
public:
|
||||||
|
explicit ObserverRegistration(Observer* const observer)
|
||||||
|
: observer_(observer) {
|
||||||
|
DCHECK(observer_);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ObserverRegistration() override {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
ServerManager* manager = GetServerManager();
|
||||||
|
if (manager) {
|
||||||
|
manager->RemoveObserver(observer_);
|
||||||
|
observer_->OnUnregistered();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Initialize() {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
GetOrCreateServerManager()->AddObserver(observer_);
|
||||||
|
observer_->OnRegistered();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Observer* const observer_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(ObserverRegistration);
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ObserverRegistration);
|
||||||
|
};
|
||||||
|
|
||||||
|
void InitializeRegistration(CefRefPtr<ObserverRegistration> registration,
|
||||||
|
const DoneCallback& callback) {
|
||||||
|
if (!CefCurrentlyOn(TID_UI)) {
|
||||||
|
CefPostTask(TID_UI,
|
||||||
|
base::Bind(InitializeRegistration, registration, callback));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DCHECK(!g_stopping);
|
||||||
|
|
||||||
|
registration->Initialize();
|
||||||
|
if (!callback.is_null())
|
||||||
|
callback.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void Start(const StartDoneCallback& callback) {
|
||||||
|
DCHECK(!callback.is_null());
|
||||||
|
if (!CefCurrentlyOn(TID_UI)) {
|
||||||
|
CefPostTask(TID_UI, base::Bind(Start, callback));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DCHECK(!g_stopping);
|
||||||
|
|
||||||
|
GetOrCreateServerManager()->Start(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stop(const DoneCallback& callback) {
|
||||||
|
DCHECK(!callback.is_null());
|
||||||
|
if (!CefCurrentlyOn(TID_UI)) {
|
||||||
|
CefPostTask(TID_UI, base::Bind(Stop, callback));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop will be called one time on test framework shutdown.
|
||||||
|
DCHECK(!g_stopping);
|
||||||
|
g_stopping = true;
|
||||||
|
|
||||||
|
ServerManager* manager = GetServerManager();
|
||||||
|
if (manager) {
|
||||||
|
manager->Stop(callback);
|
||||||
|
} else {
|
||||||
|
callback.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefRegistration> AddObserver(Observer* observer,
|
||||||
|
const DoneCallback& callback) {
|
||||||
|
DCHECK(observer);
|
||||||
|
CefRefPtr<ObserverRegistration> registration =
|
||||||
|
new ObserverRegistration(observer);
|
||||||
|
InitializeRegistration(registration, callback);
|
||||||
|
return registration.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefRegistration> AddObserverAndStart(
|
||||||
|
Observer* observer,
|
||||||
|
const StartDoneCallback& callback) {
|
||||||
|
return AddObserver(observer, base::Bind(Start, callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ObserverHelper
|
||||||
|
|
||||||
|
ObserverHelper::ObserverHelper() : weak_ptr_factory_(this) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
}
|
||||||
|
|
||||||
|
ObserverHelper::~ObserverHelper() {
|
||||||
|
DCHECK(state_ == State::NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObserverHelper::Initialize() {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
DCHECK(state_ == State::NONE);
|
||||||
|
state_ = State::INITIALIZING;
|
||||||
|
registration_ = AddObserverAndStart(
|
||||||
|
this,
|
||||||
|
base::Bind(&ObserverHelper::OnStartDone, weak_ptr_factory_.GetWeakPtr()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObserverHelper::Shutdown() {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
DCHECK(state_ == State::INITIALIZED);
|
||||||
|
state_ = State::SHUTTINGDOWN;
|
||||||
|
registration_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObserverHelper::OnStartDone(const std::string& server_origin) {
|
||||||
|
DCHECK(state_ == State::INITIALIZING);
|
||||||
|
state_ = State::INITIALIZED;
|
||||||
|
OnInitialized(server_origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObserverHelper::OnRegistered() {
|
||||||
|
DCHECK(state_ == State::INITIALIZING);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObserverHelper::OnUnregistered() {
|
||||||
|
DCHECK(state_ == State::SHUTTINGDOWN);
|
||||||
|
state_ = State::NONE;
|
||||||
|
OnShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace test_server
|
|
@ -0,0 +1,119 @@
|
||||||
|
// Copyright (c) 2020 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef CEF_TESTS_CEFTESTS_TEST_SERVER_H_
|
||||||
|
#define CEF_TESTS_CEFTESTS_TEST_SERVER_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "include/base/cef_bind.h"
|
||||||
|
#include "include/cef_registration.h"
|
||||||
|
#include "include/cef_request.h"
|
||||||
|
#include "include/cef_server.h"
|
||||||
|
|
||||||
|
namespace test_server {
|
||||||
|
|
||||||
|
extern const char kServerAddress[];
|
||||||
|
extern const uint16 kServerPort;
|
||||||
|
extern const char kServerScheme[];
|
||||||
|
extern const char kServerOrigin[];
|
||||||
|
|
||||||
|
typedef base::Closure DoneCallback;
|
||||||
|
|
||||||
|
typedef base::Callback<void(const std::string& server_origin)>
|
||||||
|
StartDoneCallback;
|
||||||
|
|
||||||
|
// Starts the server if it is not currently running, and executes |callback| on
|
||||||
|
// the UI thread. This method should be called by each test case that relies on
|
||||||
|
// the server.
|
||||||
|
void Start(const StartDoneCallback& callback);
|
||||||
|
|
||||||
|
// Stops the server if it is currently running, and executes |callback| on the
|
||||||
|
// UI thread. This method will be called by the test framework on shutdown.
|
||||||
|
void Stop(const DoneCallback& callback);
|
||||||
|
|
||||||
|
// Observer for CefServerHandler callbacks. Methods will be called on the UI
|
||||||
|
// thread.
|
||||||
|
class Observer {
|
||||||
|
public:
|
||||||
|
// Called when this Observer is registered.
|
||||||
|
virtual void OnRegistered() = 0;
|
||||||
|
|
||||||
|
// Called when this Observer is unregistered.
|
||||||
|
virtual void OnUnregistered() = 0;
|
||||||
|
|
||||||
|
// See CefServerHandler documentation for usage. Return true if the callback
|
||||||
|
// was handled.
|
||||||
|
virtual bool OnClientConnected(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual bool OnClientDisconnected(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual bool OnHttpRequest(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id,
|
||||||
|
const CefString& client_address,
|
||||||
|
CefRefPtr<CefRequest> request) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~Observer() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add an observer for CefServerHandler callbacks. Remains registered until the
|
||||||
|
// returned CefRegistration object is destroyed. Registered observers will be
|
||||||
|
// executed in the order of registration until one returns true to indicate that
|
||||||
|
// it handled the callback. |callback| will be executed on the UI thread after
|
||||||
|
// registration is complete.
|
||||||
|
CefRefPtr<CefRegistration> AddObserver(Observer* observer,
|
||||||
|
const DoneCallback& callback);
|
||||||
|
|
||||||
|
// Combination of AddObserver() followed by Start().
|
||||||
|
CefRefPtr<CefRegistration> AddObserverAndStart(
|
||||||
|
Observer* observer,
|
||||||
|
const StartDoneCallback& callback);
|
||||||
|
|
||||||
|
// Helper for managing Observer registration and callbacks. Only used on the UI
|
||||||
|
// thread.
|
||||||
|
class ObserverHelper : Observer {
|
||||||
|
public:
|
||||||
|
ObserverHelper();
|
||||||
|
~ObserverHelper() override;
|
||||||
|
|
||||||
|
// Initialize the registration. Results in a call to OnInitialized().
|
||||||
|
void Initialize();
|
||||||
|
|
||||||
|
// Shut down the registration. Results in a call to OnShutdown().
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
// Implement this method to start sending server requests after Initialize().
|
||||||
|
virtual void OnInitialized(const std::string& server_origin) = 0;
|
||||||
|
|
||||||
|
// Implement this method to continue the test after Shutdown().
|
||||||
|
virtual void OnShutdown() = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OnStartDone(const std::string& server_origin);
|
||||||
|
void OnRegistered() override;
|
||||||
|
void OnUnregistered() override;
|
||||||
|
|
||||||
|
CefRefPtr<CefRegistration> registration_;
|
||||||
|
|
||||||
|
enum class State {
|
||||||
|
NONE,
|
||||||
|
INITIALIZING,
|
||||||
|
INITIALIZED,
|
||||||
|
SHUTTINGDOWN,
|
||||||
|
} state_ = State::NONE;
|
||||||
|
|
||||||
|
base::WeakPtrFactory<ObserverHelper> weak_ptr_factory_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ObserverHelper);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace test_server
|
||||||
|
|
||||||
|
#endif // CEF_TESTS_CEFTESTS_TEST_SERVER_H_
|
|
@ -0,0 +1,257 @@
|
||||||
|
// Copyright (c) 2020 The Chromium Embedded Framework 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 <sstream>
|
||||||
|
|
||||||
|
#include "include/cef_task.h"
|
||||||
|
#include "include/cef_waitable_event.h"
|
||||||
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
|
#include "include/wrapper/cef_helpers.h"
|
||||||
|
#include "tests/ceftests/test_request.h"
|
||||||
|
#include "tests/ceftests/test_server.h"
|
||||||
|
#include "tests/ceftests/track_callback.h"
|
||||||
|
#include "tests/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct TestState {
|
||||||
|
TrackCallback got_initialized_;
|
||||||
|
TrackCallback got_connected_;
|
||||||
|
TrackCallback got_request_;
|
||||||
|
TrackCallback got_response_;
|
||||||
|
TrackCallback got_disconnected_;
|
||||||
|
TrackCallback got_shutdown_;
|
||||||
|
|
||||||
|
bool ExpectAll() {
|
||||||
|
EXPECT_TRUE(got_initialized_);
|
||||||
|
EXPECT_TRUE(got_connected_);
|
||||||
|
EXPECT_TRUE(got_request_);
|
||||||
|
EXPECT_TRUE(got_response_);
|
||||||
|
EXPECT_TRUE(got_disconnected_);
|
||||||
|
EXPECT_TRUE(got_shutdown_);
|
||||||
|
return got_initialized_ && got_connected_ && got_request_ &&
|
||||||
|
got_response_ && got_disconnected_ && got_shutdown_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const char kResponseData[] = "Test data";
|
||||||
|
|
||||||
|
class TestServerObserver : public test_server::ObserverHelper {
|
||||||
|
public:
|
||||||
|
TestServerObserver(TestState* state,
|
||||||
|
const std::string& path,
|
||||||
|
const base::Closure& done_callback)
|
||||||
|
: state_(state),
|
||||||
|
path_(path),
|
||||||
|
done_callback_(done_callback),
|
||||||
|
weak_ptr_factory_(this) {
|
||||||
|
DCHECK(state);
|
||||||
|
DCHECK(!path.empty());
|
||||||
|
DCHECK(!done_callback_.is_null());
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
~TestServerObserver() override { done_callback_.Run(); }
|
||||||
|
|
||||||
|
void OnInitialized(const std::string& server_origin) override {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
EXPECT_FALSE(state_->got_initialized_);
|
||||||
|
EXPECT_FALSE(state_->got_connected_);
|
||||||
|
EXPECT_FALSE(state_->got_request_);
|
||||||
|
EXPECT_FALSE(state_->got_response_);
|
||||||
|
EXPECT_FALSE(state_->got_disconnected_);
|
||||||
|
EXPECT_FALSE(state_->got_shutdown_);
|
||||||
|
|
||||||
|
state_->got_initialized_.yes();
|
||||||
|
|
||||||
|
url_ = server_origin + path_;
|
||||||
|
|
||||||
|
// Send a request to the server.
|
||||||
|
test_request::SendConfig config;
|
||||||
|
config.request_ = CefRequest::Create();
|
||||||
|
config.request_->SetURL(url_);
|
||||||
|
test_request::Send(config,
|
||||||
|
base::Bind(&TestServerObserver::OnRequestResponse,
|
||||||
|
weak_ptr_factory_.GetWeakPtr()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnClientConnected(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id) override {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
if (state_->got_connected_) {
|
||||||
|
// We already got the callback once. Let the next observer get the
|
||||||
|
// callback.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_TRUE(state_->got_initialized_);
|
||||||
|
EXPECT_FALSE(state_->got_request_);
|
||||||
|
EXPECT_FALSE(state_->got_response_);
|
||||||
|
EXPECT_FALSE(state_->got_disconnected_);
|
||||||
|
EXPECT_FALSE(state_->got_shutdown_);
|
||||||
|
|
||||||
|
state_->got_connected_.yes();
|
||||||
|
|
||||||
|
// We don't know if this connection is the one that we're going to
|
||||||
|
// handle, so continue propagating the callback.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnHttpRequest(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id,
|
||||||
|
const CefString& client_address,
|
||||||
|
CefRefPtr<CefRequest> request) override {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
const std::string& url = request->GetURL();
|
||||||
|
if (url != url_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
EXPECT_TRUE(state_->got_initialized_);
|
||||||
|
EXPECT_TRUE(state_->got_connected_);
|
||||||
|
EXPECT_FALSE(state_->got_request_);
|
||||||
|
EXPECT_FALSE(state_->got_response_);
|
||||||
|
EXPECT_FALSE(state_->got_disconnected_);
|
||||||
|
EXPECT_FALSE(state_->got_shutdown_);
|
||||||
|
|
||||||
|
state_->got_request_.yes();
|
||||||
|
connection_id_ = connection_id;
|
||||||
|
|
||||||
|
server->SendHttp200Response(connection_id, "text/plain", kResponseData,
|
||||||
|
sizeof(kResponseData) - 1);
|
||||||
|
|
||||||
|
// Stop propagating the callback.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnRequestResponse(const test_request::State& state) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
// Don't test for disconnected, which may race response.
|
||||||
|
EXPECT_TRUE(state_->got_initialized_);
|
||||||
|
EXPECT_TRUE(state_->got_connected_);
|
||||||
|
EXPECT_TRUE(state_->got_request_);
|
||||||
|
EXPECT_FALSE(state_->got_response_);
|
||||||
|
EXPECT_FALSE(state_->got_shutdown_);
|
||||||
|
|
||||||
|
state_->got_response_.yes();
|
||||||
|
|
||||||
|
EXPECT_STREQ(url_.c_str(), state.request_->GetURL().ToString().c_str());
|
||||||
|
EXPECT_EQ(UR_SUCCESS, state.status_);
|
||||||
|
EXPECT_EQ(ERR_NONE, state.error_code_);
|
||||||
|
EXPECT_EQ(200, state.response_->GetStatus());
|
||||||
|
EXPECT_STREQ(kResponseData, state.download_data_.c_str());
|
||||||
|
|
||||||
|
// Trigger shutdown asynchronously.
|
||||||
|
CefPostTask(TID_UI, base::Bind(&TestServerObserver::Shutdown,
|
||||||
|
weak_ptr_factory_.GetWeakPtr()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnClientDisconnected(CefRefPtr<CefServer> server,
|
||||||
|
int connection_id) override {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
if (connection_id != connection_id_) {
|
||||||
|
// Not the connection that we handled. Let the next observer get the
|
||||||
|
// callback.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't test for response, which may race disconnected.
|
||||||
|
EXPECT_TRUE(state_->got_initialized_);
|
||||||
|
EXPECT_TRUE(state_->got_connected_);
|
||||||
|
EXPECT_TRUE(state_->got_request_);
|
||||||
|
EXPECT_FALSE(state_->got_disconnected_);
|
||||||
|
EXPECT_FALSE(state_->got_shutdown_);
|
||||||
|
|
||||||
|
state_->got_disconnected_.yes();
|
||||||
|
|
||||||
|
// Stop propagating the callback.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnShutdown() override {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
EXPECT_TRUE(state_->got_initialized_);
|
||||||
|
EXPECT_TRUE(state_->got_connected_);
|
||||||
|
EXPECT_TRUE(state_->got_request_);
|
||||||
|
EXPECT_TRUE(state_->got_response_);
|
||||||
|
EXPECT_TRUE(state_->got_disconnected_);
|
||||||
|
EXPECT_FALSE(state_->got_shutdown_);
|
||||||
|
|
||||||
|
state_->got_shutdown_.yes();
|
||||||
|
|
||||||
|
// End the test.
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TestState* const state_;
|
||||||
|
const std::string path_;
|
||||||
|
const base::Closure done_callback_;
|
||||||
|
|
||||||
|
std::string url_;
|
||||||
|
int connection_id_ = -1;
|
||||||
|
|
||||||
|
base::WeakPtrFactory<TestServerObserver> weak_ptr_factory_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(TestServerObserver);
|
||||||
|
};
|
||||||
|
|
||||||
|
void CreateObserverOnUIThread(TestState* state,
|
||||||
|
const std::string& path,
|
||||||
|
const base::Closure& done_callback) {
|
||||||
|
if (!CefCurrentlyOn(TID_UI)) {
|
||||||
|
CefPostTask(TID_UI,
|
||||||
|
base::Bind(CreateObserverOnUIThread, base::Unretained(state),
|
||||||
|
path, done_callback));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
new TestServerObserver(state, path, done_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalIfDone(CefRefPtr<CefWaitableEvent> event,
|
||||||
|
size_t* count,
|
||||||
|
size_t total) {
|
||||||
|
if (++(*count) == total) {
|
||||||
|
event->Signal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST(TestServerTest, ObserverHelperSingle) {
|
||||||
|
CefRefPtr<CefWaitableEvent> event =
|
||||||
|
CefWaitableEvent::CreateWaitableEvent(true, false);
|
||||||
|
|
||||||
|
TestState state;
|
||||||
|
CreateObserverOnUIThread(&state, "/TestServerTest.ObserverHelperSingle",
|
||||||
|
base::Bind(&CefWaitableEvent::Signal, event));
|
||||||
|
event->TimedWait(2000);
|
||||||
|
|
||||||
|
EXPECT_TRUE(state.ExpectAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestServerTest, ObserverHelperMultiple) {
|
||||||
|
CefRefPtr<CefWaitableEvent> event =
|
||||||
|
CefWaitableEvent::CreateWaitableEvent(true, false);
|
||||||
|
|
||||||
|
TestState states[3];
|
||||||
|
size_t count = 0;
|
||||||
|
const size_t size = arraysize(states);
|
||||||
|
|
||||||
|
const base::Closure& done_callback =
|
||||||
|
base::Bind(SignalIfDone, event, base::Unretained(&count), size);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; ++i) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "/TestServerTest.ObserverHelperMultiple" << i;
|
||||||
|
CreateObserverOnUIThread(&states[i], ss.str(), done_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
event->TimedWait(2000);
|
||||||
|
|
||||||
|
EXPECT_EQ(size, count);
|
||||||
|
for (size_t i = 0; i < size; ++i) {
|
||||||
|
EXPECT_TRUE(states[i].ExpectAll()) << i;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,8 @@
|
||||||
#include "include/wrapper/cef_closure_task.h"
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
#include "include/wrapper/cef_scoped_temp_dir.h"
|
#include "include/wrapper/cef_scoped_temp_dir.h"
|
||||||
#include "tests/ceftests/test_handler.h"
|
#include "tests/ceftests/test_handler.h"
|
||||||
|
#include "tests/ceftests/test_request.h"
|
||||||
|
#include "tests/ceftests/test_server.h"
|
||||||
#include "tests/ceftests/test_suite.h"
|
#include "tests/ceftests/test_suite.h"
|
||||||
#include "tests/ceftests/test_util.h"
|
#include "tests/ceftests/test_util.h"
|
||||||
#include "tests/gtest/include/gtest/gtest.h"
|
#include "tests/gtest/include/gtest/gtest.h"
|
||||||
|
@ -45,9 +47,9 @@ const char kRequestSchemeCustom[] = "urcustom";
|
||||||
const char kRequestHostCustom[] = "test";
|
const char kRequestHostCustom[] = "test";
|
||||||
|
|
||||||
// Server backend.
|
// Server backend.
|
||||||
const char kRequestAddressServer[] = "127.0.0.1";
|
const char* kRequestAddressServer = test_server::kServerAddress;
|
||||||
const uint16 kRequestPortServer = 8099;
|
const uint16 kRequestPortServer = test_server::kServerPort;
|
||||||
const char kRequestSchemeServer[] = "http";
|
const char* kRequestSchemeServer = test_server::kServerScheme;
|
||||||
|
|
||||||
const char kRequestSendCookieName[] = "urcookie_send";
|
const char kRequestSendCookieName[] = "urcookie_send";
|
||||||
const char kRequestSaveCookieName[] = "urcookie_save";
|
const char kRequestSaveCookieName[] = "urcookie_save";
|
||||||
|
@ -1205,7 +1207,7 @@ class RequestSchemeHandlerFactory : public CefSchemeHandlerFactory {
|
||||||
// SERVER BACKEND
|
// SERVER BACKEND
|
||||||
|
|
||||||
// HTTP server handler.
|
// HTTP server handler.
|
||||||
class RequestServerHandler : public CefServerHandler {
|
class RequestServerHandler : public test_server::ObserverHelper {
|
||||||
public:
|
public:
|
||||||
RequestServerHandler()
|
RequestServerHandler()
|
||||||
: initialized_(false),
|
: initialized_(false),
|
||||||
|
@ -1244,8 +1246,7 @@ class RequestServerHandler : public CefServerHandler {
|
||||||
EXPECT_TRUE(complete_callback_.is_null());
|
EXPECT_TRUE(complete_callback_.is_null());
|
||||||
complete_callback_ = complete_callback;
|
complete_callback_ = complete_callback;
|
||||||
|
|
||||||
CefServer::CreateServer(kRequestAddressServer, kRequestPortServer, 10,
|
Initialize();
|
||||||
this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Results in a call to VerifyResults() and eventual execution of the
|
// Results in a call to VerifyResults() and eventual execution of the
|
||||||
|
@ -1256,73 +1257,59 @@ class RequestServerHandler : public CefServerHandler {
|
||||||
EXPECT_TRUE(complete_callback_.is_null());
|
EXPECT_TRUE(complete_callback_.is_null());
|
||||||
complete_callback_ = complete_callback;
|
complete_callback_ = complete_callback;
|
||||||
|
|
||||||
EXPECT_TRUE(server_);
|
Shutdown();
|
||||||
if (server_)
|
|
||||||
server_->Shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnServerCreated(CefRefPtr<CefServer> server) override {
|
void OnInitialized(const std::string& server_origin) override {
|
||||||
EXPECT_TRUE(server);
|
EXPECT_UI_THREAD();
|
||||||
EXPECT_TRUE(server->IsRunning());
|
EXPECT_STREQ(server_origin.c_str(), GetRequestOrigin(true).c_str());
|
||||||
EXPECT_FALSE(server->HasConnection());
|
EXPECT_FALSE(got_initialized_);
|
||||||
|
got_initialized_.yes();
|
||||||
|
|
||||||
EXPECT_FALSE(got_server_created_);
|
RunCompleteCallback(true);
|
||||||
got_server_created_.yes();
|
|
||||||
|
|
||||||
EXPECT_FALSE(server_);
|
|
||||||
server_ = server;
|
|
||||||
|
|
||||||
EXPECT_FALSE(server_runner_);
|
|
||||||
server_runner_ = server_->GetTaskRunner();
|
|
||||||
EXPECT_TRUE(server_runner_);
|
|
||||||
EXPECT_TRUE(server_runner_->BelongsToCurrentThread());
|
|
||||||
|
|
||||||
CefPostTask(TID_UI, base::Bind(&RequestServerHandler::RunCompleteCallback,
|
|
||||||
this, true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnServerDestroyed(CefRefPtr<CefServer> server) override {
|
void OnShutdown() override {
|
||||||
EXPECT_TRUE(VerifyServer(server));
|
EXPECT_UI_THREAD();
|
||||||
EXPECT_FALSE(server->IsRunning());
|
EXPECT_FALSE(got_shutdown_);
|
||||||
EXPECT_FALSE(server->HasConnection());
|
got_shutdown_.yes();
|
||||||
|
|
||||||
EXPECT_FALSE(got_server_destroyed_);
|
|
||||||
got_server_destroyed_.yes();
|
|
||||||
|
|
||||||
data_map_.SetOwnerTaskRunner(nullptr);
|
data_map_.SetOwnerTaskRunner(nullptr);
|
||||||
server_ = nullptr;
|
|
||||||
|
|
||||||
VerifyResults();
|
VerifyResults();
|
||||||
|
|
||||||
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnClientConnected(CefRefPtr<CefServer> server,
|
bool OnClientConnected(CefRefPtr<CefServer> server,
|
||||||
int connection_id) override {
|
int connection_id) override {
|
||||||
EXPECT_TRUE(VerifyServer(server));
|
EXPECT_UI_THREAD();
|
||||||
EXPECT_TRUE(server->HasConnection());
|
|
||||||
EXPECT_TRUE(server->IsValidConnection(connection_id));
|
|
||||||
|
|
||||||
EXPECT_TRUE(connection_id_set_.find(connection_id) ==
|
EXPECT_TRUE(connection_id_set_.find(connection_id) ==
|
||||||
connection_id_set_.end());
|
connection_id_set_.end());
|
||||||
connection_id_set_.insert(connection_id);
|
connection_id_set_.insert(connection_id);
|
||||||
|
|
||||||
actual_connection_ct_++;
|
actual_connection_ct_++;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnClientDisconnected(CefRefPtr<CefServer> server,
|
bool OnClientDisconnected(CefRefPtr<CefServer> server,
|
||||||
int connection_id) override {
|
int connection_id) override {
|
||||||
EXPECT_TRUE(VerifyServer(server));
|
EXPECT_UI_THREAD();
|
||||||
EXPECT_FALSE(server->IsValidConnection(connection_id));
|
|
||||||
|
|
||||||
ConnectionIdSet::iterator it = connection_id_set_.find(connection_id);
|
ConnectionIdSet::iterator it = connection_id_set_.find(connection_id);
|
||||||
EXPECT_TRUE(it != connection_id_set_.end());
|
EXPECT_TRUE(it != connection_id_set_.end());
|
||||||
connection_id_set_.erase(it);
|
connection_id_set_.erase(it);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnHttpRequest(CefRefPtr<CefServer> server,
|
bool OnHttpRequest(CefRefPtr<CefServer> server,
|
||||||
int connection_id,
|
int connection_id,
|
||||||
const CefString& client_address,
|
const CefString& client_address,
|
||||||
CefRefPtr<CefRequest> request) override {
|
CefRefPtr<CefRequest> request) override {
|
||||||
EXPECT_TRUE(VerifyServer(server));
|
EXPECT_UI_THREAD();
|
||||||
EXPECT_TRUE(VerifyConnection(connection_id));
|
EXPECT_TRUE(VerifyConnection(connection_id));
|
||||||
EXPECT_FALSE(client_address.empty());
|
EXPECT_FALSE(client_address.empty());
|
||||||
|
|
||||||
|
@ -1333,52 +1320,18 @@ class RequestServerHandler : public CefServerHandler {
|
||||||
HandleRequest(server, connection_id, request);
|
HandleRequest(server, connection_id, request);
|
||||||
|
|
||||||
actual_http_request_ct_++;
|
actual_http_request_ct_++;
|
||||||
}
|
|
||||||
|
|
||||||
void OnWebSocketRequest(CefRefPtr<CefServer> server,
|
return true;
|
||||||
int connection_id,
|
|
||||||
const CefString& client_address,
|
|
||||||
CefRefPtr<CefRequest> request,
|
|
||||||
CefRefPtr<CefCallback> callback) override {
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnWebSocketConnected(CefRefPtr<CefServer> server,
|
|
||||||
int connection_id) override {
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnWebSocketMessage(CefRefPtr<CefServer> server,
|
|
||||||
int connection_id,
|
|
||||||
const void* data,
|
|
||||||
size_t data_size) override {
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool RunningOnServerThread() {
|
|
||||||
return server_runner_ && server_runner_->BelongsToCurrentThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VerifyServer(CefRefPtr<CefServer> server) {
|
|
||||||
V_DECLARE();
|
|
||||||
V_EXPECT_TRUE(RunningOnServerThread());
|
|
||||||
V_EXPECT_TRUE(server);
|
|
||||||
V_EXPECT_TRUE(server_);
|
|
||||||
V_EXPECT_TRUE(server->GetAddress().ToString() ==
|
|
||||||
server_->GetAddress().ToString());
|
|
||||||
V_RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VerifyConnection(int connection_id) {
|
bool VerifyConnection(int connection_id) {
|
||||||
return connection_id_set_.find(connection_id) != connection_id_set_.end();
|
return connection_id_set_.find(connection_id) != connection_id_set_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerifyResults() {
|
void VerifyResults() {
|
||||||
EXPECT_TRUE(RunningOnServerThread());
|
EXPECT_TRUE(got_initialized_);
|
||||||
|
EXPECT_TRUE(got_shutdown_);
|
||||||
EXPECT_TRUE(got_server_created_);
|
|
||||||
EXPECT_TRUE(got_server_destroyed_);
|
|
||||||
EXPECT_TRUE(connection_id_set_.empty());
|
EXPECT_TRUE(connection_id_set_.empty());
|
||||||
EXPECT_EQ(expected_connection_ct_, actual_connection_ct_) << request_log_;
|
EXPECT_EQ(expected_connection_ct_, actual_connection_ct_) << request_log_;
|
||||||
EXPECT_EQ(expected_http_request_ct_, actual_http_request_ct_)
|
EXPECT_EQ(expected_http_request_ct_, actual_http_request_ct_)
|
||||||
|
@ -1409,18 +1362,18 @@ class RequestServerHandler : public CefServerHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleAuthRequest(CefRefPtr<CefServer> server,
|
static void HandleAuthRequest(CefRefPtr<CefServer> server,
|
||||||
int connection_id,
|
int connection_id,
|
||||||
CefRefPtr<CefRequest> request) {
|
CefRefPtr<CefRequest> request) {
|
||||||
CefRefPtr<CefResponse> response = CefResponse::Create();
|
CefRefPtr<CefResponse> response = CefResponse::Create();
|
||||||
GetAuthResponse(response);
|
GetAuthResponse(response);
|
||||||
SendResponse(server, connection_id, response, std::string());
|
SendResponse(server, connection_id, response, std::string());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleNormalRequest(CefRefPtr<CefServer> server,
|
static void HandleNormalRequest(CefRefPtr<CefServer> server,
|
||||||
int connection_id,
|
int connection_id,
|
||||||
CefRefPtr<CefRequest> request,
|
CefRefPtr<CefRequest> request,
|
||||||
RequestRunSettings* settings) {
|
RequestRunSettings* settings) {
|
||||||
VerifyNormalRequest(settings, request, true);
|
VerifyNormalRequest(settings, request, true);
|
||||||
|
|
||||||
CefRefPtr<CefResponse> response = CefResponse::Create();
|
CefRefPtr<CefResponse> response = CefResponse::Create();
|
||||||
|
@ -1437,11 +1390,11 @@ class RequestServerHandler : public CefServerHandler {
|
||||||
SendResponse(server, connection_id, response, response_data);
|
SendResponse(server, connection_id, response, response_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleRedirectRequest(CefRefPtr<CefServer> server,
|
static void HandleRedirectRequest(CefRefPtr<CefServer> server,
|
||||||
int connection_id,
|
int connection_id,
|
||||||
CefRefPtr<CefRequest> request,
|
CefRefPtr<CefRequest> request,
|
||||||
CefRefPtr<CefRequest> redirect_request,
|
CefRefPtr<CefRequest> redirect_request,
|
||||||
CefRefPtr<CefResponse> redirect_response) {
|
CefRefPtr<CefResponse> redirect_response) {
|
||||||
if (redirect_response->GetStatus() == 302) {
|
if (redirect_response->GetStatus() == 302) {
|
||||||
// Simulate wrong copying of POST-specific headers Content-Type and
|
// Simulate wrong copying of POST-specific headers Content-Type and
|
||||||
// Content-Length. A 302 redirect should end up in a GET request and
|
// Content-Length. A 302 redirect should end up in a GET request and
|
||||||
|
@ -1460,10 +1413,19 @@ class RequestServerHandler : public CefServerHandler {
|
||||||
SendResponse(server, connection_id, redirect_response, std::string());
|
SendResponse(server, connection_id, redirect_response, std::string());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendResponse(CefRefPtr<CefServer> server,
|
static void SendResponse(CefRefPtr<CefServer> server,
|
||||||
int connection_id,
|
int connection_id,
|
||||||
CefRefPtr<CefResponse> response,
|
CefRefPtr<CefResponse> response,
|
||||||
const std::string& response_data) {
|
const std::string& response_data) {
|
||||||
|
// Execute on the server thread because some methods require it.
|
||||||
|
CefRefPtr<CefTaskRunner> task_runner = server->GetTaskRunner();
|
||||||
|
if (!task_runner->BelongsToCurrentThread()) {
|
||||||
|
task_runner->PostTask(CefCreateClosureTask(
|
||||||
|
base::Bind(RequestServerHandler::SendResponse, server, connection_id,
|
||||||
|
response, response_data)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const int response_code = response->GetStatus();
|
const int response_code = response->GetStatus();
|
||||||
if (response_code <= 0) {
|
if (response_code <= 0) {
|
||||||
// Intentionally not responding for incomplete request tests.
|
// Intentionally not responding for incomplete request tests.
|
||||||
|
@ -1498,8 +1460,8 @@ class RequestServerHandler : public CefServerHandler {
|
||||||
EXPECT_UI_THREAD();
|
EXPECT_UI_THREAD();
|
||||||
|
|
||||||
if (startup) {
|
if (startup) {
|
||||||
// Transfer DataMap ownership to the server thread.
|
// Transfer DataMap ownership to the UI thread.
|
||||||
data_map_.SetOwnerTaskRunner(server_->GetTaskRunner());
|
data_map_.SetOwnerTaskRunner(CefTaskRunner::GetForCurrentThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_FALSE(complete_callback_.is_null());
|
EXPECT_FALSE(complete_callback_.is_null());
|
||||||
|
@ -1509,8 +1471,6 @@ class RequestServerHandler : public CefServerHandler {
|
||||||
|
|
||||||
RequestDataMap data_map_;
|
RequestDataMap data_map_;
|
||||||
|
|
||||||
CefRefPtr<CefServer> server_;
|
|
||||||
CefRefPtr<CefTaskRunner> server_runner_;
|
|
||||||
bool initialized_;
|
bool initialized_;
|
||||||
|
|
||||||
// Only accessed on the UI thread.
|
// Only accessed on the UI thread.
|
||||||
|
@ -1519,8 +1479,8 @@ class RequestServerHandler : public CefServerHandler {
|
||||||
// After initialization the below members are only accessed on the server
|
// After initialization the below members are only accessed on the server
|
||||||
// thread.
|
// thread.
|
||||||
|
|
||||||
TrackCallback got_server_created_;
|
TrackCallback got_initialized_;
|
||||||
TrackCallback got_server_destroyed_;
|
TrackCallback got_shutdown_;
|
||||||
|
|
||||||
typedef std::set<int> ConnectionIdSet;
|
typedef std::set<int> ConnectionIdSet;
|
||||||
ConnectionIdSet connection_id_set_;
|
ConnectionIdSet connection_id_set_;
|
||||||
|
@ -1531,106 +1491,6 @@ class RequestServerHandler : public CefServerHandler {
|
||||||
int actual_http_request_ct_;
|
int actual_http_request_ct_;
|
||||||
|
|
||||||
std::string request_log_;
|
std::string request_log_;
|
||||||
|
|
||||||
IMPLEMENT_REFCOUNTING(RequestServerHandler);
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(RequestServerHandler);
|
|
||||||
};
|
|
||||||
|
|
||||||
// URLREQUEST CLIENT
|
|
||||||
|
|
||||||
// Implementation of CefURLRequestClient that stores response information.
|
|
||||||
class RequestClient : public CefURLRequestClient {
|
|
||||||
public:
|
|
||||||
typedef base::Callback<void(CefRefPtr<RequestClient>)>
|
|
||||||
RequestCompleteCallback;
|
|
||||||
|
|
||||||
explicit RequestClient(const RequestCompleteCallback& complete_callback)
|
|
||||||
: complete_callback_(complete_callback) {
|
|
||||||
EXPECT_FALSE(complete_callback_.is_null());
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnRequestComplete(CefRefPtr<CefURLRequest> request) override {
|
|
||||||
request_complete_ct_++;
|
|
||||||
|
|
||||||
request_ = request->GetRequest();
|
|
||||||
EXPECT_TRUE(request_->IsReadOnly());
|
|
||||||
status_ = request->GetRequestStatus();
|
|
||||||
error_code_ = request->GetRequestError();
|
|
||||||
response_was_cached_ = request->ResponseWasCached();
|
|
||||||
response_ = request->GetResponse();
|
|
||||||
if (response_) {
|
|
||||||
EXPECT_TRUE(response_->IsReadOnly());
|
|
||||||
}
|
|
||||||
|
|
||||||
complete_callback_.Run(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnUploadProgress(CefRefPtr<CefURLRequest> request,
|
|
||||||
int64 current,
|
|
||||||
int64 total) override {
|
|
||||||
upload_progress_ct_++;
|
|
||||||
upload_total_ = total;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnDownloadProgress(CefRefPtr<CefURLRequest> request,
|
|
||||||
int64 current,
|
|
||||||
int64 total) override {
|
|
||||||
response_ = request->GetResponse();
|
|
||||||
EXPECT_TRUE(response_.get());
|
|
||||||
EXPECT_TRUE(response_->IsReadOnly());
|
|
||||||
download_progress_ct_++;
|
|
||||||
download_total_ = total;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnDownloadData(CefRefPtr<CefURLRequest> request,
|
|
||||||
const void* data,
|
|
||||||
size_t data_length) override {
|
|
||||||
response_ = request->GetResponse();
|
|
||||||
EXPECT_TRUE(response_.get());
|
|
||||||
EXPECT_TRUE(response_->IsReadOnly());
|
|
||||||
download_data_ct_++;
|
|
||||||
download_data_ += std::string(static_cast<const char*>(data), data_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetAuthCredentials(bool isProxy,
|
|
||||||
const CefString& host,
|
|
||||||
int port,
|
|
||||||
const CefString& realm,
|
|
||||||
const CefString& scheme,
|
|
||||||
CefRefPtr<CefAuthCallback> callback) override {
|
|
||||||
auth_credentials_ct_++;
|
|
||||||
if (has_authentication_) {
|
|
||||||
callback->Continue(username_, password_);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const RequestCompleteCallback complete_callback_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool has_authentication_ = false;
|
|
||||||
std::string username_;
|
|
||||||
std::string password_;
|
|
||||||
|
|
||||||
int request_complete_ct_ = 0;
|
|
||||||
int upload_progress_ct_ = 0;
|
|
||||||
int download_progress_ct_ = 0;
|
|
||||||
int download_data_ct_ = 0;
|
|
||||||
int auth_credentials_ct_ = 0;
|
|
||||||
|
|
||||||
int64 upload_total_ = 0;
|
|
||||||
int64 download_total_ = 0;
|
|
||||||
std::string download_data_;
|
|
||||||
CefRefPtr<CefRequest> request_;
|
|
||||||
CefURLRequest::Status status_ = UR_UNKNOWN;
|
|
||||||
CefURLRequest::ErrorCode error_code_ = ERR_NONE;
|
|
||||||
CefRefPtr<CefResponse> response_;
|
|
||||||
bool response_was_cached_ = false;
|
|
||||||
|
|
||||||
private:
|
|
||||||
IMPLEMENT_REFCOUNTING(RequestClient);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// SHARED TEST RUNNER
|
// SHARED TEST RUNNER
|
||||||
|
@ -2501,31 +2361,31 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send a request. |complete_callback| will be executed on request completion.
|
// Send a request. |complete_callback| will be executed on request completion.
|
||||||
void SendRequest(
|
void SendRequest(const test_request::RequestDoneCallback& done_callback) {
|
||||||
const RequestClient::RequestCompleteCallback& complete_callback) {
|
test_request::SendConfig config;
|
||||||
CefRefPtr<CefRequest> request;
|
|
||||||
if (settings_.redirect_request)
|
|
||||||
request = settings_.redirect_request;
|
|
||||||
else
|
|
||||||
request = settings_.request;
|
|
||||||
EXPECT_TRUE(request.get());
|
|
||||||
|
|
||||||
CefRefPtr<RequestClient> client = new RequestClient(complete_callback);
|
if (settings_.redirect_request)
|
||||||
|
config.request_ = settings_.redirect_request;
|
||||||
|
else
|
||||||
|
config.request_ = settings_.request;
|
||||||
|
EXPECT_TRUE(config.request_.get());
|
||||||
|
|
||||||
// Not delegating to CefRequestHandler::GetAuthCredentials.
|
// Not delegating to CefRequestHandler::GetAuthCredentials.
|
||||||
if (!use_frame_method_ && settings_.expect_authentication) {
|
if (!use_frame_method_ && settings_.expect_authentication) {
|
||||||
client->has_authentication_ = true;
|
config.has_credentials_ = true;
|
||||||
client->username_ = settings_.username;
|
config.username_ = settings_.username;
|
||||||
client->password_ = settings_.password;
|
config.password_ = settings_.password;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_frame_method_) {
|
if (use_frame_method_) {
|
||||||
EXPECT_TRUE(frame_);
|
EXPECT_TRUE(frame_);
|
||||||
frame_->CreateURLRequest(request, client.get());
|
config.frame_ = frame_;
|
||||||
} else {
|
} else {
|
||||||
CefURLRequest::Create(request, client.get(), request_context_);
|
config.request_context_ = request_context_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_request::Send(config, done_callback);
|
||||||
|
|
||||||
if (settings_.incomplete_type != RequestRunSettings::INCOMPLETE_NONE) {
|
if (settings_.incomplete_type != RequestRunSettings::INCOMPLETE_NONE) {
|
||||||
incomplete_request_callback_.Run();
|
incomplete_request_callback_.Run();
|
||||||
incomplete_request_callback_.Reset();
|
incomplete_request_callback_.Reset();
|
||||||
|
@ -2533,7 +2393,7 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify a response.
|
// Verify a response.
|
||||||
void VerifyResponse(CefRefPtr<RequestClient> client) {
|
void VerifyResponse(const test_request::State* const client) {
|
||||||
CefRefPtr<CefRequest> expected_request;
|
CefRefPtr<CefRequest> expected_request;
|
||||||
CefRefPtr<CefResponse> expected_response;
|
CefRefPtr<CefResponse> expected_response;
|
||||||
|
|
||||||
|
@ -2607,8 +2467,8 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleRunTestComplete(const base::Closure& complete_callback,
|
void SingleRunTestComplete(const base::Closure& complete_callback,
|
||||||
CefRefPtr<RequestClient> completed_client) {
|
const test_request::State& completed_client) {
|
||||||
VerifyResponse(completed_client);
|
VerifyResponse(&completed_client);
|
||||||
complete_callback.Run();
|
complete_callback.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2628,9 +2488,9 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
|
||||||
|
|
||||||
void MultipleRunTestNext(const base::Closure& complete_callback,
|
void MultipleRunTestNext(const base::Closure& complete_callback,
|
||||||
int send_count,
|
int send_count,
|
||||||
CefRefPtr<RequestClient> completed_client) {
|
const test_request::State& completed_client) {
|
||||||
// Verify the completed request.
|
// Verify the completed request.
|
||||||
VerifyResponse(completed_client);
|
VerifyResponse(&completed_client);
|
||||||
|
|
||||||
if (send_count == settings_.expected_send_count) {
|
if (send_count == settings_.expected_send_count) {
|
||||||
// All requests complete.
|
// All requests complete.
|
||||||
|
@ -2757,6 +2617,7 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
|
||||||
void ShutdownServer(const base::Closure& complete_callback) {
|
void ShutdownServer(const base::Closure& complete_callback) {
|
||||||
EXPECT_TRUE(server_handler_);
|
EXPECT_TRUE(server_handler_);
|
||||||
|
|
||||||
|
// |server_handler_| will delete itself after shutdown.
|
||||||
server_handler_->ShutdownServer(complete_callback);
|
server_handler_->ShutdownServer(complete_callback);
|
||||||
server_handler_ = nullptr;
|
server_handler_ = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -2797,7 +2658,7 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
|
||||||
TestMap test_map_;
|
TestMap test_map_;
|
||||||
|
|
||||||
// Server backend.
|
// Server backend.
|
||||||
CefRefPtr<RequestServerHandler> server_handler_;
|
RequestServerHandler* server_handler_ = nullptr;
|
||||||
|
|
||||||
// Scheme handler backend.
|
// Scheme handler backend.
|
||||||
std::string scheme_name_;
|
std::string scheme_name_;
|
||||||
|
|
Loading…
Reference in New Issue