| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/blob_storage/blob_dispatcher_host.h" | 5 #include "content/browser/blob_storage/blob_dispatcher_host.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <tuple> | 8 #include <tuple> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/memory/shared_memory.h" | 12 #include "base/memory/shared_memory.h" |
| 13 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
| 14 #include "content/browser/blob_storage/chrome_blob_storage_context.h" | 14 #include "content/browser/blob_storage/chrome_blob_storage_context.h" |
| 15 #include "content/common/fileapi/webblob_messages.h" | 15 #include "content/common/fileapi/webblob_messages.h" |
| 16 #include "content/public/common/content_switches.h" | 16 #include "content/public/common/content_switches.h" |
| 17 #include "content/public/test/test_browser_context.h" | 17 #include "content/public/test/test_browser_context.h" |
| 18 #include "content/public/test/test_browser_thread_bundle.h" | 18 #include "content/public/test/test_browser_thread_bundle.h" |
| 19 #include "content/public/test/test_file_system_context.h" |
| 19 #include "ipc/ipc_sender.h" | 20 #include "ipc/ipc_sender.h" |
| 20 #include "ipc/ipc_test_sink.h" | 21 #include "ipc/ipc_test_sink.h" |
| 21 #include "ipc/message_filter.h" | 22 #include "ipc/message_filter.h" |
| 22 #include "storage/browser/blob/blob_data_builder.h" | 23 #include "storage/browser/blob/blob_data_builder.h" |
| 23 #include "storage/browser/blob/blob_data_handle.h" | 24 #include "storage/browser/blob/blob_data_handle.h" |
| 24 #include "storage/browser/blob/blob_storage_context.h" | 25 #include "storage/browser/blob/blob_storage_context.h" |
| 25 #include "storage/common/blob_storage/blob_item_bytes_request.h" | 26 #include "storage/common/blob_storage/blob_item_bytes_request.h" |
| 26 #include "storage/common/blob_storage/blob_item_bytes_response.h" | 27 #include "storage/common/blob_storage/blob_item_bytes_response.h" |
| 27 #include "storage/common/data_element.h" | 28 #include "storage/common/data_element.h" |
| 28 #include "testing/gmock/include/gmock/gmock.h" | 29 #include "testing/gmock/include/gmock/gmock.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 52 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; | 53 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; |
| 53 | 54 |
| 54 void ConstructionCompletePopulator(bool* succeeded_pointer, | 55 void ConstructionCompletePopulator(bool* succeeded_pointer, |
| 55 IPCBlobCreationCancelCode* reason_pointer, | 56 IPCBlobCreationCancelCode* reason_pointer, |
| 56 bool succeeded, | 57 bool succeeded, |
| 57 IPCBlobCreationCancelCode reason) { | 58 IPCBlobCreationCancelCode reason) { |
| 58 *succeeded_pointer = succeeded; | 59 *succeeded_pointer = succeeded; |
| 59 *reason_pointer = reason; | 60 *reason_pointer = reason; |
| 60 } | 61 } |
| 61 | 62 |
| 63 // TODO(dmurph): Create file test that verifies security policy. |
| 62 class TestableBlobDispatcherHost : public BlobDispatcherHost { | 64 class TestableBlobDispatcherHost : public BlobDispatcherHost { |
| 63 public: | 65 public: |
| 64 TestableBlobDispatcherHost(ChromeBlobStorageContext* blob_storage_context, | 66 TestableBlobDispatcherHost(ChromeBlobStorageContext* blob_storage_context, |
| 67 storage::FileSystemContext* file_system_context, |
| 65 IPC::TestSink* sink) | 68 IPC::TestSink* sink) |
| 66 : BlobDispatcherHost(blob_storage_context), sink_(sink) { | 69 : BlobDispatcherHost(0 /* process_id */, |
| 70 make_scoped_refptr(blob_storage_context), |
| 71 make_scoped_refptr(file_system_context)), |
| 72 sink_(sink) { |
| 67 this->SetMemoryConstantsForTesting(kTestBlobStorageIPCThresholdBytes, | 73 this->SetMemoryConstantsForTesting(kTestBlobStorageIPCThresholdBytes, |
| 68 kTestBlobStorageMaxSharedMemoryBytes, | 74 kTestBlobStorageMaxSharedMemoryBytes, |
| 69 kTestBlobStorageMaxFileSizeBytes); | 75 kTestBlobStorageMaxFileSizeBytes); |
| 70 } | 76 } |
| 71 | 77 |
| 72 bool Send(IPC::Message* message) override { return sink_->Send(message); } | 78 bool Send(IPC::Message* message) override { return sink_->Send(message); } |
| 73 | 79 |
| 74 void ShutdownForBadMessage() override { shutdown_for_bad_message_ = true; } | 80 void ShutdownForBadMessage() override { shutdown_for_bad_message_ = true; } |
| 75 | 81 |
| 76 bool shutdown_for_bad_message_ = false; | 82 bool shutdown_for_bad_message_ = false; |
| 77 | 83 |
| 78 protected: | 84 protected: |
| 79 ~TestableBlobDispatcherHost() override {} | 85 ~TestableBlobDispatcherHost() override {} |
| 80 | 86 |
| 81 private: | 87 private: |
| 82 friend class base::RefCountedThreadSafe<TestableBlobDispatcherHost>; | 88 friend class base::RefCountedThreadSafe<TestableBlobDispatcherHost>; |
| 83 | 89 |
| 84 IPC::TestSink* sink_; | 90 IPC::TestSink* sink_; |
| 85 }; | 91 }; |
| 86 | 92 |
| 87 } // namespace | 93 } // namespace |
| 88 | 94 |
| 89 class BlobDispatcherHostTest : public testing::Test { | 95 class BlobDispatcherHostTest : public testing::Test { |
| 90 protected: | 96 protected: |
| 91 BlobDispatcherHostTest() | 97 BlobDispatcherHostTest() |
| 92 : chrome_blob_storage_context_( | 98 : chrome_blob_storage_context_( |
| 93 ChromeBlobStorageContext::GetFor(&browser_context_)) { | 99 ChromeBlobStorageContext::GetFor(&browser_context_)) { |
| 94 host_ = | 100 file_system_context_ = |
| 95 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_); | 101 CreateFileSystemContextForTesting(NULL, base::FilePath()); |
| 102 host_ = new TestableBlobDispatcherHost(chrome_blob_storage_context_, |
| 103 file_system_context_.get(), &sink_); |
| 96 } | 104 } |
| 97 ~BlobDispatcherHostTest() override {} | 105 ~BlobDispatcherHostTest() override {} |
| 98 | 106 |
| 99 void SetUp() override { | 107 void SetUp() override { |
| 100 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 108 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 101 if (!command_line->HasSwitch(switches::kDisableKillAfterBadIPC)) { | 109 if (!command_line->HasSwitch(switches::kDisableKillAfterBadIPC)) { |
| 102 command_line->AppendSwitch(switches::kDisableKillAfterBadIPC); | 110 command_line->AppendSwitch(switches::kDisableKillAfterBadIPC); |
| 103 } | 111 } |
| 104 // We run the run loop to initialize the chrome blob storage context. | 112 // We run the run loop to initialize the chrome blob storage context. |
| 105 base::RunLoop().RunUntilIdle(); | 113 base::RunLoop().RunUntilIdle(); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 | 260 |
| 253 bool IsBeingBuiltInHost(const std::string& uuid) { | 261 bool IsBeingBuiltInHost(const std::string& uuid) { |
| 254 return host_->async_builder_.IsBeingBuilt(uuid); | 262 return host_->async_builder_.IsBeingBuilt(uuid); |
| 255 } | 263 } |
| 256 | 264 |
| 257 IPC::TestSink sink_; | 265 IPC::TestSink sink_; |
| 258 TestBrowserThreadBundle browser_thread_bundle_; | 266 TestBrowserThreadBundle browser_thread_bundle_; |
| 259 TestBrowserContext browser_context_; | 267 TestBrowserContext browser_context_; |
| 260 ChromeBlobStorageContext* chrome_blob_storage_context_; | 268 ChromeBlobStorageContext* chrome_blob_storage_context_; |
| 261 BlobStorageContext* context_ = nullptr; | 269 BlobStorageContext* context_ = nullptr; |
| 270 scoped_refptr<storage::FileSystemContext> file_system_context_; |
| 262 scoped_refptr<TestableBlobDispatcherHost> host_; | 271 scoped_refptr<TestableBlobDispatcherHost> host_; |
| 263 }; | 272 }; |
| 264 | 273 |
| 265 TEST_F(BlobDispatcherHostTest, EmptyUUIDs) { | 274 TEST_F(BlobDispatcherHostTest, EmptyUUIDs) { |
| 266 host_->OnRegisterBlobUUID("", "", "", std::set<std::string>()); | 275 host_->OnRegisterBlobUUID("", "", "", std::set<std::string>()); |
| 267 ExpectAndResetBadMessage(); | 276 ExpectAndResetBadMessage(); |
| 268 host_->OnStartBuildingBlob("", std::vector<DataElement>()); | 277 host_->OnStartBuildingBlob("", std::vector<DataElement>()); |
| 269 ExpectAndResetBadMessage(); | 278 ExpectAndResetBadMessage(); |
| 270 host_->OnMemoryItemResponse("", std::vector<BlobItemBytesResponse>()); | 279 host_->OnMemoryItemResponse("", std::vector<BlobItemBytesResponse>()); |
| 271 ExpectAndResetBadMessage(); | 280 ExpectAndResetBadMessage(); |
| (...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 DataElement element; | 917 DataElement element; |
| 909 element.SetToBytesDescription(kDataSize); | 918 element.SetToBytesDescription(kDataSize); |
| 910 std::vector<DataElement> elements = {element}; | 919 std::vector<DataElement> elements = {element}; |
| 911 std::vector<BlobItemBytesRequest> expected_requests = { | 920 std::vector<BlobItemBytesRequest> expected_requests = { |
| 912 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 921 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
| 913 BlobItemBytesResponse response(0); | 922 BlobItemBytesResponse response(0); |
| 914 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); | 923 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
| 915 std::vector<BlobItemBytesResponse> responses = {response}; | 924 std::vector<BlobItemBytesResponse> responses = {response}; |
| 916 | 925 |
| 917 scoped_refptr<TestableBlobDispatcherHost> host2( | 926 scoped_refptr<TestableBlobDispatcherHost> host2( |
| 918 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_)); | 927 new TestableBlobDispatcherHost(chrome_blob_storage_context_, |
| 928 file_system_context_.get(), &sink_)); |
| 919 | 929 |
| 920 // Delete host with another host having a referencing, then dereference on | 930 // Delete host with another host having a referencing, then dereference on |
| 921 // second host. Verify we're still building it on first host, and then | 931 // second host. Verify we're still building it on first host, and then |
| 922 // verify that a building message from the renderer will kill it. | 932 // verify that a building message from the renderer will kill it. |
| 923 | 933 |
| 924 // Test OnStartBuilding after double dereference. | 934 // Test OnStartBuilding after double dereference. |
| 925 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 935 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
| 926 std::string(kContentDisposition), | 936 std::string(kContentDisposition), |
| 927 std::set<std::string>()); | 937 std::set<std::string>()); |
| 928 host2->OnIncrementBlobRefCount(kId); | 938 host2->OnIncrementBlobRefCount(kId); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 991 // Data elements for our transfer & checking messages. | 1001 // Data elements for our transfer & checking messages. |
| 992 DataElement element; | 1002 DataElement element; |
| 993 element.SetToBytes(kData, kDataSize); | 1003 element.SetToBytes(kData, kDataSize); |
| 994 std::vector<DataElement> elements = {element}; | 1004 std::vector<DataElement> elements = {element}; |
| 995 DataElement referencing_element; | 1005 DataElement referencing_element; |
| 996 referencing_element.SetToBlob(kId); | 1006 referencing_element.SetToBlob(kId); |
| 997 std::vector<DataElement> referencing_elements = {referencing_element}; | 1007 std::vector<DataElement> referencing_elements = {referencing_element}; |
| 998 std::set<std::string> referenced_blobs_set = {kId}; | 1008 std::set<std::string> referenced_blobs_set = {kId}; |
| 999 | 1009 |
| 1000 scoped_refptr<TestableBlobDispatcherHost> host2( | 1010 scoped_refptr<TestableBlobDispatcherHost> host2( |
| 1001 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_)); | 1011 new TestableBlobDispatcherHost(chrome_blob_storage_context_, |
| 1012 file_system_context_.get(), &sink_)); |
| 1002 | 1013 |
| 1003 // We want to have a blob referencing another blob that is building, both on | 1014 // We want to have a blob referencing another blob that is building, both on |
| 1004 // the same host and a different host. We should successfully build all blobs | 1015 // the same host and a different host. We should successfully build all blobs |
| 1005 // after the referenced blob is finished. | 1016 // after the referenced blob is finished. |
| 1006 | 1017 |
| 1007 // First we start the referenced blob. | 1018 // First we start the referenced blob. |
| 1008 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 1019 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
| 1009 std::string(kContentDisposition), | 1020 std::string(kContentDisposition), |
| 1010 std::set<std::string>()); | 1021 std::set<std::string>()); |
| 1011 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 1022 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 const std::string kId("id"); | 1065 const std::string kId("id"); |
| 1055 const std::string kSameHostReferencingId("id2"); | 1066 const std::string kSameHostReferencingId("id2"); |
| 1056 const std::string kDifferentHostReferencingId("id3"); | 1067 const std::string kDifferentHostReferencingId("id3"); |
| 1057 // Data elements for our transfer & checking messages. | 1068 // Data elements for our transfer & checking messages. |
| 1058 DataElement referencing_element; | 1069 DataElement referencing_element; |
| 1059 referencing_element.SetToBlob(kId); | 1070 referencing_element.SetToBlob(kId); |
| 1060 std::vector<DataElement> referencing_elements = {referencing_element}; | 1071 std::vector<DataElement> referencing_elements = {referencing_element}; |
| 1061 std::set<std::string> referenced_blobs_set = {kId}; | 1072 std::set<std::string> referenced_blobs_set = {kId}; |
| 1062 | 1073 |
| 1063 scoped_refptr<TestableBlobDispatcherHost> host2( | 1074 scoped_refptr<TestableBlobDispatcherHost> host2( |
| 1064 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_)); | 1075 new TestableBlobDispatcherHost(chrome_blob_storage_context_, |
| 1076 file_system_context_.get(), &sink_)); |
| 1065 | 1077 |
| 1066 // We want to have a blob referencing another blob that is building, both on | 1078 // We want to have a blob referencing another blob that is building, both on |
| 1067 // the same host and a different host. After we cancel the first blob, the | 1079 // the same host and a different host. After we cancel the first blob, the |
| 1068 // others should cancel as well. | 1080 // others should cancel as well. |
| 1069 | 1081 |
| 1070 // First we start the referenced blob. | 1082 // First we start the referenced blob. |
| 1071 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 1083 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
| 1072 std::string(kContentDisposition), | 1084 std::string(kContentDisposition), |
| 1073 std::set<std::string>()); | 1085 std::set<std::string>()); |
| 1074 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 1086 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1114 const std::string kId("id"); | 1126 const std::string kId("id"); |
| 1115 const std::string kSameHostReferencingId("id2"); | 1127 const std::string kSameHostReferencingId("id2"); |
| 1116 const std::string kDifferentHostReferencingId("id3"); | 1128 const std::string kDifferentHostReferencingId("id3"); |
| 1117 // Data elements for our transfer & checking messages. | 1129 // Data elements for our transfer & checking messages. |
| 1118 DataElement referencing_element; | 1130 DataElement referencing_element; |
| 1119 referencing_element.SetToBlob(kId); | 1131 referencing_element.SetToBlob(kId); |
| 1120 std::vector<DataElement> referencing_elements = {referencing_element}; | 1132 std::vector<DataElement> referencing_elements = {referencing_element}; |
| 1121 std::set<std::string> referenced_blobs_set = {kId}; | 1133 std::set<std::string> referenced_blobs_set = {kId}; |
| 1122 | 1134 |
| 1123 scoped_refptr<TestableBlobDispatcherHost> host2( | 1135 scoped_refptr<TestableBlobDispatcherHost> host2( |
| 1124 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_)); | 1136 new TestableBlobDispatcherHost(chrome_blob_storage_context_, |
| 1137 file_system_context_.get(), &sink_)); |
| 1125 | 1138 |
| 1126 // We want to have a blob referencing another blob that is building, both on | 1139 // We want to have a blob referencing another blob that is building, both on |
| 1127 // the same host and a different host. When we destroy the host, the other | 1140 // the same host and a different host. When we destroy the host, the other |
| 1128 // blob should cancel, as well as the blob on the other host. | 1141 // blob should cancel, as well as the blob on the other host. |
| 1129 | 1142 |
| 1130 // First we start the referenced blob. | 1143 // First we start the referenced blob. |
| 1131 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 1144 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
| 1132 std::string(kContentDisposition), | 1145 std::string(kContentDisposition), |
| 1133 std::set<std::string>()); | 1146 std::set<std::string>()); |
| 1134 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 1147 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1192 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, | 1205 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, |
| 1193 same_host_error_code); | 1206 same_host_error_code); |
| 1194 EXPECT_FALSE(other_host_built); | 1207 EXPECT_FALSE(other_host_built); |
| 1195 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, | 1208 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, |
| 1196 other_host_error_code); | 1209 other_host_error_code); |
| 1197 | 1210 |
| 1198 sink_.ClearMessages(); | 1211 sink_.ClearMessages(); |
| 1199 } | 1212 } |
| 1200 | 1213 |
| 1201 } // namespace content | 1214 } // namespace content |
| OLD | NEW |