Index: components/history/core/browser/history_backend_db_unittest.cc |
diff --git a/components/history/core/browser/history_backend_db_unittest.cc b/components/history/core/browser/history_backend_db_unittest.cc |
index eff56c24d7059519a74eecab397f1f59d34ca9a8..0973b67b00ec3c6f8ef5ebfabbeda32c467e7a6b 100644 |
--- a/components/history/core/browser/history_backend_db_unittest.cc |
+++ b/components/history/core/browser/history_backend_db_unittest.cc |
@@ -21,7 +21,15 @@ |
#include <stdint.h> |
+#include <string> |
+#include <unordered_set> |
+ |
+#include "base/format_macros.h" |
+#include "base/guid.h" |
+#include "base/strings/string_util.h" |
+#include "base/strings/stringprintf.h" |
#include "base/strings/utf_string_conversions.h" |
+#include "base/time/time.h" |
#include "components/history/core/browser/download_constants.h" |
#include "components/history/core/browser/download_row.h" |
#include "components/history/core/browser/history_constants.h" |
@@ -53,7 +61,10 @@ TEST_F(HistoryBackendDBTest, ClearBrowsingData_Downloads) { |
// was removed. |
base::Time now = base::Time(); |
uint32_t id = 1; |
- EXPECT_TRUE(AddDownload(id, DownloadState::COMPLETE, base::Time())); |
+ EXPECT_TRUE(AddDownload(id, |
+ "BC5E3854-7B1D-4DE0-B619-B0D99C8B18B4", |
+ DownloadState::COMPLETE, |
+ base::Time())); |
db_->QueryDownloads(&downloads); |
EXPECT_EQ(1U, downloads.size()); |
@@ -482,7 +493,7 @@ TEST_F(HistoryBackendDBTest, MigrateDownloadMimeType) { |
} |
} |
// Re-open the db using the HistoryDatabase, which should migrate to the |
- // current version, creating themime_type abd original_mime_type columns. |
+ // current version, creating the mime_type abd original_mime_type columns. |
CreateBackendAndDatabase(); |
DeleteBackend(); |
{ |
@@ -508,6 +519,220 @@ TEST_F(HistoryBackendDBTest, MigrateDownloadMimeType) { |
} |
} |
+TEST_F(HistoryBackendDBTest, MigrateHashHttpMethodAndGenerateGuids) { |
+ const size_t kDownloadCount = 100; |
+ ASSERT_NO_FATAL_FAILURE(CreateDBVersion(29)); |
+ base::Time now(base::Time::Now()); |
+ { |
+ sql::Connection db; |
+ ASSERT_TRUE(db.Open(history_dir_.Append(kHistoryFilename))); |
+ |
+ // In testing, it appeared that constructing a query where all rows are |
+ // specified (i.e. looks like "INSERT INTO foo (...) VALUES (...),(...)") |
+ // performs much better than executing a cached query multiple times where |
+ // the query inserts only a single row per run (i.e. looks like "INSERT INTO |
+ // (...) VALUES (...)"). For 100 records, the latter took 19s on a |
+ // developer machine while the former inserted 100 records in ~400ms. |
+ std::string download_insert_query = |
+ "INSERT INTO downloads (id, current_path, target_path, start_time, " |
+ "received_bytes, total_bytes, state, danger_type, interrupt_reason, " |
+ "end_time, opened, referrer, by_ext_id, by_ext_name, etag, " |
+ "last_modified, mime_type, original_mime_type) VALUES "; |
+ std::string url_insert_query = |
+ "INSERT INTO downloads_url_chains (id, chain_index, url) VALUES "; |
+ |
+ for (uint32_t i = 0; i < kDownloadCount; ++i) { |
+ uint32_t download_id = i * 13321; |
+ if (i != 0) |
+ download_insert_query += ","; |
+ download_insert_query += base::StringPrintf( |
+ "(%" PRId64 ", 'current_path', 'target_path', %" PRId64 |
+ ", 100, 100, 1, 0, 0, %" PRId64 |
+ ", 1, 'referrer', 'by extension ID','by extension name', 'etag', " |
+ "'last modified', 'mime/type', 'original/mime-type')", |
+ static_cast<int64_t>(download_id), |
+ static_cast<int64_t>(now.ToTimeT()), |
+ static_cast<int64_t>(now.ToTimeT())); |
+ if (i != 0) |
+ url_insert_query += ","; |
+ url_insert_query += base::StringPrintf("(%" PRId64 ", 0, 'url')", |
+ static_cast<int64_t>(download_id)); |
+ } |
+ ASSERT_TRUE(db.Execute(download_insert_query.c_str())); |
+ ASSERT_TRUE(db.Execute(url_insert_query.c_str())); |
+ } |
+ |
+ CreateBackendAndDatabase(); |
+ DeleteBackend(); |
+ |
+ { |
+ // Re-open the db for manual manipulation. |
+ sql::Connection db; |
+ ASSERT_TRUE(db.Open(history_dir_.Append(kHistoryFilename))); |
+ // The version should have been updated. |
+ int cur_version = HistoryDatabase::GetCurrentVersion(); |
+ ASSERT_LE(30, cur_version); |
+ { |
+ sql::Statement s(db.GetUniqueStatement( |
+ "SELECT value FROM meta WHERE key = 'version'")); |
+ EXPECT_TRUE(s.Step()); |
+ EXPECT_EQ(cur_version, s.ColumnInt(0)); |
+ } |
+ { |
+ sql::Statement s(db.GetUniqueStatement("SELECT guid from downloads")); |
+ std::unordered_set<std::string> guids; |
+ while (s.Step()) { |
+ std::string guid = s.ColumnString(0); |
+ EXPECT_TRUE(base::IsValidGUID(guid)); |
+ EXPECT_EQ(guid, base::ToUpperASCII(guid)); |
+ guids.insert(guid); |
+ } |
+ EXPECT_TRUE(s.Succeeded()); |
+ EXPECT_EQ(kDownloadCount, guids.size()); |
+ } |
+ } |
+} |
+ |
+TEST_F(HistoryBackendDBTest, DownloadCreateAndQuery) { |
+ CreateBackendAndDatabase(); |
+ |
+ ASSERT_EQ(0u, db_->CountDownloads()); |
+ |
+ std::vector<GURL> url_chain; |
+ url_chain.push_back(GURL("http://example.com/a")); |
+ url_chain.push_back(GURL("http://example.com/b")); |
+ url_chain.push_back(GURL("http://example.com/c")); |
+ |
+ base::Time start_time(base::Time::Now()); |
+ base::Time end_time(start_time + base::TimeDelta::FromHours(1)); |
+ |
+ DownloadRow download_A(base::FilePath(FILE_PATH_LITERAL("/path/1")), |
+ base::FilePath(FILE_PATH_LITERAL("/path/2")), |
+ url_chain, |
+ GURL("http://example.com/referrer"), |
+ "GET", |
+ "mime/type", |
+ "original/mime-type", |
+ start_time, |
+ end_time, |
+ "etag1", |
+ "last_modified_1", |
+ 100, |
+ 1000, |
+ DownloadState::INTERRUPTED, |
+ DownloadDangerType::NOT_DANGEROUS, |
+ kTestDownloadInterruptReasonCrash, |
+ "hash-value1", |
+ 1, |
+ "FE672168-26EF-4275-A149-FEC25F6A75F9", |
+ false, |
+ "extension-id", |
+ "extension-name"); |
+ ASSERT_TRUE(db_->CreateDownload(download_A)); |
+ |
+ url_chain.push_back(GURL("http://example.com/d")); |
+ |
+ DownloadRow download_B(base::FilePath(FILE_PATH_LITERAL("/path/3")), |
+ base::FilePath(FILE_PATH_LITERAL("/path/4")), |
+ url_chain, |
+ GURL("http://example.com/referrer2"), |
+ "POST", |
+ "mime/type2", |
+ "original/mime-type2", |
+ start_time, |
+ end_time, |
+ "etag2", |
+ "last_modified_2", |
+ 1001, |
+ 1001, |
+ DownloadState::COMPLETE, |
+ DownloadDangerType::DANGEROUS_FILE, |
+ kTestDownloadInterruptReasonNone, |
+ std::string(), |
+ 2, |
+ "b70f3869-7d75-4878-acb4-4caf7026d12b", |
+ false, |
+ "extension-id", |
+ "extension-name"); |
+ ASSERT_TRUE(db_->CreateDownload(download_B)); |
+ |
+ EXPECT_EQ(2u, db_->CountDownloads()); |
+ |
+ std::vector<DownloadRow> results; |
+ db_->QueryDownloads(&results); |
+ |
+ ASSERT_EQ(2u, results.size()); |
+ |
+ const DownloadRow& retrieved_download_A = |
+ results[0].id == 1 ? results[0] : results[1]; |
+ const DownloadRow& retrieved_download_B = |
+ results[0].id == 1 ? results[1] : results[0]; |
+ |
+ EXPECT_EQ(download_A, retrieved_download_A); |
+ EXPECT_EQ(download_B, retrieved_download_B); |
+} |
+ |
+TEST_F(HistoryBackendDBTest, DownloadCreateAndUpdate_VolatileFields) { |
+ CreateBackendAndDatabase(); |
+ |
+ std::vector<GURL> url_chain; |
+ url_chain.push_back(GURL("http://example.com/a")); |
+ url_chain.push_back(GURL("http://example.com/b")); |
+ url_chain.push_back(GURL("http://example.com/c")); |
+ |
+ base::Time start_time(base::Time::Now()); |
+ base::Time end_time(start_time + base::TimeDelta::FromHours(1)); |
+ |
+ DownloadRow download(base::FilePath(FILE_PATH_LITERAL("/path/1")), |
+ base::FilePath(FILE_PATH_LITERAL("/path/2")), |
+ url_chain, |
+ GURL("http://example.com/referrer"), |
+ "GET", |
+ "mime/type", |
+ "original/mime-type", |
+ start_time, |
+ end_time, |
+ "etag1", |
+ "last_modified_1", |
+ 100, |
+ 1000, |
+ DownloadState::INTERRUPTED, |
+ DownloadDangerType::NOT_DANGEROUS, |
+ 3, |
+ "some-hash-value", |
+ 1, |
+ "FE672168-26EF-4275-A149-FEC25F6A75F9", |
+ false, |
+ "extension-id", |
+ "extension-name"); |
+ db_->CreateDownload(download); |
+ |
+ download.current_path = |
+ base::FilePath(FILE_PATH_LITERAL("/new/current_path")); |
+ download.target_path = base::FilePath(FILE_PATH_LITERAL("/new/target_path")); |
+ download.mime_type = "new/mime/type"; |
+ download.original_mime_type = "new/original/mime/type"; |
+ download.received_bytes += 1000; |
+ download.state = DownloadState::CANCELLED; |
+ download.danger_type = DownloadDangerType::USER_VALIDATED; |
+ download.interrupt_reason = 4; |
+ download.end_time += base::TimeDelta::FromHours(1); |
+ download.total_bytes += 1; |
+ download.hash = "some-other-hash"; |
+ download.opened = !download.opened; |
+ download.by_ext_id = "by-new-extension-id"; |
+ download.by_ext_name = "by-new-extension-name"; |
+ download.etag = "new-etag"; |
+ download.last_modified = "new-last-modified"; |
+ |
+ ASSERT_TRUE(db_->UpdateDownload(download)); |
+ |
+ std::vector<DownloadRow> results; |
+ db_->QueryDownloads(&results); |
+ ASSERT_EQ(1u, results.size()); |
+ EXPECT_EQ(download, results[0]); |
+} |
+ |
TEST_F(HistoryBackendDBTest, ConfirmDownloadRowCreateAndDelete) { |
// Create the DB. |
CreateBackendAndDatabase(); |
@@ -516,9 +741,18 @@ TEST_F(HistoryBackendDBTest, ConfirmDownloadRowCreateAndDelete) { |
// Add some downloads. |
uint32_t id1 = 1, id2 = 2, id3 = 3; |
- AddDownload(id1, DownloadState::COMPLETE, now); |
- AddDownload(id2, DownloadState::COMPLETE, now + base::TimeDelta::FromDays(2)); |
- AddDownload(id3, DownloadState::COMPLETE, now - base::TimeDelta::FromDays(2)); |
+ AddDownload(id1, |
+ "05AF6C8E-E4E0-45D7-B5CE-BC99F7019918", |
+ DownloadState::COMPLETE, |
+ now); |
+ AddDownload(id2, |
+ "05AF6C8E-E4E0-45D7-B5CE-BC99F7019919", |
+ DownloadState::COMPLETE, |
+ now + base::TimeDelta::FromDays(2)); |
+ AddDownload(id3, |
+ "05AF6C8E-E4E0-45D7-B5CE-BC99F701991A", |
+ DownloadState::COMPLETE, |
+ now - base::TimeDelta::FromDays(2)); |
// Confirm that resulted in the correct number of rows in the DB. |
DeleteBackend(); |
@@ -564,6 +798,7 @@ TEST_F(HistoryBackendDBTest, DownloadNukeRecordsMissingURLs) { |
base::FilePath(FILE_PATH_LITERAL("foo-path")), |
url_chain, |
GURL(std::string()), |
+ std::string(), |
"application/octet-stream", |
"application/octet-stream", |
now, |
@@ -575,7 +810,9 @@ TEST_F(HistoryBackendDBTest, DownloadNukeRecordsMissingURLs) { |
DownloadState::COMPLETE, |
DownloadDangerType::NOT_DANGEROUS, |
kTestDownloadInterruptReasonNone, |
+ std::string(), |
1, |
+ "05AF6C8E-E4E0-45D7-B5CE-BC99F7019918", |
0, |
"by_ext_id", |
"by_ext_name"); |
@@ -621,7 +858,10 @@ TEST_F(HistoryBackendDBTest, ConfirmDownloadInProgressCleanup) { |
base::Time now(base::Time::Now()); |
// Put an IN_PROGRESS download in the DB. |
- AddDownload(1, DownloadState::IN_PROGRESS, now); |
+ AddDownload(1, |
+ "05AF6C8E-E4E0-45D7-B5CE-BC99F7019918", |
+ DownloadState::IN_PROGRESS, |
+ now); |
// Confirm that they made it into the DB unchanged. |
DeleteBackend(); |