1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 tvcm.require('tracing.test_utils');
8 tvcm.require('tracing.importer.etw_importer');
10 tvcm.unittest.testSuite('tracing.importer.etw_importer_test', function() {
12 test('canImport', function() {
13 assertFalse(tracing.importer.EtwImporter.canImport('string'));
14 assertFalse(tracing.importer.EtwImporter.canImport([]));
16 // Must not parse an invalid name.
17 var dummy = { name: 'dummy', content: [] };
18 assertFalse(tracing.importer.EtwImporter.canImport(dummy));
20 // Must parse an empty valid trace.
21 var valid = { name: 'ETW', content: [] };
22 assertTrue(tracing.importer.EtwImporter.canImport(valid));
25 test('getModel', function() {
28 var importer = new tracing.importer.EtwImporter(model, events);
29 assertTrue(model === importer.model);
32 test('registerEventHandler', function() {
33 // Create a dummy EtwImporter.
35 var events = ['events'];
36 var importer = new tracing.importer.EtwImporter(model, events);
37 var dummy_handler = function() {};
39 // The handler must not exists.
40 assertFalse(importer.getEventHandler('ABCDEF', 2));
42 // Register an event handler for guid: ABCDEF and opcode: 2.
43 importer.registerEventHandler('ABCDEF', 2, dummy_handler);
45 // The handler exists now, must find it.
46 assertTrue(importer.getEventHandler('ABCDEF', 2));
48 // Must be able to manage an invalid handler.
49 assertFalse(importer.getEventHandler('zzzzzz', 2));
52 test('parseEvent', function() {
55 var importer = new tracing.importer.EtwImporter(model, events);
56 var handler_called = false;
57 var dummy_handler = function() { handler_called = true; return true; };
59 // Register a valid handler.
60 importer.registerEventHandler('aaaa', 42, dummy_handler);
62 // Try to parse an invalid event with missing fields.
63 var incomplet_event = { guid: 'aaaa', 'op': 42, 'ver': 0 };
64 assertFalse(importer.parseEvent(incomplet_event));
65 assertFalse(handler_called);
67 // Try to parse a valid event.
69 guid: 'aaaa', 'op': 42, 'ver': 0, 'cpu': 0, 'ts': 0, 'payload': btoa('0')
71 assertTrue(importer.parseEvent(valid_event));
72 assertTrue(handler_called);
75 test('resetTooSmall', function() {
76 var importer = new tracing.importer.EtwImporter('dummy', []);
77 var decoder = importer.decoder_;
79 var oldByteLength = decoder.payload_.byteLength;
80 // Decode a payload too big for the actual buffer.
81 decoder.reset('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
82 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
83 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
84 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
85 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
86 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
87 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==');
88 var newByteLength = decoder.payload_.byteLength;
90 // Validate the buffer has been resized.
91 assertTrue(oldByteLength < newByteLength);
94 test('decode', function() {
97 var importer = new tracing.importer.EtwImporter(model, events);
99 var decoder = importer.decoder_;
101 decoder.reset('YQBiYw==');
102 assertTrue(decoder.decodeInt32() == 0x63620061);
104 // Decode unsigned numbers.
105 decoder.reset('AQ==');
106 assertTrue(decoder.decodeUInt8() == 0x01);
108 decoder.reset('AQI=');
109 assertTrue(decoder.decodeUInt16() == 0x0201);
111 decoder.reset('AQIDBA==');
112 assertTrue(decoder.decodeUInt32() == 0x04030201);
114 decoder.reset('AQIDBAUGBwg=');
115 assertTrue(decoder.decodeUInt64ToString() === '0807060504030201');
117 // Decode signed numbers.
118 decoder.reset('AQ==');
119 assertTrue(decoder.decodeInt8() == 0x01);
121 decoder.reset('AQI=');
122 assertTrue(decoder.decodeInt16() == 0x0201);
124 decoder.reset('AQIDBA==');
125 assertTrue(decoder.decodeInt32() == 0x04030201);
127 decoder.reset('AQIDBAUGBwg=');
128 assertTrue(decoder.decodeInt64ToString() === '0807060504030201');
130 // Last value before being a signed number.
131 decoder.reset('fw==');
132 assertTrue(decoder.decodeInt8() == 127);
134 // Decode negative numbers.
135 decoder.reset('1g==');
136 assertTrue(decoder.decodeInt8() == -42);
138 decoder.reset('gA==');
139 assertTrue(decoder.decodeInt8() == -128);
141 decoder.reset('hYI=');
142 assertTrue(decoder.decodeInt16() == -32123);
144 decoder.reset('hYL//w==');
145 assertTrue(decoder.decodeInt32() == -32123);
147 decoder.reset('Lv1ptv////8=');
148 assertTrue(decoder.decodeInt32() == -1234567890);
150 // Decode number with zero (nul) in the middle of the string.
151 decoder.reset('YQBiYw==');
152 assertTrue(decoder.decodeInt32() == 0x63620061);
155 test('decodeUInteger', function() {
156 var importer = new tracing.importer.EtwImporter('dummy', []);
157 var decoder = importer.decoder_;
159 decoder.reset('AQIDBAUGBwg=');
160 assertTrue(decoder.decodeUInteger(false) == 0x04030201);
162 decoder.reset('AQIDBAUGBwg=');
163 assertTrue(decoder.decodeUInteger(true) === '0807060504030201');
166 test('decodeString', function() {
167 var importer = new tracing.importer.EtwImporter('dummy', []);
168 var decoder = importer.decoder_;
170 decoder.reset('dGVzdAA=');
171 assertTrue(decoder.decodeString() === 'test');
173 decoder.reset('VGhpcyBpcyBhIHRlc3Qu');
174 assertTrue(decoder.decodeString() === 'This is a test.');
177 test('decodeW16String', function() {
178 var importer = new tracing.importer.EtwImporter('dummy', []);
179 var decoder = importer.decoder_;
180 decoder.reset('dABlAHMAdAAAAA==');
181 assertTrue(decoder.decodeW16String() === 'test');
184 test('decodeFixedW16String', function() {
185 var importer = new tracing.importer.EtwImporter('dummy', []);
186 var decoder = importer.decoder_;
187 decoder.reset('dABlAHMAdAAAAA==');
188 assertTrue(decoder.decodeFixedW16String(32) === 'test');
189 assertTrue(decoder.position_ == 64);
191 decoder.reset('dABlAHMAdAAAAA==');
192 assertTrue(decoder.decodeFixedW16String(1) === 't');
193 assertTrue(decoder.position_ == 2);
196 test('decodeBytes', function() {
197 var importer = new tracing.importer.EtwImporter('dummy', []);
198 var decoder = importer.decoder_;
199 decoder.reset('AAECAwQFBgc=');
200 var bytes = decoder.decodeBytes(8);
201 for (var i = 0; i < length; ++i)
202 assertTrue(bytes[i] == i);
205 test('decodeSID', function() {
206 var importer = new tracing.importer.EtwImporter('dummy', []);
207 var decoder = importer.decoder_;
209 // Decode a SID structure with 64-bit pointer.
211 'AQIDBAECAwQFBAMCAAAAAAEFAAAAAAAFFQAAAAECAwQFBgcICQoLDA0DAAA=');
212 var sid = decoder.decodeSID(true);
214 assertTrue(sid.pSid === '0403020104030201');
215 assertTrue(sid.attributes == 0x02030405);
216 assertTrue(sid.sid.length == 20);
219 test('decodeSystemTime', function() {
220 var importer = new tracing.importer.EtwImporter('dummy', []);
221 var decoder = importer.decoder_;
223 // Decode a SystemTime structure.
224 decoder.reset('AQACAAMABAAFAAYABwAIAA==');
225 var time = decoder.decodeSystemTime();
226 assertTrue(time.wYear == 1);
227 assertTrue(time.wMonth == 2);
228 assertTrue(time.wDayOfWeek == 3);
229 assertTrue(time.wDay == 4);
230 assertTrue(time.wHour == 5);
231 assertTrue(time.wMinute == 6);
232 assertTrue(time.wSecond == 7);
233 assertTrue(time.wMilliseconds == 8);
236 test('decodeTimeZoneInformation', function() {
237 var importer = new tracing.importer.EtwImporter('dummy', []);
238 var decoder = importer.decoder_;
240 // Decode a TimeZoneInformation structure.
241 decoder.reset('AQIDBGEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
242 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIAAwAEAAUABgAHAAgABA' +
243 'MCAWIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
244 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIAAwAEAAUABgAHAAgACAgI' +
246 var time = decoder.decodeTimeZoneInformation();
248 assertTrue(time.bias == 0x04030201);
249 assertTrue(time.standardBias == 0x01020304);
250 assertTrue(time.daylightBias == 0x08080808);
251 assertTrue(time.standardName === 'a');
252 assertTrue(time.daylightName === 'b');
255 test('manageThreads', function() {
258 var importer = new tracing.importer.EtwImporter(model, events);
260 // After initialisation, no threads must exists.
261 assertTrue(Object.getOwnPropertyNames(importer.tidsToPid_).length == 0);
264 var thread10 = importer.createThreadIfNeeded(1, 10);
265 var thread11 = importer.createThreadIfNeeded(1, 11);
266 var thread20 = importer.createThreadIfNeeded(2, 20);
268 assertTrue(Object.getOwnPropertyNames(importer.tidsToPid_).length == 3);
269 assertTrue(importer.tidsToPid_.hasOwnProperty(10));
270 assertTrue(importer.tidsToPid_.hasOwnProperty(11));
271 assertTrue(importer.tidsToPid_.hasOwnProperty(20));
273 // Retrieve existing threads and processes.
274 var pid10 = importer.getThreadFromWindowsTid(10);
275 var pid11 = importer.getThreadFromWindowsTid(11);
276 var pid20 = importer.getThreadFromWindowsTid(20);
278 assertTrue(pid10, 1);
279 assertTrue(pid11, 1);
280 assertTrue(pid20, 2);