fune/js/xpconnect/tests/marionette/test_preloader_telemetry.py
Henrik Skupin ca1d3a6cb3 Bug 1758909 - Improvements for test_preloader_telemetry.py r=dthayer
This patch allows to correctly await observer notifications by
using the "Execute Async Command" of Marionette which doesn't
return immediately but when resolve() is called.

Further it improves the checks for hits and misses by comparing
numbers and not just booleans. This improves the failure output.

Differential Revision: https://phabricator.services.mozilla.com/D140367
2022-03-10 20:36:34 +00:00

97 lines
3.4 KiB
Python

# Any copyright is dedicated to the Public Domain.
# http://creativecommons.org/publicdomain/zero/1.0/
from __future__ import absolute_import
import time
import os
from marionette_harness import MarionetteTestCase
LABELS_SCRIPT_PRELOADER_REQUESTS = {
"Hit": "0",
"HitChild": "1",
"Miss": "2",
}
class TestScriptPreloader(MarionetteTestCase):
def test_preloader_requests_histogram(self):
start_time = time.time()
self.invalidate_caches()
self.marionette.restart(clean=False, in_app=True)
histogram = self.get_histogram("SCRIPT_PRELOADER_REQUESTS")
misses = histogram.get(LABELS_SCRIPT_PRELOADER_REQUESTS["Miss"], 0)
hits = histogram.get(LABELS_SCRIPT_PRELOADER_REQUESTS["Hit"], 0)
child_hits = histogram.get(LABELS_SCRIPT_PRELOADER_REQUESTS["HitChild"], 0)
self.assertMuchGreaterThan(misses, hits)
self.assertMuchGreaterThan(misses, child_hits)
profile = self.marionette.profile_path
self.wait_for_file_change(
start_time, "{}/startupCache/scriptCache.bin".format(profile)
)
self.wait_for_file_change(
start_time, "{}/startupCache/scriptCache-child.bin".format(profile)
)
self.marionette.restart(clean=False, in_app=True)
histogram = self.get_histogram("SCRIPT_PRELOADER_REQUESTS")
misses = histogram.get(LABELS_SCRIPT_PRELOADER_REQUESTS["Miss"], 0)
hits = histogram.get(LABELS_SCRIPT_PRELOADER_REQUESTS["Hit"], 0)
child_hits = histogram.get(LABELS_SCRIPT_PRELOADER_REQUESTS["HitChild"], 0)
# This is just heuristic. We certainly want to be made aware if this ratio
# changes and we didn't intend it to.
self.assertSimilar(misses, hits)
self.assertNotEqual(child_hits, 0)
def assertMuchGreaterThan(self, lhs, rhs):
self.assertGreater(lhs, 4 * rhs)
def assertSimilar(self, lhs, rhs):
self.assertLess(lhs, 2 * rhs)
self.assertGreater(lhs, rhs / 2)
def wait_for_file_change(self, start_time, path):
expires = time.time() + 20
while True:
try:
if os.stat(path).st_mtime > start_time:
return
except OSError:
pass
if time.time() > expires:
raise Exception("Never observed file change for {}".format(path))
time.sleep(1)
def wait_for_observer_notification(self, name):
with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
return self.marionette.execute_async_script(
"""
const [name, resolve] = arguments;
Services.obs.addObserver(() => resolve(), name);
""",
script_args=(name,),
)
def get_histogram(self, name):
with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
return self.marionette.execute_script(
"""
const name = arguments[0];
const snapshot = Services.telemetry.getSnapshotForHistograms("main", true);
return snapshot.parent[name].values;
""",
script_args=(name,),
)
def invalidate_caches(self):
with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
return self.marionette.execute_script(
"Services.obs.notifyObservers(null, 'startupcache-invalidate');"
)