OLD | NEW |
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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 return sql::test::CreateDatabaseFromSQL(db_path, sql_path); | 59 return sql::test::CreateDatabaseFromSQL(db_path, sql_path); |
60 } | 60 } |
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(5u, 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 |
72 // [favicon_bitmaps], two indices on [icon_mapping]. | 72 // [favicon_bitmaps], 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], and [height]. |
82 EXPECT_EQ(6u, sql::test::CountTableColumns(db, "favicon_bitmaps")); | 82 EXPECT_EQ(6u, sql::test::CountTableColumns(db, "favicon_bitmaps")); |
83 | 83 |
84 // [id], [page_url], and [icon_id]. | 84 // [id], [page_url], and [icon_id]. |
85 EXPECT_EQ(3u, sql::test::CountTableColumns(db, "icon_mapping")); | 85 EXPECT_EQ(3u, sql::test::CountTableColumns(db, "icon_mapping")); |
| 86 |
| 87 // [bitmap_id], [last_requested]. |
| 88 EXPECT_EQ(2u, sql::test::CountTableColumns(db, "favicon_bitmap_usage")); |
86 } | 89 } |
87 | 90 |
88 void VerifyDatabaseEmpty(sql::Connection* db) { | 91 void VerifyDatabaseEmpty(sql::Connection* db) { |
89 size_t rows = 0; | 92 size_t rows = 0; |
90 EXPECT_TRUE(sql::test::CountTableRows(db, "favicons", &rows)); | 93 EXPECT_TRUE(sql::test::CountTableRows(db, "favicons", &rows)); |
91 EXPECT_EQ(0u, rows); | 94 EXPECT_EQ(0u, rows); |
92 EXPECT_TRUE(sql::test::CountTableRows(db, "favicon_bitmaps", &rows)); | 95 EXPECT_TRUE(sql::test::CountTableRows(db, "favicon_bitmaps", &rows)); |
93 EXPECT_EQ(0u, rows); | 96 EXPECT_EQ(0u, rows); |
94 EXPECT_TRUE(sql::test::CountTableRows(db, "icon_mapping", &rows)); | 97 EXPECT_TRUE(sql::test::CountTableRows(db, "icon_mapping", &rows)); |
95 EXPECT_EQ(0u, rows); | 98 EXPECT_EQ(0u, rows); |
| 99 EXPECT_TRUE(sql::test::CountTableRows(db, "favicon_bitmap_usage", &rows)); |
| 100 EXPECT_EQ(0u, rows); |
96 } | 101 } |
97 | 102 |
98 // Helper to check that an expected mapping exists. | 103 // Helper to check that an expected mapping exists. |
99 WARN_UNUSED_RESULT bool CheckPageHasIcon( | 104 WARN_UNUSED_RESULT bool CheckPageHasIcon( |
100 ThumbnailDatabase* db, | 105 ThumbnailDatabase* db, |
101 const GURL& page_url, | 106 const GURL& page_url, |
102 favicon_base::IconType expected_icon_type, | 107 favicon_base::IconType expected_icon_type, |
103 const GURL& expected_icon_url, | 108 const GURL& expected_icon_url, |
104 const gfx::Size& expected_icon_size, | 109 const gfx::Size& expected_icon_size, |
105 size_t expected_icon_contents_size, | 110 size_t expected_icon_contents_size, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 } | 154 } |
150 | 155 |
151 if (memcmp(favicon_bitmaps[0].bitmap_data->front(), | 156 if (memcmp(favicon_bitmaps[0].bitmap_data->front(), |
152 expected_icon_contents, expected_icon_contents_size)) { | 157 expected_icon_contents, expected_icon_contents_size)) { |
153 ADD_FAILURE() << "failed to match |expected_icon_contents|"; | 158 ADD_FAILURE() << "failed to match |expected_icon_contents|"; |
154 return false; | 159 return false; |
155 } | 160 } |
156 return true; | 161 return true; |
157 } | 162 } |
158 | 163 |
| 164 WARN_UNUSED_RESULT bool CheckBitmapLastRequestTime( |
| 165 ThumbnailDatabase* db, |
| 166 const GURL& page_url, |
| 167 favicon_base::IconType icon_type, |
| 168 const gfx::Size& icon_size, |
| 169 base::Time* request_timestamp) { |
| 170 std::vector<IconMapping> icon_mappings; |
| 171 if (!db->GetIconMappingsForPageURL(page_url, &icon_mappings)) { |
| 172 ADD_FAILURE() << "failed GetIconMappingsForPageURL()"; |
| 173 return false; |
| 174 } |
| 175 |
| 176 // Scan for the expected type. |
| 177 std::vector<IconMapping>::const_iterator icon_iter = icon_mappings.begin(); |
| 178 for (; icon_iter != icon_mappings.end(); ++icon_iter) { |
| 179 if (icon_iter->icon_type == icon_type) |
| 180 break; |
| 181 } |
| 182 if (icon_iter == icon_mappings.end()) { |
| 183 ADD_FAILURE() << "failed to find |icon_type|"; |
| 184 return false; |
| 185 } |
| 186 |
| 187 std::vector<FaviconBitmap> favicon_bitmaps; |
| 188 if (!db->GetFaviconBitmaps(icon_iter->icon_id, &favicon_bitmaps)) { |
| 189 ADD_FAILURE() << "failed GetFaviconBitmaps()"; |
| 190 return false; |
| 191 } |
| 192 |
| 193 std::vector<FaviconBitmap>::const_iterator bitmap_iter = |
| 194 favicon_bitmaps.begin(); |
| 195 for (; bitmap_iter != favicon_bitmaps.end(); ++bitmap_iter) { |
| 196 if (bitmap_iter->pixel_size == icon_size) |
| 197 break; |
| 198 } |
| 199 |
| 200 if (bitmap_iter == favicon_bitmaps.end()) { |
| 201 ADD_FAILURE() << "failed to find |icon_size|"; |
| 202 return false; |
| 203 } |
| 204 |
| 205 return db->GetFaviconBitmapLastRequestedTime(bitmap_iter->bitmap_id, |
| 206 request_timestamp); |
| 207 } |
| 208 |
159 } // namespace | 209 } // namespace |
160 | 210 |
161 class ThumbnailDatabaseTest : public testing::Test { | 211 class ThumbnailDatabaseTest : public testing::Test { |
162 public: | 212 public: |
163 ThumbnailDatabaseTest() { | 213 ThumbnailDatabaseTest() { |
164 } | 214 } |
165 ~ThumbnailDatabaseTest() override {} | 215 ~ThumbnailDatabaseTest() override {} |
166 | 216 |
167 // Initialize a thumbnail database instance from the SQL file at | 217 // Initialize a thumbnail database instance from the SQL file at |
168 // |golden_path| in the "History/" subdirectory of test data. | 218 // |golden_path| in the "History/" subdirectory of test data. |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 kBlob1)); | 809 kBlob1)); |
760 EXPECT_TRUE(CheckPageHasIcon(db.get(), | 810 EXPECT_TRUE(CheckPageHasIcon(db.get(), |
761 kPageUrl3, | 811 kPageUrl3, |
762 favicon_base::TOUCH_ICON, | 812 favicon_base::TOUCH_ICON, |
763 kIconUrl3, | 813 kIconUrl3, |
764 kLargeSize, | 814 kLargeSize, |
765 sizeof(kBlob2), | 815 sizeof(kBlob2), |
766 kBlob2)); | 816 kBlob2)); |
767 } | 817 } |
768 | 818 |
| 819 // Test loading version 8 database. |
| 820 TEST_F(ThumbnailDatabaseTest, Version8) { |
| 821 scoped_ptr<ThumbnailDatabase> db = LoadFromGolden("Favicons.v8.sql"); |
| 822 ASSERT_TRUE(db.get() != NULL); |
| 823 VerifyTablesAndColumns(&db->db_); |
| 824 |
| 825 EXPECT_TRUE(CheckPageHasIcon(db.get(), |
| 826 kPageUrl1, |
| 827 favicon_base::FAVICON, |
| 828 kIconUrl1, |
| 829 kLargeSize, |
| 830 sizeof(kBlob1), |
| 831 kBlob1)); |
| 832 EXPECT_TRUE(CheckPageHasIcon(db.get(), |
| 833 kPageUrl2, |
| 834 favicon_base::FAVICON, |
| 835 kIconUrl2, |
| 836 kLargeSize, |
| 837 sizeof(kBlob2), |
| 838 kBlob2)); |
| 839 EXPECT_TRUE(CheckPageHasIcon(db.get(), |
| 840 kPageUrl3, |
| 841 favicon_base::FAVICON, |
| 842 kIconUrl1, |
| 843 kLargeSize, |
| 844 sizeof(kBlob1), |
| 845 kBlob1)); |
| 846 EXPECT_TRUE(CheckPageHasIcon(db.get(), |
| 847 kPageUrl3, |
| 848 favicon_base::TOUCH_ICON, |
| 849 kIconUrl3, |
| 850 kLargeSize, |
| 851 sizeof(kBlob2), |
| 852 kBlob2)); |
| 853 } |
| 854 |
769 TEST_F(ThumbnailDatabaseTest, Recovery) { | 855 TEST_F(ThumbnailDatabaseTest, Recovery) { |
770 // This code tests the recovery module in concert with Chromium's | 856 // This code tests the recovery module in concert with Chromium's |
771 // custom recover virtual table. Under USE_SYSTEM_SQLITE, this is | 857 // custom recover virtual table. Under USE_SYSTEM_SQLITE, this is |
772 // not available. This is detected dynamically because corrupt | 858 // not available. This is detected dynamically because corrupt |
773 // databases still need to be handled, perhaps by Raze(), and the | 859 // databases still need to be handled, perhaps by Raze(), and the |
774 // recovery module is an obvious layer to abstract that to. | 860 // recovery module is an obvious layer to abstract that to. |
775 // TODO(shess): Handle that case for real! | 861 // TODO(shess): Handle that case for real! |
776 if (!sql::Recovery::FullRecoverySupported()) | 862 if (!sql::Recovery::FullRecoverySupported()) |
777 return; | 863 return; |
778 | 864 |
779 // Create an example database. | 865 // Create an example database. |
780 { | 866 { |
781 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v7.sql")); | 867 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v8.sql")); |
782 | 868 |
783 sql::Connection raw_db; | 869 sql::Connection raw_db; |
784 EXPECT_TRUE(raw_db.Open(file_name_)); | 870 EXPECT_TRUE(raw_db.Open(file_name_)); |
785 VerifyTablesAndColumns(&raw_db); | 871 VerifyTablesAndColumns(&raw_db); |
786 } | 872 } |
787 | 873 |
788 // Test that the contents make sense after clean open. | 874 // Test that the contents make sense after clean open. |
789 { | 875 { |
790 ThumbnailDatabase db(NULL); | 876 ThumbnailDatabase db(NULL); |
791 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); | 877 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1022 ThumbnailDatabase db(NULL); | 1108 ThumbnailDatabase db(NULL); |
1023 ASSERT_EQ(sql::INIT_OK, db.Init(db_path)); | 1109 ASSERT_EQ(sql::INIT_OK, db.Init(db_path)); |
1024 | 1110 |
1025 // Verify that the resulting schema is correct, whether it | 1111 // Verify that the resulting schema is correct, whether it |
1026 // involved razing the file or fixing things in place. | 1112 // involved razing the file or fixing things in place. |
1027 VerifyTablesAndColumns(&db.db_); | 1113 VerifyTablesAndColumns(&db.db_); |
1028 } | 1114 } |
1029 } | 1115 } |
1030 | 1116 |
1031 } // namespace history | 1117 } // namespace history |
OLD | NEW |