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

Side by Side Diff: chrome/browser/history/thumbnail_database_unittest.cc

Issue 1004373002: Add last_requested field to the favicon_bitmaps table of the favicons database. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address 2nd round of comments. Created 5 years, 9 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <algorithm> 5 #include <algorithm>
6 #include <vector> 6 #include <vector>
7 7
8 #include "base/basictypes.h" 8 #include "base/basictypes.h"
9 #include "base/files/file_enumerator.h" 9 #include "base/files/file_enumerator.h"
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 61
62 // Verify that the up-to-date database has the expected tables and 62 // Verify that the up-to-date database has the expected tables and
63 // columns. Functional tests only check whether the things which 63 // columns. Functional tests only check whether the things which
64 // should be there are, but do not check if extraneous items are 64 // should be there are, but do not check if extraneous items are
65 // present. Any extraneous items have the potential to interact 65 // present. Any extraneous items have the potential to interact
66 // negatively with future schema changes. 66 // negatively with future schema changes.
67 void VerifyTablesAndColumns(sql::Connection* db) { 67 void VerifyTablesAndColumns(sql::Connection* db) {
68 // [meta], [favicons], [favicon_bitmaps], and [icon_mapping]. 68 // [meta], [favicons], [favicon_bitmaps], and [icon_mapping].
69 EXPECT_EQ(4u, sql::test::CountSQLTables(db)); 69 EXPECT_EQ(4u, sql::test::CountSQLTables(db));
70 70
71 // Implicit index on [meta], index on [favicons], index on 71 // Implicit index on [meta], index on [favicons], index on [favicon_bitmaps],
72 // [favicon_bitmaps], two indices on [icon_mapping]. 72 // two indices on [icon_mapping].
73 EXPECT_EQ(5u, sql::test::CountSQLIndices(db)); 73 EXPECT_EQ(5u, sql::test::CountSQLIndices(db));
74 74
75 // [key] and [value]. 75 // [key] and [value].
76 EXPECT_EQ(2u, sql::test::CountTableColumns(db, "meta")); 76 EXPECT_EQ(2u, sql::test::CountTableColumns(db, "meta"));
77 77
78 // [id], [url], and [icon_type]. 78 // [id], [url], and [icon_type].
79 EXPECT_EQ(3u, sql::test::CountTableColumns(db, "favicons")); 79 EXPECT_EQ(3u, sql::test::CountTableColumns(db, "favicons"));
80 80
81 // [id], [icon_id], [last_updated], [image_data], [width], and [height]. 81 // [id], [icon_id], [last_updated], [image_data], [width], [height] and
82 EXPECT_EQ(6u, sql::test::CountTableColumns(db, "favicon_bitmaps")); 82 // [last_requested].
83 EXPECT_EQ(7u, sql::test::CountTableColumns(db, "favicon_bitmaps"));
83 84
84 // [id], [page_url], and [icon_id]. 85 // [id], [page_url], and [icon_id].
85 EXPECT_EQ(3u, sql::test::CountTableColumns(db, "icon_mapping")); 86 EXPECT_EQ(3u, sql::test::CountTableColumns(db, "icon_mapping"));
86 } 87 }
87 88
88 void VerifyDatabaseEmpty(sql::Connection* db) { 89 void VerifyDatabaseEmpty(sql::Connection* db) {
89 size_t rows = 0; 90 size_t rows = 0;
90 EXPECT_TRUE(sql::test::CountTableRows(db, "favicons", &rows)); 91 EXPECT_TRUE(sql::test::CountTableRows(db, "favicons", &rows));
91 EXPECT_EQ(0u, rows); 92 EXPECT_EQ(0u, rows);
92 EXPECT_TRUE(sql::test::CountTableRows(db, "favicon_bitmaps", &rows)); 93 EXPECT_TRUE(sql::test::CountTableRows(db, "favicon_bitmaps", &rows));
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 EXPECT_NE(0, id); 207 EXPECT_NE(0, id);
207 208
208 EXPECT_NE(0, db.AddIconMapping(url, id)); 209 EXPECT_NE(0, db.AddIconMapping(url, id));
209 std::vector<IconMapping> icon_mappings; 210 std::vector<IconMapping> icon_mappings;
210 EXPECT_TRUE(db.GetIconMappingsForPageURL(url, &icon_mappings)); 211 EXPECT_TRUE(db.GetIconMappingsForPageURL(url, &icon_mappings));
211 EXPECT_EQ(1u, icon_mappings.size()); 212 EXPECT_EQ(1u, icon_mappings.size());
212 EXPECT_EQ(url, icon_mappings.front().page_url); 213 EXPECT_EQ(url, icon_mappings.front().page_url);
213 EXPECT_EQ(id, icon_mappings.front().icon_id); 214 EXPECT_EQ(id, icon_mappings.front().icon_id);
214 } 215 }
215 216
217 TEST_F(ThumbnailDatabaseTest, LastRequestedTime) {
218 ThumbnailDatabase db(NULL);
219 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
220 db.BeginTransaction();
221
222 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
223 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
224
225 GURL url("http://google.com");
226 base::Time now = base::Time::Now();
227 favicon_base::FaviconID id =
228 db.AddFavicon(url, favicon_base::TOUCH_ICON, favicon, now, gfx::Size());
229 EXPECT_NE(0, id);
230
231 // Fetching the last requested time of a non-existent bitmap should fail.
232 base::Time last_requested = base::Time::UnixEpoch();
233 EXPECT_FALSE(db.GetFaviconBitmapLastRequestedTime(id + 1, &last_requested));
234 EXPECT_EQ(last_requested, base::Time::UnixEpoch()); // Remains unchanged.
235
236 // Fetching the last requested time of a bitmap that has no last request
237 // should return a null timestamp.
238 last_requested = base::Time::UnixEpoch();
239 EXPECT_TRUE(db.GetFaviconBitmapLastRequestedTime(id, &last_requested));
240 EXPECT_TRUE(last_requested.is_null());
241
242 // Setting the last requested time of an existing bitmap should succeed, and
243 // the set time should be returned by the corresponding "Get".
244 last_requested = base::Time::UnixEpoch();
245 EXPECT_TRUE(db.SetFaviconBitmapLastRequestedTime(id, now));
246 EXPECT_TRUE(db.GetFaviconBitmapLastRequestedTime(id, &last_requested));
247 EXPECT_EQ(last_requested, now);
248 }
249
216 TEST_F(ThumbnailDatabaseTest, UpdateIconMapping) { 250 TEST_F(ThumbnailDatabaseTest, UpdateIconMapping) {
217 ThumbnailDatabase db(NULL); 251 ThumbnailDatabase db(NULL);
218 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); 252 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
219 db.BeginTransaction(); 253 db.BeginTransaction();
220 254
221 GURL url("http://google.com"); 255 GURL url("http://google.com");
222 favicon_base::FaviconID id = db.AddFavicon(url, favicon_base::TOUCH_ICON); 256 favicon_base::FaviconID id = db.AddFavicon(url, favicon_base::TOUCH_ICON);
223 257
224 EXPECT_LT(0, db.AddIconMapping(url, id)); 258 EXPECT_LT(0, db.AddIconMapping(url, id));
225 std::vector<IconMapping> icon_mapping; 259 std::vector<IconMapping> icon_mapping;
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 // Version 4 is deprecated, the data should all be gone. 698 // Version 4 is deprecated, the data should all be gone.
665 VerifyDatabaseEmpty(&db->db_); 699 VerifyDatabaseEmpty(&db->db_);
666 } 700 }
667 701
668 // Test loading version 5 database. 702 // Test loading version 5 database.
669 TEST_F(ThumbnailDatabaseTest, Version5) { 703 TEST_F(ThumbnailDatabaseTest, Version5) {
670 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v5.sql"); 704 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v5.sql");
671 ASSERT_TRUE(db.get() != NULL); 705 ASSERT_TRUE(db.get() != NULL);
672 VerifyTablesAndColumns(&db->db_); 706 VerifyTablesAndColumns(&db->db_);
673 707
674 EXPECT_TRUE(CheckPageHasIcon(db.get(), 708 // Version 5 is deprecated, the data should all be gone.
675 kPageUrl1, 709 VerifyDatabaseEmpty(&db->db_);
676 favicon_base::FAVICON,
677 kIconUrl1,
678 gfx::Size(),
679 sizeof(kBlob1),
680 kBlob1));
681 EXPECT_TRUE(CheckPageHasIcon(db.get(),
682 kPageUrl2,
683 favicon_base::FAVICON,
684 kIconUrl2,
685 gfx::Size(),
686 sizeof(kBlob2),
687 kBlob2));
688 EXPECT_TRUE(CheckPageHasIcon(db.get(),
689 kPageUrl3,
690 favicon_base::FAVICON,
691 kIconUrl1,
692 gfx::Size(),
693 sizeof(kBlob1),
694 kBlob1));
695 EXPECT_TRUE(CheckPageHasIcon(db.get(),
696 kPageUrl3,
697 favicon_base::TOUCH_ICON,
698 kIconUrl3,
699 gfx::Size(),
700 sizeof(kBlob2),
701 kBlob2));
702 } 710 }
703 711
704 // Test loading version 6 database. 712 // Test loading version 6 database.
705 TEST_F(ThumbnailDatabaseTest, Version6) { 713 TEST_F(ThumbnailDatabaseTest, Version6) {
706 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v6.sql"); 714 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v6.sql");
707 ASSERT_TRUE(db.get() != NULL); 715 ASSERT_TRUE(db.get() != NULL);
708 VerifyTablesAndColumns(&db->db_); 716 VerifyTablesAndColumns(&db->db_);
709 717
718 EXPECT_TRUE(CheckPageHasIcon(db.get(),
719 kPageUrl1,
720 favicon_base::FAVICON,
721 kIconUrl1,
722 kLargeSize,
723 sizeof(kBlob1),
724 kBlob1));
725 EXPECT_TRUE(CheckPageHasIcon(db.get(),
726 kPageUrl2,
727 favicon_base::FAVICON,
728 kIconUrl2,
729 kLargeSize,
730 sizeof(kBlob2),
731 kBlob2));
732 EXPECT_TRUE(CheckPageHasIcon(db.get(),
733 kPageUrl3,
734 favicon_base::FAVICON,
735 kIconUrl1,
736 kLargeSize,
737 sizeof(kBlob1),
738 kBlob1));
739 EXPECT_TRUE(CheckPageHasIcon(db.get(),
740 kPageUrl3,
741 favicon_base::TOUCH_ICON,
742 kIconUrl3,
743 kLargeSize,
744 sizeof(kBlob2),
745 kBlob2));
746 }
747
748 // Test loading version 7 database.
749 TEST_F(ThumbnailDatabaseTest, Version7) {
750 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v7.sql");
751 ASSERT_TRUE(db.get() != NULL);
752 VerifyTablesAndColumns(&db->db_);
753
710 EXPECT_TRUE(CheckPageHasIcon(db.get(), 754 EXPECT_TRUE(CheckPageHasIcon(db.get(),
711 kPageUrl1, 755 kPageUrl1,
712 favicon_base::FAVICON, 756 favicon_base::FAVICON,
713 kIconUrl1, 757 kIconUrl1,
714 kLargeSize, 758 kLargeSize,
715 sizeof(kBlob1), 759 sizeof(kBlob1),
716 kBlob1)); 760 kBlob1));
717 EXPECT_TRUE(CheckPageHasIcon(db.get(), 761 EXPECT_TRUE(CheckPageHasIcon(db.get(),
718 kPageUrl2, 762 kPageUrl2,
719 favicon_base::FAVICON, 763 favicon_base::FAVICON,
(...skipping 10 matching lines...) Expand all
730 kBlob1)); 774 kBlob1));
731 EXPECT_TRUE(CheckPageHasIcon(db.get(), 775 EXPECT_TRUE(CheckPageHasIcon(db.get(),
732 kPageUrl3, 776 kPageUrl3,
733 favicon_base::TOUCH_ICON, 777 favicon_base::TOUCH_ICON,
734 kIconUrl3, 778 kIconUrl3,
735 kLargeSize, 779 kLargeSize,
736 sizeof(kBlob2), 780 sizeof(kBlob2),
737 kBlob2)); 781 kBlob2));
738 } 782 }
739 783
740 // Test loading version 7 database. 784 // Test loading version 8 database.
741 TEST_F(ThumbnailDatabaseTest, Version7) { 785 TEST_F(ThumbnailDatabaseTest, Version8) {
742 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v7.sql"); 786 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v8.sql");
743 ASSERT_TRUE(db.get() != NULL); 787 ASSERT_TRUE(db.get() != NULL);
744 VerifyTablesAndColumns(&db->db_); 788 VerifyTablesAndColumns(&db->db_);
745 789
746 EXPECT_TRUE(CheckPageHasIcon(db.get(), 790 EXPECT_TRUE(CheckPageHasIcon(db.get(),
747 kPageUrl1, 791 kPageUrl1,
748 favicon_base::FAVICON, 792 favicon_base::FAVICON,
749 kIconUrl1, 793 kIconUrl1,
750 kLargeSize, 794 kLargeSize,
751 sizeof(kBlob1), 795 sizeof(kBlob1),
752 kBlob1)); 796 kBlob1));
(...skipping 25 matching lines...) Expand all
778 // custom recover virtual table. Under USE_SYSTEM_SQLITE, this is 822 // custom recover virtual table. Under USE_SYSTEM_SQLITE, this is
779 // not available. This is detected dynamically because corrupt 823 // not available. This is detected dynamically because corrupt
780 // databases still need to be handled, perhaps by Raze(), and the 824 // databases still need to be handled, perhaps by Raze(), and the
781 // recovery module is an obvious layer to abstract that to. 825 // recovery module is an obvious layer to abstract that to.
782 // TODO(shess): Handle that case for real! 826 // TODO(shess): Handle that case for real!
783 if (!sql::Recovery::FullRecoverySupported()) 827 if (!sql::Recovery::FullRecoverySupported())
784 return; 828 return;
785 829
786 // Create an example database. 830 // Create an example database.
787 { 831 {
788 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v7.sql")); 832 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v8.sql"));
789 833
790 sql::Connection raw_db; 834 sql::Connection raw_db;
791 EXPECT_TRUE(raw_db.Open(file_name_)); 835 EXPECT_TRUE(raw_db.Open(file_name_));
792 VerifyTablesAndColumns(&raw_db); 836 VerifyTablesAndColumns(&raw_db);
793 } 837 }
794 838
795 // Test that the contents make sense after clean open. 839 // Test that the contents make sense after clean open.
796 { 840 {
797 ThumbnailDatabase db(NULL); 841 ThumbnailDatabase db(NULL);
798 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); 842 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 favicon_base::FAVICON, 947 favicon_base::FAVICON,
904 kIconUrl1, 948 kIconUrl1,
905 kLargeSize, 949 kLargeSize,
906 sizeof(kBlob1), 950 sizeof(kBlob1),
907 kBlob1)); 951 kBlob1));
908 952
909 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 953 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
910 } 954 }
911 } 955 }
912 956
957 TEST_F(ThumbnailDatabaseTest, Recovery7) {
958 // This code tests the recovery module in concert with Chromium's
959 // custom recover virtual table. Under USE_SYSTEM_SQLITE, this is
960 // not available. This is detected dynamically because corrupt
961 // databases still need to be handled, perhaps by Raze(), and the
962 // recovery module is an obvious layer to abstract that to.
963 // TODO(shess): Handle that case for real!
964 if (!sql::Recovery::FullRecoverySupported())
965 return;
966
967 // Create an example database without loading into ThumbnailDatabase
968 // (which would upgrade it).
969 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v7.sql"));
970
971 // Corrupt the |icon_mapping.page_url| index by deleting an element
972 // from the backing table but not the index.
973 {
974 sql::Connection raw_db;
975 EXPECT_TRUE(raw_db.Open(file_name_));
976 ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db));
977 }
978 const char kIndexName[] = "icon_mapping_page_url_idx";
979 const char kDeleteSql[] =
980 "DELETE FROM icon_mapping WHERE page_url = 'http://yahoo.com/'";
981 EXPECT_TRUE(
982 sql::test::CorruptTableOrIndex(file_name_, kIndexName, kDeleteSql));
983
984 // Database should be corrupt at the SQLite level.
985 {
986 sql::Connection raw_db;
987 EXPECT_TRUE(raw_db.Open(file_name_));
988 ASSERT_NE("ok", sql::test::IntegrityCheck(&raw_db));
989 }
990
991 // Open the database and access the corrupt index. Note that this upgrades
992 // the database.
993 {
994 sql::ScopedErrorIgnorer ignore_errors;
995 ignore_errors.IgnoreError(SQLITE_CORRUPT);
996 ThumbnailDatabase db(NULL);
997 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
998
999 // Data for kPageUrl2 was deleted, but the index entry remains,
1000 // this will throw SQLITE_CORRUPT. The corruption handler will
1001 // recover the database and poison the handle, so the outer call
1002 // fails.
1003 EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, NULL));
1004
1005 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
1006 }
1007
1008 // Check that the database is recovered at the SQLite level.
1009 {
1010 sql::Connection raw_db;
1011 EXPECT_TRUE(raw_db.Open(file_name_));
1012 ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db));
1013
1014 // Check that the expected tables exist.
1015 VerifyTablesAndColumns(&raw_db);
1016 }
1017
1018 // Database should also be recovered at higher levels.
1019 {
1020 ThumbnailDatabase db(NULL);
1021 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
1022
1023 // Now this fails because there is no mapping.
1024 EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, NULL));
1025
1026 // Other data was retained by recovery.
1027 EXPECT_TRUE(CheckPageHasIcon(&db,
1028 kPageUrl1,
1029 favicon_base::FAVICON,
1030 kIconUrl1,
1031 kLargeSize,
1032 sizeof(kBlob1),
1033 kBlob1));
1034 }
1035
1036 // Corrupt the database again by adjusting the header.
1037 EXPECT_TRUE(sql::test::CorruptSizeInHeader(file_name_));
1038
1039 // Database is unusable at the SQLite level.
1040 {
1041 sql::ScopedErrorIgnorer ignore_errors;
1042 ignore_errors.IgnoreError(SQLITE_CORRUPT);
1043 sql::Connection raw_db;
1044 EXPECT_TRUE(raw_db.Open(file_name_));
1045 EXPECT_FALSE(raw_db.IsSQLValid("PRAGMA integrity_check"));
1046 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
1047 }
1048
1049 // Database should be recovered during open.
1050 {
1051 sql::ScopedErrorIgnorer ignore_errors;
1052 ignore_errors.IgnoreError(SQLITE_CORRUPT);
1053 ThumbnailDatabase db(NULL);
1054 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
1055
1056 EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, NULL));
1057 EXPECT_TRUE(CheckPageHasIcon(&db,
1058 kPageUrl1,
1059 favicon_base::FAVICON,
1060 kIconUrl1,
1061 kLargeSize,
1062 sizeof(kBlob1),
1063 kBlob1));
1064
1065 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
1066 }
1067 }
1068
913 TEST_F(ThumbnailDatabaseTest, Recovery6) { 1069 TEST_F(ThumbnailDatabaseTest, Recovery6) {
914 // TODO(shess): See comment at top of Recovery test. 1070 // TODO(shess): See comment at top of Recovery test.
915 if (!sql::Recovery::FullRecoverySupported()) 1071 if (!sql::Recovery::FullRecoverySupported())
916 return; 1072 return;
917 1073
918 // Create an example database without loading into ThumbnailDatabase 1074 // Create an example database without loading into ThumbnailDatabase
919 // (which would upgrade it). 1075 // (which would upgrade it).
920 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v6.sql")); 1076 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v6.sql"));
921 1077
922 // Corrupt the database by adjusting the header. This form of corruption will 1078 // Corrupt the database by adjusting the header. This form of corruption will
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 ThumbnailDatabase db(NULL); 1185 ThumbnailDatabase db(NULL);
1030 ASSERT_EQ(sql::INIT_OK, db.Init(db_path)); 1186 ASSERT_EQ(sql::INIT_OK, db.Init(db_path));
1031 1187
1032 // Verify that the resulting schema is correct, whether it 1188 // Verify that the resulting schema is correct, whether it
1033 // involved razing the file or fixing things in place. 1189 // involved razing the file or fixing things in place.
1034 VerifyTablesAndColumns(&db.db_); 1190 VerifyTablesAndColumns(&db.db_);
1035 } 1191 }
1036 } 1192 }
1037 1193
1038 } // namespace history 1194 } // namespace history
OLDNEW
« no previous file with comments | « no previous file | chrome/test/data/History/Favicons.v8.sql » ('j') | components/history/core/browser/thumbnail_database.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698