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/dom_storage/local_storage_context_mojo.h" | 5 #include "content/browser/dom_storage/local_storage_context_mojo.h" |
6 | 6 |
| 7 #include "base/files/file_enumerator.h" |
| 8 #include "base/files/scoped_temp_dir.h" |
7 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "components/filesystem/public/interfaces/file_system.mojom.h" |
8 #include "components/leveldb/public/cpp/util.h" | 11 #include "components/leveldb/public/cpp/util.h" |
| 12 #include "content/public/browser/browser_thread.h" |
9 #include "content/public/test/test_browser_thread_bundle.h" | 13 #include "content/public/test/test_browser_thread_bundle.h" |
10 #include "content/test/mock_leveldb_database.h" | 14 #include "content/test/mock_leveldb_database.h" |
11 #include "mojo/public/cpp/bindings/binding.h" | 15 #include "mojo/public/cpp/bindings/binding.h" |
| 16 #include "mojo/public/cpp/bindings/binding_set.h" |
| 17 #include "services/file/file_service.h" |
| 18 #include "services/file/public/interfaces/constants.mojom.h" |
| 19 #include "services/file/user_id_map.h" |
| 20 #include "services/service_manager/public/cpp/interface_factory.h" |
| 21 #include "services/service_manager/public/cpp/interface_registry.h" |
| 22 #include "services/service_manager/public/cpp/service_context.h" |
| 23 #include "services/service_manager/public/cpp/service_test.h" |
| 24 #include "services/service_manager/public/interfaces/service_factory.mojom.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
13 | 26 |
14 using leveldb::StdStringToUint8Vector; | 27 using leveldb::StdStringToUint8Vector; |
15 using leveldb::Uint8VectorToStdString; | 28 using leveldb::Uint8VectorToStdString; |
16 | 29 |
17 namespace content { | 30 namespace content { |
18 | 31 |
19 namespace { | 32 namespace { |
20 | 33 |
21 void NoOpSuccess(bool success) {} | 34 void NoOpSuccess(bool success) {} |
(...skipping 30 matching lines...) Expand all Loading... |
52 mock_data_[StdStringToUint8Vector(key)] = StdStringToUint8Vector(value); | 65 mock_data_[StdStringToUint8Vector(key)] = StdStringToUint8Vector(value); |
53 } | 66 } |
54 | 67 |
55 private: | 68 private: |
56 TestBrowserThreadBundle thread_bundle_; | 69 TestBrowserThreadBundle thread_bundle_; |
57 std::map<std::vector<uint8_t>, std::vector<uint8_t>> mock_data_; | 70 std::map<std::vector<uint8_t>, std::vector<uint8_t>> mock_data_; |
58 MockLevelDBDatabase db_; | 71 MockLevelDBDatabase db_; |
59 mojo::Binding<leveldb::mojom::LevelDBDatabase> db_binding_; | 72 mojo::Binding<leveldb::mojom::LevelDBDatabase> db_binding_; |
60 | 73 |
61 std::unique_ptr<LocalStorageContextMojo> context_; | 74 std::unique_ptr<LocalStorageContextMojo> context_; |
| 75 |
| 76 DISALLOW_COPY_AND_ASSIGN(LocalStorageContextMojoTest); |
62 }; | 77 }; |
63 | 78 |
64 TEST_F(LocalStorageContextMojoTest, Basic) { | 79 TEST_F(LocalStorageContextMojoTest, Basic) { |
65 auto key = StdStringToUint8Vector("key"); | 80 auto key = StdStringToUint8Vector("key"); |
66 auto value = StdStringToUint8Vector("value"); | 81 auto value = StdStringToUint8Vector("value"); |
67 | 82 |
68 mojom::LevelDBWrapperPtr wrapper; | 83 mojom::LevelDBWrapperPtr wrapper; |
69 context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")), | 84 context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")), |
70 MakeRequest(&wrapper)); | 85 MakeRequest(&wrapper)); |
71 wrapper->Put(key, value, "source", base::Bind(&NoOpSuccess)); | 86 wrapper->Put(key, value, "source", base::Bind(&NoOpSuccess)); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 StdStringToUint8Vector("key"), | 147 StdStringToUint8Vector("key"), |
133 base::Bind(&GetCallback, run_loop.QuitClosure(), &success, &result)); | 148 base::Bind(&GetCallback, run_loop.QuitClosure(), &success, &result)); |
134 run_loop.Run(); | 149 run_loop.Run(); |
135 EXPECT_FALSE(success); | 150 EXPECT_FALSE(success); |
136 } | 151 } |
137 | 152 |
138 TEST_F(LocalStorageContextMojoTest, VersionOnlyWrittenOnCommit) { | 153 TEST_F(LocalStorageContextMojoTest, VersionOnlyWrittenOnCommit) { |
139 mojom::LevelDBWrapperPtr wrapper; | 154 mojom::LevelDBWrapperPtr wrapper; |
140 context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")), | 155 context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")), |
141 MakeRequest(&wrapper)); | 156 MakeRequest(&wrapper)); |
142 | |
143 base::RunLoop run_loop; | 157 base::RunLoop run_loop; |
144 bool success = false; | 158 bool success = false; |
145 std::vector<uint8_t> result; | 159 std::vector<uint8_t> result; |
146 wrapper->Get( | 160 wrapper->Get( |
147 StdStringToUint8Vector("key"), | 161 StdStringToUint8Vector("key"), |
148 base::Bind(&GetCallback, run_loop.QuitClosure(), &success, &result)); | 162 base::Bind(&GetCallback, run_loop.QuitClosure(), &success, &result)); |
149 run_loop.Run(); | 163 run_loop.Run(); |
150 EXPECT_FALSE(success); | 164 EXPECT_FALSE(success); |
151 wrapper.reset(); | 165 wrapper.reset(); |
152 | 166 |
153 base::RunLoop().RunUntilIdle(); | 167 base::RunLoop().RunUntilIdle(); |
154 EXPECT_TRUE(mock_data().empty()); | 168 EXPECT_TRUE(mock_data().empty()); |
155 } | 169 } |
156 | 170 |
| 171 namespace { |
| 172 |
| 173 class ServiceTestClient : public service_manager::test::ServiceTestClient, |
| 174 public service_manager::mojom::ServiceFactory, |
| 175 public service_manager::InterfaceFactory< |
| 176 service_manager::mojom::ServiceFactory> { |
| 177 public: |
| 178 explicit ServiceTestClient(service_manager::test::ServiceTest* test) |
| 179 : service_manager::test::ServiceTestClient(test) {} |
| 180 ~ServiceTestClient() override {} |
| 181 |
| 182 protected: |
| 183 bool OnConnect(const service_manager::ServiceInfo& remote_info, |
| 184 service_manager::InterfaceRegistry* registry) override { |
| 185 registry->AddInterface<service_manager::mojom::ServiceFactory>(this); |
| 186 return true; |
| 187 } |
| 188 |
| 189 void CreateService(service_manager::mojom::ServiceRequest request, |
| 190 const std::string& name) override { |
| 191 if (name == file::mojom::kServiceName) { |
| 192 file_service_context_.reset(new service_manager::ServiceContext( |
| 193 file::CreateFileService( |
| 194 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE), |
| 195 BrowserThread::GetTaskRunnerForThread(BrowserThread::DB)), |
| 196 std::move(request))); |
| 197 } |
| 198 } |
| 199 |
| 200 void Create(const service_manager::Identity& remote_identity, |
| 201 service_manager::mojom::ServiceFactoryRequest request) override { |
| 202 service_factory_bindings_.AddBinding(this, std::move(request)); |
| 203 } |
| 204 |
| 205 private: |
| 206 mojo::BindingSet<service_manager::mojom::ServiceFactory> |
| 207 service_factory_bindings_; |
| 208 std::unique_ptr<service_manager::ServiceContext> file_service_context_; |
| 209 }; |
| 210 |
| 211 } // namespace |
| 212 |
| 213 class LocalStorageContextMojoTestWithService |
| 214 : public service_manager::test::ServiceTest { |
| 215 public: |
| 216 LocalStorageContextMojoTestWithService() |
| 217 : ServiceTest("content_unittests", false) {} |
| 218 ~LocalStorageContextMojoTestWithService() override {} |
| 219 |
| 220 protected: |
| 221 void SetUp() override { |
| 222 ServiceTest::SetUp(); |
| 223 ASSERT_TRUE(temp_path_.CreateUniqueTempDir()); |
| 224 file::AssociateServiceUserIdWithUserDir(test_userid(), |
| 225 temp_path_.GetPath()); |
| 226 } |
| 227 |
| 228 void TearDown() override { |
| 229 temp_path_.Take(); |
| 230 ServiceTest::TearDown(); |
| 231 } |
| 232 |
| 233 std::unique_ptr<service_manager::Service> CreateService() override { |
| 234 return base::MakeUnique<ServiceTestClient>(this); |
| 235 } |
| 236 |
| 237 std::unique_ptr<base::MessageLoop> CreateMessageLoop() override { |
| 238 return nullptr; |
| 239 } |
| 240 |
| 241 const base::FilePath& temp_path() { return temp_path_.GetPath(); } |
| 242 |
| 243 base::FilePath FirstEntryInDir() { |
| 244 base::FileEnumerator enumerator( |
| 245 temp_path(), false /* recursive */, |
| 246 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES); |
| 247 return enumerator.Next(); |
| 248 } |
| 249 |
| 250 void DoTestPut(LocalStorageContextMojo* context, |
| 251 const std::vector<uint8_t>& key, |
| 252 const std::vector<uint8_t>& value) { |
| 253 mojom::LevelDBWrapperPtr wrapper; |
| 254 context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")), |
| 255 MakeRequest(&wrapper)); |
| 256 wrapper->Put(key, value, "source", base::Bind(&NoOpSuccess)); |
| 257 wrapper.reset(); |
| 258 base::RunLoop().RunUntilIdle(); |
| 259 } |
| 260 |
| 261 bool DoTestGet(LocalStorageContextMojo* context, |
| 262 const std::vector<uint8_t>& key, |
| 263 std::vector<uint8_t>* result) { |
| 264 mojom::LevelDBWrapperPtr wrapper; |
| 265 context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")), |
| 266 MakeRequest(&wrapper)); |
| 267 base::RunLoop run_loop; |
| 268 bool success = false; |
| 269 wrapper->Get(key, base::Bind(&GetCallback, run_loop.QuitClosure(), &success, |
| 270 result)); |
| 271 run_loop.Run(); |
| 272 return success; |
| 273 } |
| 274 |
| 275 private: |
| 276 TestBrowserThreadBundle thread_bundle_; |
| 277 base::ScopedTempDir temp_path_; |
| 278 |
| 279 DISALLOW_COPY_AND_ASSIGN(LocalStorageContextMojoTestWithService); |
| 280 }; |
| 281 |
| 282 // Enable when http://crbug.com/677194 is fixed and ServiceTest works |
| 283 // correctly on Android. |
| 284 #if defined(OS_ANDROID) |
| 285 #define MAYBE_InMemory DISABLED_InMemory |
| 286 #else |
| 287 #define MAYBE_InMemory InMemory |
| 288 #endif |
| 289 TEST_F(LocalStorageContextMojoTestWithService, MAYBE_InMemory) { |
| 290 auto context = |
| 291 base::MakeUnique<LocalStorageContextMojo>(connector(), base::FilePath()); |
| 292 auto key = StdStringToUint8Vector("key"); |
| 293 auto value = StdStringToUint8Vector("value"); |
| 294 |
| 295 mojom::LevelDBWrapperPtr wrapper; |
| 296 context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")), |
| 297 MakeRequest(&wrapper)); |
| 298 |
| 299 DoTestPut(context.get(), key, value); |
| 300 std::vector<uint8_t> result; |
| 301 EXPECT_TRUE(DoTestGet(context.get(), key, &result)); |
| 302 EXPECT_EQ(value, result); |
| 303 |
| 304 context.reset(); |
| 305 base::RunLoop().RunUntilIdle(); |
| 306 |
| 307 // Should not have created any files. |
| 308 EXPECT_TRUE(FirstEntryInDir().empty()); |
| 309 |
| 310 // Re-opening should get fresh data. |
| 311 context.reset(new LocalStorageContextMojo(connector(), base::FilePath())); |
| 312 EXPECT_FALSE(DoTestGet(context.get(), key, &result)); |
| 313 } |
| 314 |
| 315 // Enable when http://crbug.com/677194 is fixed and ServiceTest works |
| 316 // correctly on Android. |
| 317 #if defined(OS_ANDROID) |
| 318 #define MAYBE_InMemoryInvalidPath DISABLED_InMemoryInvalidPath |
| 319 #else |
| 320 #define MAYBE_InMemoryInvalidPath InMemoryInvalidPath |
| 321 #endif |
| 322 TEST_F(LocalStorageContextMojoTestWithService, MAYBE_InMemoryInvalidPath) { |
| 323 auto context = base::MakeUnique<LocalStorageContextMojo>( |
| 324 connector(), base::FilePath(FILE_PATH_LITERAL("../../"))); |
| 325 auto key = StdStringToUint8Vector("key"); |
| 326 auto value = StdStringToUint8Vector("value"); |
| 327 |
| 328 mojom::LevelDBWrapperPtr wrapper; |
| 329 context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")), |
| 330 MakeRequest(&wrapper)); |
| 331 |
| 332 DoTestPut(context.get(), key, value); |
| 333 std::vector<uint8_t> result; |
| 334 EXPECT_TRUE(DoTestGet(context.get(), key, &result)); |
| 335 EXPECT_EQ(value, result); |
| 336 |
| 337 context.reset(); |
| 338 base::RunLoop().RunUntilIdle(); |
| 339 |
| 340 // Should not have created any files. |
| 341 EXPECT_TRUE(FirstEntryInDir().empty()); |
| 342 } |
| 343 |
| 344 // Enable when http://crbug.com/677194 is fixed and ServiceTest works |
| 345 // correctly on Android. |
| 346 #if defined(OS_ANDROID) |
| 347 #define MAYBE_OnDisk DISABLED_OnDisk |
| 348 #else |
| 349 #define MAYBE_OnDisk OnDisk |
| 350 #endif |
| 351 TEST_F(LocalStorageContextMojoTestWithService, MAYBE_OnDisk) { |
| 352 base::FilePath test_path(FILE_PATH_LITERAL("test_path")); |
| 353 auto context = |
| 354 base::MakeUnique<LocalStorageContextMojo>(connector(), test_path); |
| 355 auto key = StdStringToUint8Vector("key"); |
| 356 auto value = StdStringToUint8Vector("value"); |
| 357 |
| 358 DoTestPut(context.get(), key, value); |
| 359 std::vector<uint8_t> result; |
| 360 EXPECT_TRUE(DoTestGet(context.get(), key, &result)); |
| 361 EXPECT_EQ(value, result); |
| 362 |
| 363 context.reset(); |
| 364 base::RunLoop().RunUntilIdle(); |
| 365 |
| 366 // Should have created files. |
| 367 EXPECT_EQ(test_path, FirstEntryInDir().BaseName()); |
| 368 |
| 369 // Should be able to re-open. |
| 370 context.reset(new LocalStorageContextMojo(connector(), test_path)); |
| 371 EXPECT_TRUE(DoTestGet(context.get(), key, &result)); |
| 372 EXPECT_EQ(value, result); |
| 373 } |
| 374 |
157 } // namespace content | 375 } // namespace content |
OLD | NEW |