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

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 review 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 EXPECT_TRUE(db.SetFaviconBitmapLastRequestedTime(id, now));
huangs 2015/03/19 19:14:11 NIT: add redundant last_requested = base::Time::Un
Roger McFarlane (Chromium) 2015/03/20 14:40:59 Done. Not strictly necessary since last_requested
245 EXPECT_TRUE(db.GetFaviconBitmapLastRequestedTime(id, &last_requested));
246 EXPECT_EQ(last_requested, now);
247 }
248
216 TEST_F(ThumbnailDatabaseTest, UpdateIconMapping) { 249 TEST_F(ThumbnailDatabaseTest, UpdateIconMapping) {
217 ThumbnailDatabase db(NULL); 250 ThumbnailDatabase db(NULL);
218 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); 251 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
219 db.BeginTransaction(); 252 db.BeginTransaction();
220 253
221 GURL url("http://google.com"); 254 GURL url("http://google.com");
222 favicon_base::FaviconID id = db.AddFavicon(url, favicon_base::TOUCH_ICON); 255 favicon_base::FaviconID id = db.AddFavicon(url, favicon_base::TOUCH_ICON);
223 256
224 EXPECT_LT(0, db.AddIconMapping(url, id)); 257 EXPECT_LT(0, db.AddIconMapping(url, id));
225 std::vector<IconMapping> icon_mapping; 258 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. 697 // Version 4 is deprecated, the data should all be gone.
665 VerifyDatabaseEmpty(&db->db_); 698 VerifyDatabaseEmpty(&db->db_);
666 } 699 }
667 700
668 // Test loading version 5 database. 701 // Test loading version 5 database.
669 TEST_F(ThumbnailDatabaseTest, Version5) { 702 TEST_F(ThumbnailDatabaseTest, Version5) {
670 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v5.sql"); 703 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v5.sql");
671 ASSERT_TRUE(db.get() != NULL); 704 ASSERT_TRUE(db.get() != NULL);
672 VerifyTablesAndColumns(&db->db_); 705 VerifyTablesAndColumns(&db->db_);
673 706
674 EXPECT_TRUE(CheckPageHasIcon(db.get(), 707 // Version 5 is deprecated, the data should all be gone.
675 kPageUrl1, 708 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 } 709 }
703 710
704 // Test loading version 6 database. 711 // Test loading version 6 database.
705 TEST_F(ThumbnailDatabaseTest, Version6) { 712 TEST_F(ThumbnailDatabaseTest, Version6) {
706 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v6.sql"); 713 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v6.sql");
707 ASSERT_TRUE(db.get() != NULL); 714 ASSERT_TRUE(db.get() != NULL);
708 VerifyTablesAndColumns(&db->db_); 715 VerifyTablesAndColumns(&db->db_);
709 716
717 EXPECT_TRUE(CheckPageHasIcon(db.get(),
718 kPageUrl1,
719 favicon_base::FAVICON,
720 kIconUrl1,
721 kLargeSize,
722 sizeof(kBlob1),
723 kBlob1));
724 EXPECT_TRUE(CheckPageHasIcon(db.get(),
725 kPageUrl2,
726 favicon_base::FAVICON,
727 kIconUrl2,
728 kLargeSize,
729 sizeof(kBlob2),
730 kBlob2));
731 EXPECT_TRUE(CheckPageHasIcon(db.get(),
732 kPageUrl3,
733 favicon_base::FAVICON,
734 kIconUrl1,
735 kLargeSize,
736 sizeof(kBlob1),
737 kBlob1));
738 EXPECT_TRUE(CheckPageHasIcon(db.get(),
739 kPageUrl3,
740 favicon_base::TOUCH_ICON,
741 kIconUrl3,
742 kLargeSize,
743 sizeof(kBlob2),
744 kBlob2));
745 }
746
747 // Test loading version 7 database.
748 TEST_F(ThumbnailDatabaseTest, Version7) {
749 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v7.sql");
750 ASSERT_TRUE(db.get() != NULL);
751 VerifyTablesAndColumns(&db->db_);
752
710 EXPECT_TRUE(CheckPageHasIcon(db.get(), 753 EXPECT_TRUE(CheckPageHasIcon(db.get(),
711 kPageUrl1, 754 kPageUrl1,
712 favicon_base::FAVICON, 755 favicon_base::FAVICON,
713 kIconUrl1, 756 kIconUrl1,
714 kLargeSize, 757 kLargeSize,
715 sizeof(kBlob1), 758 sizeof(kBlob1),
716 kBlob1)); 759 kBlob1));
717 EXPECT_TRUE(CheckPageHasIcon(db.get(), 760 EXPECT_TRUE(CheckPageHasIcon(db.get(),
718 kPageUrl2, 761 kPageUrl2,
719 favicon_base::FAVICON, 762 favicon_base::FAVICON,
(...skipping 10 matching lines...) Expand all
730 kBlob1)); 773 kBlob1));
731 EXPECT_TRUE(CheckPageHasIcon(db.get(), 774 EXPECT_TRUE(CheckPageHasIcon(db.get(),
732 kPageUrl3, 775 kPageUrl3,
733 favicon_base::TOUCH_ICON, 776 favicon_base::TOUCH_ICON,
734 kIconUrl3, 777 kIconUrl3,
735 kLargeSize, 778 kLargeSize,
736 sizeof(kBlob2), 779 sizeof(kBlob2),
737 kBlob2)); 780 kBlob2));
738 } 781 }
739 782
740 // Test loading version 7 database. 783 // Test loading version 8 database.
741 TEST_F(ThumbnailDatabaseTest, Version7) { 784 TEST_F(ThumbnailDatabaseTest, Version8) {
742 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v7.sql"); 785 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v8.sql");
743 ASSERT_TRUE(db.get() != NULL); 786 ASSERT_TRUE(db.get() != NULL);
744 VerifyTablesAndColumns(&db->db_); 787 VerifyTablesAndColumns(&db->db_);
745 788
746 EXPECT_TRUE(CheckPageHasIcon(db.get(), 789 EXPECT_TRUE(CheckPageHasIcon(db.get(),
747 kPageUrl1, 790 kPageUrl1,
748 favicon_base::FAVICON, 791 favicon_base::FAVICON,
749 kIconUrl1, 792 kIconUrl1,
750 kLargeSize, 793 kLargeSize,
751 sizeof(kBlob1), 794 sizeof(kBlob1),
752 kBlob1)); 795 kBlob1));
(...skipping 25 matching lines...) Expand all
778 // custom recover virtual table. Under USE_SYSTEM_SQLITE, this is 821 // custom recover virtual table. Under USE_SYSTEM_SQLITE, this is
779 // not available. This is detected dynamically because corrupt 822 // not available. This is detected dynamically because corrupt
780 // databases still need to be handled, perhaps by Raze(), and the 823 // databases still need to be handled, perhaps by Raze(), and the
781 // recovery module is an obvious layer to abstract that to. 824 // recovery module is an obvious layer to abstract that to.
782 // TODO(shess): Handle that case for real! 825 // TODO(shess): Handle that case for real!
783 if (!sql::Recovery::FullRecoverySupported()) 826 if (!sql::Recovery::FullRecoverySupported())
784 return; 827 return;
785 828
786 // Create an example database. 829 // Create an example database.
787 { 830 {
788 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v7.sql")); 831 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v8.sql"));
789 832
790 sql::Connection raw_db; 833 sql::Connection raw_db;
791 EXPECT_TRUE(raw_db.Open(file_name_)); 834 EXPECT_TRUE(raw_db.Open(file_name_));
792 VerifyTablesAndColumns(&raw_db); 835 VerifyTablesAndColumns(&raw_db);
793 } 836 }
794 837
795 // Test that the contents make sense after clean open. 838 // Test that the contents make sense after clean open.
796 { 839 {
797 ThumbnailDatabase db(NULL); 840 ThumbnailDatabase db(NULL);
798 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); 841 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, 946 favicon_base::FAVICON,
904 kIconUrl1, 947 kIconUrl1,
905 kLargeSize, 948 kLargeSize,
906 sizeof(kBlob1), 949 sizeof(kBlob1),
907 kBlob1)); 950 kBlob1));
908 951
909 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 952 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
910 } 953 }
911 } 954 }
912 955
956 TEST_F(ThumbnailDatabaseTest, Recovery7) {
957 // This code tests the recovery module in concert with Chromium's
958 // custom recover virtual table. Under USE_SYSTEM_SQLITE, this is
959 // not available. This is detected dynamically because corrupt
960 // databases still need to be handled, perhaps by Raze(), and the
961 // recovery module is an obvious layer to abstract that to.
962 // TODO(shess): Handle that case for real!
963 if (!sql::Recovery::FullRecoverySupported())
964 return;
965
966 // Create an example database without loading into ThumbnailDatabase
967 // (which would upgrade it).
968 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v7.sql"));
969
970 // Corrupt the |icon_mapping.page_url| index by deleting an element
971 // from the backing table but not the index.
972 {
973 sql::Connection raw_db;
974 EXPECT_TRUE(raw_db.Open(file_name_));
975 ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db));
976 }
977 const char kIndexName[] = "icon_mapping_page_url_idx";
978 const char kDeleteSql[] =
979 "DELETE FROM icon_mapping WHERE page_url = 'http://yahoo.com/'";
980 EXPECT_TRUE(
981 sql::test::CorruptTableOrIndex(file_name_, kIndexName, kDeleteSql));
982
983 // Database should be corrupt at the SQLite level.
984 {
985 sql::Connection raw_db;
986 EXPECT_TRUE(raw_db.Open(file_name_));
987 ASSERT_NE("ok", sql::test::IntegrityCheck(&raw_db));
988 }
989
990 // Open the database and access the corrupt index. Note that this upgrades
991 // the database.
992 {
993 sql::ScopedErrorIgnorer ignore_errors;
994 ignore_errors.IgnoreError(SQLITE_CORRUPT);
995 ThumbnailDatabase db(NULL);
996 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
997
998 // Data for kPageUrl2 was deleted, but the index entry remains,
999 // this will throw SQLITE_CORRUPT. The corruption handler will
1000 // recover the database and poison the handle, so the outer call
1001 // fails.
1002 EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, NULL));
1003
1004 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
1005 }
1006
1007 // Check that the database is recovered at the SQLite level.
1008 {
1009 sql::Connection raw_db;
1010 EXPECT_TRUE(raw_db.Open(file_name_));
1011 ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db));
1012
1013 // Check that the expected tables exist.
1014 VerifyTablesAndColumns(&raw_db);
1015 }
1016
1017 // Database should also be recovered at higher levels.
1018 {
1019 ThumbnailDatabase db(NULL);
1020 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
1021
1022 // Now this fails because there is no mapping.
1023 EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, NULL));
1024
1025 // Other data was retained by recovery.
1026 EXPECT_TRUE(CheckPageHasIcon(&db,
1027 kPageUrl1,
1028 favicon_base::FAVICON,
1029 kIconUrl1,
1030 kLargeSize,
1031 sizeof(kBlob1),
1032 kBlob1));
1033 }
1034
1035 // Corrupt the database again by adjusting the header.
1036 EXPECT_TRUE(sql::test::CorruptSizeInHeader(file_name_));
1037
1038 // Database is unusable at the SQLite level.
1039 {
1040 sql::ScopedErrorIgnorer ignore_errors;
1041 ignore_errors.IgnoreError(SQLITE_CORRUPT);
1042 sql::Connection raw_db;
1043 EXPECT_TRUE(raw_db.Open(file_name_));
1044 EXPECT_FALSE(raw_db.IsSQLValid("PRAGMA integrity_check"));
1045 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
1046 }
1047
1048 // Database should be recovered during open.
1049 {
1050 sql::ScopedErrorIgnorer ignore_errors;
1051 ignore_errors.IgnoreError(SQLITE_CORRUPT);
1052 ThumbnailDatabase db(NULL);
1053 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
1054
1055 EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, NULL));
1056 EXPECT_TRUE(CheckPageHasIcon(&db,
1057 kPageUrl1,
1058 favicon_base::FAVICON,
1059 kIconUrl1,
1060 kLargeSize,
1061 sizeof(kBlob1),
1062 kBlob1));
1063
1064 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
1065 }
1066 }
1067
913 TEST_F(ThumbnailDatabaseTest, Recovery6) { 1068 TEST_F(ThumbnailDatabaseTest, Recovery6) {
914 // TODO(shess): See comment at top of Recovery test. 1069 // TODO(shess): See comment at top of Recovery test.
915 if (!sql::Recovery::FullRecoverySupported()) 1070 if (!sql::Recovery::FullRecoverySupported())
916 return; 1071 return;
917 1072
918 // Create an example database without loading into ThumbnailDatabase 1073 // Create an example database without loading into ThumbnailDatabase
919 // (which would upgrade it). 1074 // (which would upgrade it).
920 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v6.sql")); 1075 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v6.sql"));
921 1076
922 // Corrupt the database by adjusting the header. This form of corruption will 1077 // 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); 1184 ThumbnailDatabase db(NULL);
1030 ASSERT_EQ(sql::INIT_OK, db.Init(db_path)); 1185 ASSERT_EQ(sql::INIT_OK, db.Init(db_path));
1031 1186
1032 // Verify that the resulting schema is correct, whether it 1187 // Verify that the resulting schema is correct, whether it
1033 // involved razing the file or fixing things in place. 1188 // involved razing the file or fixing things in place.
1034 VerifyTablesAndColumns(&db.db_); 1189 VerifyTablesAndColumns(&db.db_);
1035 } 1190 }
1036 } 1191 }
1037 1192
1038 } // namespace history 1193 } // namespace history
OLDNEW
« no previous file with comments | « no previous file | chrome/test/data/History/Favicons.v8.sql » ('j') | chrome/test/data/History/Favicons.v8.sql » ('J')

Powered by Google App Engine
This is Rietveld 408576698