Index: sql/connection_unittest.cc |
diff --git a/sql/connection_unittest.cc b/sql/connection_unittest.cc |
index 6ac4f8bc12d3d2739c865abf5edb59fb0167c0c0..4ee8b0288a354ef54aa306ba204ffe71a5b45c0b 100644 |
--- a/sql/connection_unittest.cc |
+++ b/sql/connection_unittest.cc |
@@ -854,6 +854,42 @@ TEST_F(SQLConnectionTest, RazeAndCloseDiagnostics) { |
// closely match real life. That would also allow testing |
// RazeWithTimeout(). |
+// On Windows, truncate silently fails against a memory-mapped file. One goal |
+// of Raze() is to truncate the file to remove blocks which generate I/O errors. |
+// Test that Raze() turns off memory mapping so that the file is truncated. |
+// [This would not cover the case of multiple connections where one of the other |
+// connections is memory-mapped. That is infrequent in Chromium.] |
+TEST_F(SQLConnectionTest, RazeTruncate) { |
+ // The empty database has 0 or 1 pages. Raze() should leave it with exactly 1 |
+ // page. Not checking directly because auto_vacuum on Android adds a freelist |
+ // page. |
+ ASSERT_TRUE(db().Raze()); |
+ int64_t expected_size; |
+ ASSERT_TRUE(base::GetFileSize(db_path(), &expected_size)); |
+ ASSERT_GT(expected_size, 0); |
+ |
+ // Cause the database to take a few pages. |
+ const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; |
+ ASSERT_TRUE(db().Execute(kCreateSql)); |
+ for (size_t i = 0; i < 24; ++i) { |
+ ASSERT_TRUE( |
+ db().Execute("INSERT INTO foo (value) VALUES (randomblob(1024))")); |
+ } |
+ int64_t db_size; |
+ ASSERT_TRUE(base::GetFileSize(db_path(), &db_size)); |
+ ASSERT_GT(db_size, expected_size); |
+ |
+ // Make a query covering most of the database file to make sure that the |
+ // blocks are actually mapped into memory. Empirically, the truncate problem |
+ // doesn't seem to happen if no blocks are mapped. |
+ EXPECT_EQ("24576", |
+ ExecuteWithResult(&db(), "SELECT SUM(LENGTH(value)) FROM foo")); |
+ |
+ ASSERT_TRUE(db().Raze()); |
+ ASSERT_TRUE(base::GetFileSize(db_path(), &db_size)); |
+ ASSERT_EQ(expected_size, db_size); |
+} |
+ |
#if defined(OS_ANDROID) |
TEST_F(SQLConnectionTest, SetTempDirForSQL) { |