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>ProfilingView tests</title> 10 <script src="base.js"></script> 11 <style> 12 .profiling-view { 13 border: 1px solid black; 14 } 15 </style> 16 </head> 17 <body> 18 <script> 19 base.require('unittest'); 20 base.require('test_utils'); 21 base.require('profiling_view'); 22 base.require('tracing_controller'); 23 </script> 24 <script> 25 'use strict'; 26 27 var testData = [ 28 {name: 'a', args: {}, pid: 52, ts: 15000, cat: 'foo', tid: 53, ph: 'B'}, 29 {name: 'a', args: {}, pid: 52, ts: 19000, cat: 'foo', tid: 53, ph: 'E'}, 30 {name: 'b', args: {}, pid: 52, ts: 32000, cat: 'foo', tid: 53, ph: 'B'}, 31 {name: 'b', args: {}, pid: 52, ts: 54000, cat: 'foo', tid: 53, ph: 'E'} 32 ]; 33 var systemTraceTestData = [ 34 'systrace.sh-8170 [000] 0.013: sched_switch: ' + 35 'prev_comm=systrace.sh prev_pid=8170 prev_prio=120 ' + 36 'prev_state=x ==> next_comm=kworker/1:0 next_pid=7873 ' + 37 'next_prio=120', 38 ' kworker/1:0-7873 [000] 0.036: sched_switch: ' + 39 'prev_comm=kworker/1:0 prev_pid=7873 prev_prio=120 ' + 40 'prev_state=S ==> next_comm=debugd next_pid=4404 next_prio=120', 41 ' debugd-4404 [000] 0.070: sched_switch: prev_comm=debugd ' + 42 'prev_pid=4404 prev_prio=120 prev_state=S ==> ' + 43 'next_comm=dbus-daemon next_pid=510 next_prio=120', 44 'systrace.sh-8182 [000] 0.000: tracing_mark_write: ' + 45 'trace_event_clock_sync: parent_ts=0.0' 46 ].join('\n'); 47 48 /* This test just instantiates a ProflingView and adds it to the DOM 49 * to help with non-unittest UI work. 50 */ 51 function testInstantiate() { 52 var view = new tracing.ProfilingView(); 53 var tracingController; 54 55 // This code emulates Chrome's responses to sendFn enough that the real 56 // tracing controller can be used to interactively test the UI. 57 var systemTraceRequested = false; 58 function send(message, opt_args) { 59 var args = opt_args || []; 60 if (message == 'beginTracing') { 61 systemTraceRequested = opt_args[0]; 62 } else if (message == 'beginRequestBufferPercentFull') { 63 setTimeout(function() { 64 view.tracingController.onRequestBufferPercentFullComplete(0.5); 65 }, 1); 66 } else if (message == 'endTracingAsync') { 67 setTimeout(function() { 68 if (systemTraceRequested) { 69 view.tracingController.onSystemTraceDataCollected( 70 systemTraceTestData); 71 } 72 view.tracingController.onTraceDataCollected(testData); 73 view.tracingController.onEndTracingComplete(); 74 }, 1); 75 } else if (message == 'loadTraceFile') { 76 setTimeout(function() { 77 view.tracingController.onLoadTraceFileComplete( 78 JSON.stringify(testData)); 79 }, 150); 80 } else if (message == 'saveTraceFile') { 81 setTimeout(function() { 82 view.tracingController.onSaveTraceFileComplete(); 83 }, 1); 84 } 85 } 86 87 tracingController = new tracing.TracingController(send); 88 tracingController.supportsSystemTracing_ = true; 89 90 view.tracingController = tracingController; 91 view.focusElement = view; 92 this.addHTMLOutput(undefined, view); 93 } 94 95 /* 96 * Just enough of the TracingController to support the tests below. 97 */ 98 function FakeTracingController() { 99 } 100 101 FakeTracingController.prototype = { 102 __proto__: base.EventTarget.prototype, 103 104 get supportsSystemTracing() { 105 return base.isChromeOS; 106 }, 107 108 beginTracing: function(opt_systemTracingEnabled, 109 opt_continuousTracingEnabled, 110 opt_traceCategories) { 111 this.wasBeginTracingCalled = true; 112 this.wasBeginTracingCalledWithSystemTracingEnabled = 113 opt_systemTracingEnabled; 114 this.wasBeginTracingCalledWithContinuousTracingEnabled = 115 opt_continuousTracingEnabled; 116 this.beginTracingCategories = opt_traceCategories; 117 }, 118 119 collectCategories: function() { 120 this.wasCollectCategoriesCalled = true; 121 }, 122 123 get traceEvents() { 124 if (!this.wasBeginTracingCalled) 125 return undefined; 126 return testData; 127 }, 128 129 get systemTraceEvents() { 130 if (!this.wasBeginTracingCalled) 131 return []; 132 if (!this.wasBeginTracingCalledWithSystemTracingEnabled) 133 return []; 134 return systemTraceTestData; 135 } 136 }; 137 138 function recordTestCommon() { 139 var view = new tracing.ProfilingView(); 140 var tracingController = new FakeTracingController(); 141 view.tracingController = tracingController; 142 143 view.querySelector('button.record').click(); 144 assertTrue(tracingController.wasCollectCategoriesCalled); 145 146 var e = new base.Event('categoriesCollected'); 147 e.categories = ['skia', 'gpu']; 148 tracingController.dispatchEvent(e); 149 150 view.categorySelectionDialog_.querySelector( 151 'button.record-categories').click(); 152 153 assertTrue(tracingController.wasBeginTracingCalled); 154 assertEquals(base.isChromeOS, 155 tracingController.wasBeginTracingCalledWithSystemTracingEnabled); 156 157 var e = new base.Event('traceEnded'); 158 e.events = tracingController.traceEvents; 159 tracingController.dispatchEvent(e); 160 assertTrue(!!view.timelineView.model); 161 } 162 163 function testSelectedCategoriesSentToTracing() { 164 var view = new tracing.ProfilingView(); 165 view.timelineView_.settings.set('cc', 'true', 'record_categories'); 166 view.timelineView_.settings.set('renderer', 'false', 'record_categories'); 167 168 var tracingController = new FakeTracingController(); 169 view.tracingController = tracingController; 170 171 view.querySelector('button.record').click(); 172 assertTrue(tracingController.wasCollectCategoriesCalled); 173 174 var e = new base.Event('categoriesCollected'); 175 e.categories = ['skia', 'gpu', 'cc', 'renderer']; 176 tracingController.dispatchEvent(e); 177 178 view.categorySelectionDialog_.querySelector('input#skia').click(); 179 view.categorySelectionDialog_.querySelector( 180 'button.record-categories').click(); 181 182 var categories = tracingController.beginTracingCategories; 183 // Renderer is disabled in settings, skia is clicked off. 184 assertEquals('-renderer,-skia', categories); 185 } 186 187 function testBadCategories() { 188 var view = new tracing.ProfilingView(); 189 view.timelineView_.settings.set('foo,bar', 'false', 'record_categories'); 190 191 var tracingController = new FakeTracingController(); 192 view.tracingController = tracingController; 193 194 view.querySelector('button.record').click(); 195 assertTrue(tracingController.wasCollectCategoriesCalled); 196 197 var e = new base.Event('categoriesCollected'); 198 e.categories = ['baz,zap', 'gpu']; 199 tracingController.dispatchEvent(e); 200 201 view.categorySelectionDialog_.querySelector( 202 'button.record-categories').click(); 203 204 var inputs = view.categorySelectionDialog_.querySelectorAll('input'); 205 var inputs_length = inputs.length; 206 for (var i = 0; i < inputs_length; ++i) { 207 // Comes from categories and should be split before getting 208 // to the category selection dialog. 209 assertNotEquals('baz,zap', inputs[i].id); 210 } 211 212 var categories = tracingController.beginTracingCategories; 213 assertEquals('', categories); 214 } 215 216 function testRecordNonCros() { 217 var old = base.isChromeOS; 218 base.isChromeOS = false; 219 try { 220 recordTestCommon(); 221 } finally { 222 base.isChromeOS = old; 223 } 224 } 225 226 function testRecordCros() { 227 var old = base.isChromeOS; 228 base.isChromeOS = true; 229 try { 230 recordTestCommon(); 231 } finally { 232 base.isChromeOS = old; 233 } 234 } 235 </script> 236 </body> 237 </html> 238