|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ |
|
3 */ |
|
4 /* A testcase to make sure reading late writes stacks works. */ |
|
5 |
|
6 const Cc = Components.classes; |
|
7 const Ci = Components.interfaces; |
|
8 const Cu = Components.utils; |
|
9 const Cr = Components.results; |
|
10 |
|
11 Cu.import("resource://gre/modules/Services.jsm", this); |
|
12 |
|
13 const Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry); |
|
14 |
|
15 // Constants from prio.h for nsIFileOutputStream.init |
|
16 const PR_WRONLY = 0x2; |
|
17 const PR_CREATE_FILE = 0x8; |
|
18 const PR_TRUNCATE = 0x20; |
|
19 const RW_OWNER = 0600; |
|
20 |
|
21 const STACK_SUFFIX1 = "stack1.txt"; |
|
22 const STACK_SUFFIX2 = "stack2.txt"; |
|
23 const STACK_BOGUS_SUFFIX = "bogus.txt"; |
|
24 const LATE_WRITE_PREFIX = "Telemetry.LateWriteFinal-"; |
|
25 |
|
26 // The names and IDs don't matter, but the format of the IDs does. |
|
27 const LOADED_MODULES = { |
|
28 '4759A7E6993548C89CAF716A67EC242D00': 'libtest.so', |
|
29 'F77AF15BB8D6419FA875954B4A3506CA00': 'libxul.so', |
|
30 '1E2F7FB590424E8F93D60BB88D66B8C500': 'libc.so' |
|
31 }; |
|
32 const N_MODULES = Object.keys(LOADED_MODULES).length; |
|
33 |
|
34 // Format of individual items is [index, offset-in-library]. |
|
35 const STACK1 = [ |
|
36 [ 0, 0 ], |
|
37 [ 1, 1 ], |
|
38 [ 2, 2 ] |
|
39 ]; |
|
40 const STACK2 = [ |
|
41 [ 0, 0 ], |
|
42 [ 1, 5 ], |
|
43 [ 2, 10 ], |
|
44 ]; |
|
45 // XXX The only error checking is for a zero-sized stack. |
|
46 const STACK_BOGUS = []; |
|
47 |
|
48 function write_string_to_file(file, contents) { |
|
49 let ostream = Cc["@mozilla.org/network/safe-file-output-stream;1"] |
|
50 .createInstance(Ci.nsIFileOutputStream); |
|
51 ostream.init(file, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, |
|
52 RW_OWNER, ostream.DEFER_OPEN); |
|
53 ostream.write(contents, contents.length); |
|
54 ostream.QueryInterface(Ci.nsISafeOutputStream).finish(); |
|
55 ostream.close(); |
|
56 } |
|
57 |
|
58 function construct_file(suffix) { |
|
59 let profileDirectory = Services.dirsvc.get("ProfD", Ci.nsIFile); |
|
60 let file = profileDirectory.clone(); |
|
61 file.append(LATE_WRITE_PREFIX + suffix); |
|
62 return file; |
|
63 } |
|
64 |
|
65 function write_late_writes_file(stack, suffix) |
|
66 { |
|
67 let file = construct_file(suffix); |
|
68 let contents = N_MODULES + "\n"; |
|
69 for (let id in LOADED_MODULES) { |
|
70 contents += id + " " + LOADED_MODULES[id] + "\n"; |
|
71 } |
|
72 |
|
73 contents += stack.length + "\n"; |
|
74 for (let element of stack) { |
|
75 contents += element[0] + " " + element[1].toString(16) + "\n"; |
|
76 } |
|
77 |
|
78 write_string_to_file(file, contents); |
|
79 } |
|
80 |
|
81 function run_test() { |
|
82 do_get_profile(); |
|
83 |
|
84 write_late_writes_file(STACK1, STACK_SUFFIX1); |
|
85 write_late_writes_file(STACK2, STACK_SUFFIX2); |
|
86 write_late_writes_file(STACK_BOGUS, STACK_BOGUS_SUFFIX); |
|
87 |
|
88 let lateWrites = Telemetry.lateWrites; |
|
89 do_check_true("memoryMap" in lateWrites); |
|
90 do_check_eq(lateWrites.memoryMap.length, 0); |
|
91 do_check_true("stacks" in lateWrites); |
|
92 do_check_eq(lateWrites.stacks.length, 0); |
|
93 |
|
94 do_test_pending(); |
|
95 Telemetry.asyncFetchTelemetryData(function () { |
|
96 actual_test(); |
|
97 }); |
|
98 } |
|
99 |
|
100 function actual_test() { |
|
101 do_check_false(construct_file(STACK_SUFFIX1).exists()); |
|
102 do_check_false(construct_file(STACK_SUFFIX2).exists()); |
|
103 do_check_false(construct_file(STACK_BOGUS_SUFFIX).exists()); |
|
104 |
|
105 let lateWrites = Telemetry.lateWrites; |
|
106 |
|
107 do_check_true("memoryMap" in lateWrites); |
|
108 do_check_eq(lateWrites.memoryMap.length, N_MODULES); |
|
109 for (let id in LOADED_MODULES) { |
|
110 let matchingLibrary = lateWrites.memoryMap.filter(function(library, idx, array) { |
|
111 return library[1] == id; |
|
112 }); |
|
113 do_check_eq(matchingLibrary.length, 1); |
|
114 let library = matchingLibrary[0] |
|
115 let name = library[0]; |
|
116 do_check_eq(LOADED_MODULES[id], name); |
|
117 } |
|
118 |
|
119 do_check_true("stacks" in lateWrites); |
|
120 do_check_eq(lateWrites.stacks.length, 2); |
|
121 let uneval_STACKS = [uneval(STACK1), uneval(STACK2)]; |
|
122 let first_stack = lateWrites.stacks[0]; |
|
123 let second_stack = lateWrites.stacks[1]; |
|
124 function stackChecker(canonicalStack) { |
|
125 let unevalCanonicalStack = uneval(canonicalStack); |
|
126 return function(obj, idx, array) { |
|
127 return unevalCanonicalStack == obj; |
|
128 } |
|
129 } |
|
130 do_check_eq(uneval_STACKS.filter(stackChecker(first_stack)).length, 1); |
|
131 do_check_eq(uneval_STACKS.filter(stackChecker(second_stack)).length, 1); |
|
132 |
|
133 do_test_finished(); |
|
134 } |