1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 Copyright (c) 2012 The Chromium Authors. All rights reserved. 5 Use of this source code is governed by a BSD-style license that can be 6 found in the LICENSE file. 7 --> 8 <head> 9 <title>Timeline stream importer tests</title> 10 <script src="../base.js"></script> 11 </head> 12 <body> 13 <script> 14 base.require('unittest'); 15 base.require('event_target'); 16 base.require('test_utils'); 17 base.require('importer.timeline_stream_importer'); 18 </script> 19 <script> 20 'use strict'; 21 22 function FakeWebSocket() { 23 base.EventTarget.call(this); 24 this.sendHook_ = undefined; 25 this.messages_ = []; 26 this.connected_ = false; 27 }; 28 29 FakeWebSocket.prototype = { 30 __proto__: base.EventTarget.prototype, 31 32 set connected(connected) { 33 if (this.connected_ == connected) 34 return; 35 this.connected_ = connected; 36 if (this.connected_) 37 base.dispatchSimpleEvent(this, 'connect'); 38 else 39 base.dispatchSimpleEvent(this, 'disconnect'); 40 }, 41 42 get readyState() { 43 if (this.connected_) 44 return WebSocket.OPEN; 45 return WebSocket.CLOSED; 46 }, 47 48 pushMessage: function(msg) { 49 this.messages_.push(JSON.stringify(msg)); 50 }, 51 52 get numPendingMessages() { 53 return this.messages_.length; 54 }, 55 56 dispatchAllPendingMessages: function() { 57 var messages = this.messages_.splice(0, this.messages_.length); 58 for (var i = 0; i < messages.length; i++) 59 this.dispatchEvent({type: 'message', data: messages[i]}); 60 }, 61 62 /** 63 * @param {function(message)} hook A function to call when send is 64 called on the socket. 65 */ 66 set sendHook(hook) { 67 this.sendHook_ = hook; 68 }, 69 70 send: function(message) { 71 if (this.sendHook_) 72 this.sendHook_(message); 73 }, 74 75 set onopen(handler) { 76 this.addEventListener('open', handler); 77 }, 78 79 set onclose(handler) { 80 this.addEventListener('close', handler); 81 }, 82 83 set onerror(handler) { 84 this.addEventListener('error', handler); 85 }, 86 87 set onmessage(handler) { 88 this.addEventListener('message', handler); 89 } 90 }; 91 92 function testImportBasic() { 93 var model = new tracing.Model(); 94 var importer = new tracing.importer.TimelineStreamImporter(model); 95 96 assertFalse(importer.paused); 97 assertFalse(importer.connected); 98 99 var socket = new FakeWebSocket(); 100 importer.connect(socket); 101 102 socket.connected = true; 103 assertTrue(importer.connected); 104 105 socket.pushMessage({ 106 cmd: 'ptd', 107 pid: 1, 108 td: { n: 3, 109 s: [ 110 {s: 10, e: 11, l: 'alligator'}, 111 {s: 14, e: 15, l: 'bandicoot'}, 112 {s: 17, e: 18, l: 'cheetah'}, 113 ] 114 } 115 }); 116 socket.dispatchAllPendingMessages(); 117 118 assertNotUndefined(model.processes[1]); 119 assertNotUndefined(model.processes[1].threads[3]); 120 var t3 = model.processes[1].threads[3]; 121 assertEquals(3, t3.slices.length); 122 123 assertEquals(model.bounds.min, 10); 124 assertEquals(model.bounds.max, 18); 125 } 126 127 function testPause() { 128 var model = new tracing.Model(); 129 var importer = new tracing.importer.TimelineStreamImporter(model); 130 131 assertFalse(importer.paused); 132 133 var socket = new FakeWebSocket(); 134 importer.connect(socket); 135 socket.connected = true; 136 137 var didSend = false; 138 socket.sendHook = function(message) { 139 var data = JSON.parse(message); 140 didSend = true; 141 assertEquals('pause', data['cmd']); 142 } 143 importer.pause(); 144 assertTrue(didSend); 145 assertTrue(importer.paused); 146 147 didSend = false; 148 socket.sendHook = function(message) { 149 var data = JSON.parse(message); 150 didSend = true; 151 assertEquals('resume', data['cmd']); 152 } 153 importer.resume(); 154 assertTrue(didSend); 155 assertFalse(importer.paused); 156 } 157 158 function testCounters() { 159 var model = new tracing.Model(); 160 var importer = new tracing.importer.TimelineStreamImporter(model); 161 162 assertFalse(importer.paused); 163 assertFalse(importer.connected); 164 165 var socket = new FakeWebSocket(); 166 importer.connect(socket); 167 168 socket.connected = true; 169 assertTrue(importer.connected); 170 171 socket.pushMessage({ 172 cmd: "pcd", 173 pid: 1, 174 cd: { 175 n: 'Allocator', 176 sn: ['Bytes'], 177 sc: [4], 178 c: [ 179 { 180 t: 2, 181 v: [16] 182 }, 183 { 184 t: 16, 185 v: [32] 186 } 187 ] 188 } 189 }); 190 191 socket.pushMessage({ 192 cmd: "pcd", 193 pid: 1, 194 cd: { 195 n: 'Allocator', 196 sn: ['Bytes'], 197 sc: [4], 198 c: [ 199 { 200 t: 32, 201 v: [48] 202 }, 203 { 204 t: 48, 205 v: [64] 206 }, 207 { 208 t: 64, 209 v: [16] 210 } 211 ] 212 } 213 }); 214 215 socket.dispatchAllPendingMessages(); 216 217 assertNotUndefined(model.processes[1]); 218 assertNotUndefined(model.processes[1].counters['streamed.Allocator']); 219 var counter = model.processes[1].counters['streamed.Allocator']; 220 assertNotUndefined(counter.samples); 221 assertEquals(counter.samples.length, 5); 222 assertEquals(counter.seriesNames.length, 1); 223 assertEquals(counter.seriesColors.length, 1); 224 assertEquals(counter.samples[2], 48); 225 assertEquals(counter.timestamps[4], 64); 226 assertEquals(model.bounds.min, 2); 227 assertEquals(model.bounds.max, 64); 228 } 229 230 function testCounterImportErrors() { 231 var model = new tracing.Model(); 232 var importer = new tracing.importer.TimelineStreamImporter(model); 233 234 assertFalse(importer.paused); 235 assertFalse(importer.connected); 236 237 var socket = new FakeWebSocket(); 238 importer.connect(socket); 239 240 socket.connected = true; 241 assertTrue(importer.connected); 242 243 socket.pushMessage({ 244 cmd: "pcd", 245 pid: 1, 246 cd: { 247 n: 'Allocator', 248 sn: ['Bytes', 'Nibbles', 'Bits'], 249 sc: [4,3,2], 250 c: [ 251 { 252 t: 2, 253 v: [16,12,2] 254 }, 255 { 256 t: 16, 257 v: [32,3,4] 258 } 259 ] 260 } 261 }); 262 263 // Test for name change import error 264 socket.pushMessage({ 265 cmd: "pcd", 266 pid: 1, 267 cd: { 268 n: 'Allocator', 269 sn: ['Bytes', 'NotNibbles', 'Bits'], 270 sc: [4,3,2], 271 c: [ 272 { 273 t: 18, 274 v: [16,12,2] 275 }, 276 { 277 t: 24, 278 v: [32,3,4] 279 } 280 ] 281 } 282 }); 283 284 socket.dispatchAllPendingMessages(); 285 286 assertNotUndefined(model.processes[1]); 287 assertEquals(model.importErrors.length, 1); 288 // test for series number change 289 socket.pushMessage({ 290 cmd: "pcd", 291 pid: 1, 292 cd: { 293 n: 'Allocator', 294 sn: ['Bytes', 'Bits'], 295 sc: [4,3], 296 c: [ 297 { 298 t: 26, 299 v: [16,12] 300 }, 301 { 302 t: 32, 303 v: [32,3] 304 } 305 ] 306 } 307 }); 308 309 socket.dispatchAllPendingMessages(); 310 assertEquals(model.importErrors.length, 2); 311 312 // test for sn.length != sc.length 313 socket.pushMessage({ 314 cmd: "pcd", 315 pid: 1, 316 cd: { 317 n: 'Allocator', 318 sn: ['Bytes', 'Nibbles', 'Bits'], 319 sc: [4,3,2,5], 320 c: [ 321 { 322 t: 2, 323 v: [16,12,2] 324 }, 325 { 326 t: 16, 327 v: [32,3,4] 328 } 329 ] 330 } 331 }); 332 333 334 socket.dispatchAllPendingMessages(); 335 assertEquals(model.importErrors.length, 3); 336 } 337 </script> 338 </body> 339 </html> 340