This source file includes following definitions.
- current_request_id_
- OnSendMessageToWorker
- OnMessage
- OnRequest
- ReceiveResponse
- VerifyCalled
- ObserveStatusChanges
- SetUp
- TearDown
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "base/basictypes.h"
#include "base/run_loop.h"
#include "content/browser/service_worker/embedded_worker_registry.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#define IPC_MESSAGE_IMPL
#include "ipc/ipc_message_macros.h"
#define IPC_MESSAGE_START TestMsgStart
IPC_MESSAGE_CONTROL0(TestMsg_Message);
IPC_MESSAGE_CONTROL1(TestMsg_Request, int);
IPC_MESSAGE_CONTROL1(TestMsg_Response, int);
namespace content {
namespace {
static const int kRenderProcessId = 1;
class MessageReceiver : public EmbeddedWorkerTestHelper {
public:
MessageReceiver(ServiceWorkerContextCore* context)
: EmbeddedWorkerTestHelper(context, kRenderProcessId),
current_embedded_worker_id_(0),
current_request_id_(0) {}
virtual ~MessageReceiver() {}
virtual bool OnSendMessageToWorker(int thread_id,
int embedded_worker_id,
int request_id,
const IPC::Message& message) OVERRIDE {
if (EmbeddedWorkerTestHelper::OnSendMessageToWorker(
thread_id, embedded_worker_id, request_id, message)) {
return true;
}
current_embedded_worker_id_ = embedded_worker_id;
current_request_id_ = request_id;
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(MessageReceiver, message)
IPC_MESSAGE_HANDLER(TestMsg_Message, OnMessage)
IPC_MESSAGE_HANDLER(TestMsg_Request, OnRequest)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
private:
void OnMessage() {
}
void OnRequest(int value) {
SimulateSendMessageToBrowser(current_embedded_worker_id_,
current_request_id_,
TestMsg_Response(value * 2));
}
int current_embedded_worker_id_;
int current_request_id_;
DISALLOW_COPY_AND_ASSIGN(MessageReceiver);
};
void ReceiveResponse(ServiceWorkerStatusCode* status_out,
int* value_out,
ServiceWorkerStatusCode status,
const IPC::Message& message) {
Tuple1<int> param;
ASSERT_TRUE(TestMsg_Response::Read(&message, ¶m));
*status_out = status;
*value_out = param.a;
}
void VerifyCalled(bool* called) {
*called = true;
}
void ObserveStatusChanges(ServiceWorkerVersion* version,
std::vector<ServiceWorkerVersion::Status>* statuses) {
statuses->push_back(version->status());
version->RegisterStatusChangeCallback(
base::Bind(&ObserveStatusChanges, make_scoped_refptr(version), statuses));
}
}
class ServiceWorkerVersionTest : public testing::Test {
protected:
ServiceWorkerVersionTest()
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
virtual void SetUp() OVERRIDE {
context_.reset(new ServiceWorkerContextCore(base::FilePath(), NULL));
helper_.reset(new MessageReceiver(context_.get()));
registration_ = new ServiceWorkerRegistration(
GURL("http://www.example.com/*"),
GURL("http://www.example.com/service_worker.js"),
1L, context_->AsWeakPtr());
version_ = new ServiceWorkerVersion(
registration_,
1L, context_->AsWeakPtr());
int embedded_worker_id = version_->embedded_worker()->embedded_worker_id();
helper_->SimulateAddProcessToWorker(embedded_worker_id, kRenderProcessId);
}
virtual void TearDown() OVERRIDE {
version_->Shutdown();
version_ = 0;
registration_->Shutdown();
registration_ = 0;
helper_.reset();
context_.reset();
}
TestBrowserThreadBundle thread_bundle_;
scoped_ptr<ServiceWorkerContextCore> context_;
scoped_ptr<EmbeddedWorkerTestHelper> helper_;
scoped_refptr<ServiceWorkerRegistration> registration_;
scoped_refptr<ServiceWorkerVersion> version_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersionTest);
};
TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) {
ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED;
ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_FAILED;
ServiceWorkerStatusCode status3 = SERVICE_WORKER_ERROR_FAILED;
version_->StartWorker(CreateReceiverOnCurrentThread(&status1));
version_->StartWorker(CreateReceiverOnCurrentThread(&status2));
EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
version_->StartWorker(CreateReceiverOnCurrentThread(&status3));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status1);
EXPECT_EQ(SERVICE_WORKER_OK, status2);
EXPECT_EQ(SERVICE_WORKER_OK, status3);
status1 = SERVICE_WORKER_ERROR_FAILED;
status2 = SERVICE_WORKER_ERROR_FAILED;
status3 = SERVICE_WORKER_ERROR_FAILED;
version_->StopWorker(CreateReceiverOnCurrentThread(&status1));
version_->StopWorker(CreateReceiverOnCurrentThread(&status2));
version_->StartWorker(CreateReceiverOnCurrentThread(&status3));
EXPECT_EQ(ServiceWorkerVersion::STOPPING, version_->running_status());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
EXPECT_EQ(SERVICE_WORKER_OK, status1);
EXPECT_EQ(SERVICE_WORKER_OK, status2);
EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status3);
}
TEST_F(ServiceWorkerVersionTest, SendMessage) {
EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
version_->SendMessage(TestMsg_Message(),
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status);
EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
ServiceWorkerStatusCode msg_status = SERVICE_WORKER_ERROR_FAILED;
ServiceWorkerStatusCode stop_status = SERVICE_WORKER_ERROR_FAILED;
version_->StopWorker(CreateReceiverOnCurrentThread(&stop_status));
version_->SendMessage(TestMsg_Message(),
CreateReceiverOnCurrentThread(&msg_status));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, stop_status);
EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, msg_status);
}
TEST_F(ServiceWorkerVersionTest, ReSendMessageAfterStop) {
EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
ServiceWorkerStatusCode start_status = SERVICE_WORKER_ERROR_FAILED;
version_->StartWorker(CreateReceiverOnCurrentThread(&start_status));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, start_status);
EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
ServiceWorkerStatusCode msg_status = SERVICE_WORKER_ERROR_FAILED;
ServiceWorkerStatusCode stop_status = SERVICE_WORKER_ERROR_FAILED;
version_->StopWorker(CreateReceiverOnCurrentThread(&stop_status));
version_->SendMessage(TestMsg_Message(),
CreateReceiverOnCurrentThread(&msg_status));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, stop_status);
EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, msg_status);
version_->SendMessage(TestMsg_Message(),
CreateReceiverOnCurrentThread(&msg_status));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, msg_status);
EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
}
TEST_F(ServiceWorkerVersionTest, SendMessageAndRegisterCallback) {
ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED;
ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_FAILED;
int value1 = -1, value2 = -1;
version_->SendMessageAndRegisterCallback(
TestMsg_Request(111),
base::Bind(&ReceiveResponse, &status1, &value1));
version_->SendMessageAndRegisterCallback(
TestMsg_Request(333),
base::Bind(&ReceiveResponse, &status2, &value2));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status1);
EXPECT_EQ(SERVICE_WORKER_OK, status2);
EXPECT_EQ(111 * 2, value1);
EXPECT_EQ(333 * 2, value2);
}
TEST_F(ServiceWorkerVersionTest, InstallAndWaitCompletion) {
EXPECT_EQ(ServiceWorkerVersion::NEW, version_->status());
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
version_->DispatchInstallEvent(-1, CreateReceiverOnCurrentThread(&status));
EXPECT_EQ(ServiceWorkerVersion::INSTALLING, version_->status());
bool status_change_called = false;
version_->RegisterStatusChangeCallback(
base::Bind(&VerifyCalled, &status_change_called));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status);
EXPECT_TRUE(status_change_called);
EXPECT_EQ(ServiceWorkerVersion::INSTALLED, version_->status());
}
TEST_F(ServiceWorkerVersionTest, ActivateAndWaitCompletion) {
version_->SetStatus(ServiceWorkerVersion::INSTALLED);
EXPECT_EQ(ServiceWorkerVersion::INSTALLED, version_->status());
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
version_->DispatchActivateEvent(CreateReceiverOnCurrentThread(&status));
EXPECT_EQ(ServiceWorkerVersion::ACTIVATING, version_->status());
bool status_change_called = false;
version_->RegisterStatusChangeCallback(
base::Bind(&VerifyCalled, &status_change_called));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status);
EXPECT_TRUE(status_change_called);
EXPECT_EQ(ServiceWorkerVersion::ACTIVE, version_->status());
}
TEST_F(ServiceWorkerVersionTest, RepeatedlyObserveStatusChanges) {
EXPECT_EQ(ServiceWorkerVersion::NEW, version_->status());
std::vector<ServiceWorkerVersion::Status> statuses;
version_->RegisterStatusChangeCallback(
base::Bind(&ObserveStatusChanges, version_, &statuses));
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
version_->DispatchInstallEvent(-1, CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status);
status = SERVICE_WORKER_ERROR_FAILED;
version_->DispatchActivateEvent(CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status);
ASSERT_EQ(4U, statuses.size());
ASSERT_EQ(ServiceWorkerVersion::INSTALLING, statuses[0]);
ASSERT_EQ(ServiceWorkerVersion::INSTALLED, statuses[1]);
ASSERT_EQ(ServiceWorkerVersion::ACTIVATING, statuses[2]);
ASSERT_EQ(ServiceWorkerVersion::ACTIVE, statuses[3]);
}
}