summaryrefslogtreecommitdiffstats
path: root/b2g/components/test/unit/test_logshake.js
diff options
context:
space:
mode:
Diffstat (limited to 'b2g/components/test/unit/test_logshake.js')
-rw-r--r--b2g/components/test/unit/test_logshake.js218
1 files changed, 218 insertions, 0 deletions
diff --git a/b2g/components/test/unit/test_logshake.js b/b2g/components/test/unit/test_logshake.js
new file mode 100644
index 000000000..cfb81b893
--- /dev/null
+++ b/b2g/components/test/unit/test_logshake.js
@@ -0,0 +1,218 @@
+/**
+ * Test the log capturing capabilities of LogShake.jsm
+ */
+
+/* jshint moz: true */
+/* global Components, LogCapture, LogShake, ok, add_test, run_next_test, dump */
+/* exported run_test */
+
+/* disable use strict warning */
+/* jshint -W097 */
+"use strict";
+
+var Cu = Components.utils;
+
+Cu.import("resource://gre/modules/LogCapture.jsm");
+Cu.import("resource://gre/modules/LogShake.jsm");
+
+const EVENTS_PER_SECOND = 6.25;
+const GRAVITY = 9.8;
+
+/**
+ * Force logshake to handle a device motion event with given components.
+ * Does not use SystemAppProxy because event needs special
+ * accelerationIncludingGravity property.
+ */
+function sendDeviceMotionEvent(x, y, z) {
+ let event = {
+ type: "devicemotion",
+ accelerationIncludingGravity: {
+ x: x,
+ y: y,
+ z: z
+ }
+ };
+ LogShake.handleEvent(event);
+}
+
+/**
+ * Send a screen change event directly, does not use SystemAppProxy due to race
+ * conditions.
+ */
+function sendScreenChangeEvent(screenEnabled) {
+ let event = {
+ type: "screenchange",
+ detail: {
+ screenEnabled: screenEnabled
+ }
+ };
+ LogShake.handleEvent(event);
+}
+
+/**
+ * Mock the readLogFile function of LogCapture.
+ * Used to detect whether LogShake activates.
+ * @return {Array<String>} Locations that LogShake tries to read
+ */
+function mockReadLogFile() {
+ let readLocations = [];
+
+ LogCapture.readLogFile = function(loc) {
+ readLocations.push(loc);
+ return null; // we don't want to provide invalid data to a parser
+ };
+
+ // Allow inspection of readLocations by caller
+ return readLocations;
+}
+
+/**
+ * Send a series of events that corresponds to a shake
+ */
+function sendSustainedShake() {
+ // Fire a series of devicemotion events that are of shake magnitude
+ for (let i = 0; i < 2 * EVENTS_PER_SECOND; i++) {
+ sendDeviceMotionEvent(0, 2 * GRAVITY, 2 * GRAVITY);
+ }
+
+}
+
+add_test(function test_do_log_capture_after_shaking() {
+ // Enable LogShake
+ LogShake.init();
+
+ let readLocations = mockReadLogFile();
+
+ sendSustainedShake();
+
+ ok(readLocations.length > 0,
+ "LogShake should attempt to read at least one log");
+
+ LogShake.uninit();
+ run_next_test();
+});
+
+add_test(function test_do_nothing_when_resting() {
+ // Enable LogShake
+ LogShake.init();
+
+ let readLocations = mockReadLogFile();
+
+ // Fire several devicemotion events that are relatively tiny
+ for (let i = 0; i < 2 * EVENTS_PER_SECOND; i++) {
+ sendDeviceMotionEvent(0, GRAVITY, GRAVITY);
+ }
+
+ ok(readLocations.length === 0,
+ "LogShake should not read any logs");
+
+ LogShake.uninit();
+ run_next_test();
+});
+
+add_test(function test_do_nothing_when_disabled() {
+ // Disable LogShake
+ LogShake.uninit();
+
+ let readLocations = mockReadLogFile();
+
+ // Fire a series of events that would normally be a shake
+ sendSustainedShake();
+
+ ok(readLocations.length === 0,
+ "LogShake should not read any logs");
+
+ run_next_test();
+});
+
+add_test(function test_do_nothing_when_screen_off() {
+ // Enable LogShake
+ LogShake.init();
+
+ // Send an event as if the screen has been turned off
+ sendScreenChangeEvent(false);
+
+ let readLocations = mockReadLogFile();
+
+ // Fire a series of events that would normally be a shake
+ sendSustainedShake();
+
+ ok(readLocations.length === 0,
+ "LogShake should not read any logs");
+
+ // Restore the screen
+ sendScreenChangeEvent(true);
+
+ LogShake.uninit();
+ run_next_test();
+});
+
+add_test(function test_do_log_capture_resilient_readLogFile() {
+ // Enable LogShake
+ LogShake.init();
+
+ let readLocations = [];
+ LogCapture.readLogFile = function(loc) {
+ readLocations.push(loc);
+ throw new Error("Exception during readLogFile for: " + loc);
+ };
+
+ // Fire a series of events that would normally be a shake
+ sendSustainedShake();
+
+ ok(readLocations.length > 0,
+ "LogShake should attempt to read at least one log");
+
+ LogShake.uninit();
+ run_next_test();
+});
+
+add_test(function test_do_log_capture_resilient_parseLog() {
+ // Enable LogShake
+ LogShake.init();
+
+ let readLocations = [];
+ LogCapture.readLogFile = function(loc) {
+ readLocations.push(loc);
+ LogShake.LOGS_WITH_PARSERS[loc] = function() {
+ throw new Error("Exception during LogParser for: " + loc);
+ };
+ return null;
+ };
+
+ // Fire a series of events that would normally be a shake
+ sendSustainedShake();
+
+ ok(readLocations.length > 0,
+ "LogShake should attempt to read at least one log");
+
+ LogShake.uninit();
+ run_next_test();
+});
+
+add_test(function test_do_nothing_when_dropped() {
+ // Enable LogShake
+ LogShake.init();
+
+ let readLocations = mockReadLogFile();
+
+ // We want a series of spikes to be ignored by LogShake. This roughly
+ // corresponds to the compare_stairs_sock graph on bug #1101994
+
+ for (let i = 0; i < 10 * EVENTS_PER_SECOND; i++) {
+ // Fire a devicemotion event that is at rest
+ sendDeviceMotionEvent(0, 0, GRAVITY);
+ // Fire a spike of motion
+ sendDeviceMotionEvent(0, 2 * GRAVITY, 2 * GRAVITY);
+ }
+
+ ok(readLocations.length === 0,
+ "LogShake should not read any logs");
+
+ LogShake.uninit();
+ run_next_test();
+});
+
+function run_test() {
+ run_next_test();
+}