OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/files/file_util.h" | 6 #include "base/files/file_util.h" |
7 #include "base/files/scoped_temp_dir.h" | 7 #include "base/files/scoped_temp_dir.h" |
8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
9 #include "content/browser/appcache/appcache_database.h" | 9 #include "content/browser/appcache/appcache_database.h" |
10 #include "content/browser/appcache/appcache_entry.h" | 10 #include "content/browser/appcache/appcache_entry.h" |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 | 428 |
429 record = kZeroRecord; | 429 record = kZeroRecord; |
430 EXPECT_TRUE(db.FindGroupForCache(1, &record)); | 430 EXPECT_TRUE(db.FindGroupForCache(1, &record)); |
431 EXPECT_EQ(1, record.group_id); | 431 EXPECT_EQ(1, record.group_id); |
432 EXPECT_EQ(kManifest2, record.manifest_url); | 432 EXPECT_EQ(kManifest2, record.manifest_url); |
433 EXPECT_EQ(kOrigin2, record.origin); | 433 EXPECT_EQ(kOrigin2, record.origin); |
434 | 434 |
435 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); | 435 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); |
436 } | 436 } |
437 | 437 |
| 438 TEST(AppCacheDatabaseTest, GroupAccessAndEvictionTimes) { |
| 439 const base::FilePath kEmptyPath; |
| 440 AppCacheDatabase db(kEmptyPath); |
| 441 EXPECT_TRUE(db.LazyOpen(true)); |
| 442 |
| 443 const GURL kManifestUrl("http://blah/manifest"); |
| 444 const GURL kOrigin(kManifestUrl.GetOrigin()); |
| 445 const base::Time kDayOne = |
| 446 base::Time() + base::TimeDelta::FromDays(1); |
| 447 const base::Time kDayTwo = kDayOne + base::TimeDelta::FromDays(1); |
| 448 |
| 449 // See that the methods behave as expected with an empty db. |
| 450 // To accomodate lazy updating, for consistency, none of them fail |
| 451 // given ids not found in the db. |
| 452 EXPECT_TRUE(db.UpdateEvictionTimes(1, kDayOne, kDayTwo)); |
| 453 EXPECT_TRUE(db.UpdateLastAccessTime(1, kDayOne)); |
| 454 EXPECT_TRUE(db.CommitLazyLastAccessTimes()); |
| 455 EXPECT_TRUE(db.LazyUpdateLastAccessTime(1, kDayTwo)); |
| 456 EXPECT_TRUE(db.CommitLazyLastAccessTimes()); |
| 457 |
| 458 // Insert a group at DAY1 |
| 459 AppCacheDatabase::GroupRecord record; |
| 460 record.group_id = 1; |
| 461 record.manifest_url = kManifestUrl; |
| 462 record.origin = kOrigin; |
| 463 record.creation_time = kDayOne; |
| 464 record.last_access_time = kDayOne; |
| 465 record.last_full_update_check_time = kDayOne; |
| 466 record.first_evictable_error_time = kDayOne; |
| 467 EXPECT_TRUE(db.InsertGroup(&record)); |
| 468 |
| 469 // Verify the round trip. |
| 470 record = AppCacheDatabase::GroupRecord(); |
| 471 EXPECT_TRUE(db.FindGroup(1, &record)); |
| 472 EXPECT_EQ(kDayOne, record.last_access_time); |
| 473 EXPECT_EQ(kDayOne, record.last_full_update_check_time); |
| 474 EXPECT_EQ(kDayOne, record.first_evictable_error_time); |
| 475 |
| 476 // Update the times to DAY2 and verify. |
| 477 EXPECT_TRUE(db.UpdateEvictionTimes(1, kDayTwo, kDayTwo)); |
| 478 EXPECT_TRUE(db.UpdateLastAccessTime(1, kDayTwo)); |
| 479 record = AppCacheDatabase::GroupRecord(); |
| 480 EXPECT_TRUE(db.FindGroup(1, &record)); |
| 481 EXPECT_EQ(kDayTwo, record.last_access_time); |
| 482 EXPECT_EQ(kDayTwo, record.last_full_update_check_time); |
| 483 EXPECT_EQ(kDayTwo, record.first_evictable_error_time); |
| 484 |
| 485 // Lazy update back to DAY1 and verify its reflected without having committed. |
| 486 EXPECT_TRUE(db.lazy_last_access_times_.empty()); |
| 487 EXPECT_TRUE(db.LazyUpdateLastAccessTime(1, kDayOne)); |
| 488 EXPECT_FALSE(db.lazy_last_access_times_.empty()); |
| 489 record = AppCacheDatabase::GroupRecord(); |
| 490 EXPECT_TRUE(db.FindGroup(1, &record)); |
| 491 EXPECT_EQ(kDayOne, record.last_access_time); |
| 492 |
| 493 // Commit the lazy value and verify it sticks. |
| 494 EXPECT_TRUE(db.CommitLazyLastAccessTimes()); |
| 495 EXPECT_TRUE(db.lazy_last_access_times_.empty()); |
| 496 record = AppCacheDatabase::GroupRecord(); |
| 497 EXPECT_TRUE(db.FindGroup(1, &record)); |
| 498 EXPECT_EQ(kDayOne, record.last_access_time); |
| 499 |
| 500 // Verify a bad lazy group id doesn't fail to commit the good ones on DAY2. |
| 501 EXPECT_TRUE(db.LazyUpdateLastAccessTime(1, kDayTwo)); |
| 502 EXPECT_TRUE(db.LazyUpdateLastAccessTime(2, kDayTwo)); |
| 503 EXPECT_EQ(2u, db.lazy_last_access_times_.size()); |
| 504 EXPECT_TRUE(db.CommitLazyLastAccessTimes()); |
| 505 EXPECT_TRUE(db.lazy_last_access_times_.empty()); |
| 506 record = AppCacheDatabase::GroupRecord(); |
| 507 EXPECT_TRUE(db.FindGroup(1, &record)); |
| 508 EXPECT_EQ(kDayTwo, record.last_access_time); |
| 509 } |
| 510 |
438 TEST(AppCacheDatabaseTest, NamespaceRecords) { | 511 TEST(AppCacheDatabaseTest, NamespaceRecords) { |
439 const base::FilePath kEmptyPath; | 512 const base::FilePath kEmptyPath; |
440 AppCacheDatabase db(kEmptyPath); | 513 AppCacheDatabase db(kEmptyPath); |
441 EXPECT_TRUE(db.LazyOpen(true)); | 514 EXPECT_TRUE(db.LazyOpen(true)); |
442 | 515 |
443 sql::ScopedErrorIgnorer ignore_errors; | 516 sql::ScopedErrorIgnorer ignore_errors; |
444 // TODO(shess): See EntryRecords test. | 517 // TODO(shess): See EntryRecords test. |
445 ignore_errors.IgnoreError(SQLITE_CONSTRAINT); | 518 ignore_errors.IgnoreError(SQLITE_CONSTRAINT); |
446 | 519 |
447 const GURL kFooNameSpace1("http://foo/namespace1"); | 520 const GURL kFooNameSpace1("http://foo/namespace1"); |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 std::map<GURL, int64> usage_map; | 811 std::map<GURL, int64> usage_map; |
739 EXPECT_TRUE(db.GetAllOriginUsage(&usage_map)); | 812 EXPECT_TRUE(db.GetAllOriginUsage(&usage_map)); |
740 EXPECT_EQ(2U, usage_map.size()); | 813 EXPECT_EQ(2U, usage_map.size()); |
741 EXPECT_EQ(1100, usage_map[kOrigin]); | 814 EXPECT_EQ(1100, usage_map[kOrigin]); |
742 EXPECT_EQ(5000, usage_map[kOtherOrigin]); | 815 EXPECT_EQ(5000, usage_map[kOtherOrigin]); |
743 } | 816 } |
744 | 817 |
745 #if defined(APPCACHE_USE_SIMPLE_CACHE) | 818 #if defined(APPCACHE_USE_SIMPLE_CACHE) |
746 // There is no such upgrade path in this case. | 819 // There is no such upgrade path in this case. |
747 #else | 820 #else |
748 TEST(AppCacheDatabaseTest, UpgradeSchema3to5) { | 821 TEST(AppCacheDatabaseTest, UpgradeSchema4to7) { |
749 // Real file on disk for this test. | 822 // Real file on disk for this test. |
750 base::ScopedTempDir temp_dir; | 823 base::ScopedTempDir temp_dir; |
751 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 824 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
752 const base::FilePath kDbFile = temp_dir.path().AppendASCII("upgrade3.db"); | 825 const base::FilePath kDbFile = temp_dir.path().AppendASCII("upgrade4.db"); |
753 | 826 |
754 const GURL kMockOrigin("http://mockorigin/"); | 827 const GURL kMockOrigin("http://mockorigin/"); |
755 const char kNamespaceUrlFormat[] = "namespace%d"; | 828 const char kNamespaceUrlFormat[] = "namespace%d"; |
| 829 const char kWhitelistUrlFormat[] = "whitelist%d"; |
756 const char kTargetUrlFormat[] = "target%d"; | 830 const char kTargetUrlFormat[] = "target%d"; |
757 const int kNumNamespaces = 10; | 831 const int kNumNamespaces = 10; |
| 832 const int kWhitelistCacheId = 1; |
758 | 833 |
759 // Create a v3 schema based database containing some fallback records. | 834 // Create a v4 schema based database containing some fallback records. |
760 { | 835 { |
761 const int kVersion3 = 3; | 836 const int kVersion4 = 4; |
762 const char kGroupsTable[] = "Groups"; | 837 const char kGroupsTable[] = "Groups"; |
763 const char kCachesTable[] = "Caches"; | 838 const char kCachesTable[] = "Caches"; |
764 const char kEntriesTable[] = "Entries"; | 839 const char kEntriesTable[] = "Entries"; |
765 const char kFallbackNameSpacesTable[] = "FallbackNameSpaces"; | 840 const char kNamespacesTable[] = "Namespaces"; |
766 const char kOnlineWhiteListsTable[] = "OnlineWhiteLists"; | 841 const char kOnlineWhiteListsTable[] = "OnlineWhiteLists"; |
767 const char kDeletableResponseIdsTable[] = "DeletableResponseIds"; | 842 const char kDeletableResponseIdsTable[] = "DeletableResponseIds"; |
768 | 843 |
769 const struct { | 844 struct TableInfo { |
770 const char* table_name; | 845 const char* table_name; |
771 const char* columns; | 846 const char* columns; |
772 } kTables3[] = { | 847 }; |
| 848 |
| 849 struct IndexInfo { |
| 850 const char* index_name; |
| 851 const char* table_name; |
| 852 const char* columns; |
| 853 bool unique; |
| 854 }; |
| 855 |
| 856 const TableInfo kTables4[] = { |
773 { kGroupsTable, | 857 { kGroupsTable, |
774 "(group_id INTEGER PRIMARY KEY," | 858 "(group_id INTEGER PRIMARY KEY," |
775 " origin TEXT," | 859 " origin TEXT," |
776 " manifest_url TEXT," | 860 " manifest_url TEXT," |
777 " creation_time INTEGER," | 861 " creation_time INTEGER," |
778 " last_access_time INTEGER)" }, | 862 " last_access_time INTEGER)" }, |
779 | 863 |
780 { kCachesTable, | 864 { kCachesTable, |
781 "(cache_id INTEGER PRIMARY KEY," | 865 "(cache_id INTEGER PRIMARY KEY," |
782 " group_id INTEGER," | 866 " group_id INTEGER," |
783 " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1))," | 867 " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1))," |
784 " update_time INTEGER," | 868 " update_time INTEGER," |
785 " cache_size INTEGER)" }, // intentionally not normalized | 869 " cache_size INTEGER)" }, // intentionally not normalized |
786 | 870 |
787 { kEntriesTable, | 871 { kEntriesTable, |
788 "(cache_id INTEGER," | 872 "(cache_id INTEGER," |
789 " url TEXT," | 873 " url TEXT," |
790 " flags INTEGER," | 874 " flags INTEGER," |
791 " response_id INTEGER," | 875 " response_id INTEGER," |
792 " response_size INTEGER)" }, | 876 " response_size INTEGER)" }, |
793 | 877 |
794 { kFallbackNameSpacesTable, | 878 { kNamespacesTable, |
795 "(cache_id INTEGER," | 879 "(cache_id INTEGER," |
796 " origin TEXT," // intentionally not normalized | 880 " origin TEXT," // intentionally not normalized |
| 881 " type INTEGER," |
797 " namespace_url TEXT," | 882 " namespace_url TEXT," |
798 " fallback_entry_url TEXT)" }, | 883 " target_url TEXT)" }, |
799 | 884 |
800 { kOnlineWhiteListsTable, | 885 { kOnlineWhiteListsTable, |
801 "(cache_id INTEGER," | 886 "(cache_id INTEGER," |
802 " namespace_url TEXT)" }, | 887 " namespace_url TEXT)" }, |
803 | 888 |
804 { kDeletableResponseIdsTable, | 889 { kDeletableResponseIdsTable, |
805 "(response_id INTEGER NOT NULL)" }, | 890 "(response_id INTEGER NOT NULL)" }, |
806 }; | 891 }; |
807 | 892 |
808 const struct { | 893 const IndexInfo kIndexes4[] = { |
809 const char* index_name; | |
810 const char* table_name; | |
811 const char* columns; | |
812 bool unique; | |
813 } kIndexes3[] = { | |
814 { "GroupsOriginIndex", | 894 { "GroupsOriginIndex", |
815 kGroupsTable, | 895 kGroupsTable, |
816 "(origin)", | 896 "(origin)", |
817 false }, | 897 false }, |
818 | 898 |
819 { "GroupsManifestIndex", | 899 { "GroupsManifestIndex", |
820 kGroupsTable, | 900 kGroupsTable, |
821 "(manifest_url)", | 901 "(manifest_url)", |
822 true }, | 902 true }, |
823 | 903 |
(...skipping 10 matching lines...) Expand all Loading... |
834 { "EntriesCacheAndUrlIndex", | 914 { "EntriesCacheAndUrlIndex", |
835 kEntriesTable, | 915 kEntriesTable, |
836 "(cache_id, url)", | 916 "(cache_id, url)", |
837 true }, | 917 true }, |
838 | 918 |
839 { "EntriesResponseIdIndex", | 919 { "EntriesResponseIdIndex", |
840 kEntriesTable, | 920 kEntriesTable, |
841 "(response_id)", | 921 "(response_id)", |
842 true }, | 922 true }, |
843 | 923 |
844 { "FallbackNameSpacesCacheIndex", | 924 { "NamespacesCacheIndex", |
845 kFallbackNameSpacesTable, | 925 kNamespacesTable, |
846 "(cache_id)", | 926 "(cache_id)", |
847 false }, | 927 false }, |
848 | 928 |
849 { "FallbackNameSpacesOriginIndex", | 929 { "NamespacesOriginIndex", |
850 kFallbackNameSpacesTable, | 930 kNamespacesTable, |
851 "(origin)", | 931 "(origin)", |
852 false }, | 932 false }, |
853 | 933 |
854 { "FallbackNameSpacesCacheAndUrlIndex", | 934 { "NamespacesCacheAndUrlIndex", |
855 kFallbackNameSpacesTable, | 935 kNamespacesTable, |
856 "(cache_id, namespace_url)", | 936 "(cache_id, namespace_url)", |
857 true }, | 937 true }, |
858 | 938 |
859 { "OnlineWhiteListCacheIndex", | 939 { "OnlineWhiteListCacheIndex", |
860 kOnlineWhiteListsTable, | 940 kOnlineWhiteListsTable, |
861 "(cache_id)", | 941 "(cache_id)", |
862 false }, | 942 false }, |
863 | 943 |
864 { "DeletableResponsesIdIndex", | 944 { "DeletableResponsesIdIndex", |
865 kDeletableResponseIdsTable, | 945 kDeletableResponseIdsTable, |
866 "(response_id)", | 946 "(response_id)", |
867 true }, | 947 true }, |
868 }; | 948 }; |
869 | 949 |
870 const int kTableCount3 = arraysize(kTables3); | 950 const int kTableCount4 = arraysize(kTables4); |
871 const int kIndexCount3 = arraysize(kIndexes3); | 951 const int kIndexCount4 = arraysize(kIndexes4); |
872 | 952 |
873 sql::Connection connection; | 953 sql::Connection connection; |
874 EXPECT_TRUE(connection.Open(kDbFile)); | 954 EXPECT_TRUE(connection.Open(kDbFile)); |
875 | 955 |
876 sql::Transaction transaction(&connection); | 956 sql::Transaction transaction(&connection); |
877 EXPECT_TRUE(transaction.Begin()); | 957 EXPECT_TRUE(transaction.Begin()); |
878 | 958 |
879 sql::MetaTable meta_table; | 959 sql::MetaTable meta_table; |
880 EXPECT_TRUE(meta_table.Init(&connection, kVersion3, kVersion3)); | 960 EXPECT_TRUE(meta_table.Init(&connection, kVersion4, kVersion4)); |
881 | 961 |
882 for (int i = 0; i < kTableCount3; ++i) { | 962 for (int i = 0; i < kTableCount4; ++i) { |
883 std::string sql("CREATE TABLE "); | 963 std::string sql("CREATE TABLE "); |
884 sql += kTables3[i].table_name; | 964 sql += kTables4[i].table_name; |
885 sql += kTables3[i].columns; | 965 sql += kTables4[i].columns; |
886 EXPECT_TRUE(connection.Execute(sql.c_str())); | 966 EXPECT_TRUE(connection.Execute(sql.c_str())); |
887 } | 967 } |
888 | 968 |
889 for (int i = 0; i < kIndexCount3; ++i) { | 969 for (int i = 0; i < kIndexCount4; ++i) { |
890 std::string sql; | 970 std::string sql; |
891 if (kIndexes3[i].unique) | 971 if (kIndexes4[i].unique) |
892 sql += "CREATE UNIQUE INDEX "; | 972 sql += "CREATE UNIQUE INDEX "; |
893 else | 973 else |
894 sql += "CREATE INDEX "; | 974 sql += "CREATE INDEX "; |
895 sql += kIndexes3[i].index_name; | 975 sql += kIndexes4[i].index_name; |
896 sql += " ON "; | 976 sql += " ON "; |
897 sql += kIndexes3[i].table_name; | 977 sql += kIndexes4[i].table_name; |
898 sql += kIndexes3[i].columns; | 978 sql += kIndexes4[i].columns; |
899 EXPECT_TRUE(connection.Execute(sql.c_str())); | 979 EXPECT_TRUE(connection.Execute(sql.c_str())); |
900 } | 980 } |
901 | 981 |
902 const char* kSql = | 982 const char* kNamespacesSql = |
903 "INSERT INTO FallbackNameSpaces" | 983 "INSERT INTO Namespaces" |
904 " (cache_id, origin, namespace_url, fallback_entry_url)" | 984 " (cache_id, origin, type, namespace_url, target_url)" |
905 " VALUES (?, ?, ?, ?)"; | 985 " VALUES (?, ?, ?, ?, ?)"; |
906 | |
907 sql::Statement statement; | 986 sql::Statement statement; |
908 statement.Assign(connection.GetUniqueStatement(kSql)); | 987 statement.Assign(connection.GetUniqueStatement(kNamespacesSql)); |
909 EXPECT_TRUE(statement.is_valid()); | 988 EXPECT_TRUE(statement.is_valid()); |
910 for (int i = 0; i < kNumNamespaces; ++i) { | 989 for (int i = 0; i < kNumNamespaces; ++i) { |
911 GURL namespace_url( | 990 GURL namespace_url( |
912 kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i))); | 991 kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i))); |
913 GURL target_url( | 992 GURL target_url( |
914 kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i))); | 993 kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i))); |
915 statement.BindInt64(0, i); | 994 statement.BindInt64(0, i); |
916 statement.BindString(1, kMockOrigin.spec().c_str()); | 995 statement.BindString(1, kMockOrigin.spec().c_str()); |
917 statement.BindString(2, namespace_url.spec().c_str()); | 996 statement.BindInt(2, APPCACHE_FALLBACK_NAMESPACE); |
918 statement.BindString(3, target_url.spec().c_str()); | 997 statement.BindString(3, namespace_url.spec().c_str()); |
| 998 statement.BindString(4, target_url.spec().c_str()); |
919 ASSERT_TRUE(statement.Run()); | 999 ASSERT_TRUE(statement.Run()); |
920 statement.Reset(true); | 1000 statement.Reset(true); |
921 } | 1001 } |
| 1002 |
| 1003 const char* kWhitelistsSql = |
| 1004 "INSERT INTO OnlineWhiteLists" |
| 1005 " (cache_id, namespace_url)" |
| 1006 " VALUES (?, ?)"; |
| 1007 statement.Assign(connection.GetUniqueStatement(kWhitelistsSql)); |
| 1008 EXPECT_TRUE(statement.is_valid()); |
| 1009 for (int i = 0; i < kNumNamespaces; ++i) { |
| 1010 GURL namespace_url( |
| 1011 kMockOrigin.Resolve(base::StringPrintf(kWhitelistUrlFormat, i))); |
| 1012 statement.BindInt64(0, kWhitelistCacheId); |
| 1013 statement.BindString(1, namespace_url.spec().c_str()); |
| 1014 ASSERT_TRUE(statement.Run()); |
| 1015 statement.Reset(true); |
| 1016 } |
922 | 1017 |
923 EXPECT_TRUE(transaction.Commit()); | 1018 EXPECT_TRUE(transaction.Commit()); |
924 } | 1019 } |
925 | 1020 |
926 // Open that database and verify that it got updated. | 1021 // Open that database and verify that it got upgraded to v7. |
927 AppCacheDatabase db(kDbFile); | 1022 AppCacheDatabase db(kDbFile); |
928 EXPECT_TRUE(db.LazyOpen(true)); | 1023 EXPECT_TRUE(db.LazyOpen(true)); |
929 | |
930 EXPECT_FALSE(db.db_->DoesTableExist("FallbackNameSpaces")); | |
931 EXPECT_FALSE(db.db_->DoesIndexExist("FallbackNamesSpacesCacheIndex")); | |
932 EXPECT_FALSE(db.db_->DoesIndexExist("FallbackNameSpacesOriginIndex")); | |
933 EXPECT_FALSE(db.db_->DoesIndexExist("FallbackNameSpacesCacheAndUrlIndex")); | |
934 | |
935 EXPECT_TRUE(db.db_->DoesTableExist("Namespaces")); | |
936 EXPECT_TRUE(db.db_->DoesIndexExist("NamespacesCacheIndex")); | |
937 EXPECT_TRUE(db.db_->DoesIndexExist("NamespacesOriginIndex")); | |
938 EXPECT_TRUE(db.db_->DoesIndexExist("NamespacesCacheAndUrlIndex")); | |
939 EXPECT_TRUE(db.db_->DoesColumnExist("Namespaces", "is_pattern")); | 1024 EXPECT_TRUE(db.db_->DoesColumnExist("Namespaces", "is_pattern")); |
940 EXPECT_TRUE(db.db_->DoesColumnExist("OnlineWhiteLists", "is_pattern")); | 1025 EXPECT_TRUE(db.db_->DoesColumnExist("OnlineWhiteLists", "is_pattern")); |
941 | 1026 EXPECT_TRUE(db.db_->DoesColumnExist("Groups", |
942 EXPECT_EQ(5, db.meta_table_->GetVersionNumber()); | 1027 "last_full_update_check_time")); |
943 EXPECT_EQ(5, db.meta_table_->GetCompatibleVersionNumber()); | 1028 EXPECT_TRUE(db.db_->DoesColumnExist("Groups", |
| 1029 "first_evictable_error_time")); |
| 1030 EXPECT_EQ(7, db.meta_table_->GetVersionNumber()); |
| 1031 EXPECT_EQ(7, db.meta_table_->GetCompatibleVersionNumber()); |
944 | 1032 |
945 std::vector<AppCacheDatabase::NamespaceRecord> intercepts; | 1033 std::vector<AppCacheDatabase::NamespaceRecord> intercepts; |
946 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks; | 1034 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks; |
947 EXPECT_TRUE(db.FindNamespacesForOrigin(kMockOrigin, &intercepts, | 1035 EXPECT_TRUE(db.FindNamespacesForOrigin(kMockOrigin, &intercepts, |
948 &fallbacks)); | 1036 &fallbacks)); |
949 EXPECT_TRUE(intercepts.empty()); | 1037 EXPECT_TRUE(intercepts.empty()); |
950 EXPECT_EQ(kNumNamespaces, static_cast<int>(fallbacks.size())); | 1038 EXPECT_EQ(kNumNamespaces, static_cast<int>(fallbacks.size())); |
951 | 1039 |
| 1040 std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelists; |
| 1041 EXPECT_TRUE(db.FindOnlineWhiteListForCache(kWhitelistCacheId, &whitelists)); |
| 1042 EXPECT_EQ(kNumNamespaces, static_cast<int>(whitelists.size())); |
| 1043 |
952 for (int i = 0; i < kNumNamespaces; ++i) { | 1044 for (int i = 0; i < kNumNamespaces; ++i) { |
953 GURL expected_namespace_url( | 1045 GURL expected_namespace_url( |
954 kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i))); | 1046 kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i))); |
955 GURL expected_target_url( | 1047 GURL expected_target_url( |
956 kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i))); | 1048 kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i))); |
| 1049 GURL expected_whitelist_url( |
| 1050 kMockOrigin.Resolve(base::StringPrintf(kWhitelistUrlFormat, i))); |
957 | 1051 |
958 EXPECT_EQ(i, fallbacks[i].cache_id); | 1052 EXPECT_EQ(i, fallbacks[i].cache_id); |
959 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[i].namespace_.type); | 1053 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[i].namespace_.type); |
960 EXPECT_EQ(kMockOrigin, fallbacks[i].origin); | 1054 EXPECT_EQ(kMockOrigin, fallbacks[i].origin); |
961 EXPECT_EQ(expected_namespace_url, fallbacks[i].namespace_.namespace_url); | 1055 EXPECT_EQ(expected_namespace_url, fallbacks[i].namespace_.namespace_url); |
962 EXPECT_EQ(expected_target_url, fallbacks[i].namespace_.target_url); | 1056 EXPECT_EQ(expected_target_url, fallbacks[i].namespace_.target_url); |
963 EXPECT_FALSE(fallbacks[i].namespace_.is_pattern); | 1057 EXPECT_FALSE(fallbacks[i].namespace_.is_pattern); |
| 1058 EXPECT_EQ(expected_whitelist_url, whitelists[i].namespace_url); |
| 1059 EXPECT_FALSE(whitelists[i].is_pattern); |
964 } | 1060 } |
965 } | 1061 } |
966 #endif // !APPCACHE_USE_SIMPLE_CACHE | 1062 #endif // !APPCACHE_USE_SIMPLE_CACHE |
967 | 1063 |
968 #if defined(APPCACHE_USE_SIMPLE_CACHE) | 1064 // Verify last_full_update_check_time and first_evictable_error_time. |
969 // There is no such upgrade path in this case. | 1065 TEST(AppCacheDatabaseTest, UpgradeSchema5or6to7) { |
970 #else | |
971 TEST(AppCacheDatabaseTest, UpgradeSchema4to5) { | |
972 // Real file on disk for this test. | 1066 // Real file on disk for this test. |
973 base::ScopedTempDir temp_dir; | 1067 base::ScopedTempDir temp_dir; |
974 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 1068 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
975 const base::FilePath kDbFile = temp_dir.path().AppendASCII("upgrade4.db"); | 1069 const base::FilePath kDbFile = |
| 1070 temp_dir.path().AppendASCII("upgrade5or6to7.db"); |
976 | 1071 |
977 const GURL kMockOrigin("http://mockorigin/"); | 1072 const GURL kMockOrigin("http://mockorigin/"); |
978 const char kNamespaceUrlFormat[] = "namespace%d"; | 1073 const base::Time kMockTime = base::Time::Now(); |
979 const char kWhitelistUrlFormat[] = "whitelist%d"; | |
980 const char kTargetUrlFormat[] = "target%d"; | |
981 const int kNumNamespaces = 10; | |
982 const int kWhitelistCacheId = 1; | |
983 | 1074 |
984 // Create a v4 schema based database containing some fallback records. | 1075 // Create a v5or6 schema based database containing two groups, one |
| 1076 // that has an associated cache as expected, and one which erroneously |
| 1077 // is missing its cache record. |
985 { | 1078 { |
986 const int kVersion4 = 4; | 1079 // The SQL schema is the same in these two cases. |
| 1080 #if defined(APPCACHE_USE_SIMPLE_CACHE) |
| 1081 const int kVersionN = 6; |
| 1082 #else |
| 1083 const int kVersionN = 5; |
| 1084 #endif // !APPCACHE_USE_SIMPLE_CACHE |
| 1085 |
987 const char kGroupsTable[] = "Groups"; | 1086 const char kGroupsTable[] = "Groups"; |
988 const char kCachesTable[] = "Caches"; | 1087 const char kCachesTable[] = "Caches"; |
989 const char kEntriesTable[] = "Entries"; | 1088 const char kEntriesTable[] = "Entries"; |
990 const char kNamespacesTable[] = "Namespaces"; | 1089 const char kNamespacesTable[] = "Namespaces"; |
991 const char kOnlineWhiteListsTable[] = "OnlineWhiteLists"; | 1090 const char kOnlineWhiteListsTable[] = "OnlineWhiteLists"; |
992 const char kDeletableResponseIdsTable[] = "DeletableResponseIds"; | 1091 const char kDeletableResponseIdsTable[] = "DeletableResponseIds"; |
993 | 1092 |
994 struct TableInfo { | 1093 struct TableInfo { |
995 const char* table_name; | 1094 const char* table_name; |
996 const char* columns; | 1095 const char* columns; |
997 }; | 1096 }; |
998 | 1097 |
999 struct IndexInfo { | 1098 struct IndexInfo { |
1000 const char* index_name; | 1099 const char* index_name; |
1001 const char* table_name; | 1100 const char* table_name; |
1002 const char* columns; | 1101 const char* columns; |
1003 bool unique; | 1102 bool unique; |
1004 }; | 1103 }; |
1005 | 1104 |
1006 const TableInfo kTables4[] = { | 1105 const TableInfo kTables5[] = { |
1007 { kGroupsTable, | 1106 { kGroupsTable, |
1008 "(group_id INTEGER PRIMARY KEY," | 1107 "(group_id INTEGER PRIMARY KEY," |
1009 " origin TEXT," | 1108 " origin TEXT," |
1010 " manifest_url TEXT," | 1109 " manifest_url TEXT," |
1011 " creation_time INTEGER," | 1110 " creation_time INTEGER," |
1012 " last_access_time INTEGER)" }, | 1111 " last_access_time INTEGER)" }, |
1013 | 1112 |
1014 { kCachesTable, | 1113 { kCachesTable, |
1015 "(cache_id INTEGER PRIMARY KEY," | 1114 "(cache_id INTEGER PRIMARY KEY," |
1016 " group_id INTEGER," | 1115 " group_id INTEGER," |
1017 " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1))," | 1116 " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1))," |
1018 " update_time INTEGER," | 1117 " update_time INTEGER," |
1019 " cache_size INTEGER)" }, // intentionally not normalized | 1118 " cache_size INTEGER)" }, // intentionally not normalized |
1020 | 1119 |
1021 { kEntriesTable, | 1120 { kEntriesTable, |
1022 "(cache_id INTEGER," | 1121 "(cache_id INTEGER," |
1023 " url TEXT," | 1122 " url TEXT," |
1024 " flags INTEGER," | 1123 " flags INTEGER," |
1025 " response_id INTEGER," | 1124 " response_id INTEGER," |
1026 " response_size INTEGER)" }, | 1125 " response_size INTEGER)" }, |
1027 | 1126 |
1028 { kNamespacesTable, | 1127 { kNamespacesTable, |
1029 "(cache_id INTEGER," | 1128 "(cache_id INTEGER," |
1030 " origin TEXT," // intentionally not normalized | 1129 " origin TEXT," // intentionally not normalized |
1031 " type INTEGER," | 1130 " type INTEGER," |
1032 " namespace_url TEXT," | 1131 " namespace_url TEXT," |
1033 " target_url TEXT)" }, | 1132 " target_url TEXT," |
| 1133 " is_pattern INTEGER CHECK(is_pattern IN (0, 1)))" }, |
1034 | 1134 |
1035 { kOnlineWhiteListsTable, | 1135 { kOnlineWhiteListsTable, |
1036 "(cache_id INTEGER," | 1136 "(cache_id INTEGER," |
1037 " namespace_url TEXT)" }, | 1137 " namespace_url TEXT," |
| 1138 " is_pattern INTEGER CHECK(is_pattern IN (0, 1)))" }, |
1038 | 1139 |
1039 { kDeletableResponseIdsTable, | 1140 { kDeletableResponseIdsTable, |
1040 "(response_id INTEGER NOT NULL)" }, | 1141 "(response_id INTEGER NOT NULL)" }, |
1041 }; | 1142 }; |
1042 | 1143 |
1043 const IndexInfo kIndexes4[] = { | 1144 const IndexInfo kIndexes5[] = { |
1044 { "GroupsOriginIndex", | 1145 { "GroupsOriginIndex", |
1045 kGroupsTable, | 1146 kGroupsTable, |
1046 "(origin)", | 1147 "(origin)", |
1047 false }, | 1148 false }, |
1048 | 1149 |
1049 { "GroupsManifestIndex", | 1150 { "GroupsManifestIndex", |
1050 kGroupsTable, | 1151 kGroupsTable, |
1051 "(manifest_url)", | 1152 "(manifest_url)", |
1052 true }, | 1153 true }, |
1053 | 1154 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 kOnlineWhiteListsTable, | 1191 kOnlineWhiteListsTable, |
1091 "(cache_id)", | 1192 "(cache_id)", |
1092 false }, | 1193 false }, |
1093 | 1194 |
1094 { "DeletableResponsesIdIndex", | 1195 { "DeletableResponsesIdIndex", |
1095 kDeletableResponseIdsTable, | 1196 kDeletableResponseIdsTable, |
1096 "(response_id)", | 1197 "(response_id)", |
1097 true }, | 1198 true }, |
1098 }; | 1199 }; |
1099 | 1200 |
1100 const int kTableCount4 = arraysize(kTables4); | 1201 const int kTableCount5 = arraysize(kTables5); |
1101 const int kIndexCount4 = arraysize(kIndexes4); | 1202 const int kIndexCount5 = arraysize(kIndexes5); |
1102 | 1203 |
1103 sql::Connection connection; | 1204 sql::Connection connection; |
1104 EXPECT_TRUE(connection.Open(kDbFile)); | 1205 EXPECT_TRUE(connection.Open(kDbFile)); |
1105 | 1206 |
1106 sql::Transaction transaction(&connection); | 1207 sql::Transaction transaction(&connection); |
1107 EXPECT_TRUE(transaction.Begin()); | 1208 EXPECT_TRUE(transaction.Begin()); |
1108 | 1209 |
1109 sql::MetaTable meta_table; | 1210 sql::MetaTable meta_table; |
1110 EXPECT_TRUE(meta_table.Init(&connection, kVersion4, kVersion4)); | 1211 EXPECT_TRUE(meta_table.Init(&connection, kVersionN, kVersionN)); |
1111 | 1212 |
1112 for (int i = 0; i < kTableCount4; ++i) { | 1213 for (int i = 0; i < kTableCount5; ++i) { |
1113 std::string sql("CREATE TABLE "); | 1214 std::string sql("CREATE TABLE "); |
1114 sql += kTables4[i].table_name; | 1215 sql += kTables5[i].table_name; |
1115 sql += kTables4[i].columns; | 1216 sql += kTables5[i].columns; |
1116 EXPECT_TRUE(connection.Execute(sql.c_str())); | 1217 EXPECT_TRUE(connection.Execute(sql.c_str())); |
1117 } | 1218 } |
1118 | 1219 |
1119 for (int i = 0; i < kIndexCount4; ++i) { | 1220 for (int i = 0; i < kIndexCount5; ++i) { |
1120 std::string sql; | 1221 std::string sql; |
1121 if (kIndexes4[i].unique) | 1222 if (kIndexes5[i].unique) |
1122 sql += "CREATE UNIQUE INDEX "; | 1223 sql += "CREATE UNIQUE INDEX "; |
1123 else | 1224 else |
1124 sql += "CREATE INDEX "; | 1225 sql += "CREATE INDEX "; |
1125 sql += kIndexes4[i].index_name; | 1226 sql += kIndexes5[i].index_name; |
1126 sql += " ON "; | 1227 sql += " ON "; |
1127 sql += kIndexes4[i].table_name; | 1228 sql += kIndexes5[i].table_name; |
1128 sql += kIndexes4[i].columns; | 1229 sql += kIndexes5[i].columns; |
1129 EXPECT_TRUE(connection.Execute(sql.c_str())); | 1230 EXPECT_TRUE(connection.Execute(sql.c_str())); |
1130 } | 1231 } |
1131 | 1232 |
1132 const char* kNamespacesSql = | 1233 sql::Statement statement; |
1133 "INSERT INTO Namespaces" | 1234 |
1134 " (cache_id, origin, type, namespace_url, target_url)" | 1235 const GURL kMockManifestUrl(kMockOrigin.Resolve("mockmanifest")); |
| 1236 const GURL kMockManifest2Url(kMockOrigin.Resolve("mockmanifest2")); |
| 1237 |
| 1238 const char* kInsertGroup = |
| 1239 "INSERT INTO Groups" |
| 1240 " (group_id, origin, manifest_url, creation_time, last_access_time)" |
1135 " VALUES (?, ?, ?, ?, ?)"; | 1241 " VALUES (?, ?, ?, ?, ?)"; |
1136 sql::Statement statement; | 1242 statement.Assign(connection.GetUniqueStatement(kInsertGroup)); |
1137 statement.Assign(connection.GetUniqueStatement(kNamespacesSql)); | |
1138 EXPECT_TRUE(statement.is_valid()); | 1243 EXPECT_TRUE(statement.is_valid()); |
1139 for (int i = 0; i < kNumNamespaces; ++i) { | 1244 statement.BindInt64(0, 1); |
1140 GURL namespace_url( | 1245 statement.BindString(1, kMockOrigin.spec().c_str()); |
1141 kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i))); | 1246 statement.BindString(2, kMockManifestUrl.spec().c_str()); |
1142 GURL target_url( | 1247 statement.BindInt64(3, kMockTime.ToInternalValue()); |
1143 kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i))); | 1248 statement.BindInt64(4, kMockTime.ToInternalValue()); |
1144 statement.BindInt64(0, i); | 1249 ASSERT_TRUE(statement.Run()); |
1145 statement.BindString(1, kMockOrigin.spec().c_str()); | 1250 statement.Reset(true); |
1146 statement.BindInt(2, APPCACHE_FALLBACK_NAMESPACE); | 1251 statement.BindInt64(0, 2); |
1147 statement.BindString(3, namespace_url.spec().c_str()); | 1252 statement.BindString(1, kMockOrigin.spec().c_str()); |
1148 statement.BindString(4, target_url.spec().c_str()); | 1253 statement.BindString(2, kMockManifest2Url.spec().c_str()); |
1149 ASSERT_TRUE(statement.Run()); | 1254 statement.BindInt64(3, kMockTime.ToInternalValue()); |
1150 statement.Reset(true); | 1255 statement.BindInt64(4, kMockTime.ToInternalValue()); |
1151 } | 1256 ASSERT_TRUE(statement.Run()); |
| 1257 statement.Reset(true); |
1152 | 1258 |
1153 const char* kWhitelistsSql = | 1259 const char* kInsertCache = |
1154 "INSERT INTO OnlineWhiteLists" | 1260 "INSERT INTO Caches" |
1155 " (cache_id, namespace_url)" | 1261 " (cache_id, group_id, online_wildcard, update_time, cache_size)" |
1156 " VALUES (?, ?)"; | 1262 " VALUES (?, ?, ?, ?, ?)"; |
1157 statement.Assign(connection.GetUniqueStatement(kWhitelistsSql)); | 1263 statement.Assign(connection.GetUniqueStatement(kInsertCache)); |
1158 EXPECT_TRUE(statement.is_valid()); | 1264 EXPECT_TRUE(statement.is_valid()); |
1159 for (int i = 0; i < kNumNamespaces; ++i) { | 1265 statement.BindInt64(0, 1); |
1160 GURL namespace_url( | 1266 statement.BindInt64(1, 1); |
1161 kMockOrigin.Resolve(base::StringPrintf(kWhitelistUrlFormat, i))); | 1267 statement.BindInt(2, 0); |
1162 statement.BindInt64(0, kWhitelistCacheId); | 1268 statement.BindInt64(3, kMockTime.ToInternalValue()); |
1163 statement.BindString(1, namespace_url.spec().c_str()); | 1269 statement.BindInt64(4, 1000); |
1164 ASSERT_TRUE(statement.Run()); | 1270 ASSERT_TRUE(statement.Run()); |
1165 statement.Reset(true); | 1271 statement.Reset(true); |
1166 } | |
1167 | 1272 |
1168 EXPECT_TRUE(transaction.Commit()); | 1273 EXPECT_TRUE(transaction.Commit()); |
1169 } | 1274 } |
1170 | 1275 |
1171 // Open that database and verify that it got upgraded to v5. | 1276 // Open that database and verify that it got upgraded to v7. |
1172 AppCacheDatabase db(kDbFile); | 1277 AppCacheDatabase db(kDbFile); |
1173 EXPECT_TRUE(db.LazyOpen(true)); | 1278 EXPECT_TRUE(db.LazyOpen(true)); |
1174 EXPECT_TRUE(db.db_->DoesColumnExist("Namespaces", "is_pattern")); | 1279 EXPECT_TRUE(db.db_->DoesColumnExist("Groups", |
1175 EXPECT_TRUE(db.db_->DoesColumnExist("OnlineWhiteLists", "is_pattern")); | 1280 "last_full_update_check_time")); |
1176 EXPECT_EQ(5, db.meta_table_->GetVersionNumber()); | 1281 EXPECT_TRUE(db.db_->DoesColumnExist("Groups", |
1177 EXPECT_EQ(5, db.meta_table_->GetCompatibleVersionNumber()); | 1282 "first_evictable_error_time")); |
| 1283 EXPECT_EQ(7, db.meta_table_->GetVersionNumber()); |
| 1284 EXPECT_EQ(7, db.meta_table_->GetCompatibleVersionNumber()); |
1178 | 1285 |
1179 std::vector<AppCacheDatabase::NamespaceRecord> intercepts; | 1286 AppCacheDatabase::GroupRecord group; |
1180 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks; | 1287 EXPECT_TRUE(db.FindGroup(1, &group)); |
1181 EXPECT_TRUE(db.FindNamespacesForOrigin(kMockOrigin, &intercepts, | 1288 EXPECT_EQ(kMockTime, group.last_full_update_check_time); |
1182 &fallbacks)); | 1289 EXPECT_EQ(kZeroTime, group.first_evictable_error_time); |
1183 EXPECT_TRUE(intercepts.empty()); | 1290 EXPECT_TRUE(db.FindGroup(2, &group)); |
1184 EXPECT_EQ(kNumNamespaces, static_cast<int>(fallbacks.size())); | 1291 EXPECT_EQ(kZeroTime, group.last_full_update_check_time); |
1185 | 1292 EXPECT_EQ(kZeroTime, group.first_evictable_error_time); |
1186 std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelists; | |
1187 EXPECT_TRUE(db.FindOnlineWhiteListForCache(kWhitelistCacheId, &whitelists)); | |
1188 EXPECT_EQ(kNumNamespaces, static_cast<int>(whitelists.size())); | |
1189 | |
1190 for (int i = 0; i < kNumNamespaces; ++i) { | |
1191 GURL expected_namespace_url( | |
1192 kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i))); | |
1193 GURL expected_target_url( | |
1194 kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i))); | |
1195 GURL expected_whitelist_url( | |
1196 kMockOrigin.Resolve(base::StringPrintf(kWhitelistUrlFormat, i))); | |
1197 | |
1198 EXPECT_EQ(i, fallbacks[i].cache_id); | |
1199 EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[i].namespace_.type); | |
1200 EXPECT_EQ(kMockOrigin, fallbacks[i].origin); | |
1201 EXPECT_EQ(expected_namespace_url, fallbacks[i].namespace_.namespace_url); | |
1202 EXPECT_EQ(expected_target_url, fallbacks[i].namespace_.target_url); | |
1203 EXPECT_FALSE(fallbacks[i].namespace_.is_pattern); | |
1204 EXPECT_EQ(expected_whitelist_url, whitelists[i].namespace_url); | |
1205 EXPECT_FALSE(whitelists[i].is_pattern); | |
1206 } | |
1207 } | 1293 } |
1208 #endif // !APPCACHE_USE_SIMPLE_CACHE | |
1209 | 1294 |
1210 } // namespace content | 1295 } // namespace content |
OLD | NEW |