зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 90063a429c82 (bug 1741868) for causing almost permafailing assertion failures on GMPServiceParent.cpp. CLOSED TREE
This commit is contained in:
Родитель
eb3a9e6bd7
Коммит
03606c7ea5
|
@ -2652,13 +2652,3 @@ pref("svg.context-properties.content.allowed-domains", "profile.accounts.firefox
|
|||
#ifdef NIGHTLY_BUILD
|
||||
pref("extensions.translations.disabled", true);
|
||||
#endif
|
||||
|
||||
// A set of scores for rating the relevancy of snapshots. The suffixes after the
|
||||
// last decimal are prefixed by `_score` and reference the functions called in
|
||||
// SnapshotScorer.
|
||||
pref("browser.snapshots.score.Visit", 1);
|
||||
pref("browser.snapshots.score.CurrentSession", 1);
|
||||
pref("browser.snapshots.score.InNavigation", 3);
|
||||
pref("browser.snapshots.score.IsOverlappingVisit", 3);
|
||||
pref("browser.snapshots.score.IsUserPersisted", 1);
|
||||
pref("browser.snapshots.score.IsUsedRemoved", -10);
|
||||
|
|
|
@ -1,209 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const EXPORTED_SYMBOLS = ["SnapshotScorer"];
|
||||
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"Services",
|
||||
"resource://gre/modules/Services.jsm"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "logConsole", function() {
|
||||
return console.createInstance({
|
||||
prefix: "SnapshotSelector",
|
||||
maxLogLevel: Services.prefs.getBoolPref(
|
||||
"browser.snapshots.scorer.log",
|
||||
false
|
||||
)
|
||||
? "Debug"
|
||||
: "Warn",
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* The snapshot scorer receives sets of snapshots and scores them based on the
|
||||
* expected relevancy to the user. This order is subsequently used to display
|
||||
* the candidates.
|
||||
*/
|
||||
const SnapshotScorer = new (class SnapshotScorer {
|
||||
/**
|
||||
* @type {Map}
|
||||
* A map of function suffixes to relevancy points. The suffixes are prefixed
|
||||
* with `_score`. Each function will be called in turn to obtain the score
|
||||
* for that item with the result multiplied by the relevancy points.
|
||||
* This map is filled from the `browser.snapshots.score.` preferences.
|
||||
*/
|
||||
#RELEVANCY_POINTS = new Map();
|
||||
|
||||
/**
|
||||
* @type {Date|null}
|
||||
* Used to override the current date for tests.
|
||||
*/
|
||||
#dateOverride = null;
|
||||
|
||||
constructor() {
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"snapshotThreshold",
|
||||
"browser.places.snapshots.threshold",
|
||||
4
|
||||
);
|
||||
|
||||
let branch = Services.prefs.getBranch("browser.snapshots.score.");
|
||||
for (let name of branch.getChildList("")) {
|
||||
this.#RELEVANCY_POINTS.set(name, branch.getIntPref(name, 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines groups of snapshots into one group, and scoring their relevance.
|
||||
* If snapshots are present in multiple groups, the snapshot with the highest
|
||||
* score is used.
|
||||
* A snapshot score must meet the `snapshotThreshold` to be included in the
|
||||
* results.
|
||||
*
|
||||
* @param {Set} currentSessionUrls
|
||||
* A set of urls that are in the current session.
|
||||
* @param {Snapshot[]} snapshotGroups
|
||||
* One or more arrays of snapshot groups to combine.
|
||||
* @returns {Snapshot[]}
|
||||
* The combined snapshot array in descending order of relevancy.
|
||||
*/
|
||||
combineAndScore(currentSessionUrls, ...snapshotGroups) {
|
||||
let combined = new Map();
|
||||
let currentDate = this.#dateOverride ?? Date.now();
|
||||
for (let group of snapshotGroups) {
|
||||
for (let snapshot of group) {
|
||||
let existing = combined.get(snapshot.url);
|
||||
let score = this.#score(snapshot, currentDate, currentSessionUrls);
|
||||
logConsole.debug("Scored", score, "for", snapshot.url);
|
||||
if (existing) {
|
||||
if (score > existing.relevancyScore) {
|
||||
snapshot.relevancyScore = score;
|
||||
combined.set(snapshot.url, snapshot);
|
||||
}
|
||||
} else if (score >= this.snapshotThreshold) {
|
||||
snapshot.relevancyScore = score;
|
||||
combined.set(snapshot.url, snapshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [...combined.values()].sort(
|
||||
(a, b) => b.relevancyScore - a.relevancyScore
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test-only. Overrides the time used in the scoring algorithm with a
|
||||
* specific time which allows for deterministic tests.
|
||||
*
|
||||
* @param {number} date
|
||||
* Epoch time to set the date to.
|
||||
*/
|
||||
overrideCurrentTimeForTests(date) {
|
||||
this.#dateOverride = date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scores a snapshot based on its relevancy.
|
||||
*
|
||||
* @param {Snapshot} snapshot
|
||||
* The snapshot to score.
|
||||
* @param {number} currentDate
|
||||
* The current time in milliseconds from the epoch.
|
||||
* @param {Set} currentSessionUrls
|
||||
* The urls of the current session.
|
||||
* @returns {number}
|
||||
* The relevancy score for the snapshot.
|
||||
*/
|
||||
#score(snapshot, currentDate, currentSessionUrls) {
|
||||
let points = 0;
|
||||
for (let [item, value] of this.#RELEVANCY_POINTS.entries()) {
|
||||
let fnName = `_score${item}`;
|
||||
if (!(fnName in this)) {
|
||||
console.error("Could not find function", fnName, "in SnapshotScorer");
|
||||
continue;
|
||||
}
|
||||
points += this[fnName](snapshot, currentSessionUrls) * value;
|
||||
}
|
||||
|
||||
let timeAgo = currentDate - snapshot.lastInteractionAt;
|
||||
timeAgo = timeAgo / (24 * 60 * 60 * 1000);
|
||||
|
||||
return points * Math.exp(timeAgo / -7);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates points based on how many times the snapshot has been visited.
|
||||
*
|
||||
* @param {Snapshot} snapshot
|
||||
* @returns {number}
|
||||
*/
|
||||
_scoreVisit(snapshot) {
|
||||
// Protect against cases where a bookmark was created without a visit.
|
||||
if (snapshot.visitCount == 0) {
|
||||
return 0;
|
||||
}
|
||||
return 2 - 1 / snapshot.visitCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates points based on if the snapshot has already been visited in
|
||||
* the current session.
|
||||
*
|
||||
* @param {Snapshot} snapshot
|
||||
* @param {Set} currentSessionUrls
|
||||
* @returns {number}
|
||||
*/
|
||||
_scoreCurrentSession(snapshot, currentSessionUrls) {
|
||||
return currentSessionUrls.has(snapshot.url) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not currently used.
|
||||
*
|
||||
* @param {Snapshot} snapshot
|
||||
* @returns {number}
|
||||
*/
|
||||
_scoreInNavigation(snapshot) {
|
||||
// In Navigation is not currently implemented.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates points based on if the snapshot has been visited within a
|
||||
* certain time period of another website.
|
||||
*
|
||||
* @param {Snapshot} snapshot
|
||||
* @returns {number}
|
||||
*/
|
||||
_scoreIsOverlappingVisit(snapshot) {
|
||||
return snapshot.overlappingVisitScore ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates points based on if the user persisted the snapshot.
|
||||
*
|
||||
* @param {Snapshot} snapshot
|
||||
* @returns {number}
|
||||
*/
|
||||
_scoreIsUserPersisted(snapshot) {
|
||||
return snapshot.userPersisted ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates points based on if the user removed the snapshot.
|
||||
*
|
||||
* @param {Snapshot} snapshot
|
||||
* @returns {number}
|
||||
*/
|
||||
_scoreIsUsedRemoved(snapshot) {
|
||||
return snapshot.removedAt ? 1 : 0;
|
||||
}
|
||||
})();
|
|
@ -13,7 +13,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
FilterAdult: "resource://activity-stream/lib/FilterAdult.jsm",
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
Snapshots: "resource:///modules/Snapshots.jsm",
|
||||
SnapshotScorer: "resource:///modules/SnapshotScorer.jsm",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "logConsole", function() {
|
||||
|
@ -88,12 +87,6 @@ class SnapshotSelector extends EventEmitter {
|
|||
* @type {PageDataCollector.DATA_TYPE | undefined}
|
||||
*/
|
||||
type: undefined,
|
||||
|
||||
/**
|
||||
* A function that returns a Set containing the urls for the current session.
|
||||
* @type {function}
|
||||
*/
|
||||
getCurrentSessionUrls: undefined,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -102,33 +95,21 @@ class SnapshotSelector extends EventEmitter {
|
|||
#task = null;
|
||||
|
||||
/**
|
||||
* @param {object} options
|
||||
* @param {number} [options.count]
|
||||
* @param {number} count
|
||||
* The maximum number of snapshots we ever need to generate. This should not
|
||||
* affect the actual snapshots generated and their order but may speed up
|
||||
* calculations.
|
||||
* @param {boolean} [options.filterAdult]
|
||||
* @param {boolean} filterAdult
|
||||
* Whether adult sites should be filtered from the snapshots.
|
||||
* @param {boolean} [options.selectOverlappingVisits]
|
||||
* @param {boolean} selectOverlappingVisits
|
||||
* Whether to select snapshots where visits overlapped the current context url
|
||||
* @param {function} [options.getCurrentSessionUrls]
|
||||
* A function that returns a Set containing the urls for the current session.
|
||||
*/
|
||||
constructor({
|
||||
count = 5,
|
||||
filterAdult = false,
|
||||
selectOverlappingVisits = false,
|
||||
getCurrentSessionUrls = () => new Set(),
|
||||
}) {
|
||||
constructor(count = 5, filterAdult = false, selectOverlappingVisits = false) {
|
||||
super();
|
||||
this.#task = new DeferredTask(
|
||||
() => this.#buildSnapshots().catch(console.error),
|
||||
500
|
||||
);
|
||||
this.#task = new DeferredTask(() => this.#buildSnapshots(), 500);
|
||||
this.#context.count = count;
|
||||
this.#context.filterAdult = filterAdult;
|
||||
this.#context.selectOverlappingVisits = selectOverlappingVisits;
|
||||
this.#context.getCurrentSessionUrls = getCurrentSessionUrls;
|
||||
SnapshotSelector.#selectors.add(this);
|
||||
}
|
||||
|
||||
|
@ -231,20 +212,10 @@ class SnapshotSelector extends EventEmitter {
|
|||
return !context.filterAdult || !FilterAdult.isAdultUrl(snapshot.url);
|
||||
});
|
||||
|
||||
logConsole.debug(
|
||||
"Found overlapping snapshots:",
|
||||
snapshots.map(s => s.url)
|
||||
);
|
||||
|
||||
snapshots = SnapshotScorer.combineAndScore(
|
||||
this.#context.getCurrentSessionUrls(),
|
||||
snapshots
|
||||
);
|
||||
|
||||
snapshots = snapshots.slice(0, context.count);
|
||||
|
||||
logConsole.debug(
|
||||
"Reduced final candidates:",
|
||||
"Found overlapping snapshots: ",
|
||||
snapshots.map(s => s.url)
|
||||
);
|
||||
|
||||
|
|
|
@ -112,11 +112,10 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
|||
* True if the user created or persisted the snapshot in some way.
|
||||
* @property {Map<type, data>} pageData
|
||||
* Collection of PageData by type. See PageDataService.jsm
|
||||
* @property {Number} overlappingVisitScore
|
||||
* @property {Number} overlappingVisitScore
|
||||
* Calculated score based on overlapping visits to the context url. In the range [0.0, 1.0]
|
||||
* @property {number} [relevancyScore]
|
||||
* The relevancy score associated with the snapshot.
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles storing and retrieving of Snapshots in the Places database.
|
||||
|
@ -437,8 +436,7 @@ const Snapshots = new (class Snapshots {
|
|||
SELECT h.url AS url, h.title AS title, created_at, removed_at,
|
||||
document_type, first_interaction_at, last_interaction_at,
|
||||
user_persisted, description, site_name, preview_image_url,
|
||||
group_concat('[' || e.type || ', ' || e.data || ']') AS page_data,
|
||||
h.visit_count
|
||||
group_concat('[' || e.type || ', ' || e.data || ']') AS page_data
|
||||
FROM moz_places_metadata_snapshots s
|
||||
JOIN moz_places h ON h.id = s.place_id
|
||||
LEFT JOIN moz_places_metadata_snapshots_extra e ON e.place_id = s.place_id
|
||||
|
@ -496,8 +494,7 @@ const Snapshots = new (class Snapshots {
|
|||
SELECT h.url AS url, h.title AS title, created_at, removed_at,
|
||||
document_type, first_interaction_at, last_interaction_at,
|
||||
user_persisted, description, site_name, preview_image_url,
|
||||
group_concat('[' || e.type || ', ' || e.data || ']') AS page_data,
|
||||
h.visit_count
|
||||
group_concat('[' || e.type || ', ' || e.data || ']') AS page_data
|
||||
FROM moz_places_metadata_snapshots s
|
||||
JOIN moz_places h ON h.id = s.place_id
|
||||
LEFT JOIN moz_places_metadata_snapshots_extra e ON e.place_id = s.place_id
|
||||
|
@ -560,8 +557,7 @@ const Snapshots = new (class Snapshots {
|
|||
let rows = await db.executeCached(
|
||||
`SELECT h.url AS url, h.title AS title, o.overlappingVisitScore, created_at, removed_at,
|
||||
document_type, first_interaction_at, last_interaction_at,
|
||||
user_persisted, description, site_name, preview_image_url, group_concat(e.data, ",") AS page_data,
|
||||
h.visit_count
|
||||
user_persisted, description, site_name, preview_image_url, group_concat(e.data, ",") AS page_data
|
||||
FROM moz_places_metadata_snapshots s JOIN moz_places h ON h.id = s.place_id JOIN (
|
||||
SELECT place_id, 1.0 AS overlappingVisitScore
|
||||
FROM
|
||||
|
@ -669,7 +665,6 @@ const Snapshots = new (class Snapshots {
|
|||
userPersisted: !!row.getResultByName("user_persisted"),
|
||||
overlappingVisitScore,
|
||||
pageData: pageData ?? new Map(),
|
||||
visitCount: row.getResultByName("visit_count"),
|
||||
};
|
||||
|
||||
snapshot.commonName = CommonNames.getName(snapshot);
|
||||
|
|
|
@ -22,7 +22,6 @@ EXTRA_JS_MODULES += [
|
|||
"InteractionsBlocklist.jsm",
|
||||
"PlacesUIUtils.jsm",
|
||||
"Snapshots.jsm",
|
||||
"SnapshotScorer.jsm",
|
||||
"SnapshotSelector.jsm",
|
||||
]
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
setTimeout: "resource://gre/modules/Timer.jsm",
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
Snapshots: "resource:///modules/Snapshots.jsm",
|
||||
SnapshotScorer: "resource:///modules/SnapshotScorer.jsm",
|
||||
SnapshotSelector: "resource:///modules/SnapshotSelector.jsm",
|
||||
TestUtils: "resource://testing-common/TestUtils.jsm",
|
||||
});
|
||||
|
@ -283,32 +282,3 @@ async function reset() {
|
|||
await Snapshots.reset();
|
||||
await Interactions.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts relevancy scores for snapshots are correct.
|
||||
*
|
||||
* @param {Snapshot[]} combinedSnapshots
|
||||
* The array of combined snapshots.
|
||||
* @param {object[]} expectedSnapshots
|
||||
* An array of objects containing expected url and relevancyScore properties.
|
||||
*/
|
||||
function assertSnapshotScores(combinedSnapshots, expectedSnapshots) {
|
||||
Assert.equal(
|
||||
combinedSnapshots.length,
|
||||
expectedSnapshots.length,
|
||||
"Should have returned the correct amount of snapshots"
|
||||
);
|
||||
|
||||
for (let i = 0; i < combinedSnapshots.length; i++) {
|
||||
Assert.equal(
|
||||
combinedSnapshots[i].url,
|
||||
expectedSnapshots[i].url,
|
||||
"Should have returned the expected URL for the snapshot"
|
||||
);
|
||||
Assert.equal(
|
||||
combinedSnapshots[i].relevancyScore,
|
||||
expectedSnapshots[i].score,
|
||||
`Should have set the expected score for ${expectedSnapshots[i].url}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,259 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that snapshots are correctly scored.
|
||||
*/
|
||||
|
||||
const SCORE_TESTS = [
|
||||
{
|
||||
testName: "Basic test",
|
||||
lastVisit: 0,
|
||||
visitCount: 1,
|
||||
currentSession: false,
|
||||
overlappingVisitScore: 0,
|
||||
userPersisted: false,
|
||||
userRemoved: false,
|
||||
score: 1,
|
||||
},
|
||||
{
|
||||
testName: "Last visit test 1",
|
||||
lastVisit: 4,
|
||||
visitCount: 1,
|
||||
currentSession: false,
|
||||
overlappingVisitScore: 0,
|
||||
userPersisted: true,
|
||||
userRemoved: false,
|
||||
score: 1.1294362440155186,
|
||||
},
|
||||
{
|
||||
testName: "Last visit test 2",
|
||||
lastVisit: 6,
|
||||
visitCount: 1,
|
||||
currentSession: false,
|
||||
overlappingVisitScore: 0,
|
||||
userPersisted: true,
|
||||
userRemoved: false,
|
||||
score: 0.8487456913539,
|
||||
},
|
||||
{
|
||||
testName: "Last visit test 3",
|
||||
lastVisit: 7,
|
||||
visitCount: 1,
|
||||
currentSession: false,
|
||||
userPersisted: true,
|
||||
userRemoved: false,
|
||||
score: 0.7357588823428847,
|
||||
},
|
||||
{
|
||||
testName: "Large visit count test",
|
||||
lastVisit: 0,
|
||||
visitCount: 100,
|
||||
currentSession: false,
|
||||
overlappingVisitScore: 0,
|
||||
userPersisted: false,
|
||||
userRemoved: false,
|
||||
score: 1.99,
|
||||
},
|
||||
{
|
||||
testName: "Zero visit count test",
|
||||
lastVisit: 0,
|
||||
visitCount: 0,
|
||||
currentSession: false,
|
||||
overlappingVisitScore: 0,
|
||||
userPersisted: true,
|
||||
userRemoved: false,
|
||||
score: 1,
|
||||
},
|
||||
{
|
||||
testName: "In current session test",
|
||||
lastVisit: 0,
|
||||
visitCount: 1,
|
||||
currentSession: true,
|
||||
overlappingVisitScore: 0,
|
||||
userPersisted: false,
|
||||
userRemoved: false,
|
||||
score: 2,
|
||||
},
|
||||
{
|
||||
testName: "Overlapping visit score test 1",
|
||||
lastVisit: 0,
|
||||
visitCount: 1,
|
||||
currentSession: false,
|
||||
overlappingVisitScore: 1.0,
|
||||
userPersisted: false,
|
||||
userRemoved: false,
|
||||
score: 4,
|
||||
},
|
||||
{
|
||||
testName: "Overlapping visit score test 2",
|
||||
lastVisit: 0,
|
||||
visitCount: 1,
|
||||
currentSession: false,
|
||||
overlappingVisitScore: 0.5,
|
||||
userPersisted: false,
|
||||
userRemoved: false,
|
||||
score: 2.5,
|
||||
},
|
||||
{
|
||||
testName: "User persisted test",
|
||||
lastVisit: 0,
|
||||
visitCount: 1,
|
||||
currentSession: false,
|
||||
overlappingVisitScore: 0,
|
||||
userPersisted: true,
|
||||
userRemoved: false,
|
||||
score: 2,
|
||||
},
|
||||
{
|
||||
testName: "User removed test",
|
||||
lastVisit: 0,
|
||||
visitCount: 1,
|
||||
currentSession: false,
|
||||
overlappingVisitScore: 0,
|
||||
userPersisted: false,
|
||||
userRemoved: true,
|
||||
score: -9, // 1 for the visit, -10 for removed
|
||||
},
|
||||
];
|
||||
|
||||
// Tests for ensuring the threshold works. Note that these need to be in reverse
|
||||
// score order.
|
||||
const THRESHOLD_TESTS = [
|
||||
{
|
||||
lastVisit: 0,
|
||||
visitCount: 100,
|
||||
currentSession: true,
|
||||
overlappingVisitScore: 1.0,
|
||||
userPersisted: true,
|
||||
userRemoved: false,
|
||||
score: 6.99,
|
||||
},
|
||||
{
|
||||
lastVisit: 0,
|
||||
visitCount: 100,
|
||||
currentSession: false,
|
||||
overlappingVisitScore: 0.35,
|
||||
userPersisted: true,
|
||||
userRemoved: false,
|
||||
score: 4.04,
|
||||
},
|
||||
{
|
||||
lastVisit: 0,
|
||||
visitCount: 1,
|
||||
currentSession: false,
|
||||
overlappingVisitScore: 0.0,
|
||||
userPersisted: false,
|
||||
userRemoved: false,
|
||||
score: 1,
|
||||
},
|
||||
];
|
||||
|
||||
add_task(async function setup() {
|
||||
let now = Date.now();
|
||||
|
||||
SnapshotScorer.overrideCurrentTimeForTests(now);
|
||||
|
||||
for (let [i, data] of [...SCORE_TESTS, ...THRESHOLD_TESTS].entries()) {
|
||||
let createdAt = now - data.lastVisit * 24 * 60 * 60 * 1000;
|
||||
let url = `https://example.com/${i}`;
|
||||
if (data.visitCount != 0) {
|
||||
await addInteractions([{ url, created_at: createdAt }]);
|
||||
if (data.visitCount > 2) {
|
||||
let urls = new Array(data.visitCount - 1);
|
||||
urls.fill(url);
|
||||
await PlacesTestUtils.addVisits(urls);
|
||||
}
|
||||
}
|
||||
await Snapshots.add({ url, userPersisted: data.userPersisted });
|
||||
|
||||
if (data.visitCount == 0) {
|
||||
// For the last updated time for the snapshot to be "now", so that we can
|
||||
// have a fixed value for the score in the test.
|
||||
await PlacesUtils.withConnectionWrapper(
|
||||
"test_snapshotscorer",
|
||||
async db => {
|
||||
await db.executeCached(
|
||||
`UPDATE moz_places_metadata_snapshots
|
||||
SET last_interaction_at = :lastInteractionAt
|
||||
WHERE place_id = (SELECT id FROM moz_places WHERE url_hash = hash(:url) AND url = :url)`,
|
||||
{ lastInteractionAt: now, url }
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (data.userRemoved) {
|
||||
await Snapshots.delete(url);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function handleSnapshotSetup(testData, snapshot, sessionUrls) {
|
||||
if (testData.overlappingVisitScore) {
|
||||
snapshot.overlappingVisitScore = testData.overlappingVisitScore;
|
||||
}
|
||||
if (testData.currentSession) {
|
||||
sessionUrls.add(snapshot.url);
|
||||
}
|
||||
}
|
||||
|
||||
add_task(async function test_scores() {
|
||||
// Set threshold to -10 as that's below the lowest we can get and we want
|
||||
// to test the full score range.
|
||||
Services.prefs.setIntPref("browser.places.snapshots.threshold", -10);
|
||||
|
||||
for (let [i, data] of SCORE_TESTS.entries()) {
|
||||
info(`${data.testName}`);
|
||||
|
||||
let sessionUrls = new Set([`https://mochitest:8888/`]);
|
||||
|
||||
let url = `https://example.com/${i}`;
|
||||
let snapshot = await Snapshots.get(url, true);
|
||||
|
||||
handleSnapshotSetup(data, snapshot, sessionUrls);
|
||||
|
||||
let snapshots = await SnapshotScorer.combineAndScore(sessionUrls, [
|
||||
snapshot,
|
||||
]);
|
||||
|
||||
assertSnapshotScores(snapshots, [
|
||||
{
|
||||
url,
|
||||
score: data.score,
|
||||
},
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function test_score_threshold() {
|
||||
const THRESHOLD = 4;
|
||||
Services.prefs.setIntPref("browser.places.snapshots.threshold", THRESHOLD);
|
||||
|
||||
let sessionUrls = new Set([`https://mochitest:8888/`]);
|
||||
let originalSnapshots = [];
|
||||
|
||||
for (let i = 0; i < THRESHOLD_TESTS.length; i++) {
|
||||
let url = `https://example.com/${i + SCORE_TESTS.length}`;
|
||||
let snapshot = await Snapshots.get(url, true);
|
||||
|
||||
handleSnapshotSetup(THRESHOLD_TESTS[i], snapshot, sessionUrls);
|
||||
originalSnapshots.push(snapshot);
|
||||
}
|
||||
|
||||
let snapshots = await SnapshotScorer.combineAndScore(
|
||||
sessionUrls,
|
||||
originalSnapshots
|
||||
);
|
||||
|
||||
assertSnapshotScores(
|
||||
snapshots,
|
||||
// map before filter so that we get the url values correct.
|
||||
THRESHOLD_TESTS.map((t, i) => {
|
||||
return {
|
||||
url: `https://example.com/${i + SCORE_TESTS.length}`,
|
||||
score: t.score,
|
||||
};
|
||||
}).filter(t => t.score > THRESHOLD)
|
||||
);
|
||||
});
|
|
@ -1,77 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that snapshots are correctly scored. Note this file does not test
|
||||
* InNavigation and InTimeWindow.
|
||||
*/
|
||||
|
||||
const TEST_URL1 = "https://example.com/";
|
||||
const TEST_URL2 = "https://invalid.com/";
|
||||
|
||||
add_task(async function setup() {
|
||||
let now = Date.now();
|
||||
SnapshotScorer.overrideCurrentTimeForTests(now);
|
||||
|
||||
await addInteractions([{ url: TEST_URL1, created_at: now }]);
|
||||
await Snapshots.add({ url: TEST_URL1, userPersisted: true });
|
||||
|
||||
await addInteractions([{ url: TEST_URL2, created_at: now }]);
|
||||
await Snapshots.add({ url: TEST_URL2, userPersisted: true });
|
||||
});
|
||||
|
||||
add_task(async function test_combining_throw_away_first() {
|
||||
let snapshot1a = await Snapshots.get(TEST_URL1);
|
||||
let snapshot1b = await Snapshots.get(TEST_URL1);
|
||||
let snapshot2 = await Snapshots.get(TEST_URL2);
|
||||
|
||||
// Set up so that 1a will be thrown away.
|
||||
snapshot1a.overlappingVisitScore = 0.5;
|
||||
snapshot2.overlappingVisitScore = 0.5;
|
||||
snapshot1b.overlappingVisitScore = 1.0;
|
||||
|
||||
let combined = SnapshotScorer.combineAndScore(
|
||||
new Set([TEST_URL1, TEST_URL2]),
|
||||
[snapshot1a],
|
||||
[snapshot1b, snapshot2]
|
||||
);
|
||||
|
||||
assertSnapshotScores(combined, [
|
||||
{
|
||||
url: TEST_URL1,
|
||||
score: 6,
|
||||
},
|
||||
{
|
||||
url: TEST_URL2,
|
||||
score: 4.5,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(async function test_combining_throw_away_second_and_sort() {
|
||||
// We swap the snapshots around a bit here to additionally test the sort.
|
||||
let snapshot1 = await Snapshots.get(TEST_URL1);
|
||||
let snapshot2a = await Snapshots.get(TEST_URL2);
|
||||
let snapshot2b = await Snapshots.get(TEST_URL2);
|
||||
|
||||
snapshot1.overlappingVisitScore = 0.5;
|
||||
snapshot2a.overlappingVisitScore = 1.0;
|
||||
snapshot2b.overlappingVisitScore = 0.5;
|
||||
|
||||
let combined = SnapshotScorer.combineAndScore(
|
||||
new Set([TEST_URL1, TEST_URL2]),
|
||||
[snapshot2a],
|
||||
[snapshot1, snapshot2b]
|
||||
);
|
||||
|
||||
assertSnapshotScores(combined, [
|
||||
{
|
||||
url: TEST_URL2,
|
||||
score: 6,
|
||||
},
|
||||
{
|
||||
url: TEST_URL1,
|
||||
score: 4.5,
|
||||
},
|
||||
]);
|
||||
});
|
|
@ -33,11 +33,8 @@ add_task(async function setup() {
|
|||
});
|
||||
|
||||
add_task(async function test_interactions_adult_basic() {
|
||||
let anySelector = new SnapshotSelector({ count: 2, filterAdult: false });
|
||||
let adultFilterSelector = new SnapshotSelector({
|
||||
count: 2,
|
||||
filterAdult: true,
|
||||
});
|
||||
let anySelector = new SnapshotSelector(2, false);
|
||||
let adultFilterSelector = new SnapshotSelector(2, true);
|
||||
|
||||
let snapshotPromise = anySelector.once("snapshots-updated");
|
||||
anySelector.rebuild();
|
||||
|
@ -67,10 +64,7 @@ add_task(async function test_interactions_adult_filter_multiple() {
|
|||
await addInteractions([{ url: TEST_URL5, created_at: Date.now() - 2000 }]);
|
||||
await Snapshots.add({ url: TEST_URL5 });
|
||||
|
||||
let adultFilterSelector = new SnapshotSelector({
|
||||
count: 2,
|
||||
filterAdult: true,
|
||||
});
|
||||
let adultFilterSelector = new SnapshotSelector(2, true);
|
||||
|
||||
let snapshotPromise = adultFilterSelector.once("snapshots-updated");
|
||||
adultFilterSelector.rebuild();
|
||||
|
|
|
@ -10,14 +10,7 @@ const TEST_URL2 = "https://example.com/2";
|
|||
const TEST_URL3 = "https://example.com/3";
|
||||
const TEST_URL4 = "https://example.com/4";
|
||||
|
||||
let selector;
|
||||
let currentSessionUrls = new Set();
|
||||
|
||||
function getCurrentSessionUrls() {
|
||||
return currentSessionUrls;
|
||||
}
|
||||
|
||||
add_task(async function test_setup() {
|
||||
add_task(async function test_enable_overlapping() {
|
||||
const ONE_MINUTE = 1000 * 60;
|
||||
const ONE_HOUR = ONE_MINUTE * 60;
|
||||
|
||||
|
@ -37,17 +30,11 @@ add_task(async function test_setup() {
|
|||
{ url: TEST_URL4, created_at: now - ONE_HOUR, updated_at: now - ONE_HOUR },
|
||||
]);
|
||||
|
||||
selector = new SnapshotSelector({
|
||||
count: 5,
|
||||
filterAdult: false,
|
||||
selectOverlappingVisits: true,
|
||||
getCurrentSessionUrls,
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_enable_overlapping() {
|
||||
// Allow all snapshots regardless of their score.
|
||||
Services.prefs.setIntPref("browser.places.snapshots.threshold", -10);
|
||||
let selector = new SnapshotSelector(
|
||||
5 /* count */,
|
||||
false /* filter adult */,
|
||||
true /* selectOverlappingVisits */
|
||||
);
|
||||
|
||||
let snapshotPromise = selector.once("snapshots-updated");
|
||||
selector.rebuild();
|
||||
|
@ -67,24 +54,3 @@ add_task(async function test_enable_overlapping() {
|
|||
// Only snapshots with overlaping interactions should be selected
|
||||
await assertSnapshotList(snapshots, [{ url: TEST_URL2 }]);
|
||||
});
|
||||
|
||||
add_task(async function test_overlapping_with_scoring() {
|
||||
// Reset the threshold, the snapshot should be lower than the required score.
|
||||
Services.prefs.clearUserPref("browser.places.snapshots.threshold");
|
||||
|
||||
let snapshotPromise = selector.once("snapshots-updated");
|
||||
selector.rebuild();
|
||||
let snapshots = await snapshotPromise;
|
||||
|
||||
await assertSnapshotList(snapshots, []);
|
||||
|
||||
// Boost the score of the expected snapshot by adding it to the current url
|
||||
// set.
|
||||
currentSessionUrls.add(TEST_URL2);
|
||||
|
||||
snapshotPromise = selector.once("snapshots-updated");
|
||||
selector.rebuild();
|
||||
snapshots = await snapshotPromise;
|
||||
|
||||
await assertSnapshotList(snapshots, [{ url: TEST_URL2 }]);
|
||||
});
|
||||
|
|
|
@ -19,7 +19,7 @@ add_task(async function test_interactions_recent() {
|
|||
{ url: TEST_URL3, created_at: now - 3000 },
|
||||
]);
|
||||
|
||||
let selector = new SnapshotSelector({ count: 2 });
|
||||
let selector = new SnapshotSelector(2);
|
||||
|
||||
let snapshotPromise = selector.once("snapshots-updated");
|
||||
selector.rebuild();
|
||||
|
|
|
@ -18,7 +18,7 @@ add_task(async function test_setUrlCoalescing() {
|
|||
{ url: TEST_URL3, created_at: now - 3000 },
|
||||
]);
|
||||
|
||||
let selector = new SnapshotSelector({ count: 2 });
|
||||
let selector = new SnapshotSelector(2);
|
||||
|
||||
let snapshotPromise = selector.once("snapshots-updated");
|
||||
selector.rebuild();
|
||||
|
|
|
@ -39,7 +39,7 @@ add_task(async () => {
|
|||
await Snapshots.add({ url: TEST_URL2 });
|
||||
await Snapshots.add({ url: TEST_URL3 });
|
||||
|
||||
let selector = new SnapshotSelector({ count: 5 });
|
||||
let selector = new SnapshotSelector(5);
|
||||
|
||||
let snapshotPromise = selector.once("snapshots-updated");
|
||||
selector.setUrl(TEST_URL4);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
prefs =
|
||||
browser.places.interactions.enabled=true
|
||||
browser.places.interactions.log=true
|
||||
browser.snapshots.scorer.log=true
|
||||
browser.pagedata.enabled=true
|
||||
browser.pagedata.log=true
|
||||
head = head_interactions.js
|
||||
|
@ -18,8 +17,6 @@ skip-if = toolkit == 'android' # bug 1730213
|
|||
[test_snapshots_pagedata.js]
|
||||
[test_snapshots_page_image.js]
|
||||
[test_snapshots_queries.js]
|
||||
[test_snapshotscorer_combining.js]
|
||||
[test_snapshotscorer.js]
|
||||
[test_snapshotselection_adult.js]
|
||||
[test_snapshotselection_overlapping.js]
|
||||
[test_snapshotselection_recent.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче