Wed, 31 Dec 2014 07:53:36 +0100
Correct small whitespace inconsistency, lost while renaming variables.
michael@0 | 1 | /* Any copyright is dedicated to the Public Domain. |
michael@0 | 2 | * http://creativecommons.org/publicdomain/zero/1.0/ */ |
michael@0 | 3 | |
michael@0 | 4 | "use strict"; |
michael@0 | 5 | |
michael@0 | 6 | const {utils: Cu} = Components; |
michael@0 | 7 | |
michael@0 | 8 | |
michael@0 | 9 | Cu.import("resource://gre/modules/Promise.jsm"); |
michael@0 | 10 | Cu.import("resource://gre/modules/Metrics.jsm"); |
michael@0 | 11 | Cu.import("resource://gre/modules/Task.jsm"); |
michael@0 | 12 | Cu.import("resource://gre/modules/services-common/utils.js"); |
michael@0 | 13 | Cu.import("resource://gre/modules/services/datareporting/sessions.jsm"); |
michael@0 | 14 | Cu.import("resource://gre/modules/services/healthreport/providers.jsm"); |
michael@0 | 15 | |
michael@0 | 16 | |
michael@0 | 17 | function run_test() { |
michael@0 | 18 | run_next_test(); |
michael@0 | 19 | } |
michael@0 | 20 | |
michael@0 | 21 | add_test(function test_constructor() { |
michael@0 | 22 | let provider = new SessionsProvider(); |
michael@0 | 23 | |
michael@0 | 24 | run_next_test(); |
michael@0 | 25 | }); |
michael@0 | 26 | |
michael@0 | 27 | add_task(function test_init() { |
michael@0 | 28 | let storage = yield Metrics.Storage("init"); |
michael@0 | 29 | let provider = new SessionsProvider(); |
michael@0 | 30 | yield provider.init(storage); |
michael@0 | 31 | yield provider.shutdown(); |
michael@0 | 32 | |
michael@0 | 33 | yield storage.close(); |
michael@0 | 34 | }); |
michael@0 | 35 | |
michael@0 | 36 | function monkeypatchStartupInfo(recorder, start=new Date(), offset=500) { |
michael@0 | 37 | Object.defineProperty(recorder, "_getStartupInfo", { |
michael@0 | 38 | value: function _getStartupInfo() { |
michael@0 | 39 | return { |
michael@0 | 40 | process: start, |
michael@0 | 41 | main: new Date(start.getTime() + offset), |
michael@0 | 42 | firstPaint: new Date(start.getTime() + 2 * offset), |
michael@0 | 43 | sessionRestored: new Date(start.getTime() + 3 * offset), |
michael@0 | 44 | }; |
michael@0 | 45 | } |
michael@0 | 46 | }); |
michael@0 | 47 | } |
michael@0 | 48 | |
michael@0 | 49 | function sleep(wait) { |
michael@0 | 50 | let deferred = Promise.defer(); |
michael@0 | 51 | |
michael@0 | 52 | let timer = CommonUtils.namedTimer(function onTimer() { |
michael@0 | 53 | deferred.resolve(); |
michael@0 | 54 | }, wait, deferred.promise, "_sleepTimer"); |
michael@0 | 55 | |
michael@0 | 56 | return deferred.promise; |
michael@0 | 57 | } |
michael@0 | 58 | |
michael@0 | 59 | function getProvider(name, now=new Date(), init=true) { |
michael@0 | 60 | return Task.spawn(function () { |
michael@0 | 61 | let storage = yield Metrics.Storage(name); |
michael@0 | 62 | let provider = new SessionsProvider(); |
michael@0 | 63 | |
michael@0 | 64 | let recorder = new SessionRecorder("testing." + name + ".sessions."); |
michael@0 | 65 | monkeypatchStartupInfo(recorder, now); |
michael@0 | 66 | provider.healthReporter = {sessionRecorder: recorder}; |
michael@0 | 67 | recorder.onStartup(); |
michael@0 | 68 | |
michael@0 | 69 | if (init) { |
michael@0 | 70 | yield provider.init(storage); |
michael@0 | 71 | } |
michael@0 | 72 | |
michael@0 | 73 | throw new Task.Result([provider, storage, recorder]); |
michael@0 | 74 | }); |
michael@0 | 75 | } |
michael@0 | 76 | |
michael@0 | 77 | add_task(function test_current_session() { |
michael@0 | 78 | let now = new Date(); |
michael@0 | 79 | let [provider, storage, recorder] = yield getProvider("current_session", now); |
michael@0 | 80 | |
michael@0 | 81 | yield sleep(25); |
michael@0 | 82 | recorder.onActivity(true); |
michael@0 | 83 | |
michael@0 | 84 | let current = provider.getMeasurement("current", 3); |
michael@0 | 85 | let values = yield current.getValues(); |
michael@0 | 86 | let fields = values.singular; |
michael@0 | 87 | |
michael@0 | 88 | for (let field of ["startDay", "activeTicks", "totalTime", "main", "firstPaint", "sessionRestored"]) { |
michael@0 | 89 | do_check_true(fields.has(field)); |
michael@0 | 90 | } |
michael@0 | 91 | |
michael@0 | 92 | do_check_eq(fields.get("startDay")[1], Metrics.dateToDays(now)); |
michael@0 | 93 | do_check_eq(fields.get("totalTime")[1], recorder.totalTime); |
michael@0 | 94 | do_check_eq(fields.get("activeTicks")[1], 1); |
michael@0 | 95 | do_check_eq(fields.get("main")[1], 500); |
michael@0 | 96 | do_check_eq(fields.get("firstPaint")[1], 1000); |
michael@0 | 97 | do_check_eq(fields.get("sessionRestored")[1], 1500); |
michael@0 | 98 | |
michael@0 | 99 | yield provider.shutdown(); |
michael@0 | 100 | yield storage.close(); |
michael@0 | 101 | }); |
michael@0 | 102 | |
michael@0 | 103 | add_task(function test_collect() { |
michael@0 | 104 | let now = new Date(); |
michael@0 | 105 | let [provider, storage, recorder] = yield getProvider("collect"); |
michael@0 | 106 | |
michael@0 | 107 | recorder.onShutdown(); |
michael@0 | 108 | yield sleep(25); |
michael@0 | 109 | |
michael@0 | 110 | for (let i = 0; i < 5; i++) { |
michael@0 | 111 | let recorder2 = new SessionRecorder("testing.collect.sessions."); |
michael@0 | 112 | recorder2.onStartup(); |
michael@0 | 113 | yield sleep(25); |
michael@0 | 114 | recorder2.onShutdown(); |
michael@0 | 115 | yield sleep(25); |
michael@0 | 116 | } |
michael@0 | 117 | |
michael@0 | 118 | recorder = new SessionRecorder("testing.collect.sessions."); |
michael@0 | 119 | recorder.onStartup(); |
michael@0 | 120 | |
michael@0 | 121 | // Collecting the provider should prune all previous sessions. |
michael@0 | 122 | let sessions = recorder.getPreviousSessions(); |
michael@0 | 123 | do_check_eq(Object.keys(sessions).length, 6); |
michael@0 | 124 | yield provider.collectConstantData(); |
michael@0 | 125 | sessions = recorder.getPreviousSessions(); |
michael@0 | 126 | do_check_eq(Object.keys(sessions).length, 0); |
michael@0 | 127 | |
michael@0 | 128 | // And those previous sessions should make it to storage. |
michael@0 | 129 | let daily = provider.getMeasurement("previous", 3); |
michael@0 | 130 | let values = yield daily.getValues(); |
michael@0 | 131 | do_check_true(values.days.hasDay(now)); |
michael@0 | 132 | do_check_eq(values.days.size, 1); |
michael@0 | 133 | let day = values.days.getDay(now); |
michael@0 | 134 | do_check_eq(day.size, 5); |
michael@0 | 135 | let previousStorageCount = day.get("main").length; |
michael@0 | 136 | |
michael@0 | 137 | for (let field of ["cleanActiveTicks", "cleanTotalTime", "main", "firstPaint", "sessionRestored"]) { |
michael@0 | 138 | do_check_true(day.has(field)); |
michael@0 | 139 | do_check_true(Array.isArray(day.get(field))); |
michael@0 | 140 | do_check_eq(day.get(field).length, 6); |
michael@0 | 141 | } |
michael@0 | 142 | |
michael@0 | 143 | let lastIndex = yield provider.getState("lastSession"); |
michael@0 | 144 | do_check_eq(lastIndex, "" + (previousStorageCount - 1)); // 0-indexed |
michael@0 | 145 | |
michael@0 | 146 | // Fake an aborted session. If we create a 2nd recorder against the same |
michael@0 | 147 | // prefs branch as a running one, this simulates what would happen if the |
michael@0 | 148 | // first recorder didn't shut down. |
michael@0 | 149 | let recorder2 = new SessionRecorder("testing.collect.sessions."); |
michael@0 | 150 | recorder2.onStartup(); |
michael@0 | 151 | do_check_eq(Object.keys(recorder.getPreviousSessions()).length, 1); |
michael@0 | 152 | yield provider.collectConstantData(); |
michael@0 | 153 | do_check_eq(Object.keys(recorder.getPreviousSessions()).length, 0); |
michael@0 | 154 | |
michael@0 | 155 | values = yield daily.getValues(); |
michael@0 | 156 | day = values.days.getDay(now); |
michael@0 | 157 | do_check_eq(day.size, previousStorageCount + 1); |
michael@0 | 158 | previousStorageCount = day.get("main").length; |
michael@0 | 159 | for (let field of ["abortedActiveTicks", "abortedTotalTime"]) { |
michael@0 | 160 | do_check_true(day.has(field)); |
michael@0 | 161 | do_check_true(Array.isArray(day.get(field))); |
michael@0 | 162 | do_check_eq(day.get(field).length, 1); |
michael@0 | 163 | } |
michael@0 | 164 | |
michael@0 | 165 | lastIndex = yield provider.getState("lastSession"); |
michael@0 | 166 | do_check_eq(lastIndex, "" + (previousStorageCount - 1)); |
michael@0 | 167 | |
michael@0 | 168 | recorder.onShutdown(); |
michael@0 | 169 | recorder2.onShutdown(); |
michael@0 | 170 | |
michael@0 | 171 | // If we try to insert a already-inserted session, it will be ignored. |
michael@0 | 172 | recorder = new SessionRecorder("testing.collect.sessions."); |
michael@0 | 173 | recorder._currentIndex = recorder._currentIndex - 1; |
michael@0 | 174 | recorder._prunedIndex = recorder._currentIndex; |
michael@0 | 175 | recorder.onStartup(); |
michael@0 | 176 | // Session is left over from recorder2. |
michael@0 | 177 | sessions = recorder.getPreviousSessions(); |
michael@0 | 178 | do_check_eq(Object.keys(sessions).length, 1); |
michael@0 | 179 | do_check_true(previousStorageCount - 1 in sessions); |
michael@0 | 180 | yield provider.collectConstantData(); |
michael@0 | 181 | lastIndex = yield provider.getState("lastSession"); |
michael@0 | 182 | do_check_eq(lastIndex, "" + (previousStorageCount - 1)); |
michael@0 | 183 | values = yield daily.getValues(); |
michael@0 | 184 | day = values.days.getDay(now); |
michael@0 | 185 | // We should not get additional entry. |
michael@0 | 186 | do_check_eq(day.get("main").length, previousStorageCount); |
michael@0 | 187 | recorder.onShutdown(); |
michael@0 | 188 | |
michael@0 | 189 | yield provider.shutdown(); |
michael@0 | 190 | yield storage.close(); |
michael@0 | 191 | }); |
michael@0 | 192 | |
michael@0 | 193 | add_task(function test_serialization() { |
michael@0 | 194 | let [provider, storage, recorder] = yield getProvider("serialization"); |
michael@0 | 195 | |
michael@0 | 196 | yield sleep(1025); |
michael@0 | 197 | recorder.onActivity(true); |
michael@0 | 198 | |
michael@0 | 199 | let current = provider.getMeasurement("current", 3); |
michael@0 | 200 | let data = yield current.getValues(); |
michael@0 | 201 | do_check_true("singular" in data); |
michael@0 | 202 | |
michael@0 | 203 | let serializer = current.serializer(current.SERIALIZE_JSON); |
michael@0 | 204 | let fields = serializer.singular(data.singular); |
michael@0 | 205 | |
michael@0 | 206 | do_check_eq(fields._v, 3); |
michael@0 | 207 | do_check_eq(fields.activeTicks, 1); |
michael@0 | 208 | do_check_eq(fields.startDay, Metrics.dateToDays(recorder.startDate)); |
michael@0 | 209 | do_check_eq(fields.main, 500); |
michael@0 | 210 | do_check_eq(fields.firstPaint, 1000); |
michael@0 | 211 | do_check_eq(fields.sessionRestored, 1500); |
michael@0 | 212 | do_check_true(fields.totalTime > 0); |
michael@0 | 213 | |
michael@0 | 214 | yield provider.shutdown(); |
michael@0 | 215 | yield storage.close(); |
michael@0 | 216 | }); |
michael@0 | 217 |