1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/services/healthreport/tests/xpcshell/test_provider_sessions.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,217 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + * http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +"use strict"; 1.8 + 1.9 +const {utils: Cu} = Components; 1.10 + 1.11 + 1.12 +Cu.import("resource://gre/modules/Promise.jsm"); 1.13 +Cu.import("resource://gre/modules/Metrics.jsm"); 1.14 +Cu.import("resource://gre/modules/Task.jsm"); 1.15 +Cu.import("resource://gre/modules/services-common/utils.js"); 1.16 +Cu.import("resource://gre/modules/services/datareporting/sessions.jsm"); 1.17 +Cu.import("resource://gre/modules/services/healthreport/providers.jsm"); 1.18 + 1.19 + 1.20 +function run_test() { 1.21 + run_next_test(); 1.22 +} 1.23 + 1.24 +add_test(function test_constructor() { 1.25 + let provider = new SessionsProvider(); 1.26 + 1.27 + run_next_test(); 1.28 +}); 1.29 + 1.30 +add_task(function test_init() { 1.31 + let storage = yield Metrics.Storage("init"); 1.32 + let provider = new SessionsProvider(); 1.33 + yield provider.init(storage); 1.34 + yield provider.shutdown(); 1.35 + 1.36 + yield storage.close(); 1.37 +}); 1.38 + 1.39 +function monkeypatchStartupInfo(recorder, start=new Date(), offset=500) { 1.40 + Object.defineProperty(recorder, "_getStartupInfo", { 1.41 + value: function _getStartupInfo() { 1.42 + return { 1.43 + process: start, 1.44 + main: new Date(start.getTime() + offset), 1.45 + firstPaint: new Date(start.getTime() + 2 * offset), 1.46 + sessionRestored: new Date(start.getTime() + 3 * offset), 1.47 + }; 1.48 + } 1.49 + }); 1.50 +} 1.51 + 1.52 +function sleep(wait) { 1.53 + let deferred = Promise.defer(); 1.54 + 1.55 + let timer = CommonUtils.namedTimer(function onTimer() { 1.56 + deferred.resolve(); 1.57 + }, wait, deferred.promise, "_sleepTimer"); 1.58 + 1.59 + return deferred.promise; 1.60 +} 1.61 + 1.62 +function getProvider(name, now=new Date(), init=true) { 1.63 + return Task.spawn(function () { 1.64 + let storage = yield Metrics.Storage(name); 1.65 + let provider = new SessionsProvider(); 1.66 + 1.67 + let recorder = new SessionRecorder("testing." + name + ".sessions."); 1.68 + monkeypatchStartupInfo(recorder, now); 1.69 + provider.healthReporter = {sessionRecorder: recorder}; 1.70 + recorder.onStartup(); 1.71 + 1.72 + if (init) { 1.73 + yield provider.init(storage); 1.74 + } 1.75 + 1.76 + throw new Task.Result([provider, storage, recorder]); 1.77 + }); 1.78 +} 1.79 + 1.80 +add_task(function test_current_session() { 1.81 + let now = new Date(); 1.82 + let [provider, storage, recorder] = yield getProvider("current_session", now); 1.83 + 1.84 + yield sleep(25); 1.85 + recorder.onActivity(true); 1.86 + 1.87 + let current = provider.getMeasurement("current", 3); 1.88 + let values = yield current.getValues(); 1.89 + let fields = values.singular; 1.90 + 1.91 + for (let field of ["startDay", "activeTicks", "totalTime", "main", "firstPaint", "sessionRestored"]) { 1.92 + do_check_true(fields.has(field)); 1.93 + } 1.94 + 1.95 + do_check_eq(fields.get("startDay")[1], Metrics.dateToDays(now)); 1.96 + do_check_eq(fields.get("totalTime")[1], recorder.totalTime); 1.97 + do_check_eq(fields.get("activeTicks")[1], 1); 1.98 + do_check_eq(fields.get("main")[1], 500); 1.99 + do_check_eq(fields.get("firstPaint")[1], 1000); 1.100 + do_check_eq(fields.get("sessionRestored")[1], 1500); 1.101 + 1.102 + yield provider.shutdown(); 1.103 + yield storage.close(); 1.104 +}); 1.105 + 1.106 +add_task(function test_collect() { 1.107 + let now = new Date(); 1.108 + let [provider, storage, recorder] = yield getProvider("collect"); 1.109 + 1.110 + recorder.onShutdown(); 1.111 + yield sleep(25); 1.112 + 1.113 + for (let i = 0; i < 5; i++) { 1.114 + let recorder2 = new SessionRecorder("testing.collect.sessions."); 1.115 + recorder2.onStartup(); 1.116 + yield sleep(25); 1.117 + recorder2.onShutdown(); 1.118 + yield sleep(25); 1.119 + } 1.120 + 1.121 + recorder = new SessionRecorder("testing.collect.sessions."); 1.122 + recorder.onStartup(); 1.123 + 1.124 + // Collecting the provider should prune all previous sessions. 1.125 + let sessions = recorder.getPreviousSessions(); 1.126 + do_check_eq(Object.keys(sessions).length, 6); 1.127 + yield provider.collectConstantData(); 1.128 + sessions = recorder.getPreviousSessions(); 1.129 + do_check_eq(Object.keys(sessions).length, 0); 1.130 + 1.131 + // And those previous sessions should make it to storage. 1.132 + let daily = provider.getMeasurement("previous", 3); 1.133 + let values = yield daily.getValues(); 1.134 + do_check_true(values.days.hasDay(now)); 1.135 + do_check_eq(values.days.size, 1); 1.136 + let day = values.days.getDay(now); 1.137 + do_check_eq(day.size, 5); 1.138 + let previousStorageCount = day.get("main").length; 1.139 + 1.140 + for (let field of ["cleanActiveTicks", "cleanTotalTime", "main", "firstPaint", "sessionRestored"]) { 1.141 + do_check_true(day.has(field)); 1.142 + do_check_true(Array.isArray(day.get(field))); 1.143 + do_check_eq(day.get(field).length, 6); 1.144 + } 1.145 + 1.146 + let lastIndex = yield provider.getState("lastSession"); 1.147 + do_check_eq(lastIndex, "" + (previousStorageCount - 1)); // 0-indexed 1.148 + 1.149 + // Fake an aborted session. If we create a 2nd recorder against the same 1.150 + // prefs branch as a running one, this simulates what would happen if the 1.151 + // first recorder didn't shut down. 1.152 + let recorder2 = new SessionRecorder("testing.collect.sessions."); 1.153 + recorder2.onStartup(); 1.154 + do_check_eq(Object.keys(recorder.getPreviousSessions()).length, 1); 1.155 + yield provider.collectConstantData(); 1.156 + do_check_eq(Object.keys(recorder.getPreviousSessions()).length, 0); 1.157 + 1.158 + values = yield daily.getValues(); 1.159 + day = values.days.getDay(now); 1.160 + do_check_eq(day.size, previousStorageCount + 1); 1.161 + previousStorageCount = day.get("main").length; 1.162 + for (let field of ["abortedActiveTicks", "abortedTotalTime"]) { 1.163 + do_check_true(day.has(field)); 1.164 + do_check_true(Array.isArray(day.get(field))); 1.165 + do_check_eq(day.get(field).length, 1); 1.166 + } 1.167 + 1.168 + lastIndex = yield provider.getState("lastSession"); 1.169 + do_check_eq(lastIndex, "" + (previousStorageCount - 1)); 1.170 + 1.171 + recorder.onShutdown(); 1.172 + recorder2.onShutdown(); 1.173 + 1.174 + // If we try to insert a already-inserted session, it will be ignored. 1.175 + recorder = new SessionRecorder("testing.collect.sessions."); 1.176 + recorder._currentIndex = recorder._currentIndex - 1; 1.177 + recorder._prunedIndex = recorder._currentIndex; 1.178 + recorder.onStartup(); 1.179 + // Session is left over from recorder2. 1.180 + sessions = recorder.getPreviousSessions(); 1.181 + do_check_eq(Object.keys(sessions).length, 1); 1.182 + do_check_true(previousStorageCount - 1 in sessions); 1.183 + yield provider.collectConstantData(); 1.184 + lastIndex = yield provider.getState("lastSession"); 1.185 + do_check_eq(lastIndex, "" + (previousStorageCount - 1)); 1.186 + values = yield daily.getValues(); 1.187 + day = values.days.getDay(now); 1.188 + // We should not get additional entry. 1.189 + do_check_eq(day.get("main").length, previousStorageCount); 1.190 + recorder.onShutdown(); 1.191 + 1.192 + yield provider.shutdown(); 1.193 + yield storage.close(); 1.194 +}); 1.195 + 1.196 +add_task(function test_serialization() { 1.197 + let [provider, storage, recorder] = yield getProvider("serialization"); 1.198 + 1.199 + yield sleep(1025); 1.200 + recorder.onActivity(true); 1.201 + 1.202 + let current = provider.getMeasurement("current", 3); 1.203 + let data = yield current.getValues(); 1.204 + do_check_true("singular" in data); 1.205 + 1.206 + let serializer = current.serializer(current.SERIALIZE_JSON); 1.207 + let fields = serializer.singular(data.singular); 1.208 + 1.209 + do_check_eq(fields._v, 3); 1.210 + do_check_eq(fields.activeTicks, 1); 1.211 + do_check_eq(fields.startDay, Metrics.dateToDays(recorder.startDate)); 1.212 + do_check_eq(fields.main, 500); 1.213 + do_check_eq(fields.firstPaint, 1000); 1.214 + do_check_eq(fields.sessionRestored, 1500); 1.215 + do_check_true(fields.totalTime > 0); 1.216 + 1.217 + yield provider.shutdown(); 1.218 + yield storage.close(); 1.219 +}); 1.220 +