1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/crashes/tests/xpcshell/test_crash_store.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,231 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + * http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +/* 1.8 + * This file tests the CrashStore type in CrashManager.jsm. 1.9 + */ 1.10 + 1.11 +"use strict"; 1.12 + 1.13 +const {classes: Cc, interfaces: Ci, utils: Cu} = Components; 1.14 + 1.15 +let bsp = Cu.import("resource://gre/modules/CrashManager.jsm", this); 1.16 +Cu.import("resource://gre/modules/osfile.jsm", this); 1.17 +Cu.import("resource://gre/modules/Task.jsm", this); 1.18 + 1.19 +const CrashStore = bsp.CrashStore; 1.20 + 1.21 +let STORE_DIR_COUNT = 0; 1.22 + 1.23 +function getStore() { 1.24 + return Task.spawn(function* () { 1.25 + let storeDir = do_get_tempdir().path; 1.26 + storeDir = OS.Path.join(storeDir, "store-" + STORE_DIR_COUNT++); 1.27 + 1.28 + yield OS.File.makeDir(storeDir, {unixMode: OS.Constants.libc.S_IRWXU}); 1.29 + 1.30 + let s = new CrashStore(storeDir); 1.31 + yield s.load(); 1.32 + 1.33 + return s; 1.34 + }); 1.35 +} 1.36 + 1.37 +function run_test() { 1.38 + run_next_test(); 1.39 +} 1.40 + 1.41 +add_task(function* test_constructor() { 1.42 + let s = new CrashStore("/some/path"); 1.43 + Assert.ok(s instanceof CrashStore); 1.44 +}); 1.45 + 1.46 +add_task(function test_add_crash() { 1.47 + let s = yield getStore(); 1.48 + 1.49 + Assert.equal(s.crashesCount, 0); 1.50 + let d = new Date(Date.now() - 5000); 1.51 + s.addMainProcessCrash("id1", d); 1.52 + 1.53 + Assert.equal(s.crashesCount, 1); 1.54 + 1.55 + let crashes = s.crashes; 1.56 + Assert.equal(crashes.length, 1); 1.57 + let c = crashes[0]; 1.58 + 1.59 + Assert.equal(c.id, "id1", "ID set properly."); 1.60 + Assert.equal(c.crashDate.getTime(), d.getTime(), "Date set."); 1.61 + 1.62 + s.addMainProcessCrash("id2", new Date()); 1.63 + Assert.equal(s.crashesCount, 2); 1.64 +}); 1.65 + 1.66 +add_task(function test_save_load() { 1.67 + let s = yield getStore(); 1.68 + 1.69 + yield s.save(); 1.70 + 1.71 + let d1 = new Date(); 1.72 + let d2 = new Date(d1.getTime() - 10000); 1.73 + s.addMainProcessCrash("id1", d1); 1.74 + s.addMainProcessCrash("id2", d2); 1.75 + 1.76 + yield s.save(); 1.77 + 1.78 + yield s.load(); 1.79 + Assert.ok(!s.corruptDate); 1.80 + let crashes = s.crashes; 1.81 + 1.82 + Assert.equal(crashes.length, 2); 1.83 + let c = s.getCrash("id1"); 1.84 + Assert.equal(c.crashDate.getTime(), d1.getTime()); 1.85 +}); 1.86 + 1.87 +add_task(function test_corrupt_json() { 1.88 + let s = yield getStore(); 1.89 + 1.90 + let buffer = new TextEncoder().encode("{bad: json-file"); 1.91 + yield OS.File.writeAtomic(s._storePath, buffer, {compression: "lz4"}); 1.92 + 1.93 + yield s.load(); 1.94 + Assert.ok(s.corruptDate, "Corrupt date is defined."); 1.95 + 1.96 + let date = s.corruptDate; 1.97 + yield s.save(); 1.98 + s._data = null; 1.99 + yield s.load(); 1.100 + Assert.ok(s.corruptDate); 1.101 + Assert.equal(date.getTime(), s.corruptDate.getTime()); 1.102 +}); 1.103 + 1.104 +add_task(function* test_add_main_crash() { 1.105 + let s = yield getStore(); 1.106 + 1.107 + s.addMainProcessCrash("id1", new Date()); 1.108 + Assert.equal(s.crashesCount, 1); 1.109 + 1.110 + let c = s.crashes[0]; 1.111 + Assert.ok(c.crashDate); 1.112 + Assert.equal(c.type, bsp.CrashStore.prototype.TYPE_MAIN_CRASH); 1.113 + Assert.ok(c.isMainProcessCrash); 1.114 + 1.115 + s.addMainProcessCrash("id2", new Date()); 1.116 + Assert.equal(s.crashesCount, 2); 1.117 + 1.118 + // Duplicate. 1.119 + s.addMainProcessCrash("id1", new Date()); 1.120 + Assert.equal(s.crashesCount, 2); 1.121 + 1.122 + Assert.equal(s.mainProcessCrashes.length, 2); 1.123 +}); 1.124 + 1.125 +add_task(function* test_add_plugin_crash() { 1.126 + let s = yield getStore(); 1.127 + 1.128 + s.addPluginCrash("id1", new Date()); 1.129 + Assert.equal(s.crashesCount, 1); 1.130 + 1.131 + let c = s.crashes[0]; 1.132 + Assert.ok(c.crashDate); 1.133 + Assert.equal(c.type, bsp.CrashStore.prototype.TYPE_PLUGIN_CRASH); 1.134 + Assert.ok(c.isPluginCrash); 1.135 + 1.136 + s.addPluginCrash("id2", new Date()); 1.137 + Assert.equal(s.crashesCount, 2); 1.138 + 1.139 + s.addPluginCrash("id1", new Date()); 1.140 + Assert.equal(s.crashesCount, 2); 1.141 + 1.142 + Assert.equal(s.pluginCrashes.length, 2); 1.143 +}); 1.144 + 1.145 +add_task(function* test_add_plugin_hang() { 1.146 + let s = yield getStore(); 1.147 + 1.148 + s.addPluginHang("id1", new Date()); 1.149 + Assert.equal(s.crashesCount, 1); 1.150 + 1.151 + let c = s.crashes[0]; 1.152 + Assert.ok(c.crashDate); 1.153 + Assert.equal(c.type, bsp.CrashStore.prototype.TYPE_PLUGIN_HANG); 1.154 + Assert.ok(c.isPluginHang); 1.155 + 1.156 + s.addPluginHang("id2", new Date()); 1.157 + Assert.equal(s.crashesCount, 2); 1.158 + 1.159 + s.addPluginHang("id1", new Date()); 1.160 + Assert.equal(s.crashesCount, 2); 1.161 + 1.162 + Assert.equal(s.pluginHangs.length, 2); 1.163 +}); 1.164 + 1.165 +add_task(function* test_add_mixed_types() { 1.166 + let s = yield getStore(); 1.167 + 1.168 + s.addMainProcessCrash("main", new Date()); 1.169 + s.addPluginCrash("pcrash", new Date()); 1.170 + s.addPluginHang("phang", new Date()); 1.171 + 1.172 + Assert.equal(s.crashesCount, 3); 1.173 + 1.174 + yield s.save(); 1.175 + 1.176 + s._data.crashes.clear(); 1.177 + Assert.equal(s.crashesCount, 0); 1.178 + 1.179 + yield s.load(); 1.180 + 1.181 + Assert.equal(s.crashesCount, 3); 1.182 + 1.183 + Assert.equal(s.mainProcessCrashes.length, 1); 1.184 + Assert.equal(s.pluginCrashes.length, 1); 1.185 + Assert.equal(s.pluginHangs.length, 1); 1.186 +}); 1.187 + 1.188 +// Crashes added beyond the high water mark behave properly. 1.189 +add_task(function* test_high_water() { 1.190 + let s = yield getStore(); 1.191 + 1.192 + let d1 = new Date(2014, 0, 1, 0, 0, 0); 1.193 + let d2 = new Date(2014, 0, 2, 0, 0, 0); 1.194 + 1.195 + for (let i = 0; i < s.HIGH_WATER_DAILY_THRESHOLD + 1; i++) { 1.196 + s.addMainProcessCrash("m1" + i, d1); 1.197 + s.addMainProcessCrash("m2" + i, d2); 1.198 + s.addPluginCrash("pc1" + i, d1); 1.199 + s.addPluginCrash("pc2" + i, d2); 1.200 + s.addPluginHang("ph1" + i, d1); 1.201 + s.addPluginHang("ph2" + i, d2); 1.202 + } 1.203 + 1.204 + // We preserve main process crashes. Plugin crashes and hangs beyond should 1.205 + // be discarded. 1.206 + Assert.equal(s.crashesCount, 6 * s.HIGH_WATER_DAILY_THRESHOLD + 2); 1.207 + Assert.equal(s.mainProcessCrashes.length, 2 * s.HIGH_WATER_DAILY_THRESHOLD + 2); 1.208 + Assert.equal(s.pluginCrashes.length, 2 * s.HIGH_WATER_DAILY_THRESHOLD); 1.209 + Assert.equal(s.pluginHangs.length, 2 * s.HIGH_WATER_DAILY_THRESHOLD); 1.210 + 1.211 + // But raw counts should be preserved. 1.212 + let day1 = bsp.dateToDays(d1); 1.213 + let day2 = bsp.dateToDays(d2); 1.214 + Assert.ok(s._countsByDay.has(day1)); 1.215 + Assert.ok(s._countsByDay.has(day2)); 1.216 + Assert.equal(s._countsByDay.get(day1).get(s.TYPE_MAIN_CRASH), 1.217 + s.HIGH_WATER_DAILY_THRESHOLD + 1); 1.218 + Assert.equal(s._countsByDay.get(day1).get(s.TYPE_PLUGIN_CRASH), 1.219 + s.HIGH_WATER_DAILY_THRESHOLD + 1); 1.220 + Assert.equal(s._countsByDay.get(day1).get(s.TYPE_PLUGIN_HANG), 1.221 + s.HIGH_WATER_DAILY_THRESHOLD + 1); 1.222 + 1.223 + yield s.save(); 1.224 + yield s.load(); 1.225 + 1.226 + Assert.ok(s._countsByDay.has(day1)); 1.227 + Assert.ok(s._countsByDay.has(day2)); 1.228 + Assert.equal(s._countsByDay.get(day1).get(s.TYPE_MAIN_CRASH), 1.229 + s.HIGH_WATER_DAILY_THRESHOLD + 1); 1.230 + Assert.equal(s._countsByDay.get(day1).get(s.TYPE_PLUGIN_CRASH), 1.231 + s.HIGH_WATER_DAILY_THRESHOLD + 1); 1.232 + Assert.equal(s._countsByDay.get(day1).get(s.TYPE_PLUGIN_HANG), 1.233 + s.HIGH_WATER_DAILY_THRESHOLD + 1); 1.234 +});