diff options
Diffstat (limited to 'toolkit/components/places/tests/unit/test_telemetry.js')
-rw-r--r-- | toolkit/components/places/tests/unit/test_telemetry.js | 166 |
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); + } +}); |