tor-browser

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

browser_handle_command_timeout.js (4994B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // The expected timeouts are reduced for this test, but we still need to wait
      7 // for the commands to fully resolve, and it might be a bit slow.
      8 requestLongerTimeout(2);
      9 
     10 const { Log } = ChromeUtils.importESModule(
     11  "resource://gre/modules/Log.sys.mjs"
     12 );
     13 
     14 class TestAppender extends Log.Appender {
     15  constructor(formatter) {
     16    super(formatter);
     17    this.messages = [];
     18  }
     19 
     20  append(message) {
     21    this.doAppend(message);
     22  }
     23 
     24  doAppend(message) {
     25    this.messages.push(message);
     26  }
     27 
     28  reset() {
     29    this.messages = [];
     30  }
     31 }
     32 
     33 add_task(async function test_commandTimeout() {
     34  const log = Log.repository.getLogger("RemoteAgent");
     35  const appender = new TestAppender(new Log.BasicFormatter());
     36  appender.level = Log.Level.Trace;
     37  log.addAppender(appender);
     38 
     39  const tab = BrowserTestUtils.addTab(
     40    gBrowser,
     41    "https://example.com/document-builder.sjs?html=tab"
     42  );
     43  const browsingContext = tab.linkedBrowser.browsingContext;
     44  await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
     45 
     46  const rootMessageHandler = createRootMessageHandler("session-id-timeout");
     47 
     48  info("Call a relatively fast command which should not trigger a ping");
     49  await rootMessageHandler.handleCommand({
     50    moduleName: "timeout",
     51    commandName: "waitFor",
     52    params: {
     53      delay: 1000,
     54    },
     55    destination: {
     56      type: WindowGlobalMessageHandler.type,
     57      id: browsingContext.id,
     58    },
     59  });
     60 
     61  assertSendingPingMessageLogged(appender.messages, false);
     62  appender.reset();
     63 
     64  info("Call a slow command which will trigger a ping");
     65  await rootMessageHandler.handleCommand({
     66    moduleName: "timeout",
     67    commandName: "waitFor",
     68    params: {
     69      delay: 5000,
     70    },
     71    destination: {
     72      type: WindowGlobalMessageHandler.type,
     73      id: browsingContext.id,
     74    },
     75  });
     76 
     77  // The command should take more time than the (reduced) timeout and a ping
     78  // should be sent. The ping should succeed since the content process / main
     79  // thread should not hang.
     80  assertSendingPingMessageLogged(appender.messages, true);
     81  assertSuccessfulPingMessageLogged(appender.messages, true);
     82  assertFailedPingMessageLogged(appender.messages, false);
     83  appender.reset();
     84 
     85  info("Call a command which hangs the content process main thread for 10s");
     86  const onBlockedCommand = rootMessageHandler.handleCommand({
     87    moduleName: "timeout",
     88    commandName: "blockProcess",
     89    params: {
     90      delay: 10000,
     91    },
     92    destination: {
     93      type: WindowGlobalMessageHandler.type,
     94      id: browsingContext.id,
     95    },
     96  });
     97 
     98  info("Wait until the ping message has been logged");
     99  await TestUtils.waitForCondition(() =>
    100    appender.messages.find(m =>
    101      m.message.startsWith("MessageHandlerFrameParent ping")
    102    )
    103  );
    104 
    105  // This time expect messages logged for a failed Ping.
    106  assertSendingPingMessageLogged(appender.messages, true);
    107  assertSuccessfulPingMessageLogged(appender.messages, false);
    108  assertFailedPingMessageLogged(appender.messages, true);
    109  appender.reset();
    110 
    111  await onBlockedCommand;
    112 
    113  rootMessageHandler.destroy();
    114  gBrowser.removeTab(tab);
    115 });
    116 
    117 /**
    118 * Assert helper to check if the message corresponding to MessageHandler
    119 * sending a ping can be found or not in the provided messages array.
    120 *
    121 * @param {Array} messages
    122 *     The array of log appender messages to check.
    123 * @param {boolean} expected
    124 *     True if the message expects to be found, false otherwise.
    125 */
    126 function assertSendingPingMessageLogged(messages, expected) {
    127  is(
    128    !!messages.find(m => m.message.includes("sending ping")),
    129    expected,
    130    expected ? "A ping was sent and logged" : "No ping was sent"
    131  );
    132 }
    133 
    134 /**
    135 * Assert helper to check if the message corresponding to a MessageHandler
    136 * successful ping can be found or not in the provided messages array.
    137 *
    138 * @param {Array} messages
    139 *     The array of log appender messages to check.
    140 * @param {boolean} expected
    141 *     True if the message expects to be found, false otherwise.
    142 */
    143 function assertSuccessfulPingMessageLogged(messages, expected) {
    144  is(
    145    !!messages.find(m =>
    146      /MessageHandlerFrameParent ping for command [a-zA-Z.]+ to \w+ was successful/.test(
    147        m.message
    148      )
    149    ),
    150    expected,
    151    expected ? "Successful ping logged" : "No successful ping logged"
    152  );
    153 }
    154 
    155 /**
    156 * Assert helper to check if the message corresponding to a MessageHandler
    157 * failed ping can be found or not in the provided messages array.
    158 *
    159 * @param {Array} messages
    160 *     The array of log appender messages to check.
    161 * @param {boolean} expected
    162 *     True if the message expects to be found, false otherwise.
    163 */
    164 function assertFailedPingMessageLogged(messages, expected) {
    165  is(
    166    !!messages.find(m =>
    167      /MessageHandlerFrameParent ping for command [a-zA-Z.]+ to \w+ timed out/.test(
    168        m.message
    169      )
    170    ),
    171    expected,
    172    expected ? "Failed ping logged" : "No failed ping logged"
    173  );
    174 }