Html程序  |  238行  |  7.94 KB

<!DOCTYPE HTML>
<html>
<!--
Copyright (c) 2012 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<head>
<title>ProfilingView tests</title>
<script src="base.js"></script>
<style>
  .profiling-view {
    border: 1px solid black;
  }
</style>
</head>
<body>
  <script>
    base.require('unittest');
    base.require('test_utils');
    base.require('profiling_view');
    base.require('tracing_controller');
  </script>
  <script>
    'use strict';

    var testData = [
      {name: 'a', args: {}, pid: 52, ts: 15000, cat: 'foo', tid: 53, ph: 'B'},
      {name: 'a', args: {}, pid: 52, ts: 19000, cat: 'foo', tid: 53, ph: 'E'},
      {name: 'b', args: {}, pid: 52, ts: 32000, cat: 'foo', tid: 53, ph: 'B'},
      {name: 'b', args: {}, pid: 52, ts: 54000, cat: 'foo', tid: 53, ph: 'E'}
    ];
    var systemTraceTestData = [
      'systrace.sh-8170  [000] 0.013: sched_switch: ' +
                'prev_comm=systrace.sh prev_pid=8170 prev_prio=120 ' +
                'prev_state=x ==> next_comm=kworker/1:0 next_pid=7873 ' +
                'next_prio=120',
      ' kworker/1:0-7873  [000] 0.036: sched_switch: ' +
                'prev_comm=kworker/1:0 prev_pid=7873 prev_prio=120 ' +
                'prev_state=S ==> next_comm=debugd next_pid=4404 next_prio=120',
      '     debugd-4404  [000] 0.070: sched_switch: prev_comm=debugd ' +
                'prev_pid=4404 prev_prio=120 prev_state=S ==> ' +
                'next_comm=dbus-daemon next_pid=510 next_prio=120',
      'systrace.sh-8182  [000] 0.000: tracing_mark_write: ' +
                'trace_event_clock_sync: parent_ts=0.0'
    ].join('\n');

    /* This test just instantiates a ProflingView and adds it to the DOM
     * to help with non-unittest UI work.
     */
    function testInstantiate() {
      var view = new tracing.ProfilingView();
      var tracingController;

      // This code emulates Chrome's responses to sendFn enough that the real
      // tracing controller can be used to interactively test the UI.
      var systemTraceRequested = false;
      function send(message, opt_args) {
        var args = opt_args || [];
        if (message == 'beginTracing') {
          systemTraceRequested = opt_args[0];
        } else if (message == 'beginRequestBufferPercentFull') {
          setTimeout(function() {
            view.tracingController.onRequestBufferPercentFullComplete(0.5);
          }, 1);
        } else if (message == 'endTracingAsync') {
          setTimeout(function() {
            if (systemTraceRequested) {
              view.tracingController.onSystemTraceDataCollected(
                  systemTraceTestData);
            }
            view.tracingController.onTraceDataCollected(testData);
            view.tracingController.onEndTracingComplete();
          }, 1);
        } else if (message == 'loadTraceFile') {
          setTimeout(function() {
            view.tracingController.onLoadTraceFileComplete(
                JSON.stringify(testData));
          }, 150);
        } else if (message == 'saveTraceFile') {
          setTimeout(function() {
            view.tracingController.onSaveTraceFileComplete();
          }, 1);
        }
      }

      tracingController = new tracing.TracingController(send);
      tracingController.supportsSystemTracing_ = true;

      view.tracingController = tracingController;
      view.focusElement = view;
      this.addHTMLOutput(undefined, view);
    }

    /*
     * Just enough of the TracingController to support the tests below.
     */
    function FakeTracingController() {
    }

    FakeTracingController.prototype = {
      __proto__: base.EventTarget.prototype,

      get supportsSystemTracing() {
        return base.isChromeOS;
      },

      beginTracing: function(opt_systemTracingEnabled,
                             opt_continuousTracingEnabled,
                             opt_traceCategories) {
        this.wasBeginTracingCalled = true;
        this.wasBeginTracingCalledWithSystemTracingEnabled =
            opt_systemTracingEnabled;
        this.wasBeginTracingCalledWithContinuousTracingEnabled =
            opt_continuousTracingEnabled;
        this.beginTracingCategories = opt_traceCategories;
      },

      collectCategories: function() {
        this.wasCollectCategoriesCalled = true;
      },

      get traceEvents() {
        if (!this.wasBeginTracingCalled)
          return undefined;
        return testData;
      },

      get systemTraceEvents() {
        if (!this.wasBeginTracingCalled)
          return [];
        if (!this.wasBeginTracingCalledWithSystemTracingEnabled)
          return [];
        return systemTraceTestData;
      }
    };

    function recordTestCommon() {
      var view = new tracing.ProfilingView();
      var tracingController = new FakeTracingController();
      view.tracingController = tracingController;

      view.querySelector('button.record').click();
      assertTrue(tracingController.wasCollectCategoriesCalled);

      var e = new base.Event('categoriesCollected');
      e.categories = ['skia', 'gpu'];
      tracingController.dispatchEvent(e);

      view.categorySelectionDialog_.querySelector(
          'button.record-categories').click();

      assertTrue(tracingController.wasBeginTracingCalled);
      assertEquals(base.isChromeOS,
          tracingController.wasBeginTracingCalledWithSystemTracingEnabled);

      var e = new base.Event('traceEnded');
      e.events = tracingController.traceEvents;
      tracingController.dispatchEvent(e);
      assertTrue(!!view.timelineView.model);
    }

    function testSelectedCategoriesSentToTracing() {
      var view = new tracing.ProfilingView();
      view.timelineView_.settings.set('cc', 'true', 'record_categories');
      view.timelineView_.settings.set('renderer', 'false', 'record_categories');

      var tracingController = new FakeTracingController();
      view.tracingController = tracingController;

      view.querySelector('button.record').click();
      assertTrue(tracingController.wasCollectCategoriesCalled);

      var e = new base.Event('categoriesCollected');
      e.categories = ['skia', 'gpu', 'cc', 'renderer'];
      tracingController.dispatchEvent(e);

      view.categorySelectionDialog_.querySelector('input#skia').click();
      view.categorySelectionDialog_.querySelector(
          'button.record-categories').click();

      var categories = tracingController.beginTracingCategories;
      // Renderer is disabled in settings, skia is clicked off.
      assertEquals('-renderer,-skia', categories);
    }

    function testBadCategories() {
      var view = new tracing.ProfilingView();
      view.timelineView_.settings.set('foo,bar', 'false', 'record_categories');

      var tracingController = new FakeTracingController();
      view.tracingController = tracingController;

      view.querySelector('button.record').click();
      assertTrue(tracingController.wasCollectCategoriesCalled);

      var e = new base.Event('categoriesCollected');
      e.categories = ['baz,zap', 'gpu'];
      tracingController.dispatchEvent(e);

      view.categorySelectionDialog_.querySelector(
          'button.record-categories').click();

      var inputs = view.categorySelectionDialog_.querySelectorAll('input');
      var inputs_length = inputs.length;
      for (var i = 0; i < inputs_length; ++i) {
        // Comes from categories and should be split before getting
        // to the category selection dialog.
        assertNotEquals('baz,zap', inputs[i].id);
      }

      var categories = tracingController.beginTracingCategories;
      assertEquals('', categories);
    }

    function testRecordNonCros() {
      var old = base.isChromeOS;
      base.isChromeOS = false;
      try {
        recordTestCommon();
      } finally {
        base.isChromeOS = old;
      }
    }

    function testRecordCros() {
      var old = base.isChromeOS;
      base.isChromeOS = true;
      try {
        recordTestCommon();
      } finally {
        base.isChromeOS = old;
      }
    }
  </script>
</body>
</html>