tor-browser

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

test_protocol_async.js (4494B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 /**
      7 * Make sure we get replies in the same order that we sent their
      8 * requests even when earlier requests take several event ticks to
      9 * complete.
     10 */
     11 
     12 const { waitForTick } = require("resource://devtools/shared/DevToolsUtils.js");
     13 const protocol = require("resource://devtools/shared/protocol.js");
     14 const { Arg, RetVal } = protocol;
     15 
     16 const rootSpec = protocol.generateActorSpec({
     17  typeName: "root",
     18 
     19  methods: {
     20    simpleReturn: {
     21      response: { value: RetVal() },
     22    },
     23    promiseReturn: {
     24      request: { toWait: Arg(0, "number") },
     25      response: { value: RetVal("number") },
     26    },
     27    simpleThrow: {
     28      response: { value: RetVal("number") },
     29    },
     30    promiseThrow: {
     31      request: { toWait: Arg(0, "number") },
     32      response: { value: RetVal("number") },
     33    },
     34  },
     35 });
     36 
     37 class RootActor extends protocol.Actor {
     38  constructor(conn) {
     39    super(conn, rootSpec);
     40 
     41    // Root actor owns itself.
     42    this.manage(this);
     43    this.actorID = "root";
     44    this.sequence = 0;
     45  }
     46 
     47  sayHello() {
     48    return {
     49      from: "root",
     50      applicationType: "xpcshell-tests",
     51      traits: [],
     52    };
     53  }
     54 
     55  simpleReturn() {
     56    return this.sequence++;
     57  }
     58 
     59  // Guarantee that this resolves after simpleReturn returns.
     60  async promiseReturn(toWait) {
     61    const sequence = this.sequence++;
     62 
     63    // Wait until the number of requests specified by toWait have
     64    // happened, to test queuing.
     65    while (this.sequence - sequence < toWait) {
     66      await waitForTick();
     67    }
     68 
     69    return sequence;
     70  }
     71 
     72  simpleThrow() {
     73    throw new Error(this.sequence++);
     74  }
     75 
     76  // Guarantee that this resolves after simpleReturn returns.
     77  promiseThrow(toWait) {
     78    return this.promiseReturn(toWait).then(Promise.reject);
     79  }
     80 }
     81 
     82 class RootFront extends protocol.FrontClassWithSpec(rootSpec) {
     83  constructor(client) {
     84    super(client);
     85    this.actorID = "root";
     86    // Root owns itself.
     87    this.manage(this);
     88  }
     89 
     90  connect() {}
     91 }
     92 protocol.registerFront(RootFront);
     93 
     94 add_task(async function () {
     95  DevToolsServer.createRootActor = conn => new RootActor(conn);
     96  DevToolsServer.init();
     97 
     98  const trace = connectPipeTracing();
     99  const client = new DevToolsClient(trace);
    100  await client.connect();
    101 
    102  const rootFront = client.mainRoot;
    103 
    104  const calls = [];
    105  let sequence = 0;
    106 
    107  // Execute a call that won't finish processing until 2
    108  // more calls have happened
    109  calls.push(
    110    rootFront.promiseReturn(2).then(ret => {
    111      // Check right return order
    112      Assert.equal(sequence, 0);
    113      // Check request handling order
    114      Assert.equal(ret, sequence++);
    115    })
    116  );
    117 
    118  // Put a few requests into the backlog
    119 
    120  calls.push(
    121    rootFront.simpleReturn().then(ret => {
    122      // Check right return order
    123      Assert.equal(sequence, 1);
    124      // Check request handling order
    125      Assert.equal(ret, sequence++);
    126    })
    127  );
    128 
    129  calls.push(
    130    rootFront.simpleReturn().then(ret => {
    131      // Check right return order
    132      Assert.equal(sequence, 2);
    133      // Check request handling order
    134      Assert.equal(ret, sequence++);
    135    })
    136  );
    137 
    138  calls.push(
    139    rootFront.simpleThrow().then(
    140      () => {
    141        Assert.ok(false, "simpleThrow shouldn't succeed!");
    142      },
    143      () => {
    144        // Check right return order
    145        Assert.equal(sequence++, 3);
    146      }
    147    )
    148  );
    149 
    150  calls.push(
    151    rootFront.promiseThrow(2).then(
    152      () => {
    153        Assert.ok(false, "promiseThrow shouldn't succeed!");
    154      },
    155      () => {
    156        // Check right return order
    157        Assert.equal(sequence++, 4);
    158        Assert.ok(true, "simple throw should throw");
    159      }
    160    )
    161  );
    162 
    163  calls.push(
    164    rootFront.simpleReturn().then(ret => {
    165      // Check right return order
    166      Assert.equal(sequence, 5);
    167      // Check request handling order
    168      Assert.equal(ret, sequence++);
    169    })
    170  );
    171 
    172  // Break up the backlog with a long request that waits
    173  // for another simpleReturn before completing
    174  calls.push(
    175    rootFront.promiseReturn(1).then(ret => {
    176      // Check right return order
    177      Assert.equal(sequence, 6);
    178      // Check request handling order
    179      Assert.equal(ret, sequence++);
    180    })
    181  );
    182 
    183  calls.push(
    184    rootFront.simpleReturn().then(ret => {
    185      // Check right return order
    186      Assert.equal(sequence, 7);
    187      // Check request handling order
    188      Assert.equal(ret, sequence++);
    189    })
    190  );
    191 
    192  await Promise.all(calls);
    193  await client.close();
    194 });