TestReadWrite.cpp (44852B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "gtest/gtest.h" 8 #include "mozilla/BasePrincipal.h" 9 #include "mozilla/UniquePtr.h" 10 #include "mozilla/dom/ServiceWorkerRegistrar.h" 11 #include "mozilla/dom/ServiceWorkerRegistrarTypes.h" 12 #include "mozilla/ipc/PBackgroundSharedTypes.h" 13 #include "nsAppDirectoryServiceDefs.h" 14 #include "nsIFile.h" 15 #include "nsIOutputStream.h" 16 #include "nsIServiceWorkerManager.h" 17 #include "nsNetUtil.h" 18 #include "nsPrintfCString.h" 19 #include "prtime.h" 20 21 using namespace mozilla::dom; 22 using namespace mozilla::ipc; 23 24 namespace { 25 26 struct HandlerStats { 27 uint32_t swLoadCount; 28 uint32_t swUpdatedCount; 29 uint32_t swUnregisteredCount; 30 nsCString lastValue; 31 32 uint32_t swLoad2Count; 33 uint32_t swUpdated2Count; 34 uint32_t swUnregistered2Count; 35 nsCString lastValue2; 36 }; 37 38 constinit mozilla::UniquePtr<HandlerStats> gHandlerStats; 39 40 void MaybeCreateHandlerStats() { 41 if (!gHandlerStats) { 42 gHandlerStats.reset(new HandlerStats()); 43 } 44 } 45 46 void swLoaded(const ServiceWorkerRegistrationData& data, 47 const nsACString& aValue) { 48 MaybeCreateHandlerStats(); 49 gHandlerStats->swLoadCount++; 50 gHandlerStats->lastValue = aValue; 51 } 52 53 void swUpdated(const ServiceWorkerRegistrationData& data) { 54 MaybeCreateHandlerStats(); 55 gHandlerStats->swUpdatedCount++; 56 } 57 58 void swUnregistered(const ServiceWorkerRegistrationData& data) { 59 MaybeCreateHandlerStats(); 60 gHandlerStats->swUnregisteredCount++; 61 } 62 63 void swLoaded2(const ServiceWorkerRegistrationData& data, 64 const nsACString& aValue) { 65 MaybeCreateHandlerStats(); 66 gHandlerStats->swLoad2Count++; 67 gHandlerStats->lastValue2 = aValue; 68 } 69 70 void swUpdated2(const ServiceWorkerRegistrationData& data) { 71 MaybeCreateHandlerStats(); 72 gHandlerStats->swUpdated2Count++; 73 } 74 75 void swUnregistered2(const ServiceWorkerRegistrationData& data) { 76 MaybeCreateHandlerStats(); 77 gHandlerStats->swUnregistered2Count++; 78 } 79 80 } // namespace 81 82 class ServiceWorkerRegistrarTest : public ServiceWorkerRegistrar { 83 public: 84 ServiceWorkerRegistrarTest() { 85 nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, 86 getter_AddRefs(mProfileDir)); 87 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv)); 88 MOZ_RELEASE_ASSERT(mProfileDir); 89 90 mExpandoHandlers.AppendElement(ExpandoHandler{ 91 nsCString("handler_test"), swLoaded, swUpdated, swUnregistered}); 92 mExpandoHandlers.AppendElement(ExpandoHandler{ 93 nsCString("handler_test2"), swLoaded2, swUpdated2, swUnregistered2}); 94 } 95 96 nsresult TestReadData() { return ReadData(); } 97 nsresult TestWriteData() MOZ_NO_THREAD_SAFETY_ANALYSIS { 98 return WriteData(mData); 99 } 100 void TestDeleteData() { DeleteData(); } 101 102 void TestRegisterServiceWorker(const ServiceWorkerRegistrationData& aData) { 103 mozilla::MonitorAutoLock lock(mMonitor); 104 RegisterServiceWorkerInternal(aData); 105 } 106 107 nsTArray<ServiceWorkerData>& TestGetData() MOZ_NO_THREAD_SAFETY_ANALYSIS { 108 return mData; 109 } 110 }; 111 112 already_AddRefed<nsIFile> GetFile() { 113 nsCOMPtr<nsIFile> file; 114 nsresult rv = 115 NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(file)); 116 if (NS_WARN_IF(NS_FAILED(rv))) { 117 return nullptr; 118 } 119 120 file->Append(nsLiteralString(SERVICEWORKERREGISTRAR_FILE)); 121 return file.forget(); 122 } 123 124 bool CreateFile(const nsACString& aData) { 125 nsCOMPtr<nsIFile> file = GetFile(); 126 127 nsCOMPtr<nsIOutputStream> stream; 128 nsresult rv = NS_NewLocalFileOutputStream(getter_AddRefs(stream), file); 129 if (NS_WARN_IF(NS_FAILED(rv))) { 130 return false; 131 } 132 133 uint32_t count; 134 rv = stream->Write(aData.Data(), aData.Length(), &count); 135 if (NS_WARN_IF(NS_FAILED(rv))) { 136 return false; 137 } 138 139 if (count != aData.Length()) { 140 return false; 141 } 142 143 return true; 144 } 145 146 TEST(ServiceWorkerRegistrar, TestNoFile) 147 { 148 nsCOMPtr<nsIFile> file = GetFile(); 149 ASSERT_TRUE(file) 150 << "GetFile must return a nsIFIle"; 151 152 bool exists; 153 nsresult rv = file->Exists(&exists); 154 ASSERT_EQ(NS_OK, rv) << "nsIFile::Exists cannot fail"; 155 156 if (exists) { 157 rv = file->Remove(false); 158 ASSERT_EQ(NS_OK, rv) << "nsIFile::Remove cannot fail"; 159 } 160 161 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 162 163 rv = swr->TestReadData(); 164 ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail"; 165 166 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& data = 167 swr->TestGetData(); 168 ASSERT_EQ((uint32_t)0, data.Length()) 169 << "No data should be found in an empty file"; 170 } 171 172 TEST(ServiceWorkerRegistrar, TestEmptyFile) 173 { 174 ASSERT_TRUE(CreateFile(""_ns)) 175 << "CreateFile should not fail"; 176 177 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 178 179 nsresult rv = swr->TestReadData(); 180 ASSERT_NE(NS_OK, rv) << "ReadData() should fail if the file is empty"; 181 182 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& data = 183 swr->TestGetData(); 184 ASSERT_EQ((uint32_t)0, data.Length()) 185 << "No data should be found in an empty file"; 186 } 187 188 TEST(ServiceWorkerRegistrar, TestRightVersionFile) 189 { 190 nsCString buffer; 191 buffer.AppendInt(static_cast<uint32_t>(SERVICEWORKERREGISTRAR_VERSION)); 192 buffer.Append("\n"); 193 194 ASSERT_TRUE(CreateFile(buffer)) 195 << "CreateFile should not fail"; 196 197 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 198 199 nsresult rv = swr->TestReadData(); 200 ASSERT_EQ(NS_OK, rv) 201 << "ReadData() should not fail when the version is correct"; 202 203 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& data = 204 swr->TestGetData(); 205 ASSERT_EQ((uint32_t)0, data.Length()) 206 << "No data should be found in an empty file"; 207 } 208 209 TEST(ServiceWorkerRegistrar, TestWrongVersionFile) 210 { 211 nsCString buffer; 212 buffer.AppendInt(static_cast<uint32_t>(SERVICEWORKERREGISTRAR_VERSION)); 213 buffer.Append("bla\n"); 214 215 ASSERT_TRUE(CreateFile(buffer)) 216 << "CreateFile should not fail"; 217 218 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 219 220 nsresult rv = swr->TestReadData(); 221 ASSERT_NE(NS_OK, rv) 222 << "ReadData() should fail when the version is not correct"; 223 224 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& data = 225 swr->TestGetData(); 226 ASSERT_EQ((uint32_t)0, data.Length()) 227 << "No data should be found in an empty file"; 228 } 229 230 TEST(ServiceWorkerRegistrar, TestReadData) 231 { 232 nsCString buffer; 233 buffer.AppendInt(static_cast<uint32_t>(SERVICEWORKERREGISTRAR_VERSION)); 234 buffer.Append("\n"); 235 236 buffer.AppendLiteral("^inBrowser=1\n"); 237 buffer.AppendLiteral("https://scope_0.org\ncurrentWorkerURL 0\n"); 238 buffer.Append(SERVICEWORKERREGISTRAR_TRUE "\n"); 239 buffer.AppendLiteral("cacheName 0\n"); 240 buffer.AppendInt(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 241 16); 242 buffer.AppendLiteral("\n"); 243 buffer.AppendInt(0); 244 buffer.AppendLiteral("\n"); 245 buffer.AppendInt(0); 246 buffer.AppendLiteral("\n"); 247 buffer.AppendInt(0); 248 buffer.AppendLiteral("\n"); 249 buffer.AppendInt(0); 250 buffer.AppendLiteral("\n"); 251 buffer.AppendLiteral("true\n"); 252 buffer.AppendInt(0); 253 buffer.AppendLiteral("\n"); 254 buffer.AppendInt(0); 255 buffer.AppendLiteral("\n"); 256 buffer.AppendInt(0); 257 buffer.AppendLiteral("\n"); 258 buffer.AppendInt(0); 259 buffer.AppendLiteral("\n"); 260 buffer.AppendInt(0); 261 buffer.AppendLiteral("\n"); 262 buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 263 264 buffer.AppendLiteral("\n"); 265 buffer.AppendLiteral("https://scope_1.org\ncurrentWorkerURL 1\n"); 266 buffer.Append(SERVICEWORKERREGISTRAR_FALSE "\n"); 267 buffer.AppendLiteral("cacheName 1\n"); 268 buffer.AppendInt(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_ALL, 16); 269 buffer.AppendLiteral("\n"); 270 PRTime ts = PR_Now(); 271 buffer.AppendInt(ts); 272 buffer.AppendLiteral("\n"); 273 buffer.AppendInt(ts); 274 buffer.AppendLiteral("\n"); 275 buffer.AppendInt(ts); 276 buffer.AppendLiteral("\n"); 277 buffer.AppendInt(1); 278 buffer.AppendLiteral("\n"); 279 buffer.AppendLiteral("false\n"); 280 buffer.AppendInt(0); 281 buffer.AppendLiteral("\n"); 282 buffer.AppendInt(0); 283 buffer.AppendLiteral("\n"); 284 buffer.AppendInt(0); 285 buffer.AppendLiteral("\n"); 286 buffer.AppendInt(0); 287 buffer.AppendLiteral("\n"); 288 buffer.AppendInt(0); 289 buffer.AppendLiteral("\n"); 290 buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 291 292 ASSERT_TRUE(CreateFile(buffer)) 293 << "CreateFile should not fail"; 294 295 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 296 297 nsresult rv = swr->TestReadData(); 298 ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail"; 299 300 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& data = 301 swr->TestGetData(); 302 ASSERT_EQ((uint32_t)2, data.Length()) << "2 entries should be found"; 303 304 const mozilla::ipc::PrincipalInfo& info0 = data[0].mRegistration.principal(); 305 ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 306 << "First principal must be content"; 307 const mozilla::ipc::ContentPrincipalInfo& cInfo0 = 308 data[0].mRegistration.principal(); 309 310 nsAutoCString suffix0; 311 cInfo0.attrs().CreateSuffix(suffix0); 312 313 ASSERT_STREQ("", suffix0.get()); 314 ASSERT_STREQ("https://scope_0.org", cInfo0.spec().get()); 315 ASSERT_STREQ("https://scope_0.org", data[0].mRegistration.scope().get()); 316 ASSERT_STREQ("currentWorkerURL 0", 317 data[0].mRegistration.currentWorkerURL().get()); 318 ASSERT_TRUE(data[0].mRegistration.currentWorkerHandlesFetch()); 319 ASSERT_STREQ("cacheName 0", 320 NS_ConvertUTF16toUTF8(data[0].mRegistration.cacheName()).get()); 321 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 322 data[0].mRegistration.updateViaCache()); 323 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerInstalledTime()); 324 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerActivatedTime()); 325 ASSERT_EQ((int64_t)0, data[0].mRegistration.lastUpdateTime()); 326 ASSERT_EQ(false, data[0].mRegistration.navigationPreloadState().enabled()); 327 ASSERT_STREQ( 328 "true", 329 data[0].mRegistration.navigationPreloadState().headerValue().get()); 330 331 const mozilla::ipc::PrincipalInfo& info1 = data[1].mRegistration.principal(); 332 ASSERT_EQ(info1.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 333 << "First principal must be content"; 334 const mozilla::ipc::ContentPrincipalInfo& cInfo1 = 335 data[1].mRegistration.principal(); 336 337 nsAutoCString suffix1; 338 cInfo1.attrs().CreateSuffix(suffix1); 339 340 ASSERT_STREQ("", suffix1.get()); 341 ASSERT_STREQ("https://scope_1.org", cInfo1.spec().get()); 342 ASSERT_STREQ("https://scope_1.org", data[1].mRegistration.scope().get()); 343 ASSERT_STREQ("currentWorkerURL 1", 344 data[1].mRegistration.currentWorkerURL().get()); 345 ASSERT_FALSE(data[1].mRegistration.currentWorkerHandlesFetch()); 346 ASSERT_STREQ("cacheName 1", 347 NS_ConvertUTF16toUTF8(data[1].mRegistration.cacheName()).get()); 348 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_ALL, 349 data[1].mRegistration.updateViaCache()); 350 ASSERT_EQ((int64_t)ts, data[1].mRegistration.currentWorkerInstalledTime()); 351 ASSERT_EQ((int64_t)ts, data[1].mRegistration.currentWorkerActivatedTime()); 352 ASSERT_EQ((int64_t)ts, data[1].mRegistration.lastUpdateTime()); 353 ASSERT_EQ(true, data[1].mRegistration.navigationPreloadState().enabled()); 354 ASSERT_STREQ( 355 "false", 356 data[1].mRegistration.navigationPreloadState().headerValue().get()); 357 } 358 359 TEST(ServiceWorkerRegistrar, TestDeleteData) 360 { 361 ASSERT_TRUE(CreateFile("Foobar"_ns)) 362 << "CreateFile should not fail"; 363 364 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 365 366 swr->TestDeleteData(); 367 368 nsCOMPtr<nsIFile> file = GetFile(); 369 370 bool exists; 371 nsresult rv = file->Exists(&exists); 372 ASSERT_EQ(NS_OK, rv) << "nsIFile::Exists cannot fail"; 373 374 ASSERT_FALSE(exists) 375 << "The file should not exist after a DeleteData()."; 376 } 377 378 TEST(ServiceWorkerRegistrar, TestWriteData) 379 { 380 { 381 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 382 383 ServiceWorkerRegistrationData reg; 384 385 reg.scope() = "https://scope_write_0.org"_ns; 386 reg.currentWorkerURL() = "currentWorkerURL write 0"_ns; 387 reg.currentWorkerHandlesFetch() = true; 388 reg.cacheName() = u"cacheName write 0"_ns; 389 reg.updateViaCache() = 390 nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS; 391 392 reg.currentWorkerInstalledTime() = PR_Now(); 393 reg.currentWorkerActivatedTime() = PR_Now(); 394 reg.lastUpdateTime() = PR_Now(); 395 396 const auto spec = "spec write 0"_ns; 397 reg.principal() = mozilla::ipc::ContentPrincipalInfo( 398 mozilla::OriginAttributes(), spec, spec, mozilla::Nothing(), spec); 399 400 swr->TestRegisterServiceWorker(reg); 401 402 nsresult rv = swr->TestWriteData(); 403 ASSERT_EQ(NS_OK, rv) << "WriteData() should not fail"; 404 } 405 406 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 407 408 nsresult rv = swr->TestReadData(); 409 ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail"; 410 411 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& dataArr = 412 swr->TestGetData(); 413 ASSERT_EQ((uint32_t)1, dataArr.Length()) << "1 entries should be found"; 414 415 const auto& data = dataArr[0]; 416 417 ASSERT_EQ(data.mRegistration.principal().type(), 418 mozilla::ipc::PrincipalInfo::TContentPrincipalInfo); 419 const mozilla::ipc::ContentPrincipalInfo& cInfo = 420 data.mRegistration.principal(); 421 422 mozilla::OriginAttributes attrs; 423 nsAutoCString suffix, expectSuffix; 424 attrs.CreateSuffix(expectSuffix); 425 cInfo.attrs().CreateSuffix(suffix); 426 427 ASSERT_STREQ(expectSuffix.get(), suffix.get()); 428 429 ASSERT_STREQ("https://scope_write_0.org", cInfo.spec().get()); 430 ASSERT_STREQ("https://scope_write_0.org", data.mRegistration.scope().get()); 431 ASSERT_STREQ("currentWorkerURL write 0", 432 data.mRegistration.currentWorkerURL().get()); 433 434 ASSERT_EQ(true, data.mRegistration.currentWorkerHandlesFetch()); 435 436 ASSERT_STREQ("cacheName write 0", 437 NS_ConvertUTF16toUTF8(data.mRegistration.cacheName()).get()); 438 439 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 440 data.mRegistration.updateViaCache()); 441 442 ASSERT_NE((int64_t)0, data.mRegistration.currentWorkerInstalledTime()); 443 ASSERT_NE((int64_t)0, data.mRegistration.currentWorkerActivatedTime()); 444 ASSERT_NE((int64_t)0, data.mRegistration.lastUpdateTime()); 445 } 446 447 TEST(ServiceWorkerRegistrar, TestVersion2Migration) 448 { 449 nsAutoCString buffer( 450 "2" 451 "\n"); 452 453 buffer.AppendLiteral("^appId=123&inBrowser=1\n"); 454 buffer.AppendLiteral( 455 "spec 0\nhttps://scope_0.org\nscriptSpec 0\ncurrentWorkerURL " 456 "0\nactiveCache 0\nwaitingCache 0\n"); 457 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 458 459 buffer.AppendLiteral("\n"); 460 buffer.AppendLiteral( 461 "spec 1\nhttps://scope_1.org\nscriptSpec 1\ncurrentWorkerURL " 462 "1\nactiveCache 1\nwaitingCache 1\n"); 463 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 464 465 ASSERT_TRUE(CreateFile(buffer)) 466 << "CreateFile should not fail"; 467 468 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 469 470 nsresult rv = swr->TestReadData(); 471 ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail"; 472 473 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& data = 474 swr->TestGetData(); 475 ASSERT_EQ((uint32_t)2, data.Length()) << "2 entries should be found"; 476 477 const mozilla::ipc::PrincipalInfo& info0 = data[0].mRegistration.principal(); 478 ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 479 << "First principal must be content"; 480 const mozilla::ipc::ContentPrincipalInfo& cInfo0 = 481 data[0].mRegistration.principal(); 482 483 nsAutoCString suffix0; 484 cInfo0.attrs().CreateSuffix(suffix0); 485 486 ASSERT_STREQ("", suffix0.get()); 487 ASSERT_STREQ("https://scope_0.org", cInfo0.spec().get()); 488 ASSERT_STREQ("https://scope_0.org", data[0].mRegistration.scope().get()); 489 ASSERT_STREQ("currentWorkerURL 0", 490 data[0].mRegistration.currentWorkerURL().get()); 491 ASSERT_EQ(true, data[0].mRegistration.currentWorkerHandlesFetch()); 492 ASSERT_STREQ("activeCache 0", 493 NS_ConvertUTF16toUTF8(data[0].mRegistration.cacheName()).get()); 494 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 495 data[0].mRegistration.updateViaCache()); 496 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerInstalledTime()); 497 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerActivatedTime()); 498 ASSERT_EQ((int64_t)0, data[0].mRegistration.lastUpdateTime()); 499 500 const mozilla::ipc::PrincipalInfo& info1 = data[1].mRegistration.principal(); 501 ASSERT_EQ(info1.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 502 << "First principal must be content"; 503 const mozilla::ipc::ContentPrincipalInfo& cInfo1 = 504 data[1].mRegistration.principal(); 505 506 nsAutoCString suffix1; 507 cInfo1.attrs().CreateSuffix(suffix1); 508 509 ASSERT_STREQ("", suffix1.get()); 510 ASSERT_STREQ("https://scope_1.org", cInfo1.spec().get()); 511 ASSERT_STREQ("https://scope_1.org", data[1].mRegistration.scope().get()); 512 ASSERT_STREQ("currentWorkerURL 1", 513 data[1].mRegistration.currentWorkerURL().get()); 514 ASSERT_EQ(true, data[1].mRegistration.currentWorkerHandlesFetch()); 515 ASSERT_STREQ("activeCache 1", 516 NS_ConvertUTF16toUTF8(data[1].mRegistration.cacheName()).get()); 517 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 518 data[1].mRegistration.updateViaCache()); 519 ASSERT_EQ((int64_t)0, data[1].mRegistration.currentWorkerInstalledTime()); 520 ASSERT_EQ((int64_t)0, data[1].mRegistration.currentWorkerActivatedTime()); 521 ASSERT_EQ((int64_t)0, data[1].mRegistration.lastUpdateTime()); 522 } 523 524 TEST(ServiceWorkerRegistrar, TestVersion3Migration) 525 { 526 nsAutoCString buffer( 527 "3" 528 "\n"); 529 530 buffer.AppendLiteral("^appId=123&inBrowser=1\n"); 531 buffer.AppendLiteral( 532 "spec 0\nhttps://scope_0.org\ncurrentWorkerURL 0\ncacheName 0\n"); 533 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 534 535 buffer.AppendLiteral("\n"); 536 buffer.AppendLiteral( 537 "spec 1\nhttps://scope_1.org\ncurrentWorkerURL 1\ncacheName 1\n"); 538 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 539 540 ASSERT_TRUE(CreateFile(buffer)) 541 << "CreateFile should not fail"; 542 543 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 544 545 nsresult rv = swr->TestReadData(); 546 ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail"; 547 548 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& data = 549 swr->TestGetData(); 550 ASSERT_EQ((uint32_t)2, data.Length()) << "2 entries should be found"; 551 552 const mozilla::ipc::PrincipalInfo& info0 = data[0].mRegistration.principal(); 553 ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 554 << "First principal must be content"; 555 const mozilla::ipc::ContentPrincipalInfo& cInfo0 = 556 data[0].mRegistration.principal(); 557 558 nsAutoCString suffix0; 559 cInfo0.attrs().CreateSuffix(suffix0); 560 561 ASSERT_STREQ("", suffix0.get()); 562 ASSERT_STREQ("https://scope_0.org", cInfo0.spec().get()); 563 ASSERT_STREQ("https://scope_0.org", data[0].mRegistration.scope().get()); 564 ASSERT_STREQ("currentWorkerURL 0", 565 data[0].mRegistration.currentWorkerURL().get()); 566 ASSERT_EQ(true, data[0].mRegistration.currentWorkerHandlesFetch()); 567 ASSERT_STREQ("cacheName 0", 568 NS_ConvertUTF16toUTF8(data[0].mRegistration.cacheName()).get()); 569 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 570 data[0].mRegistration.updateViaCache()); 571 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerInstalledTime()); 572 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerActivatedTime()); 573 ASSERT_EQ((int64_t)0, data[0].mRegistration.lastUpdateTime()); 574 575 const mozilla::ipc::PrincipalInfo& info1 = data[1].mRegistration.principal(); 576 ASSERT_EQ(info1.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 577 << "First principal must be content"; 578 const mozilla::ipc::ContentPrincipalInfo& cInfo1 = 579 data[1].mRegistration.principal(); 580 581 nsAutoCString suffix1; 582 cInfo1.attrs().CreateSuffix(suffix1); 583 584 ASSERT_STREQ("", suffix1.get()); 585 ASSERT_STREQ("https://scope_1.org", cInfo1.spec().get()); 586 ASSERT_STREQ("https://scope_1.org", data[1].mRegistration.scope().get()); 587 ASSERT_STREQ("currentWorkerURL 1", 588 data[1].mRegistration.currentWorkerURL().get()); 589 ASSERT_EQ(true, data[1].mRegistration.currentWorkerHandlesFetch()); 590 ASSERT_STREQ("cacheName 1", 591 NS_ConvertUTF16toUTF8(data[1].mRegistration.cacheName()).get()); 592 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 593 data[1].mRegistration.updateViaCache()); 594 ASSERT_EQ((int64_t)0, data[1].mRegistration.currentWorkerInstalledTime()); 595 ASSERT_EQ((int64_t)0, data[1].mRegistration.currentWorkerActivatedTime()); 596 ASSERT_EQ((int64_t)0, data[1].mRegistration.lastUpdateTime()); 597 } 598 599 TEST(ServiceWorkerRegistrar, TestVersion4Migration) 600 { 601 nsAutoCString buffer( 602 "4" 603 "\n"); 604 605 buffer.AppendLiteral("^appId=123&inBrowser=1\n"); 606 buffer.AppendLiteral( 607 "https://scope_0.org\ncurrentWorkerURL 0\ncacheName 0\n"); 608 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 609 610 buffer.AppendLiteral("\n"); 611 buffer.AppendLiteral( 612 "https://scope_1.org\ncurrentWorkerURL 1\ncacheName 1\n"); 613 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 614 615 ASSERT_TRUE(CreateFile(buffer)) 616 << "CreateFile should not fail"; 617 618 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 619 620 nsresult rv = swr->TestReadData(); 621 ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail"; 622 623 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& data = 624 swr->TestGetData(); 625 ASSERT_EQ((uint32_t)2, data.Length()) << "2 entries should be found"; 626 627 const mozilla::ipc::PrincipalInfo& info0 = data[0].mRegistration.principal(); 628 ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 629 << "First principal must be content"; 630 const mozilla::ipc::ContentPrincipalInfo& cInfo0 = 631 data[0].mRegistration.principal(); 632 633 nsAutoCString suffix0; 634 cInfo0.attrs().CreateSuffix(suffix0); 635 636 ASSERT_STREQ("", suffix0.get()); 637 ASSERT_STREQ("https://scope_0.org", cInfo0.spec().get()); 638 ASSERT_STREQ("https://scope_0.org", data[0].mRegistration.scope().get()); 639 ASSERT_STREQ("currentWorkerURL 0", 640 data[0].mRegistration.currentWorkerURL().get()); 641 // default is true 642 ASSERT_EQ(true, data[0].mRegistration.currentWorkerHandlesFetch()); 643 ASSERT_STREQ("cacheName 0", 644 NS_ConvertUTF16toUTF8(data[0].mRegistration.cacheName()).get()); 645 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 646 data[0].mRegistration.updateViaCache()); 647 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerInstalledTime()); 648 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerActivatedTime()); 649 ASSERT_EQ((int64_t)0, data[0].mRegistration.lastUpdateTime()); 650 651 const mozilla::ipc::PrincipalInfo& info1 = data[1].mRegistration.principal(); 652 ASSERT_EQ(info1.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 653 << "First principal must be content"; 654 const mozilla::ipc::ContentPrincipalInfo& cInfo1 = 655 data[1].mRegistration.principal(); 656 657 nsAutoCString suffix1; 658 cInfo1.attrs().CreateSuffix(suffix1); 659 660 ASSERT_STREQ("", suffix1.get()); 661 ASSERT_STREQ("https://scope_1.org", cInfo1.spec().get()); 662 ASSERT_STREQ("https://scope_1.org", data[1].mRegistration.scope().get()); 663 ASSERT_STREQ("currentWorkerURL 1", 664 data[1].mRegistration.currentWorkerURL().get()); 665 // default is true 666 ASSERT_EQ(true, data[1].mRegistration.currentWorkerHandlesFetch()); 667 ASSERT_STREQ("cacheName 1", 668 NS_ConvertUTF16toUTF8(data[1].mRegistration.cacheName()).get()); 669 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 670 data[1].mRegistration.updateViaCache()); 671 ASSERT_EQ((int64_t)0, data[1].mRegistration.currentWorkerInstalledTime()); 672 ASSERT_EQ((int64_t)0, data[1].mRegistration.currentWorkerActivatedTime()); 673 ASSERT_EQ((int64_t)0, data[1].mRegistration.lastUpdateTime()); 674 } 675 676 TEST(ServiceWorkerRegistrar, TestVersion5Migration) 677 { 678 nsAutoCString buffer( 679 "5" 680 "\n"); 681 682 buffer.AppendLiteral("^appId=123&inBrowser=1\n"); 683 buffer.AppendLiteral("https://scope_0.org\ncurrentWorkerURL 0\n"); 684 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TRUE "\n"); 685 buffer.AppendLiteral("cacheName 0\n"); 686 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 687 688 buffer.AppendLiteral("\n"); 689 buffer.AppendLiteral("https://scope_1.org\ncurrentWorkerURL 1\n"); 690 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_FALSE "\n"); 691 buffer.AppendLiteral("cacheName 1\n"); 692 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 693 694 ASSERT_TRUE(CreateFile(buffer)) 695 << "CreateFile should not fail"; 696 697 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 698 699 nsresult rv = swr->TestReadData(); 700 ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail"; 701 702 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& data = 703 swr->TestGetData(); 704 ASSERT_EQ((uint32_t)2, data.Length()) << "2 entries should be found"; 705 706 const mozilla::ipc::PrincipalInfo& info0 = data[0].mRegistration.principal(); 707 ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 708 << "First principal must be content"; 709 const mozilla::ipc::ContentPrincipalInfo& cInfo0 = 710 data[0].mRegistration.principal(); 711 712 nsAutoCString suffix0; 713 cInfo0.attrs().CreateSuffix(suffix0); 714 715 ASSERT_STREQ("", suffix0.get()); 716 ASSERT_STREQ("https://scope_0.org", cInfo0.spec().get()); 717 ASSERT_STREQ("https://scope_0.org", data[0].mRegistration.scope().get()); 718 ASSERT_STREQ("currentWorkerURL 0", 719 data[0].mRegistration.currentWorkerURL().get()); 720 ASSERT_TRUE(data[0].mRegistration.currentWorkerHandlesFetch()); 721 ASSERT_STREQ("cacheName 0", 722 NS_ConvertUTF16toUTF8(data[0].mRegistration.cacheName()).get()); 723 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 724 data[0].mRegistration.updateViaCache()); 725 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerInstalledTime()); 726 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerActivatedTime()); 727 ASSERT_EQ((int64_t)0, data[0].mRegistration.lastUpdateTime()); 728 729 const mozilla::ipc::PrincipalInfo& info1 = data[1].mRegistration.principal(); 730 ASSERT_EQ(info1.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 731 << "First principal must be content"; 732 const mozilla::ipc::ContentPrincipalInfo& cInfo1 = 733 data[1].mRegistration.principal(); 734 735 nsAutoCString suffix1; 736 cInfo1.attrs().CreateSuffix(suffix1); 737 738 ASSERT_STREQ("", suffix1.get()); 739 ASSERT_STREQ("https://scope_1.org", cInfo1.spec().get()); 740 ASSERT_STREQ("https://scope_1.org", data[1].mRegistration.scope().get()); 741 ASSERT_STREQ("currentWorkerURL 1", 742 data[1].mRegistration.currentWorkerURL().get()); 743 ASSERT_FALSE(data[1].mRegistration.currentWorkerHandlesFetch()); 744 ASSERT_STREQ("cacheName 1", 745 NS_ConvertUTF16toUTF8(data[1].mRegistration.cacheName()).get()); 746 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 747 data[1].mRegistration.updateViaCache()); 748 ASSERT_EQ((int64_t)0, data[1].mRegistration.currentWorkerInstalledTime()); 749 ASSERT_EQ((int64_t)0, data[1].mRegistration.currentWorkerActivatedTime()); 750 ASSERT_EQ((int64_t)0, data[1].mRegistration.lastUpdateTime()); 751 } 752 753 TEST(ServiceWorkerRegistrar, TestVersion6Migration) 754 { 755 nsAutoCString buffer( 756 "6" 757 "\n"); 758 759 buffer.AppendLiteral("^appId=123&inBrowser=1\n"); 760 buffer.AppendLiteral("https://scope_0.org\ncurrentWorkerURL 0\n"); 761 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TRUE "\n"); 762 buffer.AppendLiteral("cacheName 0\n"); 763 buffer.AppendInt(nsIRequest::LOAD_NORMAL, 16); 764 buffer.AppendLiteral("\n"); 765 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 766 767 buffer.AppendLiteral("\n"); 768 buffer.AppendLiteral("https://scope_1.org\ncurrentWorkerURL 1\n"); 769 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_FALSE "\n"); 770 buffer.AppendLiteral("cacheName 1\n"); 771 buffer.AppendInt(nsIRequest::VALIDATE_ALWAYS, 16); 772 buffer.AppendLiteral("\n"); 773 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 774 775 ASSERT_TRUE(CreateFile(buffer)) 776 << "CreateFile should not fail"; 777 778 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 779 780 nsresult rv = swr->TestReadData(); 781 ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail"; 782 783 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& data = 784 swr->TestGetData(); 785 ASSERT_EQ((uint32_t)2, data.Length()) << "2 entries should be found"; 786 787 const mozilla::ipc::PrincipalInfo& info0 = data[0].mRegistration.principal(); 788 ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 789 << "First principal must be content"; 790 const mozilla::ipc::ContentPrincipalInfo& cInfo0 = 791 data[0].mRegistration.principal(); 792 793 nsAutoCString suffix0; 794 cInfo0.attrs().CreateSuffix(suffix0); 795 796 ASSERT_STREQ("", suffix0.get()); 797 ASSERT_STREQ("https://scope_0.org", cInfo0.spec().get()); 798 ASSERT_STREQ("https://scope_0.org", data[0].mRegistration.scope().get()); 799 ASSERT_STREQ("currentWorkerURL 0", 800 data[0].mRegistration.currentWorkerURL().get()); 801 ASSERT_TRUE(data[0].mRegistration.currentWorkerHandlesFetch()); 802 ASSERT_STREQ("cacheName 0", 803 NS_ConvertUTF16toUTF8(data[0].mRegistration.cacheName()).get()); 804 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_ALL, 805 data[0].mRegistration.updateViaCache()); 806 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerInstalledTime()); 807 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerActivatedTime()); 808 ASSERT_EQ((int64_t)0, data[0].mRegistration.lastUpdateTime()); 809 810 const mozilla::ipc::PrincipalInfo& info1 = data[1].mRegistration.principal(); 811 ASSERT_EQ(info1.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 812 << "First principal must be content"; 813 const mozilla::ipc::ContentPrincipalInfo& cInfo1 = 814 data[1].mRegistration.principal(); 815 816 nsAutoCString suffix1; 817 cInfo1.attrs().CreateSuffix(suffix1); 818 819 ASSERT_STREQ("", suffix1.get()); 820 ASSERT_STREQ("https://scope_1.org", cInfo1.spec().get()); 821 ASSERT_STREQ("https://scope_1.org", data[1].mRegistration.scope().get()); 822 ASSERT_STREQ("currentWorkerURL 1", 823 data[1].mRegistration.currentWorkerURL().get()); 824 ASSERT_FALSE(data[1].mRegistration.currentWorkerHandlesFetch()); 825 ASSERT_STREQ("cacheName 1", 826 NS_ConvertUTF16toUTF8(data[1].mRegistration.cacheName()).get()); 827 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 828 data[1].mRegistration.updateViaCache()); 829 ASSERT_EQ((int64_t)0, data[1].mRegistration.currentWorkerInstalledTime()); 830 ASSERT_EQ((int64_t)0, data[1].mRegistration.currentWorkerActivatedTime()); 831 ASSERT_EQ((int64_t)0, data[1].mRegistration.lastUpdateTime()); 832 } 833 834 TEST(ServiceWorkerRegistrar, TestVersion7Migration) 835 { 836 nsAutoCString buffer( 837 "7" 838 "\n"); 839 840 buffer.AppendLiteral("^appId=123&inBrowser=1\n"); 841 buffer.AppendLiteral("https://scope_0.org\ncurrentWorkerURL 0\n"); 842 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TRUE "\n"); 843 buffer.AppendLiteral("cacheName 0\n"); 844 buffer.AppendInt(nsIRequest::LOAD_NORMAL, 16); 845 buffer.AppendLiteral("\n"); 846 buffer.AppendInt(0); 847 buffer.AppendLiteral("\n"); 848 buffer.AppendInt(0); 849 buffer.AppendLiteral("\n"); 850 buffer.AppendInt(0); 851 buffer.AppendLiteral("\n"); 852 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 853 854 buffer.AppendLiteral("\n"); 855 buffer.AppendLiteral("https://scope_1.org\ncurrentWorkerURL 1\n"); 856 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_FALSE "\n"); 857 buffer.AppendLiteral("cacheName 1\n"); 858 buffer.AppendInt(nsIRequest::VALIDATE_ALWAYS, 16); 859 buffer.AppendLiteral("\n"); 860 PRTime ts = PR_Now(); 861 buffer.AppendInt(ts); 862 buffer.AppendLiteral("\n"); 863 buffer.AppendInt(ts); 864 buffer.AppendLiteral("\n"); 865 buffer.AppendInt(ts); 866 buffer.AppendLiteral("\n"); 867 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 868 869 ASSERT_TRUE(CreateFile(buffer)) 870 << "CreateFile should not fail"; 871 872 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 873 874 nsresult rv = swr->TestReadData(); 875 ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail"; 876 877 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& data = 878 swr->TestGetData(); 879 ASSERT_EQ((uint32_t)2, data.Length()) << "2 entries should be found"; 880 881 const mozilla::ipc::PrincipalInfo& info0 = data[0].mRegistration.principal(); 882 ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 883 << "First principal must be content"; 884 const mozilla::ipc::ContentPrincipalInfo& cInfo0 = 885 data[0].mRegistration.principal(); 886 887 nsAutoCString suffix0; 888 cInfo0.attrs().CreateSuffix(suffix0); 889 890 ASSERT_STREQ("", suffix0.get()); 891 ASSERT_STREQ("https://scope_0.org", cInfo0.spec().get()); 892 ASSERT_STREQ("https://scope_0.org", data[0].mRegistration.scope().get()); 893 ASSERT_STREQ("currentWorkerURL 0", 894 data[0].mRegistration.currentWorkerURL().get()); 895 ASSERT_TRUE(data[0].mRegistration.currentWorkerHandlesFetch()); 896 ASSERT_STREQ("cacheName 0", 897 NS_ConvertUTF16toUTF8(data[0].mRegistration.cacheName()).get()); 898 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_ALL, 899 data[0].mRegistration.updateViaCache()); 900 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerInstalledTime()); 901 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerActivatedTime()); 902 ASSERT_EQ((int64_t)0, data[0].mRegistration.lastUpdateTime()); 903 904 const mozilla::ipc::PrincipalInfo& info1 = data[1].mRegistration.principal(); 905 ASSERT_EQ(info1.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 906 << "First principal must be content"; 907 const mozilla::ipc::ContentPrincipalInfo& cInfo1 = 908 data[1].mRegistration.principal(); 909 910 nsAutoCString suffix1; 911 cInfo1.attrs().CreateSuffix(suffix1); 912 913 ASSERT_STREQ("", suffix1.get()); 914 ASSERT_STREQ("https://scope_1.org", cInfo1.spec().get()); 915 ASSERT_STREQ("https://scope_1.org", data[1].mRegistration.scope().get()); 916 ASSERT_STREQ("currentWorkerURL 1", 917 data[1].mRegistration.currentWorkerURL().get()); 918 ASSERT_FALSE(data[1].mRegistration.currentWorkerHandlesFetch()); 919 ASSERT_STREQ("cacheName 1", 920 NS_ConvertUTF16toUTF8(data[1].mRegistration.cacheName()).get()); 921 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 922 data[1].mRegistration.updateViaCache()); 923 ASSERT_EQ((int64_t)ts, data[1].mRegistration.currentWorkerInstalledTime()); 924 ASSERT_EQ((int64_t)ts, data[1].mRegistration.currentWorkerActivatedTime()); 925 ASSERT_EQ((int64_t)ts, data[1].mRegistration.lastUpdateTime()); 926 } 927 928 TEST(ServiceWorkerRegistrar, TestDedupeRead) 929 { 930 nsAutoCString buffer( 931 "3" 932 "\n"); 933 934 // unique entries 935 buffer.AppendLiteral("^inBrowser=1\n"); 936 buffer.AppendLiteral( 937 "spec 0\nhttps://scope_0.org\ncurrentWorkerURL 0\ncacheName 0\n"); 938 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 939 940 buffer.AppendLiteral("\n"); 941 buffer.AppendLiteral( 942 "spec 1\nhttps://scope_1.org\ncurrentWorkerURL 1\ncacheName 1\n"); 943 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 944 945 // dupe entries 946 buffer.AppendLiteral("^inBrowser=1\n"); 947 buffer.AppendLiteral( 948 "spec 1\nhttps://scope_0.org\ncurrentWorkerURL 0\ncacheName 0\n"); 949 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 950 951 buffer.AppendLiteral("^inBrowser=1\n"); 952 buffer.AppendLiteral( 953 "spec 2\nhttps://scope_0.org\ncurrentWorkerURL 0\ncacheName 0\n"); 954 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 955 956 buffer.AppendLiteral("\n"); 957 buffer.AppendLiteral( 958 "spec 3\nhttps://scope_1.org\ncurrentWorkerURL 1\ncacheName 1\n"); 959 buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 960 961 ASSERT_TRUE(CreateFile(buffer)) 962 << "CreateFile should not fail"; 963 964 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 965 966 nsresult rv = swr->TestReadData(); 967 ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail"; 968 969 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& data = 970 swr->TestGetData(); 971 ASSERT_EQ((uint32_t)2, data.Length()) << "2 entries should be found"; 972 973 const mozilla::ipc::PrincipalInfo& info0 = data[0].mRegistration.principal(); 974 ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 975 << "First principal must be content"; 976 const mozilla::ipc::ContentPrincipalInfo& cInfo0 = 977 data[0].mRegistration.principal(); 978 979 nsAutoCString suffix0; 980 cInfo0.attrs().CreateSuffix(suffix0); 981 982 ASSERT_STREQ("", suffix0.get()); 983 ASSERT_STREQ("https://scope_0.org", cInfo0.spec().get()); 984 ASSERT_STREQ("https://scope_0.org", data[0].mRegistration.scope().get()); 985 ASSERT_STREQ("currentWorkerURL 0", 986 data[0].mRegistration.currentWorkerURL().get()); 987 ASSERT_EQ(true, data[0].mRegistration.currentWorkerHandlesFetch()); 988 ASSERT_STREQ("cacheName 0", 989 NS_ConvertUTF16toUTF8(data[0].mRegistration.cacheName()).get()); 990 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 991 data[0].mRegistration.updateViaCache()); 992 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerInstalledTime()); 993 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerActivatedTime()); 994 ASSERT_EQ((int64_t)0, data[0].mRegistration.lastUpdateTime()); 995 996 const mozilla::ipc::PrincipalInfo& info1 = data[1].mRegistration.principal(); 997 ASSERT_EQ(info1.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) 998 << "First principal must be content"; 999 const mozilla::ipc::ContentPrincipalInfo& cInfo1 = 1000 data[1].mRegistration.principal(); 1001 1002 nsAutoCString suffix1; 1003 cInfo1.attrs().CreateSuffix(suffix1); 1004 1005 ASSERT_STREQ("", suffix1.get()); 1006 ASSERT_STREQ("https://scope_1.org", cInfo1.spec().get()); 1007 ASSERT_STREQ("https://scope_1.org", data[1].mRegistration.scope().get()); 1008 ASSERT_STREQ("currentWorkerURL 1", 1009 data[1].mRegistration.currentWorkerURL().get()); 1010 ASSERT_EQ(true, data[1].mRegistration.currentWorkerHandlesFetch()); 1011 ASSERT_STREQ("cacheName 1", 1012 NS_ConvertUTF16toUTF8(data[1].mRegistration.cacheName()).get()); 1013 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 1014 data[1].mRegistration.updateViaCache()); 1015 ASSERT_EQ((int64_t)0, data[1].mRegistration.currentWorkerInstalledTime()); 1016 ASSERT_EQ((int64_t)0, data[1].mRegistration.currentWorkerActivatedTime()); 1017 ASSERT_EQ((int64_t)0, data[1].mRegistration.lastUpdateTime()); 1018 } 1019 1020 TEST(ServiceWorkerRegistrar, TestDedupeWrite) 1021 { 1022 { 1023 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 1024 1025 for (int i = 0; i < 2; ++i) { 1026 ServiceWorkerRegistrationData reg; 1027 1028 reg.scope() = "https://scope_write.dedupe"_ns; 1029 reg.type() = WorkerType::Classic; 1030 reg.currentWorkerURL() = nsPrintfCString("currentWorkerURL write %d", i); 1031 reg.currentWorkerHandlesFetch() = true; 1032 reg.cacheName() = 1033 NS_ConvertUTF8toUTF16(nsPrintfCString("cacheName write %d", i)); 1034 reg.updateViaCache() = 1035 nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS; 1036 1037 nsAutoCString spec; 1038 spec.AppendPrintf("spec write dedupe/%d", i); 1039 1040 reg.principal() = mozilla::ipc::ContentPrincipalInfo( 1041 mozilla::OriginAttributes(), spec, spec, mozilla::Nothing(), spec); 1042 1043 swr->TestRegisterServiceWorker(reg); 1044 } 1045 1046 nsresult rv = swr->TestWriteData(); 1047 ASSERT_EQ(NS_OK, rv) << "WriteData() should not fail"; 1048 } 1049 1050 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 1051 1052 nsresult rv = swr->TestReadData(); 1053 ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail"; 1054 1055 // Duplicate entries should be removed. 1056 const nsTArray<ServiceWorkerRegistrar::ServiceWorkerData>& data = 1057 swr->TestGetData(); 1058 ASSERT_EQ((uint32_t)1, data.Length()) << "1 entry should be found"; 1059 1060 ASSERT_EQ(data[0].mRegistration.principal().type(), 1061 mozilla::ipc::PrincipalInfo::TContentPrincipalInfo); 1062 const mozilla::ipc::ContentPrincipalInfo& cInfo = 1063 data[0].mRegistration.principal(); 1064 1065 mozilla::OriginAttributes attrs; 1066 nsAutoCString suffix, expectSuffix; 1067 attrs.CreateSuffix(expectSuffix); 1068 cInfo.attrs().CreateSuffix(suffix); 1069 1070 // Last entry passed to RegisterServiceWorkerInternal() should overwrite 1071 // previous values. So expect "1" in values here. 1072 ASSERT_STREQ(expectSuffix.get(), suffix.get()); 1073 ASSERT_STREQ("https://scope_write.dedupe", cInfo.spec().get()); 1074 ASSERT_STREQ("https://scope_write.dedupe", 1075 data[0].mRegistration.scope().get()); 1076 ASSERT_STREQ("currentWorkerURL write 1", 1077 data[0].mRegistration.currentWorkerURL().get()); 1078 ASSERT_EQ(true, data[0].mRegistration.currentWorkerHandlesFetch()); 1079 ASSERT_STREQ("cacheName write 1", 1080 NS_ConvertUTF16toUTF8(data[0].mRegistration.cacheName()).get()); 1081 ASSERT_EQ(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 1082 data[0].mRegistration.updateViaCache()); 1083 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerInstalledTime()); 1084 ASSERT_EQ((int64_t)0, data[0].mRegistration.currentWorkerActivatedTime()); 1085 ASSERT_EQ((int64_t)0, data[0].mRegistration.lastUpdateTime()); 1086 } 1087 1088 TEST(ServiceWorkerRegistrar, TestLoadHandler) 1089 { 1090 nsCString buffer; 1091 buffer.AppendInt(static_cast<uint32_t>(SERVICEWORKERREGISTRAR_VERSION)); 1092 buffer.Append("\n"); 1093 1094 buffer.AppendLiteral("^inBrowser=1\n"); 1095 buffer.AppendLiteral("https://scope_0.org\ncurrentWorkerURL 0\n"); 1096 buffer.Append(SERVICEWORKERREGISTRAR_TRUE "\n"); 1097 buffer.AppendLiteral("cacheName 0\n"); 1098 buffer.AppendInt(nsIServiceWorkerRegistrationInfo::UPDATE_VIA_CACHE_IMPORTS, 1099 16); 1100 buffer.AppendLiteral("\n"); 1101 buffer.AppendInt(0); 1102 buffer.AppendLiteral("\n"); 1103 buffer.AppendInt(0); 1104 buffer.AppendLiteral("\n"); 1105 buffer.AppendInt(0); 1106 buffer.AppendLiteral("\n"); 1107 buffer.AppendInt(0); 1108 buffer.AppendLiteral("\n"); 1109 buffer.AppendLiteral("true\n"); 1110 buffer.AppendInt(2); 1111 buffer.AppendLiteral("\n"); 1112 buffer.AppendLiteral("handler_test\n"); 1113 buffer.AppendLiteral("hello world!\n"); 1114 buffer.AppendLiteral("handler_test2\n"); 1115 buffer.AppendLiteral("hello\n"); 1116 buffer.AppendInt(0); 1117 buffer.AppendLiteral("\n"); 1118 buffer.AppendInt(0); 1119 buffer.AppendLiteral("\n"); 1120 buffer.AppendInt(0); 1121 buffer.AppendLiteral("\n"); 1122 buffer.AppendInt(0); 1123 buffer.AppendLiteral("\n"); 1124 buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n"); 1125 1126 ASSERT_TRUE(CreateFile(buffer)) 1127 << "CreateFile should not fail"; 1128 1129 { 1130 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 1131 nsresult rv = swr->TestReadData(); 1132 ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail"; 1133 1134 ASSERT_EQ(gHandlerStats->swLoadCount, (uint32_t)1) 1135 << "First handle correctly called"; 1136 ASSERT_EQ(gHandlerStats->lastValue, nsCString("hello world!")) 1137 << "First handle correctly called correct value)"; 1138 ASSERT_EQ(gHandlerStats->swUnregisteredCount, (uint32_t)0) 1139 << "No unregister calls yet"; 1140 1141 ASSERT_EQ(gHandlerStats->swLoad2Count, (uint32_t)1) 1142 << "Second handle correctly called"; 1143 ASSERT_EQ(gHandlerStats->lastValue2, nsCString("hello")) 1144 << "Second handle correctly called correct value)"; 1145 ASSERT_EQ(gHandlerStats->swUnregistered2Count, (uint32_t)0) 1146 << "No unregister calls yet"; 1147 1148 rv = swr->TestWriteData(); 1149 ASSERT_EQ(NS_OK, rv) << "WriteData() should not fail"; 1150 } 1151 1152 { 1153 RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest; 1154 nsresult rv = swr->TestReadData(); 1155 ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail"; 1156 1157 ASSERT_EQ(gHandlerStats->swLoadCount, (uint32_t)2) 1158 << "First handle correctly called"; 1159 ASSERT_EQ(gHandlerStats->lastValue, nsCString("hello world!")) 1160 << "First handle correctly called correct value)"; 1161 ASSERT_EQ(gHandlerStats->swUnregisteredCount, (uint32_t)0) 1162 << "No unregister calls yet"; 1163 1164 ASSERT_EQ(gHandlerStats->swLoad2Count, (uint32_t)2) 1165 << "Second handle correctly called"; 1166 ASSERT_EQ(gHandlerStats->lastValue2, nsCString("hello")) 1167 << "Second handle correctly called correct value)"; 1168 ASSERT_EQ(gHandlerStats->swUnregistered2Count, (uint32_t)0) 1169 << "No unregister calls yet"; 1170 } 1171 } 1172 1173 int main(int argc, char** argv) { 1174 ::testing::InitGoogleTest(&argc, argv); 1175 1176 int rv = RUN_ALL_TESTS(); 1177 return rv; 1178 }