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

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

Issue 74933002: Revert 235492 "[sql] Recover Favicons v5 databases, with more re..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
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/file_util.h" 9 #include "base/file_util.h"
10 #include "base/files/file_enumerator.h" 10 #include "base/files/file_enumerator.h"
(...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 EXPECT_TRUE( 783 EXPECT_TRUE(
784 CheckPageHasIcon(&db, kPageUrl2, chrome::FAVICON, 784 CheckPageHasIcon(&db, kPageUrl2, chrome::FAVICON,
785 kIconUrl2, kLargeSize, sizeof(kBlob2), kBlob2)); 785 kIconUrl2, kLargeSize, sizeof(kBlob2), kBlob2));
786 } 786 }
787 787
788 // Corrupt the |icon_mapping.page_url| index by deleting an element 788 // Corrupt the |icon_mapping.page_url| index by deleting an element
789 // from the backing table but not the index. 789 // from the backing table but not the index.
790 { 790 {
791 sql::Connection raw_db; 791 sql::Connection raw_db;
792 EXPECT_TRUE(raw_db.Open(file_name_)); 792 EXPECT_TRUE(raw_db.Open(file_name_));
793 ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db)); 793 {
794 sql::Statement statement(
795 raw_db.GetUniqueStatement("PRAGMA integrity_check"));
796 EXPECT_TRUE(statement.Step());
797 ASSERT_EQ("ok", statement.ColumnString(0));
798 }
794 799
795 const char kIndexName[] = "icon_mapping_page_url_idx"; 800 const char kIndexName[] = "icon_mapping_page_url_idx";
796 const int idx_root_page = GetRootPage(&raw_db, kIndexName); 801 const int idx_root_page = GetRootPage(&raw_db, kIndexName);
797 const int page_size = GetPageSize(&raw_db); 802 const int page_size = GetPageSize(&raw_db);
798 scoped_ptr<char[]> buf(new char[page_size]); 803 scoped_ptr<char[]> buf(new char[page_size]);
799 EXPECT_TRUE(ReadPage(file_name_, idx_root_page, buf.get(), page_size)); 804 EXPECT_TRUE(ReadPage(file_name_, idx_root_page, buf.get(), page_size));
800 805
801 { 806 {
802 const char kDeleteSql[] = "DELETE FROM icon_mapping WHERE page_url = ?"; 807 const char kDeleteSql[] = "DELETE FROM icon_mapping WHERE page_url = ?";
803 sql::Statement statement(raw_db.GetUniqueStatement(kDeleteSql)); 808 sql::Statement statement(raw_db.GetUniqueStatement(kDeleteSql));
804 statement.BindString(0, URLDatabase::GURLToDatabaseURL(kPageUrl2)); 809 statement.BindString(0, URLDatabase::GURLToDatabaseURL(kPageUrl2));
805 EXPECT_TRUE(statement.Run()); 810 EXPECT_TRUE(statement.Run());
806 } 811 }
807 raw_db.Close(); 812 raw_db.Close();
808 813
809 EXPECT_TRUE(WritePage(file_name_, idx_root_page, buf.get(), page_size)); 814 EXPECT_TRUE(WritePage(file_name_, idx_root_page, buf.get(), page_size));
810 } 815 }
811 816
812 // Database should be corrupt at the SQLite level. 817 // Database should be corrupt at the SQLite level.
813 { 818 {
814 sql::Connection raw_db; 819 sql::Connection raw_db;
815 EXPECT_TRUE(raw_db.Open(file_name_)); 820 EXPECT_TRUE(raw_db.Open(file_name_));
816 ASSERT_NE("ok", sql::test::IntegrityCheck(&raw_db)); 821 sql::Statement statement(
822 raw_db.GetUniqueStatement("PRAGMA integrity_check"));
823 EXPECT_TRUE(statement.Step());
824 ASSERT_NE("ok", statement.ColumnString(0));
817 } 825 }
818 826
819 // Open the database and access the corrupt index. 827 // Open the database and access the corrupt index.
820 { 828 {
821 sql::ScopedErrorIgnorer ignore_errors; 829 sql::ScopedErrorIgnorer ignore_errors;
822 ignore_errors.IgnoreError(SQLITE_CORRUPT); 830 ignore_errors.IgnoreError(SQLITE_CORRUPT);
823 ThumbnailDatabase db; 831 ThumbnailDatabase db;
824 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); 832 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
825 833
826 // Data for kPageUrl2 was deleted, but the index entry remains, 834 // Data for kPageUrl2 was deleted, but the index entry remains,
827 // this will throw SQLITE_CORRUPT. The corruption handler will 835 // this will throw SQLITE_CORRUPT. The corruption handler will
828 // recover the database and poison the handle, so the outer call 836 // recover the database and poison the handle, so the outer call
829 // fails. 837 // fails.
830 EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, NULL)); 838 EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, NULL));
831 839
832 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 840 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
833 } 841 }
834 842
835 // Check that the database is recovered at the SQLite level. 843 // Check that the database is recovered at the SQLite level.
836 { 844 {
837 sql::Connection raw_db; 845 sql::Connection raw_db;
838 EXPECT_TRUE(raw_db.Open(file_name_)); 846 EXPECT_TRUE(raw_db.Open(file_name_));
839 ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db)); 847 sql::Statement statement(
848 raw_db.GetUniqueStatement("PRAGMA integrity_check"));
849 EXPECT_TRUE(statement.Step());
850 EXPECT_EQ("ok", statement.ColumnString(0));
840 851
841 // Check that the expected tables exist. 852 // Check that the expected tables exist.
842 VerifyTablesAndColumns(&raw_db); 853 VerifyTablesAndColumns(&raw_db);
843 } 854 }
844 855
845 // Database should also be recovered at higher levels. 856 // Database should also be recovered at higher levels.
846 { 857 {
847 ThumbnailDatabase db; 858 ThumbnailDatabase db;
848 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); 859 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
849 860
850 // Now this fails because there is no mapping. 861 // Now this fails because there is no mapping.
851 EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, NULL)); 862 EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, NULL));
852 863
853 // Other data was retained by recovery. 864 // Other data was retained by recovery.
854 EXPECT_TRUE( 865 EXPECT_TRUE(
855 CheckPageHasIcon(&db, kPageUrl1, chrome::FAVICON, 866 CheckPageHasIcon(&db, kPageUrl1, chrome::FAVICON,
856 kIconUrl1, kLargeSize, sizeof(kBlob1), kBlob1)); 867 kIconUrl1, kLargeSize, sizeof(kBlob1), kBlob1));
857 } 868 }
858 869
859 // Corrupt the database again by adjusting the header. 870 // Corrupt the database again by making the actual file shorter than
860 EXPECT_TRUE(sql::test::CorruptSizeInHeader(file_name_)); 871 // the header expects.
872 {
873 int64 db_size = 0;
874 EXPECT_TRUE(file_util::GetFileSize(file_name_, &db_size));
875 {
876 sql::Connection raw_db;
877 EXPECT_TRUE(raw_db.Open(file_name_));
878 EXPECT_TRUE(raw_db.Execute("CREATE TABLE t(x)"));
879 }
880 file_util::ScopedFILE file(file_util::OpenFile(file_name_, "rb+"));
881 ASSERT_TRUE(file.get() != NULL);
882 EXPECT_EQ(0, fseek(file.get(), static_cast<long>(db_size), SEEK_SET));
883 EXPECT_TRUE(file_util::TruncateFile(file.get()));
884 }
861 885
862 // Database is unusable at the SQLite level. 886 // Database is unusable at the SQLite level.
863 { 887 {
864 sql::ScopedErrorIgnorer ignore_errors; 888 sql::ScopedErrorIgnorer ignore_errors;
865 ignore_errors.IgnoreError(SQLITE_CORRUPT); 889 ignore_errors.IgnoreError(SQLITE_CORRUPT);
866 sql::Connection raw_db; 890 sql::Connection raw_db;
867 EXPECT_TRUE(raw_db.Open(file_name_)); 891 EXPECT_TRUE(raw_db.Open(file_name_));
868 EXPECT_FALSE(raw_db.IsSQLValid("PRAGMA integrity_check")); 892 EXPECT_FALSE(raw_db.IsSQLValid("PRAGMA integrity_check"));
869 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 893 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
870 } 894 }
(...skipping 16 matching lines...) Expand all
887 911
888 TEST_F(ThumbnailDatabaseTest, Recovery6) { 912 TEST_F(ThumbnailDatabaseTest, Recovery6) {
889 // TODO(shess): See comment at top of Recovery test. 913 // TODO(shess): See comment at top of Recovery test.
890 if (!sql::Recovery::FullRecoverySupported()) 914 if (!sql::Recovery::FullRecoverySupported())
891 return; 915 return;
892 916
893 // Create an example database without loading into ThumbnailDatabase 917 // Create an example database without loading into ThumbnailDatabase
894 // (which would upgrade it). 918 // (which would upgrade it).
895 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v6.sql")); 919 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v6.sql"));
896 920
897 // Corrupt the database again by adjusting the header. This form of 921 // Corrupt the database by making the actual file shorter than the
898 // corruption will cause immediate failures during Open(), before 922 // SQLite header expects. This form of corruption will cause
899 // the migration code runs, so the version-6 recovery will occur. 923 // immediate failures during Open(), before the migration code runs,
900 EXPECT_TRUE(sql::test::CorruptSizeInHeader(file_name_)); 924 // so the version-6 recovery will occur.
925 {
926 int64 db_size = 0;
927 EXPECT_TRUE(file_util::GetFileSize(file_name_, &db_size));
928 {
929 sql::Connection raw_db;
930 EXPECT_TRUE(raw_db.Open(file_name_));
931 EXPECT_TRUE(raw_db.Execute("CREATE TABLE t(x)"));
932 }
933 file_util::ScopedFILE file(file_util::OpenFile(file_name_, "rb+"));
934 ASSERT_TRUE(file.get() != NULL);
935 EXPECT_EQ(0, fseek(file.get(), static_cast<long>(db_size), SEEK_SET));
936 EXPECT_TRUE(file_util::TruncateFile(file.get()));
937 }
901 938
902 // Database is unusable at the SQLite level. 939 // Database is unusable at the SQLite level.
903 { 940 {
904 sql::ScopedErrorIgnorer ignore_errors; 941 sql::ScopedErrorIgnorer ignore_errors;
905 ignore_errors.IgnoreError(SQLITE_CORRUPT); 942 ignore_errors.IgnoreError(SQLITE_CORRUPT);
906 sql::Connection raw_db; 943 sql::Connection raw_db;
907 EXPECT_TRUE(raw_db.Open(file_name_)); 944 EXPECT_TRUE(raw_db.Open(file_name_));
908 EXPECT_FALSE(raw_db.IsSQLValid("PRAGMA integrity_check")); 945 EXPECT_FALSE(raw_db.IsSQLValid("PRAGMA integrity_check"));
909 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 946 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
910 } 947 }
(...skipping 15 matching lines...) Expand all
926 kIconUrl3, kLargeSize, sizeof(kBlob2), kBlob2)); 963 kIconUrl3, kLargeSize, sizeof(kBlob2), kBlob2));
927 964
928 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 965 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
929 } 966 }
930 967
931 // Check that the database is recovered at a SQLite level, and that 968 // Check that the database is recovered at a SQLite level, and that
932 // the current schema is in place. 969 // the current schema is in place.
933 { 970 {
934 sql::Connection raw_db; 971 sql::Connection raw_db;
935 EXPECT_TRUE(raw_db.Open(file_name_)); 972 EXPECT_TRUE(raw_db.Open(file_name_));
936 ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db)); 973 sql::Statement statement(
937 974 raw_db.GetUniqueStatement("PRAGMA integrity_check"));
938 // Check that the expected tables exist. 975 EXPECT_TRUE(statement.Step());
939 VerifyTablesAndColumns(&raw_db); 976 EXPECT_EQ("ok", statement.ColumnString(0));
940 }
941 }
942
943 TEST_F(ThumbnailDatabaseTest, Recovery5) {
944 // Create an example database without loading into ThumbnailDatabase
945 // (which would upgrade it).
946 EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "Favicons.v5.sql"));
947
948 // Corrupt the database again by adjusting the header. This form of
949 // corruption will cause immediate failures during Open(), before
950 // the migration code runs, so the version-5 recovery will occur.
951 EXPECT_TRUE(sql::test::CorruptSizeInHeader(file_name_));
952
953 // Database is unusable at the SQLite level.
954 {
955 sql::ScopedErrorIgnorer ignore_errors;
956 ignore_errors.IgnoreError(SQLITE_CORRUPT);
957 sql::Connection raw_db;
958 EXPECT_TRUE(raw_db.Open(file_name_));
959 EXPECT_FALSE(raw_db.IsSQLValid("PRAGMA integrity_check"));
960 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
961 }
962
963 // Database should be recovered during open.
964 {
965 sql::ScopedErrorIgnorer ignore_errors;
966 ignore_errors.IgnoreError(SQLITE_CORRUPT);
967 ThumbnailDatabase db;
968 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
969
970 // Test that some data is present, copied from
971 // ThumbnailDatabaseTest.Version5 .
972 EXPECT_TRUE(
973 CheckPageHasIcon(&db, kPageUrl3, chrome::FAVICON,
974 kIconUrl1, gfx::Size(), sizeof(kBlob1), kBlob1));
975 EXPECT_TRUE(
976 CheckPageHasIcon(&db, kPageUrl3, chrome::TOUCH_ICON,
977 kIconUrl3, gfx::Size(), sizeof(kBlob2), kBlob2));
978
979 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
980 }
981
982 // Check that the database is recovered at a SQLite level, and that
983 // the current schema is in place.
984 {
985 sql::Connection raw_db;
986 EXPECT_TRUE(raw_db.Open(file_name_));
987 ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db));
988 977
989 // Check that the expected tables exist. 978 // Check that the expected tables exist.
990 VerifyTablesAndColumns(&raw_db); 979 VerifyTablesAndColumns(&raw_db);
991 } 980 }
992 } 981 }
993 982
994 // Test that various broken schema found in the wild can be opened 983 // Test that various broken schema found in the wild can be opened
995 // successfully, and result in the correct schema. 984 // successfully, and result in the correct schema.
996 TEST_F(ThumbnailDatabaseTest, WildSchema) { 985 TEST_F(ThumbnailDatabaseTest, WildSchema) {
997 base::FilePath sql_path; 986 base::FilePath sql_path;
(...skipping 16 matching lines...) Expand all
1014 ThumbnailDatabase db; 1003 ThumbnailDatabase db;
1015 ASSERT_EQ(sql::INIT_OK, db.Init(db_path)); 1004 ASSERT_EQ(sql::INIT_OK, db.Init(db_path));
1016 1005
1017 // Verify that the resulting schema is correct, whether it 1006 // Verify that the resulting schema is correct, whether it
1018 // involved razing the file or fixing things in place. 1007 // involved razing the file or fixing things in place.
1019 VerifyTablesAndColumns(&db.db_); 1008 VerifyTablesAndColumns(&db.db_);
1020 } 1009 }
1021 } 1010 }
1022 1011
1023 } // namespace history 1012 } // namespace history
OLDNEW
« no previous file with comments | « trunk/src/chrome/browser/history/thumbnail_database.cc ('k') | trunk/src/sql/connection_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698