| 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 |