summaryrefslogtreecommitdiffstats
path: root/toolkit/components/places/tests/migration
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /toolkit/components/places/tests/migration
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/places/tests/migration')
-rw-r--r--toolkit/components/places/tests/migration/favicons_v41.sqlitebin0 -> 229376 bytes
-rw-r--r--toolkit/components/places/tests/migration/head_migration.js47
-rw-r--r--toolkit/components/places/tests/migration/places_outdated.sqlitebin0 -> 155648 bytes
-rw-r--r--toolkit/components/places/tests/migration/places_v52.sqlitebin0 -> 1212416 bytes
-rw-r--r--toolkit/components/places/tests/migration/places_v54.sqlitebin0 -> 1212416 bytes
-rw-r--r--toolkit/components/places/tests/migration/places_v66.sqlitebin0 -> 1703936 bytes
-rw-r--r--toolkit/components/places/tests/migration/places_v68.sqlitebin0 -> 1703936 bytes
-rw-r--r--toolkit/components/places/tests/migration/places_v69.sqlitebin0 -> 1703936 bytes
-rw-r--r--toolkit/components/places/tests/migration/places_v70.sqlitebin0 -> 1703936 bytes
-rw-r--r--toolkit/components/places/tests/migration/places_v72.sqlitebin0 -> 1409024 bytes
-rw-r--r--toolkit/components/places/tests/migration/places_v74.sqlitebin0 -> 1441792 bytes
-rw-r--r--toolkit/components/places/tests/migration/places_v75.sqlitebin0 -> 1507328 bytes
-rw-r--r--toolkit/components/places/tests/migration/test_current_from_downgraded.js29
-rw-r--r--toolkit/components/places/tests/migration/test_current_from_outdated.js47
-rw-r--r--toolkit/components/places/tests/migration/test_current_from_v53.js23
-rw-r--r--toolkit/components/places/tests/migration/test_current_from_v54.js58
-rw-r--r--toolkit/components/places/tests/migration/test_current_from_v66.js53
-rw-r--r--toolkit/components/places/tests/migration/test_current_from_v68.js35
-rw-r--r--toolkit/components/places/tests/migration/test_current_from_v69.js84
-rw-r--r--toolkit/components/places/tests/migration/test_current_from_v70.js96
-rw-r--r--toolkit/components/places/tests/migration/test_current_from_v72.js29
-rw-r--r--toolkit/components/places/tests/migration/test_current_from_v74.js22
-rw-r--r--toolkit/components/places/tests/migration/xpcshell.toml38
23 files changed, 561 insertions, 0 deletions
diff --git a/toolkit/components/places/tests/migration/favicons_v41.sqlite b/toolkit/components/places/tests/migration/favicons_v41.sqlite
new file mode 100644
index 0000000000..a59d9d286f
--- /dev/null
+++ b/toolkit/components/places/tests/migration/favicons_v41.sqlite
Binary files differ
diff --git a/toolkit/components/places/tests/migration/head_migration.js b/toolkit/components/places/tests/migration/head_migration.js
new file mode 100644
index 0000000000..a58aada16a
--- /dev/null
+++ b/toolkit/components/places/tests/migration/head_migration.js
@@ -0,0 +1,47 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Import common head.
+{
+ /* import-globals-from ../head_common.js */
+ let commonFile = do_get_file("../head_common.js", false);
+ let uri = Services.io.newFileURI(commonFile);
+ Services.scriptloader.loadSubScript(uri.spec, this);
+}
+
+// Put any other stuff relative to this test folder below.
+
+const CURRENT_SCHEMA_VERSION = Ci.nsINavHistoryService.DATABASE_SCHEMA_VERSION;
+const FIRST_UPGRADABLE_SCHEMA_VERSION = 52;
+
+async function assertAnnotationsRemoved(db, expectedAnnos) {
+ for (let anno of expectedAnnos) {
+ let rows = await db.execute(
+ `
+ SELECT id FROM moz_anno_attributes
+ WHERE name = :anno
+ `,
+ { anno }
+ );
+
+ Assert.equal(rows.length, 0, `${anno} should not exist in the database`);
+ }
+}
+
+async function assertNoOrphanAnnotations(db) {
+ let rows = await db.execute(`
+ SELECT item_id FROM moz_items_annos
+ WHERE item_id NOT IN (SELECT id from moz_bookmarks)
+ `);
+
+ Assert.equal(rows.length, 0, `Should have no orphan annotations.`);
+
+ rows = await db.execute(`
+ SELECT id FROM moz_anno_attributes
+ WHERE id NOT IN (SELECT id from moz_items_annos)
+ `);
+
+ Assert.equal(rows.length, 0, `Should have no orphan annotation attributes.`);
+}
diff --git a/toolkit/components/places/tests/migration/places_outdated.sqlite b/toolkit/components/places/tests/migration/places_outdated.sqlite
new file mode 100644
index 0000000000..2852a4cf97
--- /dev/null
+++ b/toolkit/components/places/tests/migration/places_outdated.sqlite
Binary files differ
diff --git a/toolkit/components/places/tests/migration/places_v52.sqlite b/toolkit/components/places/tests/migration/places_v52.sqlite
new file mode 100644
index 0000000000..f4d32f6c94
--- /dev/null
+++ b/toolkit/components/places/tests/migration/places_v52.sqlite
Binary files differ
diff --git a/toolkit/components/places/tests/migration/places_v54.sqlite b/toolkit/components/places/tests/migration/places_v54.sqlite
new file mode 100644
index 0000000000..a203b28c10
--- /dev/null
+++ b/toolkit/components/places/tests/migration/places_v54.sqlite
Binary files differ
diff --git a/toolkit/components/places/tests/migration/places_v66.sqlite b/toolkit/components/places/tests/migration/places_v66.sqlite
new file mode 100644
index 0000000000..9578ee11e6
--- /dev/null
+++ b/toolkit/components/places/tests/migration/places_v66.sqlite
Binary files differ
diff --git a/toolkit/components/places/tests/migration/places_v68.sqlite b/toolkit/components/places/tests/migration/places_v68.sqlite
new file mode 100644
index 0000000000..414fa170ec
--- /dev/null
+++ b/toolkit/components/places/tests/migration/places_v68.sqlite
Binary files differ
diff --git a/toolkit/components/places/tests/migration/places_v69.sqlite b/toolkit/components/places/tests/migration/places_v69.sqlite
new file mode 100644
index 0000000000..bc3053c18e
--- /dev/null
+++ b/toolkit/components/places/tests/migration/places_v69.sqlite
Binary files differ
diff --git a/toolkit/components/places/tests/migration/places_v70.sqlite b/toolkit/components/places/tests/migration/places_v70.sqlite
new file mode 100644
index 0000000000..907e7f5046
--- /dev/null
+++ b/toolkit/components/places/tests/migration/places_v70.sqlite
Binary files differ
diff --git a/toolkit/components/places/tests/migration/places_v72.sqlite b/toolkit/components/places/tests/migration/places_v72.sqlite
new file mode 100644
index 0000000000..59d0d8fdab
--- /dev/null
+++ b/toolkit/components/places/tests/migration/places_v72.sqlite
Binary files differ
diff --git a/toolkit/components/places/tests/migration/places_v74.sqlite b/toolkit/components/places/tests/migration/places_v74.sqlite
new file mode 100644
index 0000000000..e7078a054f
--- /dev/null
+++ b/toolkit/components/places/tests/migration/places_v74.sqlite
Binary files differ
diff --git a/toolkit/components/places/tests/migration/places_v75.sqlite b/toolkit/components/places/tests/migration/places_v75.sqlite
new file mode 100644
index 0000000000..2dd624b945
--- /dev/null
+++ b/toolkit/components/places/tests/migration/places_v75.sqlite
Binary files differ
diff --git a/toolkit/components/places/tests/migration/test_current_from_downgraded.js b/toolkit/components/places/tests/migration/test_current_from_downgraded.js
new file mode 100644
index 0000000000..5daec14e2f
--- /dev/null
+++ b/toolkit/components/places/tests/migration/test_current_from_downgraded.js
@@ -0,0 +1,29 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This test ensures we can pass twice through migration methods without
+// failing, that is what happens in case of a downgrade followed by an upgrade.
+
+add_task(async function setup() {
+ let dbFile = PathUtils.join(
+ do_get_cwd().path,
+ `places_v${CURRENT_SCHEMA_VERSION}.sqlite`
+ );
+ Assert.ok(await IOUtils.exists(dbFile));
+ await setupPlacesDatabase(`places_v${CURRENT_SCHEMA_VERSION}.sqlite`);
+ // Downgrade the schema version to the first supported one.
+ let path = PathUtils.join(PathUtils.profileDir, DB_FILENAME);
+ let db = await Sqlite.openConnection({ path });
+ await db.setSchemaVersion(FIRST_UPGRADABLE_SCHEMA_VERSION);
+ await db.close();
+});
+
+add_task(async function database_is_valid() {
+ Assert.equal(
+ PlacesUtils.history.databaseStatus,
+ PlacesUtils.history.DATABASE_STATUS_UPGRADED
+ );
+
+ let db = await PlacesUtils.promiseDBConnection();
+ Assert.equal(await db.getSchemaVersion(), CURRENT_SCHEMA_VERSION);
+});
diff --git a/toolkit/components/places/tests/migration/test_current_from_outdated.js b/toolkit/components/places/tests/migration/test_current_from_outdated.js
new file mode 100644
index 0000000000..e7fad5b3a4
--- /dev/null
+++ b/toolkit/components/places/tests/migration/test_current_from_outdated.js
@@ -0,0 +1,47 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * This file tests migration from a preliminary schema version 6 that
+ * lacks frecency column and moz_inputhistory table.
+ */
+
+add_task(async function setup() {
+ await setupPlacesDatabase("places_outdated.sqlite");
+});
+
+add_task(async function corrupt_database_not_exists() {
+ let corruptPath = PathUtils.join(
+ PathUtils.profileDir,
+ "places.sqlite.corrupt"
+ );
+ Assert.ok(
+ !(await IOUtils.exists(corruptPath)),
+ "Corrupt file should not exist"
+ );
+});
+
+add_task(async function database_is_valid() {
+ Assert.equal(
+ PlacesUtils.history.databaseStatus,
+ PlacesUtils.history.DATABASE_STATUS_CORRUPT
+ );
+
+ let db = await PlacesUtils.promiseDBConnection();
+ Assert.equal(await db.getSchemaVersion(), CURRENT_SCHEMA_VERSION);
+});
+
+add_task(async function check_columns() {
+ // Check the database has been replaced, these would throw otherwise.
+ let db = await PlacesUtils.promiseDBConnection();
+ await db.execute("SELECT frecency from moz_places");
+ await db.execute("SELECT 1 from moz_inputhistory");
+});
+
+add_task(async function corrupt_database_exists() {
+ let corruptPath = PathUtils.join(
+ PathUtils.profileDir,
+ "places.sqlite.corrupt"
+ );
+ Assert.ok(await IOUtils.exists(corruptPath), "Corrupt file should exist");
+});
diff --git a/toolkit/components/places/tests/migration/test_current_from_v53.js b/toolkit/components/places/tests/migration/test_current_from_v53.js
new file mode 100644
index 0000000000..ce7b31c8df
--- /dev/null
+++ b/toolkit/components/places/tests/migration/test_current_from_v53.js
@@ -0,0 +1,23 @@
+add_task(async function setup() {
+ // Since this migration doesn't affect places.sqlite, we can reuse v43.
+ await setupPlacesDatabase("places_v52.sqlite");
+ await setupPlacesDatabase("favicons_v41.sqlite", "favicons.sqlite");
+});
+
+add_task(async function database_is_valid() {
+ // Accessing the database for the first time triggers migration.
+ Assert.equal(
+ PlacesUtils.history.databaseStatus,
+ PlacesUtils.history.DATABASE_STATUS_UPGRADED
+ );
+
+ let db = await PlacesUtils.promiseDBConnection();
+ Assert.equal(await db.getSchemaVersion(), CURRENT_SCHEMA_VERSION);
+
+ let count = (
+ await db.execute(
+ `SELECT count(*) FROM moz_icons_to_pages WHERE expire_ms = 0`
+ )
+ )[0].getResultByIndex(0);
+ Assert.equal(count, 0, "All the expirations should be set");
+});
diff --git a/toolkit/components/places/tests/migration/test_current_from_v54.js b/toolkit/components/places/tests/migration/test_current_from_v54.js
new file mode 100644
index 0000000000..94c8a26474
--- /dev/null
+++ b/toolkit/components/places/tests/migration/test_current_from_v54.js
@@ -0,0 +1,58 @@
+add_task(async function setup() {
+ // Since this migration doesn't affect places.sqlite, we can reuse v43.
+ await setupPlacesDatabase("places_v54.sqlite");
+ await setupPlacesDatabase("favicons_v41.sqlite", "favicons.sqlite");
+});
+
+add_task(async function database_is_valid() {
+ // Accessing the database for the first time triggers migration.
+ Assert.equal(
+ PlacesUtils.history.databaseStatus,
+ PlacesUtils.history.DATABASE_STATUS_UPGRADED
+ );
+
+ let db = await PlacesUtils.promiseDBConnection();
+ Assert.equal(await db.getSchemaVersion(), CURRENT_SCHEMA_VERSION);
+
+ for (let table of [
+ "moz_places_metadata",
+ "moz_places_metadata_search_queries",
+ ]) {
+ let count = (
+ await db.execute(`SELECT count(*) FROM ${table}`)
+ )[0].getResultByIndex(0);
+ Assert.equal(count, 0, `Empty table ${table}`);
+ }
+
+ for (let table of [
+ "moz_places_metadata_snapshots",
+ "moz_places_metadata_snapshots_extra",
+ "moz_places_metadata_snapshots_groups",
+ "moz_places_metadata_groups_to_snapshots",
+ "moz_session_metadata",
+ "moz_session_to_places",
+ ]) {
+ await Assert.rejects(
+ db.execute(`SELECT count(*) FROM ${table}`),
+ /no such table/,
+ `Table ${table} should not exist`
+ );
+ }
+});
+
+add_task(async function scrolling_fields_in_database() {
+ let db = await PlacesUtils.promiseDBConnection();
+ await db.execute(
+ `SELECT scrolling_time,scrolling_distance FROM moz_places_metadata`
+ );
+});
+
+add_task(async function site_name_field_in_database() {
+ let db = await PlacesUtils.promiseDBConnection();
+ await db.execute(`SELECT site_name FROM moz_places`);
+});
+
+add_task(async function previews_tombstones_in_database() {
+ let db = await PlacesUtils.promiseDBConnection();
+ await db.execute(`SELECT hash FROM moz_previews_tombstones`);
+});
diff --git a/toolkit/components/places/tests/migration/test_current_from_v66.js b/toolkit/components/places/tests/migration/test_current_from_v66.js
new file mode 100644
index 0000000000..5ea14f3b9d
--- /dev/null
+++ b/toolkit/components/places/tests/migration/test_current_from_v66.js
@@ -0,0 +1,53 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function setup() {
+ const path = await setupPlacesDatabase("places_v66.sqlite");
+
+ const db = await Sqlite.openConnection({ path });
+ await db.execute(`
+ INSERT INTO moz_inputhistory (input, use_count, place_id)
+ VALUES
+ ('abc', 1, 1),
+ ('aBc', 0.9, 1),
+ ('ABC', 5, 1),
+ ('ABC', 1, 2),
+ ('DEF', 1, 3)
+ `);
+ await db.close();
+});
+
+add_task(async function database_is_valid() {
+ // Accessing the database for the first time triggers migration.
+ Assert.equal(
+ PlacesUtils.history.databaseStatus,
+ PlacesUtils.history.DATABASE_STATUS_UPGRADED
+ );
+
+ let db = await PlacesUtils.promiseDBConnection();
+ Assert.equal(await db.getSchemaVersion(), CURRENT_SCHEMA_VERSION);
+});
+
+add_task(async function moz_inputhistory() {
+ await PlacesUtils.withConnectionWrapper("test_sqlite_migration", async db => {
+ const rows = await db.execute(
+ "SELECT * FROM moz_inputhistory ORDER BY place_id"
+ );
+
+ Assert.equal(rows.length, 3);
+
+ Assert.equal(rows[0].getResultByName("place_id"), 1);
+ Assert.equal(rows[0].getResultByName("input"), "abc");
+ Assert.equal(rows[0].getResultByName("use_count"), 5);
+
+ Assert.equal(rows[1].getResultByName("place_id"), 2);
+ Assert.equal(rows[1].getResultByName("input"), "abc");
+ Assert.equal(rows[1].getResultByName("use_count"), 1);
+
+ Assert.equal(rows[2].getResultByName("place_id"), 3);
+ Assert.equal(rows[2].getResultByName("input"), "def");
+ Assert.equal(rows[2].getResultByName("use_count"), 1);
+ });
+});
diff --git a/toolkit/components/places/tests/migration/test_current_from_v68.js b/toolkit/components/places/tests/migration/test_current_from_v68.js
new file mode 100644
index 0000000000..689fcbfd40
--- /dev/null
+++ b/toolkit/components/places/tests/migration/test_current_from_v68.js
@@ -0,0 +1,35 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function setup() {
+ const path = await setupPlacesDatabase("places_v68.sqlite");
+
+ const db = await Sqlite.openConnection({ path });
+ await db.execute("INSERT INTO moz_historyvisits (from_visit) VALUES (-1)");
+ await db.close();
+});
+
+add_task(async function database_is_valid() {
+ // Accessing the database for the first time triggers migration.
+ Assert.equal(
+ PlacesUtils.history.databaseStatus,
+ PlacesUtils.history.DATABASE_STATUS_UPGRADED
+ );
+
+ const db = await PlacesUtils.promiseDBConnection();
+ Assert.equal(await db.getSchemaVersion(), CURRENT_SCHEMA_VERSION);
+});
+
+add_task(async function moz_historyvisits() {
+ await PlacesUtils.withConnectionWrapper("test_sqlite_migration", async db => {
+ const rows = await db.execute(
+ "SELECT * FROM moz_historyvisits WHERE from_visit=-1"
+ );
+
+ Assert.equal(rows.length, 1);
+ Assert.equal(rows[0].getResultByName("source"), 0);
+ Assert.equal(rows[0].getResultByName("triggeringPlaceId"), null);
+ });
+});
diff --git a/toolkit/components/places/tests/migration/test_current_from_v69.js b/toolkit/components/places/tests/migration/test_current_from_v69.js
new file mode 100644
index 0000000000..09c66fb66e
--- /dev/null
+++ b/toolkit/components/places/tests/migration/test_current_from_v69.js
@@ -0,0 +1,84 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function setup() {
+ const path = await setupPlacesDatabase("places_v69.sqlite");
+
+ const db = await Sqlite.openConnection({ path });
+ await db.execute(`
+ INSERT INTO moz_places (url, guid, url_hash, origin_id, frecency)
+ VALUES
+ ('https://test1.com', '___________1', '123456', 100, 0),
+ ('https://test2.com', '___________2', '123456', 101, -1),
+ ('https://test3.com', '___________3', '123456', 102, -1234)
+ `);
+ await db.execute(`
+ INSERT INTO moz_origins (id, prefix, host, frecency)
+ VALUES
+ (100, 'https://', 'test1.com', 0),
+ (101, 'https://', 'test2.com', 0),
+ (102, 'https://', 'test3.com', 0)
+ `);
+ await db.close();
+});
+
+add_task(async function database_is_valid() {
+ // Accessing the database for the first time triggers migration.
+ Assert.equal(
+ PlacesUtils.history.databaseStatus,
+ PlacesUtils.history.DATABASE_STATUS_UPGRADED
+ );
+
+ const db = await PlacesUtils.promiseDBConnection();
+ Assert.equal(await db.getSchemaVersion(), CURRENT_SCHEMA_VERSION);
+});
+
+add_task(async function moz_historyvisits() {
+ await PlacesUtils.withConnectionWrapper("test_sqlite_migration", async db => {
+ function expectedFrecency(guid) {
+ switch (guid) {
+ case "___________1":
+ return 0;
+ case "___________2":
+ return -1;
+ case "___________3":
+ return 1234;
+ default:
+ throw new Error("Unknown guid");
+ }
+ }
+ const rows = await db.execute(
+ "SELECT guid, frecency FROM moz_places WHERE url_hash = '123456'"
+ );
+ for (let row of rows) {
+ Assert.equal(
+ row.getResultByName("frecency"),
+ expectedFrecency(row.getResultByName("guid")),
+ "Check expected frecency"
+ );
+ }
+ const origins = new Map(
+ (await db.execute("SELECT host, frecency FROM moz_origins")).map(r => [
+ r.getResultByName("host"),
+ r.getResultByName("frecency"),
+ ])
+ );
+ Assert.equal(origins.get("test1.com"), 0);
+ Assert.equal(origins.get("test2.com"), 0);
+ Assert.equal(origins.get("test3.com"), 1234);
+
+ const statSum = (
+ await db.execute(
+ "SELECT value FROM moz_meta WHERE key = 'origin_frecency_sum'"
+ )
+ )[0].getResultByName("value");
+ const sum = (
+ await db.execute(
+ "SELECT SUM(frecency) AS sum from moz_origins WHERE frecency > 0"
+ )
+ )[0].getResultByName("sum");
+ Assert.equal(sum, statSum, "Check stats were updated");
+ });
+});
diff --git a/toolkit/components/places/tests/migration/test_current_from_v70.js b/toolkit/components/places/tests/migration/test_current_from_v70.js
new file mode 100644
index 0000000000..e5e41852e3
--- /dev/null
+++ b/toolkit/components/places/tests/migration/test_current_from_v70.js
@@ -0,0 +1,96 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function setup() {
+ let path = await setupPlacesDatabase("places_v70.sqlite");
+
+ let db = await Sqlite.openConnection({ path });
+ await db.execute(`
+ INSERT INTO moz_places (url, guid, url_hash, origin_id, frecency, foreign_count)
+ VALUES
+ ('https://test1.com', '___________1', '123456', 100, 0, 2),
+ ('https://test2.com', '___________2', '123456', 101, -1, 2),
+ ('https://test3.com', '___________3', '123456', 102, -1234, 1)
+ `);
+ await db.execute(`
+ INSERT INTO moz_origins (id, prefix, host, frecency)
+ VALUES
+ (100, 'https://', 'test1.com', 0),
+ (101, 'https://', 'test2.com', 0),
+ (102, 'https://', 'test3.com', 0)
+ `);
+ await db.execute(
+ `INSERT INTO moz_session_metadata
+ (id, guid)
+ VALUES (0, "0")
+ `
+ );
+
+ await db.execute(
+ `INSERT INTO moz_places_metadata_snapshots
+ (place_id, created_at, first_interaction_at, last_interaction_at)
+ VALUES ((SELECT id FROM moz_places WHERE guid = :guid), 0, 0, 0)
+ `,
+ { guid: "___________1" }
+ );
+ await db.execute(
+ `INSERT INTO moz_bookmarks
+ (fk, guid)
+ VALUES ((SELECT id FROM moz_places WHERE guid = :guid), :guid)
+ `,
+ { guid: "___________1" }
+ );
+
+ await db.execute(
+ `INSERT INTO moz_places_metadata_snapshots
+ (place_id, created_at, first_interaction_at, last_interaction_at)
+ VALUES ((SELECT id FROM moz_places WHERE guid = :guid), 0, 0, 0)
+ `,
+ { guid: "___________2" }
+ );
+ await db.execute(
+ `INSERT INTO moz_session_to_places
+ (session_id, place_id)
+ VALUES (0, (SELECT id FROM moz_places WHERE guid = :guid))
+ `,
+ { guid: "___________2" }
+ );
+
+ await db.execute(
+ `INSERT INTO moz_session_to_places
+ (session_id, place_id)
+ VALUES (0, (SELECT id FROM moz_places WHERE guid = :guid))
+ `,
+ { guid: "___________3" }
+ );
+
+ await db.close();
+});
+
+add_task(async function database_is_valid() {
+ // Accessing the database for the first time triggers migration.
+ Assert.equal(
+ PlacesUtils.history.databaseStatus,
+ PlacesUtils.history.DATABASE_STATUS_UPGRADED
+ );
+
+ const db = await PlacesUtils.promiseDBConnection();
+ Assert.equal(await db.getSchemaVersion(), CURRENT_SCHEMA_VERSION);
+
+ let rows = await db.execute("SELECT guid, foreign_count FROM moz_places");
+ for (let row of rows) {
+ let guid = row.getResultByName("guid");
+ let count = row.getResultByName("foreign_count");
+ if (guid == "___________1") {
+ Assert.equal(count, 1, "test1 should have the correct foreign_count");
+ }
+ if (guid == "___________2") {
+ Assert.equal(count, 0, "test2 should have the correct foreign_count");
+ }
+ if (guid == "___________3") {
+ Assert.equal(count, 0, "test3 should have the correct foreign_count");
+ }
+ }
+});
diff --git a/toolkit/components/places/tests/migration/test_current_from_v72.js b/toolkit/components/places/tests/migration/test_current_from_v72.js
new file mode 100644
index 0000000000..626279fce4
--- /dev/null
+++ b/toolkit/components/places/tests/migration/test_current_from_v72.js
@@ -0,0 +1,29 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function setup() {
+ await setupPlacesDatabase("places_v72.sqlite");
+});
+
+add_task(async function database_is_valid() {
+ // Accessing the database for the first time triggers migration.
+ Assert.equal(
+ PlacesUtils.history.databaseStatus,
+ PlacesUtils.history.DATABASE_STATUS_UPGRADED
+ );
+
+ const db = await PlacesUtils.promiseDBConnection();
+ Assert.equal(await db.getSchemaVersion(), CURRENT_SCHEMA_VERSION);
+
+ await db.execute(
+ "SELECT recalc_frecency, alt_frecency, recalc_alt_frecency FROM moz_origins"
+ );
+
+ await db.execute("SELECT alt_frecency, recalc_alt_frecency FROM moz_places");
+ Assert.ok(
+ await db.indexExists("moz_places_altfrecencyindex"),
+ "Should have created an index"
+ );
+});
diff --git a/toolkit/components/places/tests/migration/test_current_from_v74.js b/toolkit/components/places/tests/migration/test_current_from_v74.js
new file mode 100644
index 0000000000..82c535f78f
--- /dev/null
+++ b/toolkit/components/places/tests/migration/test_current_from_v74.js
@@ -0,0 +1,22 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function setup() {
+ await setupPlacesDatabase("places_v74.sqlite");
+});
+
+add_task(async function database_is_valid() {
+ // Accessing the database for the first time triggers migration.
+ Assert.equal(
+ PlacesUtils.history.databaseStatus,
+ PlacesUtils.history.DATABASE_STATUS_UPGRADED
+ );
+
+ const db = await PlacesUtils.promiseDBConnection();
+ Assert.equal(await db.getSchemaVersion(), CURRENT_SCHEMA_VERSION);
+
+ await db.execute("SELECT * FROM moz_places_extra");
+ await db.execute("SELECT * from moz_historyvisits_extra");
+});
diff --git a/toolkit/components/places/tests/migration/xpcshell.toml b/toolkit/components/places/tests/migration/xpcshell.toml
new file mode 100644
index 0000000000..b127fa501f
--- /dev/null
+++ b/toolkit/components/places/tests/migration/xpcshell.toml
@@ -0,0 +1,38 @@
+[DEFAULT]
+head = "head_migration.js"
+skip-if = ["condprof"] # Not worth running conditioned profiles on these migration
+# tests for databases. See discussion in bug 1838791.
+
+support-files = [
+ "favicons_v41.sqlite",
+ "places_outdated.sqlite",
+ "places_v52.sqlite",
+ "places_v54.sqlite",
+ "places_v66.sqlite",
+ "places_v68.sqlite",
+ "places_v69.sqlite",
+ "places_v70.sqlite",
+ "places_v72.sqlite",
+ "places_v74.sqlite",
+ "places_v75.sqlite",
+]
+
+["test_current_from_downgraded.js"]
+
+["test_current_from_outdated.js"]
+
+["test_current_from_v53.js"]
+
+["test_current_from_v54.js"]
+
+["test_current_from_v66.js"]
+
+["test_current_from_v68.js"]
+
+["test_current_from_v69.js"]
+
+["test_current_from_v70.js"]
+
+["test_current_from_v72.js"]
+
+["test_current_from_v74.js"]