toolkit/components/telemetry/tests/unit/test_TelemetryLateWrites.js

changeset 0
6474c204b198
     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 +}

mercurial