OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/fileapi/fileapi_message_filter.h" | 5 #include "content/browser/fileapi/fileapi_message_filter.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
11 #include "base/memory/shared_memory.h" | |
11 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
12 #include "content/browser/fileapi/chrome_blob_storage_context.h" | 13 #include "content/browser/fileapi/chrome_blob_storage_context.h" |
14 #include "content/browser/streams/stream_registry.h" | |
13 #include "content/common/fileapi/webblob_messages.h" | 15 #include "content/common/fileapi/webblob_messages.h" |
14 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
15 #include "content/public/common/common_param_traits.h" | 17 #include "content/public/common/common_param_traits.h" |
16 #include "content/public/test/mock_render_process_host.h" | 18 #include "content/public/test/mock_render_process_host.h" |
17 #include "content/public/test/test_browser_context.h" | 19 #include "content/public/test/test_browser_context.h" |
18 #include "content/public/test/test_browser_thread.h" | 20 #include "content/public/test/test_browser_thread.h" |
21 #include "net/base/io_buffer.h" | |
19 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
20 #include "webkit/browser/blob/blob_storage_controller.h" | 23 #include "webkit/browser/blob/blob_storage_controller.h" |
21 #include "webkit/browser/fileapi/file_system_context.h" | 24 #include "webkit/browser/fileapi/file_system_context.h" |
22 #include "webkit/browser/fileapi/mock_file_system_context.h" | 25 #include "webkit/browser/fileapi/mock_file_system_context.h" |
23 #include "webkit/common/blob/blob_data.h" | 26 #include "webkit/common/blob/blob_data.h" |
24 | 27 |
25 namespace content { | 28 namespace content { |
26 | 29 |
30 namespace { | |
31 | |
32 const char kFakeBlobInternalUrlSpec[] = | |
33 "blob:blobinternal%3A///dc83ede4-9bbd-453b-be2e-60fd623fcc93"; | |
34 const char kFakeBlobInternalUrlSpec2[] = | |
35 "blob:blobinternal%3A///d28ae2e7-d233-4dda-9598-d135fe5d403e"; | |
36 | |
37 const char kFakeContentType[] = "fake/type"; | |
38 | |
39 } // namespace | |
40 | |
27 class FileAPIMessageFilterTest : public testing::Test { | 41 class FileAPIMessageFilterTest : public testing::Test { |
28 public: | 42 public: |
29 FileAPIMessageFilterTest() | 43 FileAPIMessageFilterTest() |
30 : io_browser_thread_(BrowserThread::IO, &message_loop_) { | 44 : io_browser_thread_(BrowserThread::IO, &message_loop_) { |
31 } | 45 } |
32 | 46 |
33 protected: | 47 protected: |
34 virtual void SetUp() OVERRIDE { | 48 virtual void SetUp() OVERRIDE { |
35 file_system_context_ = | 49 file_system_context_ = |
36 fileapi::CreateFileSystemContextForTesting(NULL, base::FilePath()); | 50 fileapi::CreateFileSystemContextForTesting(NULL, base::FilePath()); |
51 stream_context_ = StreamContext::GetFor(&browser_context_); | |
52 blob_storage_context_ = ChromeBlobStorageContext::GetFor(&browser_context_); | |
53 | |
54 filter_ = new FileAPIMessageFilter( | |
55 0 /* process_id */, | |
56 browser_context_.GetRequestContext(), | |
57 file_system_context_.get(), | |
58 blob_storage_context_, | |
59 stream_context_); | |
60 | |
61 // Complete initialization. | |
62 message_loop_.RunUntilIdle(); | |
63 } | |
64 | |
65 // To test via OnMessageReceived(const IPC::Message&) which is called by the | |
66 // channel proxy. Since OnMessageReceived is hidden on FileAPIMessageFilter, | |
67 // cast it. | |
68 IPC::ChannelProxy::MessageFilter* GetUpcastedFilter() { | |
69 return static_cast<IPC::ChannelProxy::MessageFilter*>(filter_.get()); | |
kinuko
2013/07/23 13:57:23
nit: since we almost always call OnMessageReceived
tyoshino (SeeGerritForStatus)
2013/07/24 12:14:20
Done.
| |
37 } | 70 } |
38 | 71 |
39 base::MessageLoop message_loop_; | 72 base::MessageLoop message_loop_; |
40 TestBrowserThread io_browser_thread_; | 73 TestBrowserThread io_browser_thread_; |
41 | 74 |
42 TestBrowserContext browser_context_; | 75 TestBrowserContext browser_context_; |
43 scoped_refptr<fileapi::FileSystemContext> file_system_context_; | 76 scoped_refptr<fileapi::FileSystemContext> file_system_context_; |
77 StreamContext* stream_context_; | |
78 ChromeBlobStorageContext* blob_storage_context_; | |
79 | |
80 scoped_refptr<FileAPIMessageFilter> filter_; | |
44 }; | 81 }; |
45 | 82 |
46 TEST_F(FileAPIMessageFilterTest, BuildEmptyBlob) { | 83 TEST_F(FileAPIMessageFilterTest, BuildEmptyBlob) { |
47 scoped_refptr<FileAPIMessageFilter> filter( | |
48 new FileAPIMessageFilter( | |
49 0 /* process_id */, | |
50 browser_context_.GetRequestContext(), | |
51 file_system_context_.get(), | |
52 ChromeBlobStorageContext::GetFor(&browser_context_))); | |
53 | |
54 // Complete initialization. | |
55 message_loop_.RunUntilIdle(); | |
56 | |
57 webkit_blob::BlobStorageController* controller = | 84 webkit_blob::BlobStorageController* controller = |
58 ChromeBlobStorageContext::GetFor(&browser_context_)->controller(); | 85 blob_storage_context_->controller(); |
59 | 86 |
60 const GURL kUrl("blob:foobar"); | 87 const GURL kUrl("blob:foobar"); |
61 const GURL kDifferentUrl("blob:barfoo"); | 88 const GURL kDifferentUrl("blob:barfoo"); |
62 const std::string kContentType = "fake/type"; | |
63 | 89 |
64 EXPECT_EQ(NULL, controller->GetBlobDataFromUrl(kUrl)); | 90 EXPECT_EQ(NULL, controller->GetBlobDataFromUrl(kUrl)); |
65 | 91 |
66 // Test via OnMessageReceived(const IPC::Message&) which is called by the | |
67 // channel proxy. Since OnMessageReceived is hidden on FileAPIMessageFilter, | |
68 // cast it. | |
69 IPC::ChannelProxy::MessageFilter* casted_filter = | |
70 static_cast<IPC::ChannelProxy::MessageFilter*>(filter.get()); | |
71 | |
72 BlobHostMsg_StartBuildingBlob start_message(kUrl); | 92 BlobHostMsg_StartBuildingBlob start_message(kUrl); |
73 EXPECT_TRUE(casted_filter->OnMessageReceived(start_message)); | 93 EXPECT_TRUE(GetUpcastedFilter()->OnMessageReceived(start_message)); |
74 | 94 |
75 // Blob is still being built. Nothing should be returned. | 95 // Blob is still being built. Nothing should be returned. |
76 EXPECT_EQ(NULL, controller->GetBlobDataFromUrl(kUrl)); | 96 EXPECT_EQ(NULL, controller->GetBlobDataFromUrl(kUrl)); |
77 | 97 |
78 BlobHostMsg_FinishBuildingBlob finish_message(kUrl, kContentType); | 98 BlobHostMsg_FinishBuildingBlob finish_message(kUrl, kFakeContentType); |
79 EXPECT_TRUE(casted_filter->OnMessageReceived(finish_message)); | 99 EXPECT_TRUE(GetUpcastedFilter()->OnMessageReceived(finish_message)); |
80 | 100 |
81 // Now, Blob is built. | 101 // Now, Blob is built. |
82 webkit_blob::BlobData* blob_data = controller->GetBlobDataFromUrl(kUrl); | 102 webkit_blob::BlobData* blob_data = controller->GetBlobDataFromUrl(kUrl); |
83 ASSERT_FALSE(blob_data == NULL); | 103 ASSERT_FALSE(blob_data == NULL); |
84 EXPECT_EQ(0U, blob_data->items().size()); | 104 EXPECT_EQ(0U, blob_data->items().size()); |
85 EXPECT_EQ(kContentType, blob_data->content_type()); | 105 EXPECT_EQ(kFakeContentType, blob_data->content_type()); |
86 | 106 |
87 // Nothing should be returned for a URL we didn't use. | 107 // Nothing should be returned for a URL we didn't use. |
88 EXPECT_TRUE(controller->GetBlobDataFromUrl(kDifferentUrl) == NULL); | 108 EXPECT_TRUE(controller->GetBlobDataFromUrl(kDifferentUrl) == NULL); |
89 } | 109 } |
90 | 110 |
111 TEST_F(FileAPIMessageFilterTest, BuildEmptyStream) { | |
112 StreamRegistry* stream_registry = stream_context_->registry(); | |
113 | |
114 webkit_blob::BlobStorageController* blob_controller = | |
115 blob_storage_context_->controller(); | |
116 | |
117 const GURL kUrl(kFakeBlobInternalUrlSpec); | |
118 const GURL kDifferentUrl("blob:barfoo"); | |
119 | |
120 EXPECT_EQ(NULL, stream_registry->GetStream(kUrl).get()); | |
121 EXPECT_EQ(NULL, blob_controller->GetBlobDataFromUrl(kUrl)); | |
122 | |
123 BlobHostMsg_StartBuildingStream start_message(kUrl, kFakeContentType); | |
124 EXPECT_TRUE(GetUpcastedFilter()->OnMessageReceived(start_message)); | |
125 | |
126 const int kBufferSize = 10; | |
127 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize)); | |
128 int bytes_read = 0; | |
129 | |
130 scoped_refptr<Stream> stream = stream_registry->GetStream(kUrl); | |
131 // Stream becomes available for read right after registration. | |
132 ASSERT_FALSE(stream.get() == NULL); | |
133 EXPECT_EQ(Stream::STREAM_EMPTY, | |
134 stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read)); | |
135 EXPECT_EQ(0, bytes_read); | |
136 stream = NULL; | |
137 | |
138 BlobHostMsg_FinishBuildingStream finish_message(kUrl); | |
139 EXPECT_TRUE(GetUpcastedFilter()->OnMessageReceived(finish_message)); | |
140 | |
141 // Blob controller shouldn't be affected. | |
142 EXPECT_EQ(NULL, blob_controller->GetBlobDataFromUrl(kUrl)); | |
143 | |
144 stream = stream_registry->GetStream(kUrl); | |
145 ASSERT_FALSE(stream.get() == NULL); | |
146 EXPECT_EQ(Stream::STREAM_EMPTY, | |
147 stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read)); | |
148 EXPECT_EQ(0, bytes_read); | |
149 | |
150 // Run loop to finish transfer. | |
151 message_loop_.RunUntilIdle(); | |
152 | |
153 EXPECT_EQ(Stream::STREAM_COMPLETE, | |
154 stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read)); | |
155 EXPECT_EQ(0, bytes_read); | |
156 | |
157 // Nothing should be returned for a URL we didn't use. | |
158 EXPECT_TRUE(stream_registry->GetStream(kDifferentUrl).get() == NULL); | |
159 } | |
160 | |
161 TEST_F(FileAPIMessageFilterTest, BuildNonEmptyStream) { | |
162 StreamRegistry* stream_registry = stream_context_->registry(); | |
163 | |
164 const GURL kUrl(kFakeBlobInternalUrlSpec); | |
165 | |
166 EXPECT_EQ(NULL, stream_registry->GetStream(kUrl).get()); | |
167 | |
168 BlobHostMsg_StartBuildingStream start_message(kUrl, kFakeContentType); | |
169 EXPECT_TRUE(GetUpcastedFilter()->OnMessageReceived(start_message)); | |
170 | |
171 webkit_blob::BlobData::Item item; | |
172 const std::string kFakeData = "foobarbaz"; | |
173 item.SetToBytes(kFakeData.data(), kFakeData.size()); | |
174 BlobHostMsg_AppendBlobDataItemToBlobOrStream append_message(kUrl, item); | |
175 EXPECT_TRUE(GetUpcastedFilter()->OnMessageReceived(append_message)); | |
176 | |
177 BlobHostMsg_FinishBuildingStream finish_message(kUrl); | |
178 EXPECT_TRUE(GetUpcastedFilter()->OnMessageReceived(finish_message)); | |
179 | |
180 // Run loop to finish transfer and commit finalize command. | |
181 message_loop_.RunUntilIdle(); | |
182 | |
183 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kFakeData.size())); | |
184 int bytes_read = 0; | |
185 | |
186 scoped_refptr<Stream> stream = stream_registry->GetStream(kUrl); | |
187 ASSERT_FALSE(stream.get() == NULL); | |
188 | |
189 EXPECT_EQ(Stream::STREAM_HAS_DATA, | |
190 stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read)); | |
191 EXPECT_EQ(kFakeData.size(), static_cast<size_t>(bytes_read)); | |
192 EXPECT_EQ(kFakeData, std::string(buffer->data(), bytes_read)); | |
193 | |
194 EXPECT_EQ(Stream::STREAM_COMPLETE, | |
195 stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read)); | |
196 EXPECT_EQ(0, bytes_read); | |
197 } | |
198 | |
199 TEST_F(FileAPIMessageFilterTest, BuildStreamWithSharedMemory) { | |
200 StreamRegistry* stream_registry = stream_context_->registry(); | |
201 | |
202 const GURL kUrl(kFakeBlobInternalUrlSpec); | |
203 | |
204 EXPECT_EQ(NULL, stream_registry->GetStream(kUrl).get()); | |
205 | |
206 BlobHostMsg_StartBuildingStream start_message(kUrl, kFakeContentType); | |
207 EXPECT_TRUE(GetUpcastedFilter()->OnMessageReceived(start_message)); | |
208 | |
209 const std::string kFakeData = "foobarbaz"; | |
210 | |
211 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory); | |
212 ASSERT_TRUE(shared_memory->CreateAndMapAnonymous(kFakeData.size())); | |
213 memcpy(shared_memory->memory(), kFakeData.data(), kFakeData.size()); | |
214 BlobHostMsg_SyncAppendSharedMemoryToBlobOrStream append_message( | |
215 kUrl, shared_memory->handle(), kFakeData.size()); | |
216 EXPECT_TRUE(GetUpcastedFilter()->OnMessageReceived(append_message)); | |
217 | |
218 BlobHostMsg_FinishBuildingStream finish_message(kUrl); | |
219 EXPECT_TRUE(GetUpcastedFilter()->OnMessageReceived(finish_message)); | |
220 | |
221 // Run loop to finish transfer and commit finalize command. | |
222 message_loop_.RunUntilIdle(); | |
223 | |
224 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kFakeData.size())); | |
225 int bytes_read = 0; | |
226 | |
227 scoped_refptr<Stream> stream = stream_registry->GetStream(kUrl); | |
228 ASSERT_FALSE(stream.get() == NULL); | |
229 | |
230 EXPECT_EQ(Stream::STREAM_HAS_DATA, | |
231 stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read)); | |
232 EXPECT_EQ(kFakeData.size(), static_cast<size_t>(bytes_read)); | |
233 EXPECT_EQ(kFakeData, std::string(buffer->data(), bytes_read)); | |
234 | |
235 EXPECT_EQ(Stream::STREAM_COMPLETE, | |
236 stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read)); | |
237 EXPECT_EQ(0, bytes_read); | |
238 } | |
239 | |
240 TEST_F(FileAPIMessageFilterTest, BuildStreamAndCallOnChannelClosing) { | |
241 StreamRegistry* stream_registry = stream_context_->registry(); | |
242 | |
243 const GURL kUrl(kFakeBlobInternalUrlSpec); | |
244 | |
245 BlobHostMsg_StartBuildingStream start_message(kUrl, kFakeContentType); | |
246 EXPECT_TRUE(GetUpcastedFilter()->OnMessageReceived(start_message)); | |
247 | |
248 ASSERT_FALSE(stream_registry->GetStream(kUrl).get() == NULL); | |
249 | |
250 filter_->OnChannelClosing(); | |
251 | |
252 ASSERT_EQ(NULL, stream_registry->GetStream(kUrl).get()); | |
253 } | |
254 | |
255 TEST_F(FileAPIMessageFilterTest, CloneStream) { | |
256 StreamRegistry* stream_registry = stream_context_->registry(); | |
257 | |
258 const GURL kUrl(kFakeBlobInternalUrlSpec); | |
259 const GURL kDestUrl(kFakeBlobInternalUrlSpec2); | |
260 | |
261 BlobHostMsg_StartBuildingStream start_message(kUrl, kFakeContentType); | |
262 EXPECT_TRUE(GetUpcastedFilter()->OnMessageReceived(start_message)); | |
263 | |
264 BlobHostMsg_CloneBlobOrStream clone_message(kDestUrl, kUrl); | |
265 EXPECT_TRUE(GetUpcastedFilter()->OnMessageReceived(clone_message)); | |
266 | |
267 ASSERT_FALSE(stream_registry->GetStream(kUrl).get() == NULL); | |
268 ASSERT_FALSE(stream_registry->GetStream(kDestUrl).get() == NULL); | |
269 } | |
270 | |
91 } // namespace fileapi | 271 } // namespace fileapi |
OLD | NEW |