OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/child/blob_storage/blob_transport_controller.h" | 5 #include "content/child/blob_storage/blob_transport_controller.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include "base/memory/ptr_util.h" | 10 #include "base/bind.h" |
11 #include "base/bind_helpers.h" | |
12 #include "base/files/file.h" | |
13 #include "base/files/file_path.h" | |
14 #include "base/files/file_util.h" | |
11 #include "base/memory/shared_memory.h" | 15 #include "base/memory/shared_memory.h" |
16 #include "base/message_loop/message_loop.h" | |
17 #include "base/process/process_handle.h" | |
18 #include "base/test/test_file_util.h" | |
12 #include "base/test/test_simple_task_runner.h" | 19 #include "base/test/test_simple_task_runner.h" |
20 #include "base/thread_task_runner_handle.h" | |
13 #include "base/tuple.h" | 21 #include "base/tuple.h" |
14 #include "content/child/blob_storage/blob_consolidation.h" | 22 #include "content/child/blob_storage/blob_consolidation.h" |
15 #include "content/child/thread_safe_sender.h" | 23 #include "content/child/thread_safe_sender.h" |
16 #include "content/common/fileapi/webblob_messages.h" | 24 #include "content/common/fileapi/webblob_messages.h" |
25 #include "ipc/ipc_message.h" | |
26 #include "ipc/ipc_platform_file.h" | |
17 #include "ipc/ipc_sender.h" | 27 #include "ipc/ipc_sender.h" |
18 #include "ipc/ipc_sync_message_filter.h" | 28 #include "ipc/ipc_sync_message_filter.h" |
19 #include "ipc/ipc_test_sink.h" | 29 #include "ipc/ipc_test_sink.h" |
20 #include "storage/common/blob_storage/blob_item_bytes_request.h" | 30 #include "storage/common/blob_storage/blob_item_bytes_request.h" |
21 #include "storage/common/blob_storage/blob_item_bytes_response.h" | 31 #include "storage/common/blob_storage/blob_item_bytes_response.h" |
22 #include "testing/gmock/include/gmock/gmock.h" | 32 #include "testing/gmock/include/gmock/gmock.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 33 #include "testing/gtest/include/gtest/gtest.h" |
24 | 34 |
35 using base::File; | |
36 using base::FilePath; | |
37 using base::TestSimpleTaskRunner; | |
25 using storage::BlobItemBytesRequest; | 38 using storage::BlobItemBytesRequest; |
26 using storage::BlobItemBytesResponse; | 39 using storage::BlobItemBytesResponse; |
27 using storage::DataElement; | 40 using storage::DataElement; |
41 using storage::IPCBlobCreationCancelCode; | |
28 | 42 |
29 namespace content { | 43 namespace content { |
30 namespace { | 44 namespace { |
31 | 45 |
32 class OtherThreadTestSimpleTaskRunner : public base::TestSimpleTaskRunner { | 46 class OtherThreadTestSimpleTaskRunner : public base::TestSimpleTaskRunner { |
33 public: | 47 public: |
34 bool RunsTasksOnCurrentThread() const override { return false; } | 48 bool RunsTasksOnCurrentThread() const override { return false; } |
35 | 49 |
36 protected: | 50 protected: |
37 ~OtherThreadTestSimpleTaskRunner() override {} | 51 ~OtherThreadTestSimpleTaskRunner() override {} |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 } | 94 } |
81 | 95 |
82 static blink::WebThreadSafeData CreateData(const std::string& str) { | 96 static blink::WebThreadSafeData CreateData(const std::string& str) { |
83 return blink::WebThreadSafeData(str.c_str(), str.size()); | 97 return blink::WebThreadSafeData(str.c_str(), str.size()); |
84 } | 98 } |
85 | 99 |
86 } // namespace | 100 } // namespace |
87 | 101 |
88 class BlobTransportControllerTest : public testing::Test { | 102 class BlobTransportControllerTest : public testing::Test { |
89 public: | 103 public: |
90 BlobTransportControllerTest() | 104 BlobTransportControllerTest() : thread_runner_handle_(io_thread_runner_) {} |
91 : io_thread_runner_(new base::TestSimpleTaskRunner()), | |
92 main_thread_runner_(new OtherThreadTestSimpleTaskRunner()) {} | |
93 | 105 |
94 void SetUp() override { | 106 void SetUp() override { |
95 sender_ = new BlobTransportControllerTestSender(&sink_); | 107 sender_ = new BlobTransportControllerTestSender(&sink_); |
96 BlobTransportController::GetInstance()->ClearForTesting(); | 108 BlobTransportController::GetInstance()->CancelAllBlobTransfers(); |
109 } | |
110 | |
111 void OnMemoryRequest( | |
112 BlobTransportController* holder, | |
113 const std::string uuid, | |
114 const std::vector<storage::BlobItemBytesRequest>& requests, | |
115 std::vector<base::SharedMemoryHandle>* memory_handles, | |
116 std::vector<IPC::PlatformFileForTransit> file_handles) { | |
117 holder->OnMemoryRequest(uuid, requests, memory_handles, file_handles, | |
118 file_thread_runner_.get(), &sink_); | |
119 } | |
120 | |
121 FilePath CreateTemporaryFile() { | |
122 FilePath path; | |
123 EXPECT_TRUE(base::CreateTemporaryFile(&path)); | |
124 files_opened_.push_back(path); | |
125 return path; | |
97 } | 126 } |
98 | 127 |
99 void ExpectRegisterAndStartMessage(const std::string& expected_uuid, | 128 void ExpectRegisterAndStartMessage(const std::string& expected_uuid, |
100 const std::string& expected_content_type, | 129 const std::string& expected_content_type, |
101 std::vector<DataElement>* descriptions) { | 130 std::vector<DataElement>* descriptions) { |
102 const IPC::Message* register_message = | 131 const IPC::Message* register_message = |
103 sink_.GetUniqueMessageMatching(BlobStorageMsg_RegisterBlobUUID::ID); | 132 sink_.GetUniqueMessageMatching(BlobStorageMsg_RegisterBlobUUID::ID); |
104 const IPC::Message* start_message = | 133 const IPC::Message* start_message = |
105 sink_.GetUniqueMessageMatching(BlobStorageMsg_StartBuildingBlob::ID); | 134 sink_.GetUniqueMessageMatching(BlobStorageMsg_StartBuildingBlob::ID); |
106 ASSERT_TRUE(register_message); | 135 ASSERT_TRUE(register_message); |
107 ASSERT_TRUE(start_message); | 136 ASSERT_TRUE(start_message); |
108 base::Tuple<std::string, std::string, std::string, std::set<std::string>> | 137 base::Tuple<std::string, std::string, std::string, std::set<std::string>> |
109 register_contents; | 138 register_contents; |
110 base::Tuple<std::string, std::vector<DataElement>> start_contents; | 139 base::Tuple<std::string, std::vector<DataElement>> start_contents; |
111 BlobStorageMsg_RegisterBlobUUID::Read(register_message, ®ister_contents); | 140 BlobStorageMsg_RegisterBlobUUID::Read(register_message, ®ister_contents); |
112 BlobStorageMsg_StartBuildingBlob::Read(start_message, &start_contents); | 141 BlobStorageMsg_StartBuildingBlob::Read(start_message, &start_contents); |
113 EXPECT_EQ(expected_uuid, base::get<0>(register_contents)); | 142 EXPECT_EQ(expected_uuid, base::get<0>(register_contents)); |
114 EXPECT_EQ(expected_uuid, base::get<0>(start_contents)); | 143 EXPECT_EQ(expected_uuid, base::get<0>(start_contents)); |
115 EXPECT_EQ(expected_content_type, base::get<1>(register_contents)); | 144 EXPECT_EQ(expected_content_type, base::get<1>(register_contents)); |
116 if (descriptions) | 145 if (descriptions) |
117 *descriptions = base::get<1>(start_contents); | 146 *descriptions = base::get<1>(start_contents); |
118 // We don't have dispositions from the renderer. | 147 // We don't have dispositions from the renderer. |
119 EXPECT_TRUE(base::get<2>(register_contents).empty()); | 148 EXPECT_TRUE(base::get<2>(register_contents).empty()); |
149 sink_.ClearMessages(); | |
150 } | |
151 | |
152 void ExpectMemoryResponses( | |
153 const std::string& expected_uuid, | |
154 std::vector<storage::BlobItemBytesResponse> expected_responses) { | |
155 const IPC::Message* responses_message = | |
156 sink_.GetUniqueMessageMatching(BlobStorageMsg_MemoryItemResponse::ID); | |
157 ASSERT_TRUE(responses_message); | |
158 base::Tuple<std::string, std::vector<storage::BlobItemBytesResponse>> | |
159 responses_content; | |
160 BlobStorageMsg_MemoryItemResponse::Read(responses_message, | |
161 &responses_content); | |
162 EXPECT_EQ(expected_uuid, base::get<0>(responses_content)); | |
163 EXPECT_EQ(expected_responses, base::get<1>(responses_content)); | |
164 sink_.ClearMessages(); | |
165 } | |
166 | |
167 void ExpectCancel(const std::string& expected_uuid, | |
168 storage::IPCBlobCreationCancelCode expected_code) { | |
169 const IPC::Message* cancel_message = | |
170 sink_.GetUniqueMessageMatching(BlobStorageMsg_CancelBuildingBlob::ID); | |
171 ASSERT_TRUE(cancel_message); | |
172 base::Tuple<std::string, storage::IPCBlobCreationCancelCode> cancel_content; | |
173 BlobStorageMsg_CancelBuildingBlob::Read(cancel_message, &cancel_content); | |
174 EXPECT_EQ(expected_uuid, base::get<0>(cancel_content)); | |
175 EXPECT_EQ(expected_code, base::get<1>(cancel_content)); | |
120 } | 176 } |
121 | 177 |
122 void TearDown() override { | 178 void TearDown() override { |
123 BlobTransportController::GetInstance()->ClearForTesting(); | 179 BlobTransportController::GetInstance()->CancelAllBlobTransfers(); |
180 for (const FilePath& path : files_opened_) { | |
181 EXPECT_TRUE(base::DeleteFile(path, false)); | |
182 } | |
183 EXPECT_FALSE(io_thread_runner_->HasPendingTask()); | |
184 EXPECT_FALSE(file_thread_runner_->HasPendingTask()); | |
185 EXPECT_FALSE(main_thread_runner_->HasPendingTask()); | |
124 } | 186 } |
125 | 187 |
188 protected: | |
189 std::vector<FilePath> files_opened_; | |
190 | |
126 IPC::TestSink sink_; | 191 IPC::TestSink sink_; |
127 scoped_refptr<BlobTransportControllerTestSender> sender_; | 192 scoped_refptr<BlobTransportControllerTestSender> sender_; |
128 scoped_refptr<base::TestSimpleTaskRunner> io_thread_runner_; | 193 |
129 scoped_refptr<OtherThreadTestSimpleTaskRunner> main_thread_runner_; | 194 // Thread runners. |
195 scoped_refptr<base::TestSimpleTaskRunner> io_thread_runner_ = | |
196 new TestSimpleTaskRunner(); | |
197 scoped_refptr<base::TestSimpleTaskRunner> file_thread_runner_ = | |
198 new TestSimpleTaskRunner(); | |
199 scoped_refptr<OtherThreadTestSimpleTaskRunner> main_thread_runner_ = | |
200 new OtherThreadTestSimpleTaskRunner(); | |
201 | |
202 // We set this to the IO thread runner, as this is used for the | |
203 // OnMemoryRequest calls, which are on that thread. | |
204 base::ThreadTaskRunnerHandle thread_runner_handle_; | |
130 }; | 205 }; |
131 | 206 |
132 TEST_F(BlobTransportControllerTest, Descriptions) { | 207 TEST_F(BlobTransportControllerTest, Descriptions) { |
133 const std::string kBlobUUID = "uuid"; | 208 const std::string kBlobUUID = "uuid"; |
134 const std::string KRefBlobUUID = "refuuid"; | 209 const std::string KRefBlobUUID = "refuuid"; |
135 const std::string kBadBlobUUID = "uuuidBad"; | 210 const std::string kBadBlobUUID = "uuuidBad"; |
136 const size_t kShortcutSize = 11; | 211 const size_t kShortcutSize = 11; |
137 | 212 |
138 // The first two data elements should be combined and the data shortcut. | 213 // The first two data elements should be combined and the data shortcut. |
139 std::unique_ptr<BlobConsolidation> consolidation(new BlobConsolidation()); | 214 scoped_refptr<BlobConsolidation> consolidation(new BlobConsolidation()); |
140 consolidation->AddBlobItem(KRefBlobUUID, 10, 10); | 215 consolidation->AddBlobItem(KRefBlobUUID, 10, 10); |
141 consolidation->AddDataItem(CreateData("Hello")); | 216 consolidation->AddDataItem(CreateData("Hello")); |
142 consolidation->AddDataItem(CreateData("Hello2")); | 217 consolidation->AddDataItem(CreateData("Hello2")); |
143 consolidation->AddBlobItem(KRefBlobUUID, 0, 10); | 218 consolidation->AddBlobItem(KRefBlobUUID, 0, 10); |
144 consolidation->AddDataItem(CreateData("Hello3")); | 219 consolidation->AddDataItem(CreateData("Hello3")); |
145 | 220 |
146 std::vector<DataElement> out; | 221 std::vector<DataElement> out; |
147 BlobTransportController::GetDescriptions(consolidation.get(), kShortcutSize, | 222 BlobTransportController::GetDescriptions(consolidation.get(), kShortcutSize, |
148 &out); | 223 &out); |
149 | 224 |
150 std::vector<DataElement> expected; | 225 std::vector<DataElement> expected; |
151 expected.push_back(MakeBlobElement(KRefBlobUUID, 10, 10)); | 226 expected.push_back(MakeBlobElement(KRefBlobUUID, 10, 10)); |
152 expected.push_back(MakeDataElement("HelloHello2")); | 227 expected.push_back(MakeDataElement("HelloHello2")); |
153 expected.push_back(MakeBlobElement(KRefBlobUUID, 0, 10)); | 228 expected.push_back(MakeBlobElement(KRefBlobUUID, 0, 10)); |
154 expected.push_back(MakeDataDescriptionElement(6)); | 229 expected.push_back(MakeDataDescriptionElement(6)); |
155 EXPECT_EQ(expected, out); | 230 EXPECT_EQ(expected, out); |
156 } | 231 } |
157 | 232 |
158 TEST_F(BlobTransportControllerTest, Responses) { | 233 TEST_F(BlobTransportControllerTest, Responses) { |
159 using ResponsesStatus = BlobTransportController::ResponsesStatus; | |
160 const std::string kBlobUUID = "uuid"; | 234 const std::string kBlobUUID = "uuid"; |
161 const std::string KRefBlobUUID = "refuuid"; | 235 const std::string KRefBlobUUID = "refuuid"; |
162 const std::string kBadBlobUUID = "uuuidBad"; | 236 const std::string kBadBlobUUID = "uuuidBad"; |
163 BlobTransportController* holder = BlobTransportController::GetInstance(); | 237 BlobTransportController* holder = BlobTransportController::GetInstance(); |
164 | 238 |
165 // The first two data elements should be combined. | 239 // The first two data elements should be combined. |
166 BlobConsolidation* consolidation = new BlobConsolidation(); | 240 scoped_refptr<BlobConsolidation> consolidation = new BlobConsolidation(); |
167 consolidation->AddBlobItem(KRefBlobUUID, 10, 10); | 241 consolidation->AddBlobItem(KRefBlobUUID, 10, 10); |
168 consolidation->AddDataItem(CreateData("Hello")); | 242 consolidation->AddDataItem(CreateData("Hello")); |
169 consolidation->AddDataItem(CreateData("Hello2")); | 243 consolidation->AddDataItem(CreateData("Hello2")); |
170 consolidation->AddBlobItem(KRefBlobUUID, 0, 10); | 244 consolidation->AddBlobItem(KRefBlobUUID, 0, 10); |
171 consolidation->AddDataItem(CreateData("Hello3")); | 245 consolidation->AddDataItem(CreateData("Hello3")); |
172 // See the above test for the expected descriptions layout. | 246 // See the above test for the expected descriptions layout. |
173 | 247 |
174 holder->blob_storage_[kBlobUUID] = base::WrapUnique(consolidation); | 248 holder->blob_storage_[kBlobUUID] = consolidation; |
175 | 249 |
176 std::vector<BlobItemBytesRequest> requests; | 250 std::vector<BlobItemBytesRequest> requests; |
177 std::vector<base::SharedMemoryHandle> memory_handles; | 251 std::vector<base::SharedMemoryHandle> memory_handles; |
178 std::vector<IPC::PlatformFileForTransit> file_handles; | 252 std::vector<IPC::PlatformFileForTransit> file_handles; |
179 std::vector<storage::BlobItemBytesResponse> output; | |
180 | 253 |
181 // Request for all of first data | 254 // Request for all of first data |
182 requests.push_back(BlobItemBytesRequest::CreateIPCRequest(0, 1, 0, 11)); | 255 requests.push_back(BlobItemBytesRequest::CreateIPCRequest(0, 1, 0, 11)); |
183 EXPECT_EQ(ResponsesStatus::SUCCESS, | 256 OnMemoryRequest(holder, kBlobUUID, requests, &memory_handles, file_handles); |
184 holder->GetResponses(kBlobUUID, requests, &memory_handles, | |
185 file_handles, &output)); | |
186 EXPECT_EQ(1u, output.size()); | |
187 std::vector<storage::BlobItemBytesResponse> expected; | 257 std::vector<storage::BlobItemBytesResponse> expected; |
188 expected.push_back(ResponseWithData(0, "HelloHello2")); | 258 expected.push_back(ResponseWithData(0, "HelloHello2")); |
189 EXPECT_EQ(expected, output); | 259 ExpectMemoryResponses(kBlobUUID, expected); |
190 | 260 |
191 // Part of second data | 261 // Part of second data |
192 output.clear(); | |
193 requests[0] = BlobItemBytesRequest::CreateIPCRequest(1000, 3, 1, 5); | 262 requests[0] = BlobItemBytesRequest::CreateIPCRequest(1000, 3, 1, 5); |
194 EXPECT_EQ(ResponsesStatus::SUCCESS, | 263 OnMemoryRequest(holder, kBlobUUID, requests, &memory_handles, file_handles); |
195 holder->GetResponses(kBlobUUID, requests, &memory_handles, | |
196 file_handles, &output)); | |
197 EXPECT_EQ(1u, output.size()); | |
198 expected.clear(); | 264 expected.clear(); |
199 expected.push_back(ResponseWithData(1000, "ello3")); | 265 expected.push_back(ResponseWithData(1000, "ello3")); |
200 EXPECT_EQ(expected, output); | 266 ExpectMemoryResponses(kBlobUUID, expected); |
201 | 267 |
202 // Both data segments | 268 // Both data segments |
203 output.clear(); | |
204 requests[0] = BlobItemBytesRequest::CreateIPCRequest(0, 1, 0, 11); | 269 requests[0] = BlobItemBytesRequest::CreateIPCRequest(0, 1, 0, 11); |
205 requests.push_back(BlobItemBytesRequest::CreateIPCRequest(1, 3, 0, 6)); | 270 requests.push_back(BlobItemBytesRequest::CreateIPCRequest(1, 3, 0, 6)); |
206 EXPECT_EQ(ResponsesStatus::SUCCESS, | 271 OnMemoryRequest(holder, kBlobUUID, requests, &memory_handles, file_handles); |
207 holder->GetResponses(kBlobUUID, requests, &memory_handles, | |
208 file_handles, &output)); | |
209 EXPECT_EQ(2u, output.size()); | |
210 expected.clear(); | 272 expected.clear(); |
211 expected.push_back(ResponseWithData(0, "HelloHello2")); | 273 expected.push_back(ResponseWithData(0, "HelloHello2")); |
212 expected.push_back(ResponseWithData(1, "Hello3")); | 274 expected.push_back(ResponseWithData(1, "Hello3")); |
213 EXPECT_EQ(expected, output); | 275 ExpectMemoryResponses(kBlobUUID, expected); |
214 } | 276 } |
215 | 277 |
216 TEST_F(BlobTransportControllerTest, SharedMemory) { | 278 TEST_F(BlobTransportControllerTest, SharedMemory) { |
217 using ResponsesStatus = BlobTransportController::ResponsesStatus; | |
218 const std::string kBlobUUID = "uuid"; | 279 const std::string kBlobUUID = "uuid"; |
219 const std::string KRefBlobUUID = "refuuid"; | 280 const std::string KRefBlobUUID = "refuuid"; |
220 const std::string kBadBlobUUID = "uuuidBad"; | 281 const std::string kBadBlobUUID = "uuuidBad"; |
221 BlobTransportController* holder = BlobTransportController::GetInstance(); | 282 BlobTransportController* holder = BlobTransportController::GetInstance(); |
222 | 283 |
223 // The first two data elements should be combined. | 284 // The first two data elements should be combined. |
224 BlobConsolidation* consolidation = new BlobConsolidation(); | 285 scoped_refptr<BlobConsolidation> consolidation = new BlobConsolidation(); |
225 consolidation->AddBlobItem(KRefBlobUUID, 10, 10); | 286 consolidation->AddBlobItem(KRefBlobUUID, 10, 10); |
226 consolidation->AddDataItem(CreateData("Hello")); | 287 consolidation->AddDataItem(CreateData("Hello")); |
227 consolidation->AddDataItem(CreateData("Hello2")); | 288 consolidation->AddDataItem(CreateData("Hello2")); |
228 consolidation->AddBlobItem(KRefBlobUUID, 0, 10); | 289 consolidation->AddBlobItem(KRefBlobUUID, 0, 10); |
229 consolidation->AddDataItem(CreateData("Hello3")); | 290 consolidation->AddDataItem(CreateData("Hello3")); |
230 // See the above test for the expected descriptions layout. | 291 // See the above test for the expected descriptions layout. |
231 | 292 |
232 holder->blob_storage_[kBlobUUID] = base::WrapUnique(consolidation); | 293 holder->blob_storage_[kBlobUUID] = consolidation; |
233 | 294 |
234 std::vector<BlobItemBytesRequest> requests; | 295 std::vector<BlobItemBytesRequest> requests; |
235 std::vector<base::SharedMemoryHandle> memory_handles; | 296 std::vector<base::SharedMemoryHandle> memory_handles; |
236 std::vector<IPC::PlatformFileForTransit> file_handles; | 297 std::vector<IPC::PlatformFileForTransit> file_handles; |
237 std::vector<storage::BlobItemBytesResponse> output; | |
238 | 298 |
239 // Request for all data in shared memory | 299 // Request for all data in shared memory |
240 requests.push_back( | 300 requests.push_back( |
241 BlobItemBytesRequest::CreateSharedMemoryRequest(0, 1, 0, 11, 0, 0)); | 301 BlobItemBytesRequest::CreateSharedMemoryRequest(0, 1, 0, 11, 0, 0)); |
242 requests.push_back( | 302 requests.push_back( |
243 BlobItemBytesRequest::CreateSharedMemoryRequest(1, 3, 0, 6, 0, 11)); | 303 BlobItemBytesRequest::CreateSharedMemoryRequest(1, 3, 0, 6, 0, 11)); |
244 base::SharedMemory memory; | 304 base::SharedMemory memory; |
245 memory.CreateAndMapAnonymous(11 + 6); | 305 memory.CreateAndMapAnonymous(11 + 6); |
246 base::SharedMemoryHandle handle = | 306 base::SharedMemoryHandle handle = |
247 base::SharedMemory::DuplicateHandle(memory.handle()); | 307 base::SharedMemory::DuplicateHandle(memory.handle()); |
248 CHECK(base::SharedMemory::NULLHandle() != handle); | 308 CHECK(base::SharedMemory::NULLHandle() != handle); |
249 memory_handles.push_back(handle); | 309 memory_handles.push_back(handle); |
250 | 310 |
251 EXPECT_EQ(ResponsesStatus::SUCCESS, | 311 OnMemoryRequest(holder, kBlobUUID, requests, &memory_handles, file_handles); |
252 holder->GetResponses(kBlobUUID, requests, &memory_handles, | |
253 file_handles, &output)); | |
254 EXPECT_EQ(2u, output.size()); | |
255 std::vector<storage::BlobItemBytesResponse> expected; | 312 std::vector<storage::BlobItemBytesResponse> expected; |
256 expected.push_back(BlobItemBytesResponse(0)); | 313 expected.push_back(BlobItemBytesResponse(0)); |
257 expected.push_back(BlobItemBytesResponse(1)); | 314 expected.push_back(BlobItemBytesResponse(1)); |
258 EXPECT_EQ(expected, output); | 315 ExpectMemoryResponses(kBlobUUID, expected); |
259 std::string expected_memory = "HelloHello2Hello3"; | 316 std::string expected_memory = "HelloHello2Hello3"; |
260 const char* mem_location = static_cast<const char*>(memory.memory()); | 317 const char* mem_location = static_cast<const char*>(memory.memory()); |
261 std::vector<char> value(mem_location, mem_location + memory.requested_size()); | 318 std::vector<char> value(mem_location, mem_location + memory.requested_size()); |
262 EXPECT_THAT(value, testing::ElementsAreArray(expected_memory.c_str(), | 319 EXPECT_THAT(value, testing::ElementsAreArray(expected_memory.c_str(), |
263 expected_memory.size())); | 320 expected_memory.size())); |
264 } | 321 } |
265 | 322 |
266 TEST_F(BlobTransportControllerTest, TestPublicMethods) { | 323 TEST_F(BlobTransportControllerTest, Disk) { |
324 const std::string kBlobUUID = "uuid"; | |
325 const std::string KRefBlobUUID = "refuuid"; | |
michaeln
2016/04/28 00:16:57
K --> k
dmurph
2016/05/09 19:55:47
Done.
| |
326 const std::string kBadBlobUUID = "uuuidBad"; | |
327 BlobTransportController* holder = BlobTransportController::GetInstance(); | |
328 FilePath path1 = CreateTemporaryFile(); | |
329 File file(path1, File::FLAG_OPEN | File::FLAG_WRITE | File::FLAG_READ); | |
330 ASSERT_TRUE(file.IsValid()); | |
331 ASSERT_TRUE(file.SetLength(11 + 6)); | |
332 // The first two data elements should be combined. | |
333 scoped_refptr<BlobConsolidation> consolidation(new BlobConsolidation()); | |
334 consolidation->AddBlobItem(KRefBlobUUID, 10, 10); | |
335 consolidation->AddDataItem(CreateData("Hello")); | |
336 consolidation->AddDataItem(CreateData("Hello2")); | |
337 consolidation->AddBlobItem(KRefBlobUUID, 0, 10); | |
338 consolidation->AddDataItem(CreateData("Hello3")); | |
michaeln
2016/04/28 00:16:57
maybe factor the constants and test consolidation
dmurph
2016/05/09 19:55:47
Done.
| |
339 // See the above test for the expected descriptions layout. | |
340 holder->blob_storage_[kBlobUUID] = consolidation; | |
341 holder->main_thread_runner_ = main_thread_runner_; | |
342 std::vector<BlobItemBytesRequest> requests; | |
343 std::vector<base::SharedMemoryHandle> memory_handles; | |
344 std::vector<IPC::PlatformFileForTransit> file_handles; | |
345 // Request for all data in shared memory | |
michaeln
2016/04/28 00:16:57
should the comment say 'files'?
dmurph
2016/05/09 19:55:47
Done.
| |
346 requests.push_back( | |
347 BlobItemBytesRequest::CreateFileRequest(0, 1, 0, 11, 0, 0)); | |
348 requests.push_back( | |
349 BlobItemBytesRequest::CreateFileRequest(1, 3, 0, 6, 0, 11)); | |
350 file_handles.push_back(IPC::TakePlatformFileForTransit(std::move(file))); | |
351 OnMemoryRequest(holder, kBlobUUID, requests, &memory_handles, file_handles); | |
352 EXPECT_TRUE(file_thread_runner_->HasPendingTask()); | |
353 EXPECT_FALSE(io_thread_runner_->HasPendingTask()); | |
354 file_thread_runner_->RunPendingTasks(); | |
355 EXPECT_FALSE(file_thread_runner_->HasPendingTask()); | |
356 EXPECT_TRUE(io_thread_runner_->HasPendingTask()); | |
357 io_thread_runner_->RunPendingTasks(); | |
358 std::vector<storage::BlobItemBytesResponse> expected = { | |
359 BlobItemBytesResponse(0), BlobItemBytesResponse(1)}; | |
360 ExpectMemoryResponses(kBlobUUID, expected); | |
361 std::string expected_memory = "HelloHello2Hello3"; | |
362 file = IPC::PlatformFileForTransitToFile(file_handles[0]); | |
363 file_handles.clear(); | |
364 char data[11 + 6]; | |
365 file.Read(0, data, 11 + 6); | |
366 std::vector<char> value(data, data + 11 + 6); | |
367 EXPECT_THAT(value, testing::ElementsAreArray(expected_memory.c_str(), | |
368 expected_memory.size())); | |
369 | |
370 // Finally, test that we get errors correctly. | |
371 FilePath path2 = CreateTemporaryFile(); | |
372 EXPECT_TRUE(base::MakeFileUnwritable(path2)); | |
373 File file2(path2, File::FLAG_OPEN | File::FLAG_WRITE); | |
374 EXPECT_FALSE(file2.IsValid()); | |
375 file_handles.push_back(IPC::TakePlatformFileForTransit(std::move(file2))); | |
376 OnMemoryRequest(holder, kBlobUUID, requests, &memory_handles, file_handles); | |
377 EXPECT_TRUE(file_thread_runner_->HasPendingTask()); | |
378 file_thread_runner_->RunPendingTasks(); | |
379 EXPECT_TRUE(io_thread_runner_->HasPendingTask()); | |
380 io_thread_runner_->RunPendingTasks(); | |
381 // Clear the main thread task, as it has the AddRef job. | |
382 EXPECT_TRUE(main_thread_runner_->HasPendingTask()); | |
383 main_thread_runner_->ClearPendingTasks(); | |
384 ExpectCancel(kBlobUUID, IPCBlobCreationCancelCode::FILE_WRITE_FAILED); | |
385 } | |
386 | |
387 TEST_F(BlobTransportControllerTest, PublicMethods) { | |
267 const std::string kBlobUUID = "uuid"; | 388 const std::string kBlobUUID = "uuid"; |
268 const std::string kBlobContentType = "content_type"; | 389 const std::string kBlobContentType = "content_type"; |
269 const std::string kBlob2UUID = "uuid2"; | 390 const std::string kBlob2UUID = "uuid2"; |
270 const std::string kBlob2ContentType = "content_type2"; | 391 const std::string kBlob2ContentType = "content_type2"; |
271 const std::string KRefBlobUUID = "refuuid"; | 392 const std::string KRefBlobUUID = "refuuid"; |
272 std::vector<DataElement> message_descriptions; | 393 std::vector<DataElement> message_descriptions; |
273 BlobTransportController* holder = BlobTransportController::GetInstance(); | 394 BlobTransportController* holder = BlobTransportController::GetInstance(); |
274 | 395 |
275 BlobConsolidation* consolidation = new BlobConsolidation(); | 396 scoped_refptr<BlobConsolidation> consolidation = new BlobConsolidation(); |
276 consolidation->AddBlobItem(KRefBlobUUID, 10, 10); | 397 consolidation->AddBlobItem(KRefBlobUUID, 10, 10); |
277 BlobTransportController::InitiateBlobTransfer( | 398 BlobTransportController::InitiateBlobTransfer( |
278 kBlobUUID, kBlobContentType, base::WrapUnique(consolidation), sender_, | 399 kBlobUUID, kBlobContentType, consolidation, sender_, |
279 io_thread_runner_.get(), main_thread_runner_); | 400 io_thread_runner_.get(), main_thread_runner_); |
280 // Check that we have the 'increase ref' pending task. | 401 // Check that we have the 'increase ref' pending task. |
281 EXPECT_TRUE(main_thread_runner_->HasPendingTask()); | 402 EXPECT_TRUE(main_thread_runner_->HasPendingTask()); |
282 // Check that we have the 'store' pending task. | 403 // Check that we have the 'store' pending task. |
283 EXPECT_TRUE(io_thread_runner_->HasPendingTask()); | 404 EXPECT_TRUE(io_thread_runner_->HasPendingTask()); |
284 // Check that we've sent the data. | 405 // Check that we've sent the data. |
285 ExpectRegisterAndStartMessage(kBlobUUID, kBlobContentType, | 406 ExpectRegisterAndStartMessage(kBlobUUID, kBlobContentType, |
286 &message_descriptions); | 407 &message_descriptions); |
287 main_thread_runner_->ClearPendingTasks(); | 408 main_thread_runner_->ClearPendingTasks(); |
288 | 409 |
289 // Check that we got the correct start message. | 410 // Check that we got the correct start message. |
290 EXPECT_FALSE(holder->IsTransporting(kBlobUUID)); | 411 EXPECT_FALSE(holder->IsTransporting(kBlobUUID)); |
291 io_thread_runner_->RunPendingTasks(); | 412 io_thread_runner_->RunPendingTasks(); |
292 EXPECT_TRUE(holder->IsTransporting(kBlobUUID)); | 413 EXPECT_TRUE(holder->IsTransporting(kBlobUUID)); |
293 base::Tuple<std::string, std::vector<DataElement>> message_contents; | |
294 EXPECT_EQ(MakeBlobElement(KRefBlobUUID, 10, 10), message_descriptions[0]); | 414 EXPECT_EQ(MakeBlobElement(KRefBlobUUID, 10, 10), message_descriptions[0]); |
295 | 415 |
296 holder->OnCancel(kBlobUUID, | 416 holder->OnCancel(kBlobUUID, IPCBlobCreationCancelCode::OUT_OF_MEMORY); |
297 storage::IPCBlobCreationCancelCode::OUT_OF_MEMORY); | |
298 EXPECT_FALSE(holder->IsTransporting(kBlobUUID)); | 417 EXPECT_FALSE(holder->IsTransporting(kBlobUUID)); |
299 // Check we have the 'decrease ref' task. | 418 // Check we have the 'decrease ref' task. |
300 EXPECT_TRUE(main_thread_runner_->HasPendingTask()); | 419 EXPECT_TRUE(main_thread_runner_->HasPendingTask()); |
301 main_thread_runner_->ClearPendingTasks(); | 420 main_thread_runner_->ClearPendingTasks(); |
302 sink_.ClearMessages(); | 421 sink_.ClearMessages(); |
303 | 422 |
304 // Add the second. | 423 // Add the second. |
305 BlobConsolidation* consolidation2 = new BlobConsolidation(); | 424 scoped_refptr<BlobConsolidation> consolidation2 = new BlobConsolidation(); |
306 consolidation2->AddBlobItem(KRefBlobUUID, 10, 10); | 425 consolidation2->AddBlobItem(KRefBlobUUID, 10, 10); |
307 BlobTransportController::InitiateBlobTransfer( | 426 BlobTransportController::InitiateBlobTransfer( |
308 kBlob2UUID, kBlob2ContentType, base::WrapUnique(consolidation2), sender_, | 427 kBlob2UUID, kBlob2ContentType, consolidation2, sender_, |
309 io_thread_runner_.get(), main_thread_runner_); | 428 io_thread_runner_.get(), main_thread_runner_); |
310 EXPECT_TRUE(main_thread_runner_->HasPendingTask()); | 429 EXPECT_TRUE(main_thread_runner_->HasPendingTask()); |
311 main_thread_runner_->ClearPendingTasks(); | 430 main_thread_runner_->ClearPendingTasks(); |
312 sink_.ClearMessages(); | 431 sink_.ClearMessages(); |
313 | 432 |
314 io_thread_runner_->RunPendingTasks(); | 433 io_thread_runner_->RunPendingTasks(); |
315 EXPECT_TRUE(holder->IsTransporting(kBlob2UUID)); | 434 EXPECT_TRUE(holder->IsTransporting(kBlob2UUID)); |
316 | 435 |
317 // Finish the second one. | 436 // Finish the second one. |
318 holder->OnDone(kBlob2UUID); | 437 holder->OnDone(kBlob2UUID); |
319 EXPECT_FALSE(holder->IsTransporting(kBlob2UUID)); | 438 EXPECT_FALSE(holder->IsTransporting(kBlob2UUID)); |
320 EXPECT_TRUE(main_thread_runner_->HasPendingTask()); | 439 EXPECT_TRUE(main_thread_runner_->HasPendingTask()); |
321 main_thread_runner_->ClearPendingTasks(); | 440 main_thread_runner_->ClearPendingTasks(); |
322 } | 441 } |
323 | 442 |
324 TEST_F(BlobTransportControllerTest, ResponsesErrors) { | 443 TEST_F(BlobTransportControllerTest, MemoryResponsesPublicMethod) { |
michaeln
2016/04/28 00:16:57
Maybe this test and the Responses test could be me
dmurph
2016/05/09 19:55:47
Done.
| |
325 using ResponsesStatus = BlobTransportController::ResponsesStatus; | |
326 const std::string kBlobUUID = "uuid"; | 444 const std::string kBlobUUID = "uuid"; |
327 const std::string KRefBlobUUID = "refuuid"; | 445 const std::string kBlobContentType = "content_type"; |
328 const std::string kBadBlobUUID = "uuuidBad"; | 446 const std::string kData = "HelloHello2Hello3"; |
447 const int kDataSize = 17; | |
448 // Here we test that we receive data responses when we request them. | |
329 BlobTransportController* holder = BlobTransportController::GetInstance(); | 449 BlobTransportController* holder = BlobTransportController::GetInstance(); |
330 | 450 |
331 BlobConsolidation* consolidation = new BlobConsolidation(); | 451 scoped_refptr<BlobConsolidation> consolidation(new BlobConsolidation()); |
332 consolidation->AddBlobItem(KRefBlobUUID, 10, 10); | 452 // These items should be combined. |
453 consolidation->AddDataItem(CreateData("Hello")); | |
454 consolidation->AddDataItem(CreateData("Hello2")); | |
455 consolidation->AddDataItem(CreateData("Hello3")); | |
456 BlobTransportController::InitiateBlobTransfer( | |
457 kBlobUUID, kBlobContentType, consolidation, sender_, | |
458 io_thread_runner_.get(), main_thread_runner_); | |
459 // Check that we have the 'increase ref' pending task. | |
460 EXPECT_TRUE(main_thread_runner_->HasPendingTask()); | |
461 // Check that we have the 'store' pending task. | |
462 EXPECT_TRUE(io_thread_runner_->HasPendingTask()); | |
463 // Check that we've sent the data. | |
464 std::vector<DataElement> message_descriptions; | |
465 ExpectRegisterAndStartMessage(kBlobUUID, kBlobContentType, | |
466 &message_descriptions); | |
467 main_thread_runner_->ClearPendingTasks(); | |
333 | 468 |
334 holder->blob_storage_[kBlobUUID] = base::WrapUnique(consolidation); | 469 // Check that we got the correct start message. |
470 EXPECT_FALSE(holder->IsTransporting(kBlobUUID)); | |
471 io_thread_runner_->RunPendingTasks(); | |
472 EXPECT_TRUE(holder->IsTransporting(kBlobUUID)); | |
473 ASSERT_EQ(1u, message_descriptions.size()); | |
474 EXPECT_EQ(MakeDataElement("HelloHello2Hello3"), message_descriptions[0]); | |
475 EXPECT_FALSE(main_thread_runner_->HasPendingTask()); | |
335 | 476 |
477 // Now we request the memory. | |
336 std::vector<BlobItemBytesRequest> requests; | 478 std::vector<BlobItemBytesRequest> requests; |
337 std::vector<base::SharedMemoryHandle> memory_handles; | 479 std::vector<base::SharedMemoryHandle> memory_handles; |
338 std::vector<IPC::PlatformFileForTransit> file_handles; | 480 std::vector<IPC::PlatformFileForTransit> file_handles; |
339 std::vector<storage::BlobItemBytesResponse> output; | 481 requests.push_back( |
482 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)); | |
483 OnMemoryRequest(holder, kBlobUUID, requests, &memory_handles, file_handles); | |
340 | 484 |
341 // Error conditions | 485 std::vector<BlobItemBytesResponse> expected_responses; |
342 EXPECT_EQ(ResponsesStatus::BLOB_NOT_FOUND, | 486 BlobItemBytesResponse expected(0); |
343 holder->GetResponses(kBadBlobUUID, requests, &memory_handles, | 487 expected.inline_data = std::vector<char>(kData.begin(), kData.end()); |
344 file_handles, &output)); | 488 expected_responses.push_back(expected); |
345 EXPECT_EQ(0u, output.size()); | 489 ExpectMemoryResponses(kBlobUUID, expected_responses); |
490 EXPECT_FALSE(main_thread_runner_->HasPendingTask()); | |
491 holder->OnDone(kBlobUUID); | |
492 EXPECT_TRUE(main_thread_runner_->HasPendingTask()); | |
493 main_thread_runner_->ClearPendingTasks(); | |
346 } | 494 } |
347 | 495 |
348 } // namespace content | 496 } // namespace content |
OLD | NEW |