| Index: content/browser/fileapi/fileapi_message_filter_unittest.cc
|
| diff --git a/content/browser/fileapi/fileapi_message_filter_unittest.cc b/content/browser/fileapi/fileapi_message_filter_unittest.cc
|
| index a290454a1dfb1f1e5233a414791b9f0386b4a91b..06b112ba64ddbfe2d23167638c941a4b7dc619f8 100644
|
| --- a/content/browser/fileapi/fileapi_message_filter_unittest.cc
|
| +++ b/content/browser/fileapi/fileapi_message_filter_unittest.cc
|
| @@ -8,9 +8,12 @@
|
| #include <vector>
|
|
|
| #include "base/memory/ref_counted.h"
|
| +#include "base/memory/shared_memory.h"
|
| #include "base/message_loop/message_loop.h"
|
| +#include "base/process/process.h"
|
| #include "content/browser/child_process_security_policy_impl.h"
|
| #include "content/browser/fileapi/chrome_blob_storage_context.h"
|
| +#include "content/browser/streams/stream_registry.h"
|
| #include "content/common/fileapi/file_system_messages.h"
|
| #include "content/common/fileapi/webblob_messages.h"
|
| #include "content/public/browser/browser_thread.h"
|
| @@ -18,6 +21,7 @@
|
| #include "content/public/test/mock_render_process_host.h"
|
| #include "content/public/test/test_browser_context.h"
|
| #include "content/public/test/test_browser_thread.h"
|
| +#include "net/base/io_buffer.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "webkit/browser/blob/blob_storage_controller.h"
|
| #include "webkit/browser/fileapi/file_system_context.h"
|
| @@ -26,6 +30,17 @@
|
|
|
| namespace content {
|
|
|
| +namespace {
|
| +
|
| +const char kFakeBlobInternalUrlSpec[] =
|
| + "blob:blobinternal%3A///dc83ede4-9bbd-453b-be2e-60fd623fcc93";
|
| +const char kFakeBlobInternalUrlSpec2[] =
|
| + "blob:blobinternal%3A///d28ae2e7-d233-4dda-9598-d135fe5d403e";
|
| +
|
| +const char kFakeContentType[] = "fake/type";
|
| +
|
| +} // namespace
|
| +
|
| class FileAPIMessageFilterTest : public testing::Test {
|
| public:
|
| FileAPIMessageFilterTest()
|
| @@ -45,6 +60,28 @@ class FileAPIMessageFilterTest : public testing::Test {
|
| types[i],
|
| fileapi::FileSystemContext::GetPermissionPolicy(types[i]));
|
| }
|
| +
|
| + stream_context_ = StreamContext::GetFor(&browser_context_);
|
| + blob_storage_context_ = ChromeBlobStorageContext::GetFor(&browser_context_);
|
| +
|
| + filter_ = new FileAPIMessageFilter(
|
| + 0 /* process_id */,
|
| + browser_context_.GetRequestContext(),
|
| + file_system_context_.get(),
|
| + blob_storage_context_,
|
| + stream_context_);
|
| +
|
| + // Complete initialization.
|
| + message_loop_.RunUntilIdle();
|
| + }
|
| +
|
| + // Tests via OnMessageReceived(const IPC::Message&). The channel proxy calls
|
| + // this method. Since OnMessageReceived is hidden on FileAPIMessageFilter,
|
| + // we need to cast it.
|
| + bool InvokeOnMessageReceived(const IPC::Message& message) {
|
| + IPC::ChannelProxy::MessageFilter* casted_filter =
|
| + static_cast<IPC::ChannelProxy::MessageFilter*>(filter_.get());
|
| + return casted_filter->OnMessageReceived(message);
|
| }
|
|
|
| base::MessageLoop message_loop_;
|
| @@ -52,48 +89,35 @@ class FileAPIMessageFilterTest : public testing::Test {
|
|
|
| TestBrowserContext browser_context_;
|
| scoped_refptr<fileapi::FileSystemContext> file_system_context_;
|
| + StreamContext* stream_context_;
|
| + ChromeBlobStorageContext* blob_storage_context_;
|
| +
|
| + scoped_refptr<FileAPIMessageFilter> filter_;
|
| };
|
|
|
| TEST_F(FileAPIMessageFilterTest, BuildEmptyBlob) {
|
| - scoped_refptr<FileAPIMessageFilter> filter(
|
| - new FileAPIMessageFilter(
|
| - 0 /* process_id */,
|
| - browser_context_.GetRequestContext(),
|
| - file_system_context_.get(),
|
| - ChromeBlobStorageContext::GetFor(&browser_context_)));
|
| -
|
| - // Complete initialization.
|
| - message_loop_.RunUntilIdle();
|
| -
|
| webkit_blob::BlobStorageController* controller =
|
| - ChromeBlobStorageContext::GetFor(&browser_context_)->controller();
|
| + blob_storage_context_->controller();
|
|
|
| const GURL kUrl("blob:foobar");
|
| const GURL kDifferentUrl("blob:barfoo");
|
| - const std::string kContentType = "fake/type";
|
|
|
| EXPECT_EQ(NULL, controller->GetBlobDataFromUrl(kUrl));
|
|
|
| - // Test via OnMessageReceived(const IPC::Message&) which is called by the
|
| - // channel proxy. Since OnMessageReceived is hidden on FileAPIMessageFilter,
|
| - // cast it.
|
| - IPC::ChannelProxy::MessageFilter* casted_filter =
|
| - static_cast<IPC::ChannelProxy::MessageFilter*>(filter.get());
|
| -
|
| - BlobHostMsg_StartBuildingBlob start_message(kUrl);
|
| - EXPECT_TRUE(casted_filter->OnMessageReceived(start_message));
|
| + BlobHostMsg_StartBuilding start_message(kUrl);
|
| + EXPECT_TRUE(InvokeOnMessageReceived(start_message));
|
|
|
| // Blob is still being built. Nothing should be returned.
|
| EXPECT_EQ(NULL, controller->GetBlobDataFromUrl(kUrl));
|
|
|
| - BlobHostMsg_FinishBuildingBlob finish_message(kUrl, kContentType);
|
| - EXPECT_TRUE(casted_filter->OnMessageReceived(finish_message));
|
| + BlobHostMsg_FinishBuilding finish_message(kUrl, kFakeContentType);
|
| + EXPECT_TRUE(InvokeOnMessageReceived(finish_message));
|
|
|
| // Now, Blob is built.
|
| webkit_blob::BlobData* blob_data = controller->GetBlobDataFromUrl(kUrl);
|
| ASSERT_FALSE(blob_data == NULL);
|
| EXPECT_EQ(0U, blob_data->items().size());
|
| - EXPECT_EQ(kContentType, blob_data->content_type());
|
| + EXPECT_EQ(kFakeContentType, blob_data->content_type());
|
|
|
| // Nothing should be returned for a URL we didn't use.
|
| EXPECT_TRUE(controller->GetBlobDataFromUrl(kDifferentUrl) == NULL);
|
| @@ -105,7 +129,8 @@ TEST_F(FileAPIMessageFilterTest, CloseChannelWithInflightRequest) {
|
| 0 /* process_id */,
|
| browser_context_.GetRequestContext(),
|
| file_system_context_.get(),
|
| - ChromeBlobStorageContext::GetFor(&browser_context_)));
|
| + ChromeBlobStorageContext::GetFor(&browser_context_),
|
| + StreamContext::GetFor(&browser_context_)));
|
| filter->OnChannelConnected(0);
|
|
|
| // Complete initialization.
|
| @@ -132,13 +157,15 @@ TEST_F(FileAPIMessageFilterTest, MultipleFilters) {
|
| 0 /* process_id */,
|
| browser_context_.GetRequestContext(),
|
| file_system_context_.get(),
|
| - ChromeBlobStorageContext::GetFor(&browser_context_)));
|
| + ChromeBlobStorageContext::GetFor(&browser_context_),
|
| + StreamContext::GetFor(&browser_context_)));
|
| scoped_refptr<FileAPIMessageFilter> filter2(
|
| new FileAPIMessageFilter(
|
| 1 /* process_id */,
|
| browser_context_.GetRequestContext(),
|
| file_system_context_.get(),
|
| - ChromeBlobStorageContext::GetFor(&browser_context_)));
|
| + ChromeBlobStorageContext::GetFor(&browser_context_),
|
| + StreamContext::GetFor(&browser_context_)));
|
| filter1->OnChannelConnected(0);
|
| filter2->OnChannelConnected(1);
|
|
|
| @@ -160,4 +187,171 @@ TEST_F(FileAPIMessageFilterTest, MultipleFilters) {
|
| message_loop_.RunUntilIdle();
|
| }
|
|
|
| -} // namespace fileapi
|
| +TEST_F(FileAPIMessageFilterTest, BuildEmptyStream) {
|
| + StreamRegistry* stream_registry = stream_context_->registry();
|
| +
|
| + webkit_blob::BlobStorageController* blob_controller =
|
| + blob_storage_context_->controller();
|
| +
|
| + const GURL kUrl(kFakeBlobInternalUrlSpec);
|
| + const GURL kDifferentUrl("blob:barfoo");
|
| +
|
| + EXPECT_EQ(NULL, stream_registry->GetStream(kUrl).get());
|
| + EXPECT_EQ(NULL, blob_controller->GetBlobDataFromUrl(kUrl));
|
| +
|
| + StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType);
|
| + EXPECT_TRUE(InvokeOnMessageReceived(start_message));
|
| +
|
| + const int kBufferSize = 10;
|
| + scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
|
| + int bytes_read = 0;
|
| +
|
| + scoped_refptr<Stream> stream = stream_registry->GetStream(kUrl);
|
| + // Stream becomes available for read right after registration.
|
| + ASSERT_FALSE(stream.get() == NULL);
|
| + EXPECT_EQ(Stream::STREAM_EMPTY,
|
| + stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read));
|
| + EXPECT_EQ(0, bytes_read);
|
| + stream = NULL;
|
| +
|
| + StreamHostMsg_FinishBuilding finish_message(kUrl);
|
| + EXPECT_TRUE(InvokeOnMessageReceived(finish_message));
|
| +
|
| + // Blob controller shouldn't be affected.
|
| + EXPECT_EQ(NULL, blob_controller->GetBlobDataFromUrl(kUrl));
|
| +
|
| + stream = stream_registry->GetStream(kUrl);
|
| + ASSERT_FALSE(stream.get() == NULL);
|
| + EXPECT_EQ(Stream::STREAM_EMPTY,
|
| + stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read));
|
| + EXPECT_EQ(0, bytes_read);
|
| +
|
| + // Run loop to finish transfer.
|
| + message_loop_.RunUntilIdle();
|
| +
|
| + EXPECT_EQ(Stream::STREAM_COMPLETE,
|
| + stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read));
|
| + EXPECT_EQ(0, bytes_read);
|
| +
|
| + // Nothing should be returned for a URL we didn't use.
|
| + EXPECT_TRUE(stream_registry->GetStream(kDifferentUrl).get() == NULL);
|
| +}
|
| +
|
| +TEST_F(FileAPIMessageFilterTest, BuildNonEmptyStream) {
|
| + StreamRegistry* stream_registry = stream_context_->registry();
|
| +
|
| + const GURL kUrl(kFakeBlobInternalUrlSpec);
|
| +
|
| + EXPECT_EQ(NULL, stream_registry->GetStream(kUrl).get());
|
| +
|
| + StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType);
|
| + EXPECT_TRUE(InvokeOnMessageReceived(start_message));
|
| +
|
| + webkit_blob::BlobData::Item item;
|
| + const std::string kFakeData = "foobarbaz";
|
| + item.SetToBytes(kFakeData.data(), kFakeData.size());
|
| + StreamHostMsg_AppendBlobDataItem append_message(kUrl, item);
|
| + EXPECT_TRUE(InvokeOnMessageReceived(append_message));
|
| +
|
| + StreamHostMsg_FinishBuilding finish_message(kUrl);
|
| + EXPECT_TRUE(InvokeOnMessageReceived(finish_message));
|
| +
|
| + // Run loop to finish transfer and commit finalize command.
|
| + message_loop_.RunUntilIdle();
|
| +
|
| + scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kFakeData.size()));
|
| + int bytes_read = 0;
|
| +
|
| + scoped_refptr<Stream> stream = stream_registry->GetStream(kUrl);
|
| + ASSERT_FALSE(stream.get() == NULL);
|
| +
|
| + EXPECT_EQ(Stream::STREAM_HAS_DATA,
|
| + stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read));
|
| + EXPECT_EQ(kFakeData.size(), static_cast<size_t>(bytes_read));
|
| + EXPECT_EQ(kFakeData, std::string(buffer->data(), bytes_read));
|
| +
|
| + EXPECT_EQ(Stream::STREAM_COMPLETE,
|
| + stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read));
|
| + EXPECT_EQ(0, bytes_read);
|
| +}
|
| +
|
| +TEST_F(FileAPIMessageFilterTest, BuildStreamWithSharedMemory) {
|
| + StreamRegistry* stream_registry = stream_context_->registry();
|
| +
|
| + const GURL kUrl(kFakeBlobInternalUrlSpec);
|
| +
|
| + EXPECT_EQ(NULL, stream_registry->GetStream(kUrl).get());
|
| +
|
| + // For win, we need to set valid PID to the filter.
|
| + // OnAppendSharedMemoryToStream passes the peer process's handle to
|
| + // SharedMemory's constructor. If it's incorrect, DuplicateHandle won't work
|
| + // correctly.
|
| + static_cast<IPC::ChannelProxy::MessageFilter*>(
|
| + filter_.get())->OnChannelConnected(base::Process::Current().pid());
|
| +
|
| + StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType);
|
| + EXPECT_TRUE(InvokeOnMessageReceived(start_message));
|
| +
|
| + const std::string kFakeData = "foobarbaz";
|
| +
|
| + scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
|
| + ASSERT_TRUE(shared_memory->CreateAndMapAnonymous(kFakeData.size()));
|
| + memcpy(shared_memory->memory(), kFakeData.data(), kFakeData.size());
|
| + StreamHostMsg_SyncAppendSharedMemory append_message(
|
| + kUrl, shared_memory->handle(), kFakeData.size());
|
| + EXPECT_TRUE(InvokeOnMessageReceived(append_message));
|
| +
|
| + StreamHostMsg_FinishBuilding finish_message(kUrl);
|
| + EXPECT_TRUE(InvokeOnMessageReceived(finish_message));
|
| +
|
| + // Run loop to finish transfer and commit finalize command.
|
| + message_loop_.RunUntilIdle();
|
| +
|
| + scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kFakeData.size()));
|
| + int bytes_read = 0;
|
| +
|
| + scoped_refptr<Stream> stream = stream_registry->GetStream(kUrl);
|
| + ASSERT_FALSE(stream.get() == NULL);
|
| +
|
| + EXPECT_EQ(Stream::STREAM_HAS_DATA,
|
| + stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read));
|
| + EXPECT_EQ(kFakeData.size(), static_cast<size_t>(bytes_read));
|
| + EXPECT_EQ(kFakeData, std::string(buffer->data(), bytes_read));
|
| +
|
| + EXPECT_EQ(Stream::STREAM_COMPLETE,
|
| + stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read));
|
| + EXPECT_EQ(0, bytes_read);
|
| +}
|
| +
|
| +TEST_F(FileAPIMessageFilterTest, BuildStreamAndCallOnChannelClosing) {
|
| + StreamRegistry* stream_registry = stream_context_->registry();
|
| +
|
| + const GURL kUrl(kFakeBlobInternalUrlSpec);
|
| +
|
| + StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType);
|
| + EXPECT_TRUE(InvokeOnMessageReceived(start_message));
|
| +
|
| + ASSERT_FALSE(stream_registry->GetStream(kUrl).get() == NULL);
|
| +
|
| + filter_->OnChannelClosing();
|
| +
|
| + ASSERT_EQ(NULL, stream_registry->GetStream(kUrl).get());
|
| +}
|
| +
|
| +TEST_F(FileAPIMessageFilterTest, CloneStream) {
|
| + StreamRegistry* stream_registry = stream_context_->registry();
|
| +
|
| + const GURL kUrl(kFakeBlobInternalUrlSpec);
|
| + const GURL kDestUrl(kFakeBlobInternalUrlSpec2);
|
| +
|
| + StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType);
|
| + EXPECT_TRUE(InvokeOnMessageReceived(start_message));
|
| +
|
| + StreamHostMsg_Clone clone_message(kDestUrl, kUrl);
|
| + EXPECT_TRUE(InvokeOnMessageReceived(clone_message));
|
| +
|
| + ASSERT_FALSE(stream_registry->GetStream(kUrl).get() == NULL);
|
| + ASSERT_FALSE(stream_registry->GetStream(kDestUrl).get() == NULL);
|
| +}
|
| +
|
| +} // namespace content
|
|
|