1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/telemetry/tests/unit/test_TelemetryLateWrites.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,134 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ 1.6 +*/ 1.7 +/* A testcase to make sure reading late writes stacks works. */ 1.8 + 1.9 +const Cc = Components.classes; 1.10 +const Ci = Components.interfaces; 1.11 +const Cu = Components.utils; 1.12 +const Cr = Components.results; 1.13 + 1.14 +Cu.import("resource://gre/modules/Services.jsm", this); 1.15 + 1.16 +const Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry); 1.17 + 1.18 +// Constants from prio.h for nsIFileOutputStream.init 1.19 +const PR_WRONLY = 0x2; 1.20 +const PR_CREATE_FILE = 0x8; 1.21 +const PR_TRUNCATE = 0x20; 1.22 +const RW_OWNER = 0600; 1.23 + 1.24 +const STACK_SUFFIX1 = "stack1.txt"; 1.25 +const STACK_SUFFIX2 = "stack2.txt"; 1.26 +const STACK_BOGUS_SUFFIX = "bogus.txt"; 1.27 +const LATE_WRITE_PREFIX = "Telemetry.LateWriteFinal-"; 1.28 + 1.29 +// The names and IDs don't matter, but the format of the IDs does. 1.30 +const LOADED_MODULES = { 1.31 + '4759A7E6993548C89CAF716A67EC242D00': 'libtest.so', 1.32 + 'F77AF15BB8D6419FA875954B4A3506CA00': 'libxul.so', 1.33 + '1E2F7FB590424E8F93D60BB88D66B8C500': 'libc.so' 1.34 +}; 1.35 +const N_MODULES = Object.keys(LOADED_MODULES).length; 1.36 + 1.37 +// Format of individual items is [index, offset-in-library]. 1.38 +const STACK1 = [ 1.39 + [ 0, 0 ], 1.40 + [ 1, 1 ], 1.41 + [ 2, 2 ] 1.42 +]; 1.43 +const STACK2 = [ 1.44 + [ 0, 0 ], 1.45 + [ 1, 5 ], 1.46 + [ 2, 10 ], 1.47 +]; 1.48 +// XXX The only error checking is for a zero-sized stack. 1.49 +const STACK_BOGUS = []; 1.50 + 1.51 +function write_string_to_file(file, contents) { 1.52 + let ostream = Cc["@mozilla.org/network/safe-file-output-stream;1"] 1.53 + .createInstance(Ci.nsIFileOutputStream); 1.54 + ostream.init(file, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 1.55 + RW_OWNER, ostream.DEFER_OPEN); 1.56 + ostream.write(contents, contents.length); 1.57 + ostream.QueryInterface(Ci.nsISafeOutputStream).finish(); 1.58 + ostream.close(); 1.59 +} 1.60 + 1.61 +function construct_file(suffix) { 1.62 + let profileDirectory = Services.dirsvc.get("ProfD", Ci.nsIFile); 1.63 + let file = profileDirectory.clone(); 1.64 + file.append(LATE_WRITE_PREFIX + suffix); 1.65 + return file; 1.66 +} 1.67 + 1.68 +function write_late_writes_file(stack, suffix) 1.69 +{ 1.70 + let file = construct_file(suffix); 1.71 + let contents = N_MODULES + "\n"; 1.72 + for (let id in LOADED_MODULES) { 1.73 + contents += id + " " + LOADED_MODULES[id] + "\n"; 1.74 + } 1.75 + 1.76 + contents += stack.length + "\n"; 1.77 + for (let element of stack) { 1.78 + contents += element[0] + " " + element[1].toString(16) + "\n"; 1.79 + } 1.80 + 1.81 + write_string_to_file(file, contents); 1.82 +} 1.83 + 1.84 +function run_test() { 1.85 + do_get_profile(); 1.86 + 1.87 + write_late_writes_file(STACK1, STACK_SUFFIX1); 1.88 + write_late_writes_file(STACK2, STACK_SUFFIX2); 1.89 + write_late_writes_file(STACK_BOGUS, STACK_BOGUS_SUFFIX); 1.90 + 1.91 + let lateWrites = Telemetry.lateWrites; 1.92 + do_check_true("memoryMap" in lateWrites); 1.93 + do_check_eq(lateWrites.memoryMap.length, 0); 1.94 + do_check_true("stacks" in lateWrites); 1.95 + do_check_eq(lateWrites.stacks.length, 0); 1.96 + 1.97 + do_test_pending(); 1.98 + Telemetry.asyncFetchTelemetryData(function () { 1.99 + actual_test(); 1.100 + }); 1.101 +} 1.102 + 1.103 +function actual_test() { 1.104 + do_check_false(construct_file(STACK_SUFFIX1).exists()); 1.105 + do_check_false(construct_file(STACK_SUFFIX2).exists()); 1.106 + do_check_false(construct_file(STACK_BOGUS_SUFFIX).exists()); 1.107 + 1.108 + let lateWrites = Telemetry.lateWrites; 1.109 + 1.110 + do_check_true("memoryMap" in lateWrites); 1.111 + do_check_eq(lateWrites.memoryMap.length, N_MODULES); 1.112 + for (let id in LOADED_MODULES) { 1.113 + let matchingLibrary = lateWrites.memoryMap.filter(function(library, idx, array) { 1.114 + return library[1] == id; 1.115 + }); 1.116 + do_check_eq(matchingLibrary.length, 1); 1.117 + let library = matchingLibrary[0] 1.118 + let name = library[0]; 1.119 + do_check_eq(LOADED_MODULES[id], name); 1.120 + } 1.121 + 1.122 + do_check_true("stacks" in lateWrites); 1.123 + do_check_eq(lateWrites.stacks.length, 2); 1.124 + let uneval_STACKS = [uneval(STACK1), uneval(STACK2)]; 1.125 + let first_stack = lateWrites.stacks[0]; 1.126 + let second_stack = lateWrites.stacks[1]; 1.127 + function stackChecker(canonicalStack) { 1.128 + let unevalCanonicalStack = uneval(canonicalStack); 1.129 + return function(obj, idx, array) { 1.130 + return unevalCanonicalStack == obj; 1.131 + } 1.132 + } 1.133 + do_check_eq(uneval_STACKS.filter(stackChecker(first_stack)).length, 1); 1.134 + do_check_eq(uneval_STACKS.filter(stackChecker(second_stack)).length, 1); 1.135 + 1.136 + do_test_finished(); 1.137 +}