tor-browser

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

audiocontext-playoutstats.html (5741B)


      1 <!DOCTYPE html>
      2 <html>
      3  <head>
      4    <title>Testing AudioContext.playoutStats attribute</title>
      5    <script src="/resources/testharness.js"></script>
      6    <script src="/resources/testharnessreport.js"></script>
      7  </head>
      8 
      9  <body>
     10    <script>
     11      function should_be_in_range(value, min, max) {
     12        assert_greater_than_equal(value, min);
     13        assert_less_than_equal(value, max);
     14      }
     15 
     16      promise_test(async (t) => {
     17        let context = new AudioContext();
     18        assert_not_equals(context.playoutStats, null);
     19 
     20        // Initially, the stats should all be 0.
     21        let stats = context.playoutStats;
     22        assert_equals(stats.totalFramesDuration, 0);
     23        assert_equals(stats.fallbackFramesDuration, 0);
     24        assert_equals(stats.fallbackFramesEvents, 0);
     25        assert_equals(stats.minimumLatency, 0);
     26        assert_equals(stats.maximumLatency, 0);
     27        assert_equals(stats.averageLatency, 0);
     28 
     29        // Asynchronously wait for 1.5 seconds. We will then check that the
     30        // stats reflect that the context has been playing for at least 0.9
     31        // seconds. The 0.1 second margin is needed because the stats are
     32        // updated once per second, and the context is not guaranteed to have
     33        // been playing for exactly 1 second by the time they are updated.
     34        // The extra 0.5 seconds of margin after the 1 second mark is to avoid
     35        // flakiness.
     36        // Note that awaiting moves us to a new task in the execution cycle,
     37        // which allows the stats to change.
     38        await new Promise((r) => step_timeout(r, 1500));
     39        assert_greater_than(stats.totalFramesDuration, 900);
     40        should_be_in_range(
     41          stats.fallbackFramesDuration,
     42          0,
     43          stats.totalFramesDuration
     44        );
     45        assert_greater_than_equal(stats.fallbackFramesEvents, 0);
     46        assert_greater_than_equal(stats.minimumLatency, 0);
     47        assert_greater_than_equal(stats.maximumLatency, 0);
     48        should_be_in_range(
     49          stats.averageLatency,
     50          stats.minimumLatency,
     51          stats.maximumLatency
     52        );
     53      }, "Test that the stats increase during playout");
     54 
     55      promise_test(async (t) => {
     56        let context = new AudioContext();
     57 
     58        // Wait a while so that we get stats that aren't all zeroes.
     59        await new Promise((r) => step_timeout(r, 1500));
     60        let stats = context.playoutStats;
     61        assert_greater_than(stats.totalFramesDuration, 1000);
     62 
     63        // Check that the stats from the toJSON object match the PlayoutStats
     64        // object.
     65        let json = stats.toJSON();
     66        assert_equals(json.totalFramesDuration, stats.totalFramesDuration);
     67        assert_equals(
     68          json.fallbackFramesDuration,
     69          stats.fallbackFramesDuration
     70        );
     71        assert_equals(json.fallbackFramesEvents, stats.fallbackFramesEvents);
     72        assert_equals(json.minimumLatency, stats.minimumLatency);
     73        assert_equals(json.maximumLatency, stats.maximumLatency);
     74        assert_equals(json.averageLatency, stats.averageLatency);
     75      }, "Test that toJSON reflects the current stats");
     76 
     77      promise_test(async (t) => {
     78        let context = new AudioContext();
     79 
     80        // Wait a while so that we get stats that aren't all zeroes.
     81        await new Promise((r) => step_timeout(r, 1500));
     82        let stats = context.playoutStats;
     83        assert_greater_than(stats.totalFramesDuration, 1000);
     84 
     85        // Average latency should be between minimum and maximum.
     86        let beforeReset = stats.toJSON();
     87        should_be_in_range(
     88          beforeReset.averageLatency,
     89          beforeReset.minimumLatency,
     90          beforeReset.maximumLatency
     91        );
     92 
     93        // After a reset, the minimum, maximum and average latencies should be
     94        // the same.
     95        stats.resetLatency();
     96        let afterReset = stats.toJSON();
     97        assert_equals(afterReset.minimumLatency, afterReset.averageLatency);
     98        assert_equals(afterReset.maximumLatency, afterReset.averageLatency);
     99      }, "Test PlayoutStats.resetLatency()");
    100 
    101      promise_test(async (t) => {
    102        // Tests that the API adheres to run to completion semantics, as
    103        // defined here: https://w3ctag.github.io/design-principles/#js-rtc
    104        let context = new AudioContext();
    105 
    106        // Wait a while so that we get stats that aren't all zeroes.
    107        await new Promise((r) => step_timeout(r, 1500));
    108        let stats = context.playoutStats;
    109        assert_greater_than(stats.totalFramesDuration, 1000);
    110        let beforeWait = stats.toJSON();
    111 
    112        // Synchronously wait 1500 ms.
    113        const start = performance.now();
    114        while (performance.now() - start < 1500);
    115 
    116        // We are still in the same execution cycle, so the stats shouldn't
    117        // have changed.
    118        assert_equals(
    119          stats.totalFramesDuration,
    120          beforeWait.totalFramesDuration
    121        );
    122        assert_equals(
    123          stats.fallbackFramesDuration,
    124          beforeWait.fallbackFramesDuration
    125        );
    126        assert_equals(
    127          stats.fallbackFramesEvents,
    128          beforeWait.fallbackFramesEvents
    129        );
    130        assert_equals(stats.minimumLatency, beforeWait.minimumLatency);
    131        assert_equals(stats.maximumLatency, beforeWait.maximumLatency);
    132        assert_equals(stats.averageLatency, beforeWait.averageLatency);
    133 
    134        // Move to the next execution cycle. Since it was 500 ms since the
    135        // stats were last updated, they have now increased.
    136        await Promise.resolve();
    137        assert_greater_than(
    138          stats.totalFramesDuration,
    139          beforeWait.totalFramesDuration
    140        );
    141      }, "Test that stats are unchanged within the same execution cycle.");
    142    </script>
    143  </body>
    144 </html>