summaryrefslogtreecommitdiffstats
path: root/toolkit/components/places/tests/unit/test_telemetry.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/places/tests/unit/test_telemetry.js')
-rw-r--r--toolkit/components/places/tests/unit/test_telemetry.js166
1 files changed, 166 insertions, 0 deletions
diff --git a/toolkit/components/places/tests/unit/test_telemetry.js b/toolkit/components/places/tests/unit/test_telemetry.js
new file mode 100644
index 000000000..99f36d78c
--- /dev/null
+++ b/toolkit/components/places/tests/unit/test_telemetry.js
@@ -0,0 +1,166 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Tests common Places telemetry probes by faking the telemetry service.
+
+Components.utils.import("resource://gre/modules/PlacesDBUtils.jsm");
+
+var histograms = {
+ PLACES_PAGES_COUNT: val => do_check_eq(val, 1),
+ PLACES_BOOKMARKS_COUNT: val => do_check_eq(val, 1),
+ PLACES_TAGS_COUNT: val => do_check_eq(val, 1),
+ PLACES_KEYWORDS_COUNT: val => do_check_eq(val, 1),
+ PLACES_SORTED_BOOKMARKS_PERC: val => do_check_eq(val, 100),
+ PLACES_TAGGED_BOOKMARKS_PERC: val => do_check_eq(val, 100),
+ PLACES_DATABASE_FILESIZE_MB: val => do_check_true(val > 0),
+ PLACES_DATABASE_PAGESIZE_B: val => do_check_eq(val, 32768),
+ PLACES_DATABASE_SIZE_PER_PAGE_B: val => do_check_true(val > 0),
+ PLACES_EXPIRATION_STEPS_TO_CLEAN2: val => do_check_true(val > 1),
+ // PLACES_AUTOCOMPLETE_1ST_RESULT_TIME_MS: val => do_check_true(val > 1),
+ PLACES_IDLE_FRECENCY_DECAY_TIME_MS: val => do_check_true(val >= 0),
+ PLACES_IDLE_MAINTENANCE_TIME_MS: val => do_check_true(val > 0),
+ // One from the `setItemAnnotation` call; the other from the mobile root.
+ // This can be removed along with the anno in bug 1306445.
+ PLACES_ANNOS_BOOKMARKS_COUNT: val => do_check_eq(val, 2),
+ PLACES_ANNOS_PAGES_COUNT: val => do_check_eq(val, 1),
+ PLACES_MAINTENANCE_DAYSFROMLAST: val => do_check_true(val >= 0),
+}
+
+/**
+ * Forces an expiration run.
+ *
+ * @param [optional] aLimit
+ * Limit for the expiration. Pass -1 for unlimited.
+ * Any other non-positive value will just expire orphans.
+ *
+ * @return {Promise}
+ * @resolves When expiration finishes.
+ * @rejects Never.
+ */
+function promiseForceExpirationStep(aLimit) {
+ let promise = promiseTopicObserved(PlacesUtils.TOPIC_EXPIRATION_FINISHED);
+ let expire = Cc["@mozilla.org/places/expiration;1"].getService(Ci.nsIObserver);
+ expire.observe(null, "places-debug-start-expiration", aLimit);
+ return promise;
+}
+
+/**
+ * Returns a PRTime in the past usable to add expirable visits.
+ *
+ * param [optional] daysAgo
+ * Expiration ignores any visit added in the last 7 days, so by default
+ * this will be set to 7.
+ * @note to be safe against DST issues we go back one day more.
+ */
+function getExpirablePRTime(daysAgo = 7) {
+ let dateObj = new Date();
+ // Normalize to midnight
+ dateObj.setHours(0);
+ dateObj.setMinutes(0);
+ dateObj.setSeconds(0);
+ dateObj.setMilliseconds(0);
+ dateObj = new Date(dateObj.getTime() - (daysAgo + 1) * 86400000);
+ return dateObj.getTime() * 1000;
+}
+
+add_task(function* test_execute()
+{
+ // Put some trash in the database.
+ let uri = NetUtil.newURI("http://moz.org/");
+
+ let folderId = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId,
+ "moz test",
+ PlacesUtils.bookmarks.DEFAULT_INDEX);
+ let itemId = PlacesUtils.bookmarks.insertBookmark(folderId,
+ uri,
+ PlacesUtils.bookmarks.DEFAULT_INDEX,
+ "moz test");
+ PlacesUtils.tagging.tagURI(uri, ["tag"]);
+ yield PlacesUtils.keywords.insert({ url: uri.spec, keyword: "keyword"});
+
+ // Set a large annotation.
+ let content = "";
+ while (content.length < 1024) {
+ content += "0";
+ }
+ PlacesUtils.annotations.setItemAnnotation(itemId, "test-anno", content, 0,
+ PlacesUtils.annotations.EXPIRE_NEVER);
+ PlacesUtils.annotations.setPageAnnotation(uri, "test-anno", content, 0,
+ PlacesUtils.annotations.EXPIRE_NEVER);
+
+ // Request to gather telemetry data.
+ Cc["@mozilla.org/places/categoriesStarter;1"]
+ .getService(Ci.nsIObserver)
+ .observe(null, "gather-telemetry", null);
+
+ yield PlacesTestUtils.promiseAsyncUpdates();
+
+ // Test expiration probes.
+ let timeInMicroseconds = getExpirablePRTime(8);
+
+ function newTimeInMicroseconds() {
+ timeInMicroseconds = timeInMicroseconds + 1000;
+ return timeInMicroseconds;
+ }
+
+ for (let i = 0; i < 3; i++) {
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://" + i + ".moz.org/"),
+ visitDate: newTimeInMicroseconds()
+ });
+ }
+ Services.prefs.setIntPref("places.history.expiration.max_pages", 0);
+ yield promiseForceExpirationStep(2);
+ yield promiseForceExpirationStep(2);
+
+ // Test autocomplete probes.
+ /*
+ // This is useful for manual testing by changing the minimum time for
+ // autocomplete telemetry to 0, but there is no way to artificially delay
+ // autocomplete by more than 50ms in a realiable way.
+ Services.prefs.setIntPref("browser.urlbar.search.sources", 3);
+ Services.prefs.setIntPref("browser.urlbar.default.behavior", 0);
+ function AutoCompleteInput(aSearches) {
+ this.searches = aSearches;
+ }
+ AutoCompleteInput.prototype = {
+ timeout: 10,
+ textValue: "",
+ searchParam: "",
+ popupOpen: false,
+ minResultsForPopup: 0,
+ invalidate: function() {},
+ disableAutoComplete: false,
+ completeDefaultIndex: false,
+ get popup() { return this; },
+ onSearchBegin: function() {},
+ onSearchComplete: function() {},
+ setSelectedIndex: function() {},
+ get searchCount() { return this.searches.length; },
+ getSearchAt: function(aIndex) { return this.searches[aIndex]; },
+ QueryInterface: XPCOMUtils.generateQI([
+ Ci.nsIAutoCompleteInput,
+ Ci.nsIAutoCompletePopup,
+ ])
+ };
+ let controller = Cc["@mozilla.org/autocomplete/controller;1"].
+ getService(Ci.nsIAutoCompleteController);
+ controller.input = new AutoCompleteInput(["unifiedcomplete"]);
+ controller.startSearch("moz");
+ */
+
+ // Test idle probes.
+ PlacesUtils.history.QueryInterface(Ci.nsIObserver)
+ .observe(null, "idle-daily", null);
+ PlacesDBUtils.maintenanceOnIdle();
+
+ yield promiseTopicObserved("places-maintenance-finished");
+
+ for (let histogramId in histograms) {
+ do_print("checking histogram " + histogramId);
+ let validate = histograms[histogramId];
+ let snapshot = Services.telemetry.getHistogramById(histogramId).snapshot();
+ validate(snapshot.sum);
+ do_check_true(snapshot.counts.reduce((a, b) => a + b) > 0);
+ }
+});