toolkit/components/crashes/tests/xpcshell/test_crash_manager.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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 {classes: Cc, interfaces: Ci, utils: Cu} = Components;
michael@0 7
michael@0 8 let bsp = Cu.import("resource://gre/modules/CrashManager.jsm", this);
michael@0 9 Cu.import("resource://gre/modules/Promise.jsm", this);
michael@0 10 Cu.import("resource://gre/modules/Task.jsm", this);
michael@0 11 Cu.import("resource://gre/modules/osfile.jsm", this);
michael@0 12
michael@0 13 Cu.import("resource://testing-common/CrashManagerTest.jsm", this);
michael@0 14
michael@0 15 const DUMMY_DATE = new Date(Date.now() - 10 * 24 * 60 * 60 * 1000);
michael@0 16 DUMMY_DATE.setMilliseconds(0);
michael@0 17
michael@0 18 function run_test() {
michael@0 19 do_get_profile();
michael@0 20 configureLogging();
michael@0 21 run_next_test();
michael@0 22 }
michael@0 23
michael@0 24 add_task(function* test_constructor_ok() {
michael@0 25 let m = new CrashManager({
michael@0 26 pendingDumpsDir: "/foo",
michael@0 27 submittedDumpsDir: "/bar",
michael@0 28 eventsDirs: [],
michael@0 29 storeDir: "/baz",
michael@0 30 });
michael@0 31 Assert.ok(m, "CrashManager can be created.");
michael@0 32 });
michael@0 33
michael@0 34 add_task(function* test_constructor_invalid() {
michael@0 35 Assert.throws(() => {
michael@0 36 new CrashManager({foo: true});
michael@0 37 });
michael@0 38 });
michael@0 39
michael@0 40 add_task(function* test_get_manager() {
michael@0 41 let m = yield getManager();
michael@0 42 Assert.ok(m, "CrashManager obtained.");
michael@0 43
michael@0 44 yield m.createDummyDump(true);
michael@0 45 yield m.createDummyDump(false);
michael@0 46 });
michael@0 47
michael@0 48 // Unsubmitted dump files on disk are detected properly.
michael@0 49 add_task(function* test_pending_dumps() {
michael@0 50 let m = yield getManager();
michael@0 51 let now = Date.now();
michael@0 52 let ids = [];
michael@0 53 const COUNT = 5;
michael@0 54
michael@0 55 for (let i = 0; i < COUNT; i++) {
michael@0 56 ids.push(yield m.createDummyDump(false, new Date(now - i * 86400000)));
michael@0 57 }
michael@0 58 yield m.createIgnoredDumpFile("ignored", false);
michael@0 59
michael@0 60 let entries = yield m.pendingDumps();
michael@0 61 Assert.equal(entries.length, COUNT, "proper number detected.");
michael@0 62
michael@0 63 for (let entry of entries) {
michael@0 64 Assert.equal(typeof(entry), "object", "entry is an object");
michael@0 65 Assert.ok("id" in entry, "id in entry");
michael@0 66 Assert.ok("path" in entry, "path in entry");
michael@0 67 Assert.ok("date" in entry, "date in entry");
michael@0 68 Assert.notEqual(ids.indexOf(entry.id), -1, "ID is known");
michael@0 69 }
michael@0 70
michael@0 71 for (let i = 0; i < COUNT; i++) {
michael@0 72 Assert.equal(entries[i].id, ids[COUNT-i-1], "Entries sorted by mtime");
michael@0 73 }
michael@0 74 });
michael@0 75
michael@0 76 // Submitted dump files on disk are detected properly.
michael@0 77 add_task(function* test_submitted_dumps() {
michael@0 78 let m = yield getManager();
michael@0 79 let COUNT = 5;
michael@0 80
michael@0 81 for (let i = 0; i < COUNT; i++) {
michael@0 82 yield m.createDummyDump(true);
michael@0 83 }
michael@0 84 yield m.createIgnoredDumpFile("ignored", true);
michael@0 85
michael@0 86 let entries = yield m.submittedDumps();
michael@0 87 Assert.equal(entries.length, COUNT, "proper number detected.");
michael@0 88
michael@0 89 let hrID = yield m.createDummyDump(true, new Date(), true);
michael@0 90 entries = yield m.submittedDumps();
michael@0 91 Assert.equal(entries.length, COUNT + 1, "hr- in filename detected.");
michael@0 92
michael@0 93 let gotIDs = new Set([e.id for (e of entries)]);
michael@0 94 Assert.ok(gotIDs.has(hrID));
michael@0 95 });
michael@0 96
michael@0 97 // The store should expire after inactivity.
michael@0 98 add_task(function* test_store_expires() {
michael@0 99 let m = yield getManager();
michael@0 100
michael@0 101 Object.defineProperty(m, "STORE_EXPIRATION_MS", {
michael@0 102 value: 250,
michael@0 103 });
michael@0 104
michael@0 105 let store = yield m._getStore();
michael@0 106 Assert.ok(store);
michael@0 107 Assert.equal(store, m._store);
michael@0 108
michael@0 109 yield sleep(300);
michael@0 110 Assert.ok(!m._store, "Store has gone away.");
michael@0 111 });
michael@0 112
michael@0 113 // Ensure discovery of unprocessed events files works.
michael@0 114 add_task(function* test_unprocessed_events_files() {
michael@0 115 let m = yield getManager();
michael@0 116 yield m.createEventsFile("1", "test.1", new Date(), "foo", 0);
michael@0 117 yield m.createEventsFile("2", "test.1", new Date(), "bar", 0);
michael@0 118 yield m.createEventsFile("1", "test.1", new Date(), "baz", 1);
michael@0 119
michael@0 120 let paths = yield m._getUnprocessedEventsFiles();
michael@0 121 Assert.equal(paths.length, 3);
michael@0 122 });
michael@0 123
michael@0 124 // Ensure only 1 aggregateEventsFiles() is allowed at a time.
michael@0 125 add_task(function* test_aggregate_events_locking() {
michael@0 126 let m = yield getManager();
michael@0 127
michael@0 128 let p1 = m.aggregateEventsFiles();
michael@0 129 let p2 = m.aggregateEventsFiles();
michael@0 130
michael@0 131 Assert.strictEqual(p1, p2, "Same promise should be returned.");
michael@0 132 });
michael@0 133
michael@0 134 // Malformed events files should be deleted.
michael@0 135 add_task(function* test_malformed_files_deleted() {
michael@0 136 let m = yield getManager();
michael@0 137
michael@0 138 yield m.createEventsFile("1", "crash.main.1", new Date(), "foo\nbar");
michael@0 139
michael@0 140 let count = yield m.aggregateEventsFiles();
michael@0 141 Assert.equal(count, 1);
michael@0 142 let crashes = yield m.getCrashes();
michael@0 143 Assert.equal(crashes.length, 0);
michael@0 144
michael@0 145 count = yield m.aggregateEventsFiles();
michael@0 146 Assert.equal(count, 0);
michael@0 147 });
michael@0 148
michael@0 149 // Unknown event types should be ignored.
michael@0 150 add_task(function* test_aggregate_ignore_unknown_events() {
michael@0 151 let m = yield getManager();
michael@0 152
michael@0 153 yield m.createEventsFile("1", "crash.main.1", DUMMY_DATE, "id1");
michael@0 154 yield m.createEventsFile("2", "foobar.1", new Date(), "dummy");
michael@0 155
michael@0 156 let count = yield m.aggregateEventsFiles();
michael@0 157 Assert.equal(count, 2);
michael@0 158
michael@0 159 count = yield m.aggregateEventsFiles();
michael@0 160 Assert.equal(count, 1);
michael@0 161
michael@0 162 count = yield m.aggregateEventsFiles();
michael@0 163 Assert.equal(count, 1);
michael@0 164 });
michael@0 165
michael@0 166 add_task(function* test_prune_old() {
michael@0 167 let m = yield getManager();
michael@0 168 let oldDate = new Date(Date.now() - 86400000);
michael@0 169 let newDate = new Date(Date.now() - 10000);
michael@0 170 yield m.createEventsFile("1", "crash.main.1", oldDate, "id1");
michael@0 171 yield m.createEventsFile("2", "crash.plugin.1", newDate, "id2");
michael@0 172
michael@0 173 yield m.aggregateEventsFiles();
michael@0 174
michael@0 175 let crashes = yield m.getCrashes();
michael@0 176 Assert.equal(crashes.length, 2);
michael@0 177
michael@0 178 yield m.pruneOldCrashes(new Date(oldDate.getTime() + 10000));
michael@0 179
michael@0 180 crashes = yield m.getCrashes();
michael@0 181 Assert.equal(crashes.length, 1, "Old crash has been pruned.");
michael@0 182
michael@0 183 let c = crashes[0];
michael@0 184 Assert.equal(c.id, "id2", "Proper crash was pruned.");
michael@0 185
michael@0 186 // We can't test exact boundary conditions because dates from filesystem
michael@0 187 // don't have same guarantees as JS dates.
michael@0 188 yield m.pruneOldCrashes(new Date(newDate.getTime() + 5000));
michael@0 189 crashes = yield m.getCrashes();
michael@0 190 Assert.equal(crashes.length, 0);
michael@0 191 });
michael@0 192
michael@0 193 add_task(function* test_schedule_maintenance() {
michael@0 194 let m = yield getManager();
michael@0 195 yield m.createEventsFile("1", "crash.main.1", DUMMY_DATE, "id1");
michael@0 196
michael@0 197 let oldDate = new Date(Date.now() - m.PURGE_OLDER_THAN_DAYS * 2 * 24 * 60 * 60 * 1000);
michael@0 198 yield m.createEventsFile("2", "crash.main.1", oldDate, "id2");
michael@0 199
michael@0 200 yield m.scheduleMaintenance(25);
michael@0 201 let crashes = yield m.getCrashes();
michael@0 202 Assert.equal(crashes.length, 1);
michael@0 203 Assert.equal(crashes[0].id, "id1");
michael@0 204 });
michael@0 205
michael@0 206 add_task(function* test_main_crash_event_file() {
michael@0 207 let m = yield getManager();
michael@0 208 yield m.createEventsFile("1", "crash.main.1", DUMMY_DATE, "id1");
michael@0 209 let count = yield m.aggregateEventsFiles();
michael@0 210 Assert.equal(count, 1);
michael@0 211
michael@0 212 let crashes = yield m.getCrashes();
michael@0 213 Assert.equal(crashes.length, 1);
michael@0 214 Assert.equal(crashes[0].id, "id1");
michael@0 215 Assert.equal(crashes[0].type, "main-crash");
michael@0 216 Assert.deepEqual(crashes[0].crashDate, DUMMY_DATE);
michael@0 217
michael@0 218 count = yield m.aggregateEventsFiles();
michael@0 219 Assert.equal(count, 0);
michael@0 220 });
michael@0 221
michael@0 222 add_task(function* test_multiline_crash_id_rejected() {
michael@0 223 let m = yield getManager();
michael@0 224 yield m.createEventsFile("1", "crash.main.1", DUMMY_DATE, "id1\nid2");
michael@0 225 yield m.aggregateEventsFiles();
michael@0 226 let crashes = yield m.getCrashes();
michael@0 227 Assert.equal(crashes.length, 0);
michael@0 228 });
michael@0 229
michael@0 230 add_task(function* test_plugin_crash_event_file() {
michael@0 231 let m = yield getManager();
michael@0 232 yield m.createEventsFile("1", "crash.plugin.1", DUMMY_DATE, "id1");
michael@0 233 let count = yield m.aggregateEventsFiles();
michael@0 234 Assert.equal(count, 1);
michael@0 235
michael@0 236 let crashes = yield m.getCrashes();
michael@0 237 Assert.equal(crashes.length, 1);
michael@0 238 Assert.equal(crashes[0].id, "id1");
michael@0 239 Assert.equal(crashes[0].type, "plugin-crash");
michael@0 240 Assert.deepEqual(crashes[0].crashDate, DUMMY_DATE);
michael@0 241
michael@0 242 count = yield m.aggregateEventsFiles();
michael@0 243 Assert.equal(count, 0);
michael@0 244 });
michael@0 245
michael@0 246 add_task(function* test_plugin_hang_event_file() {
michael@0 247 let m = yield getManager();
michael@0 248 yield m.createEventsFile("1", "hang.plugin.1", DUMMY_DATE, "id1");
michael@0 249 let count = yield m.aggregateEventsFiles();
michael@0 250 Assert.equal(count, 1);
michael@0 251
michael@0 252 let crashes = yield m.getCrashes();
michael@0 253 Assert.equal(crashes.length, 1);
michael@0 254 Assert.equal(crashes[0].id, "id1");
michael@0 255 Assert.equal(crashes[0].type, "plugin-hang");
michael@0 256 Assert.deepEqual(crashes[0].crashDate, DUMMY_DATE);
michael@0 257
michael@0 258 count = yield m.aggregateEventsFiles();
michael@0 259 Assert.equal(count, 0);
michael@0 260 });
michael@0 261
michael@0 262 // Excessive amounts of files should be processed properly.
michael@0 263 add_task(function* test_high_water_mark() {
michael@0 264 let m = yield getManager();
michael@0 265
michael@0 266 let store = yield m._getStore();
michael@0 267
michael@0 268 for (let i = 0; i < store.HIGH_WATER_DAILY_THRESHOLD + 1; i++) {
michael@0 269 yield m.createEventsFile("m" + i, "crash.main.1", DUMMY_DATE, "m" + i);
michael@0 270 yield m.createEventsFile("pc" + i, "crash.plugin.1", DUMMY_DATE, "pc" + i);
michael@0 271 yield m.createEventsFile("ph" + i, "hang.plugin.1", DUMMY_DATE, "ph" + i);
michael@0 272 }
michael@0 273
michael@0 274 let count = yield m.aggregateEventsFiles();
michael@0 275 Assert.equal(count, 3 * bsp.CrashStore.prototype.HIGH_WATER_DAILY_THRESHOLD + 3);
michael@0 276
michael@0 277 // Need to fetch again in case the first one was garbage collected.
michael@0 278 store = yield m._getStore();
michael@0 279 // +1 is for preserved main process crash.
michael@0 280 Assert.equal(store.crashesCount, 3 * store.HIGH_WATER_DAILY_THRESHOLD + 1);
michael@0 281 });

mercurial