Html程序  |  340行  |  7.37 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>Timeline stream importer tests</title>
<script src="base.js"></script>
</head>
<body>
<script>
  base.require('unittest');
  base.require('event_target');
  base.require('test_utils');
  base.require('timeline_stream_importer');
</script>
<script>
  'use strict';

  function FakeWebSocket() {
    base.EventTarget.call(this);
    this.sendHook_ = undefined;
    this.messages_ = [];
    this.connected_ = false;
  };

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

    set connected(connected) {
      if (this.connected_ == connected)
        return;
      this.connected_ = connected;
      if (this.connected_)
        base.dispatchSimpleEvent(this, 'connect');
      else
        base.dispatchSimpleEvent(this, 'disconnect');
    },

    get readyState() {
      if (this.connected_)
        return WebSocket.OPEN;
      return WebSocket.CLOSED;
    },

    pushMessage: function(msg) {
      this.messages_.push(JSON.stringify(msg));
    },

    get numPendingMessages() {
      return this.messages_.length;
    },

    dispatchAllPendingMessages: function() {
      var messages = this.messages_.splice(0, this.messages_.length);
      for (var i = 0; i < messages.length; i++)
        this.dispatchEvent({type: 'message', data: messages[i]});
    },

    /**
     * @param {function(message)} hook A function to call when send is
     called on the socket.
     */
    set sendHook(hook) {
      this.sendHook_ = hook;
    },

    send: function(message) {
      if (this.sendHook_)
        this.sendHook_(message);
    },

    set onopen(handler) {
      this.addEventListener('open', handler);
    },

    set onclose(handler) {
      this.addEventListener('close', handler);
    },

    set onerror(handler) {
      this.addEventListener('error', handler);
    },

    set onmessage(handler) {
      this.addEventListener('message', handler);
    }
  };

  function testImportBasic() {
    var model = new tracing.TimelineModel();
    var importer = new tracing.TimelineStreamImporter(model);

    assertFalse(importer.paused);
    assertFalse(importer.connected);

    var socket = new FakeWebSocket();
    importer.connect(socket);

    socket.connected = true;
    assertTrue(importer.connected);

    socket.pushMessage({
        cmd: 'ptd',
        pid: 1,
        td: { n: 3,
              s: [
                {s: 10, e: 11, l: 'alligator'},
                {s: 14, e: 15, l: 'bandicoot'},
                {s: 17, e: 18, l: 'cheetah'},
              ]
            }
        });
    socket.dispatchAllPendingMessages();

    assertNotUndefined(model.processes[1]);
    assertNotUndefined(model.processes[1].threads[3]);
    var t3 = model.processes[1].threads[3];
    assertEquals(3, t3.slices.length);

    assertEquals(model.minTimestamp, 10);
    assertEquals(model.maxTimestamp, 18);
  }

  function testPause() {
    var model = new tracing.TimelineModel();
    var importer = new tracing.TimelineStreamImporter(model);

    assertFalse(importer.paused);

    var socket = new FakeWebSocket();
    importer.connect(socket);
    socket.connected = true;

    var didSend = false;
    socket.sendHook = function(message) {
      var data = JSON.parse(message);
      didSend = true;
      assertEquals('pause', data['cmd']);
    }
    importer.pause();
    assertTrue(didSend);
    assertTrue(importer.paused);

    didSend = false;
    socket.sendHook = function(message) {
      var data = JSON.parse(message);
      didSend = true;
      assertEquals('resume', data['cmd']);
    }
    importer.resume();
    assertTrue(didSend);
    assertFalse(importer.paused);
  }

  function testCounters() {
    var model = new tracing.TimelineModel();
    var importer = new tracing.TimelineStreamImporter(model);

    assertFalse(importer.paused);
    assertFalse(importer.connected);

    var socket = new FakeWebSocket();
    importer.connect(socket);

    socket.connected = true;
    assertTrue(importer.connected);

    socket.pushMessage({
      cmd: "pcd",
      pid: 1,
      cd: {
        n: 'Allocator',
        sn: ['Bytes'],
        sc: [4],
        c: [
          {
            t: 2,
            v: [16]
          },
          {
            t: 16,
            v: [32]
          }
        ]
      }
    });

    socket.pushMessage({
      cmd: "pcd",
      pid: 1,
      cd: {
        n: 'Allocator',
        sn: ['Bytes'],
        sc: [4],
        c: [
          {
            t: 32,
            v: [48]
          },
          {
            t: 48,
            v: [64]
          },
          {
            t: 64,
            v: [16]
          }
        ]
      }
    });

    socket.dispatchAllPendingMessages();

    assertNotUndefined(model.processes[1]);
    assertNotUndefined(model.processes[1].counters['streamed.Allocator']);
    var counter = model.processes[1].counters['streamed.Allocator'];
    assertNotUndefined(counter.samples);
    assertEquals(counter.samples.length, 5);
    assertEquals(counter.seriesNames.length, 1);
    assertEquals(counter.seriesColors.length, 1);
    assertEquals(counter.samples[2], 48);
    assertEquals(counter.timestamps[4], 64);
    assertEquals(model.minTimestamp, 2);
    assertEquals(model.maxTimestamp, 64);
  }

  function testCounterImportErrors() {
    var model = new tracing.TimelineModel();
    var importer = new tracing.TimelineStreamImporter(model);

    assertFalse(importer.paused);
    assertFalse(importer.connected);

    var socket = new FakeWebSocket();
    importer.connect(socket);

    socket.connected = true;
    assertTrue(importer.connected);

    socket.pushMessage({
      cmd: "pcd",
      pid: 1,
      cd: {
        n: 'Allocator',
        sn: ['Bytes', 'Nibbles', 'Bits'],
        sc: [4,3,2],
        c: [
          {
            t: 2,
            v: [16,12,2]
          },
          {
            t: 16,
            v: [32,3,4]
          }
        ]
      }
    });

    // Test for name change import error
    socket.pushMessage({
      cmd: "pcd",
      pid: 1,
      cd: {
        n: 'Allocator',
        sn: ['Bytes', 'NotNibbles', 'Bits'],
        sc: [4,3,2],
        c: [
          {
            t: 18,
            v: [16,12,2]
          },
          {
            t: 24,
            v: [32,3,4]
          }
        ]
      }
    });

    socket.dispatchAllPendingMessages();

    assertNotUndefined(model.processes[1]);
    assertEquals(model.importErrors.length, 1);
    // test for series number change
    socket.pushMessage({
      cmd: "pcd",
      pid: 1,
      cd: {
        n: 'Allocator',
        sn: ['Bytes', 'Bits'],
        sc: [4,3],
        c: [
          {
            t: 26,
            v: [16,12]
          },
          {
            t: 32,
            v: [32,3]
          }
        ]
      }
    });

    socket.dispatchAllPendingMessages();
    assertEquals(model.importErrors.length, 2);

    // test for sn.length != sc.length
    socket.pushMessage({
      cmd: "pcd",
      pid: 1,
      cd: {
        n: 'Allocator',
        sn: ['Bytes', 'Nibbles', 'Bits'],
        sc: [4,3,2,5],
        c: [
          {
            t: 2,
            v: [16,12,2]
          },
          {
            t: 16,
            v: [32,3,4]
          }
        ]
      }
    });


    socket.dispatchAllPendingMessages();
    assertEquals(model.importErrors.length, 3);
  }
</script>
</body>
</html>