tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

RTCDataChannel-stats.html (7992B)


      1 <!doctype html>
      2 <html>
      3  <head>
      4    <meta charset="utf-8"/>
      5    <meta name="timeout" content="long"/>
      6    <script src="/resources/testharness.js"></script>
      7    <script src="/resources/testharnessreport.js"></script>
      8    <script src="../webrtc/RTCPeerConnection-helper.js"></script>
      9    <script src="../webrtc/RTCDataChannel-helper.js"></script>
     10    <script src="../webrtc/RTCDataChannel-worker-shim.js"></script>
     11  </head>
     12  <body>
     13    <script>
     14 
     15 async function getDcStats(pc) {
     16  const stats = await pc.getStats();
     17  return [...stats.values()].filter(({type}) => type == "data-channel");
     18 }
     19 
     20 // Oh boy here we go!
     21 for (const which of ['neither', 'offerer', 'answerer']) {
     22 
     23  promise_test(async test => {
     24    const {offerer, answerer, offererChannel, answererChannel} =
     25      await makeDataChannelTestFixture(which, {},
     26        which == 'offerer' ? new WorkerBackedDataChannel() : null,
     27        which == 'answerer' ? new WorkerBackedDataChannel() : null);
     28 
     29    const dcStats1 = await getDcStats(offerer);
     30    assert_equals(dcStats1.length, 1,
     31      "One RTCDataChannel results in one data-channel stats object (offerer)");
     32 
     33    const dcStats2 = await getDcStats(answerer);
     34    assert_equals(dcStats2.length, 1,
     35      "One RTCDataChannel results in one data-channel stats object (answerer)");
     36  }, `${which} on worker: Check that RTCDataChannelStats are present`);
     37 
     38  promise_test(async test => {
     39    const {offerer, answerer, offererChannel, answererChannel} =
     40      await makeDataChannelTestFixture(which, {},
     41        which == 'offerer' ? new WorkerBackedDataChannel() : null,
     42        which == 'answerer' ? new WorkerBackedDataChannel() : null);
     43 
     44    test.add_cleanup(() => offerer.close());
     45    test.add_cleanup(() => answerer.close());
     46 
     47    for (const [pc, channel, type] of [
     48      [offerer, offererChannel, "offerer"],
     49      [answerer, answererChannel, "answerer"],
     50    ]) {
     51      const dcStats = await getDcStats(pc);
     52      assert_equals(dcStats.length, 1,
     53      `One RTCDataChannel results in one data-channel stats object (${type})`);
     54 
     55      assert_equals(dcStats[0].label, channel.label,
     56        `Stats label should match (${type})`);
     57      assert_equals(dcStats[0].protocol, channel.protocol,
     58        `Stats protocol should match (${type})`);
     59      assert_equals(dcStats[0].dataChannelIdentifier, channel.id,
     60        `Stats dataChannelIdentifier/id should match (${type})`);
     61      assert_equals(dcStats[0].state, channel.readyState,
     62        `Stats state/readyState should match (${type})`);
     63      assert_equals(dcStats[0].messagesSent, 0,
     64        `Initial messagesSent should be 0 (${type})`);
     65      assert_equals(dcStats[0].bytesSent, 0,
     66        `Initial bytesSent should be 0 (${type})`);
     67      assert_equals(dcStats[0].messagesReceived, 0,
     68        `Initial messagesReceived should be 0 (${type})`);
     69      assert_equals(dcStats[0].bytesReceived, 0,
     70        `Initial bytesReceived should be 0 (${type})`);
     71    };
     72  }, `${which} on worker: Check that RTCDataChannelStats have a valid initial state`);
     73 
     74  async function getDcCounterStats(pc) {
     75    const dcStats = await getDcStats(pc);
     76    return {
     77      bytesSent: dcStats[0].bytesSent,
     78      bytesReceived: dcStats[0].bytesReceived,
     79      messagesSent: dcStats[0].messagesSent,
     80      messagesReceived: dcStats[0].messagesReceived,
     81    };
     82  }
     83 
     84  promise_test(async test => {
     85    const {offerer, answerer, offererChannel, answererChannel} =
     86      await makeDataChannelTestFixture(which, {},
     87        which == 'offerer' ? new WorkerBackedDataChannel() : null,
     88        which == 'answerer' ? new WorkerBackedDataChannel() : null);
     89 
     90    test.add_cleanup(() => offerer.close());
     91    test.add_cleanup(() => answerer.close());
     92 
     93    for (const message of ['hello', '', '世界你好']) {
     94      for (const [sender, senderDc, receiver, receiverDc] of [
     95        [offerer, offererChannel, answerer, answererChannel],
     96        [answerer, answererChannel, offerer, offererChannel],
     97      ]) {
     98        const senderCountersBefore = await getDcCounterStats(sender);
     99        const receiverCountersBefore = await getDcCounterStats(receiver);
    100 
    101        senderDc.send(message);
    102        const recvEvent = await new Promise(r => receiverDc.onmessage = r);
    103        assert_equals(recvEvent.data, message);
    104        const encoder = new TextEncoder();
    105        const byteLength = encoder.encode(message).length;
    106 
    107        const senderCountersAfter = await getDcCounterStats(sender);
    108        const receiverCountersAfter = await getDcCounterStats(receiver);
    109 
    110        // Don't bother checking the other way around for zeroes
    111        assert_equals(senderCountersAfter.bytesSent,
    112          senderCountersBefore.bytesSent + byteLength,
    113          "Got expected sender bytesSent");
    114        assert_equals(senderCountersAfter.messagesSent,
    115          senderCountersBefore.messagesSent + 1,
    116          "Got expected sender messagesSent");
    117 
    118        assert_equals(receiverCountersAfter.bytesReceived,
    119          receiverCountersBefore.bytesReceived + byteLength,
    120          "Got expected receiver bytesReceived");
    121        assert_equals(receiverCountersAfter.messagesReceived,
    122          receiverCountersBefore.messagesReceived + 1,
    123          "Got expected receiver messagesReceived");
    124      }
    125    }
    126  }, `${which} on worker: Check that RTCDataChannelStats messages/bytes Sent/Received are correct for various strings`);
    127 
    128  // ASCII encoded buffer representation of the string
    129  const helloBuffer = Uint8Array.of(0x68, 0x65, 0x6c, 0x6c, 0x6f);
    130  const emptyBuffer = new Uint8Array();
    131  const helloBlob = new Blob([helloBuffer]);
    132 
    133  // UTF-8 encoded buffer representation of the string
    134  const unicodeBuffer = Uint8Array.of(
    135    0xe4, 0xb8, 0x96, 0xe7, 0x95, 0x8c,
    136    0xe4, 0xbd, 0xa0, 0xe5, 0xa5, 0xbd);
    137 
    138  // TODO: How finely-grained should we make these? Each one requires ICE, so we
    139  // can't do each case separately. What should the top-level loop be?
    140  for (const binaryType of ["arraybuffer", "blob"]) {
    141    promise_test(async test => {
    142    const {offerer, answerer, offererChannel, answererChannel} =
    143      await makeDataChannelTestFixture(which, {},
    144        which == 'offerer' ? new WorkerBackedDataChannel() : null,
    145        which == 'answerer' ? new WorkerBackedDataChannel() : null);
    146 
    147      test.add_cleanup(() => offerer.close());
    148      test.add_cleanup(() => answerer.close());
    149 
    150      for (const [message, bytes] of [
    151        [helloBlob, 5],
    152        [helloBuffer.buffer, 5],
    153        [helloBuffer, 5],
    154        [unicodeBuffer, 12]
    155      ]) {
    156        for (const [sender, senderDc, receiver, receiverDc] of [
    157          [offerer, offererChannel, answerer, answererChannel],
    158          [answerer, answererChannel, offerer, offererChannel],
    159        ]) {
    160 
    161          receiver.binaryType = binaryType;
    162 
    163          const senderCountersBefore = await getDcCounterStats(sender);
    164          const receiverCountersBefore = await getDcCounterStats(receiver);
    165 
    166          senderDc.send(message);
    167          const recvEvent = await new Promise(r => receiverDc.onmessage = r);
    168 
    169          const senderCountersAfter = await getDcCounterStats(sender);
    170          const receiverCountersAfter = await getDcCounterStats(receiver);
    171 
    172          assert_equals(senderCountersAfter.bytesSent,
    173            senderCountersBefore.bytesSent + bytes,
    174            "Got expected sender bytesSent");
    175          assert_equals(senderCountersAfter.messagesSent,
    176            senderCountersBefore.messagesSent + 1,
    177            "Got expected sender messagesSent");
    178 
    179          assert_equals(receiverCountersAfter.bytesReceived,
    180            receiverCountersBefore.bytesReceived + bytes,
    181            "Got expected receiver bytesReceived");
    182          assert_equals(receiverCountersAfter.messagesReceived,
    183            receiverCountersBefore.messagesReceived + 1,
    184            "Got expected receiver messagesReceived");
    185        }
    186      }
    187    }, `${which} on worker: Check that RTCDataChannelStats messages/bytes Sent/Received are correct for various binary messages received as ${binaryType}`);
    188  }
    189 }
    190    </script>
    191  </body>
    192 </html>