Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: content/browser/appcache/appcache_database_unittest.cc

Issue 879393002: Expire appcaches that fail to update for "too long". (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698