toolkit/devtools/server/tests/unit/test_protocol_async.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/devtools/server/tests/unit/test_protocol_async.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,174 @@
     1.4 +/* Any copyright is dedicated to the Public Domain.
     1.5 +   http://creativecommons.org/publicdomain/zero/1.0/ */
     1.6 +
     1.7 +/**
     1.8 + * Make sure we get replies in the same order that we sent their
     1.9 + * requests even when earlier requests take several event ticks to
    1.10 + * complete.
    1.11 + */
    1.12 +
    1.13 +let protocol = devtools.require("devtools/server/protocol");
    1.14 +let {method, Arg, Option, RetVal} = protocol;
    1.15 +let events = devtools.require("sdk/event/core");
    1.16 +
    1.17 +function simpleHello() {
    1.18 +  return {
    1.19 +    from: "root",
    1.20 +    applicationType: "xpcshell-tests",
    1.21 +    traits: [],
    1.22 +  }
    1.23 +}
    1.24 +
    1.25 +let RootActor = protocol.ActorClass({
    1.26 +  typeName: "root",
    1.27 +  initialize: function(conn) {
    1.28 +    protocol.Actor.prototype.initialize.call(this, conn);
    1.29 +    // Root actor owns itself.
    1.30 +    this.manage(this);
    1.31 +    this.actorID = "root";
    1.32 +    this.sequence = 0;
    1.33 +  },
    1.34 +
    1.35 +  sayHello: simpleHello,
    1.36 +
    1.37 +  simpleReturn: method(function() {
    1.38 +    return this.sequence++;
    1.39 +  }, {
    1.40 +    response: { value: RetVal() },
    1.41 +  }),
    1.42 +
    1.43 +  promiseReturn: method(function(toWait) {
    1.44 +    // Guarantee that this resolves after simpleReturn returns.
    1.45 +    let deferred = promise.defer();
    1.46 +    let sequence = this.sequence++;
    1.47 +
    1.48 +    // Wait until the number of requests specified by toWait have
    1.49 +    // happened, to test queuing.
    1.50 +    let check = () => {
    1.51 +      if ((this.sequence - sequence) < toWait) {
    1.52 +        do_execute_soon(check);
    1.53 +        return;
    1.54 +      }
    1.55 +      deferred.resolve(sequence);
    1.56 +    }
    1.57 +    do_execute_soon(check);
    1.58 +
    1.59 +    return deferred.promise;
    1.60 +  }, {
    1.61 +    request: { toWait: Arg(0, "number") },
    1.62 +    response: { value: RetVal("number") },
    1.63 +  }),
    1.64 +
    1.65 +  simpleThrow: method(function() {
    1.66 +    throw new Error(this.sequence++);
    1.67 +  }, {
    1.68 +    response: { value: RetVal("number") }
    1.69 +  }),
    1.70 +
    1.71 +  promiseThrow: method(function() {
    1.72 +    // Guarantee that this resolves after simpleReturn returns.
    1.73 +    let deferred = promise.defer();
    1.74 +    let sequence = this.sequence++;
    1.75 +    // This should be enough to force a failure if the code is broken.
    1.76 +    do_timeout(150, () => {
    1.77 +      deferred.reject(sequence++);
    1.78 +    });
    1.79 +    return deferred.promise;
    1.80 +  }, {
    1.81 +    response: { value: RetVal("number") },
    1.82 +  })
    1.83 +});
    1.84 +
    1.85 +let RootFront = protocol.FrontClass(RootActor, {
    1.86 +  initialize: function(client) {
    1.87 +    this.actorID = "root";
    1.88 +    protocol.Front.prototype.initialize.call(this, client);
    1.89 +    // Root owns itself.
    1.90 +    this.manage(this);
    1.91 +  }
    1.92 +});
    1.93 +
    1.94 +function run_test()
    1.95 +{
    1.96 +  DebuggerServer.createRootActor = RootActor;
    1.97 +  DebuggerServer.init(() => true);
    1.98 +
    1.99 +  let trace = connectPipeTracing();
   1.100 +  let client = new DebuggerClient(trace);
   1.101 +  let rootClient;
   1.102 +
   1.103 +  client.connect((applicationType, traits) => {
   1.104 +    rootClient = RootFront(client);
   1.105 +
   1.106 +    let calls = [];
   1.107 +    let sequence = 0;
   1.108 +
   1.109 +    // Execute a call that won't finish processing until 2
   1.110 +    // more calls have happened
   1.111 +    calls.push(rootClient.promiseReturn(2).then(ret => {
   1.112 +      do_check_eq(sequence, 0); // Check right return order
   1.113 +      do_check_eq(ret, sequence++); // Check request handling order
   1.114 +    }));
   1.115 +
   1.116 +    // Put a few requests into the backlog
   1.117 +
   1.118 +    calls.push(rootClient.simpleReturn().then(ret => {
   1.119 +      do_check_eq(sequence, 1); // Check right return order
   1.120 +      do_check_eq(ret, sequence++); // Check request handling order
   1.121 +    }));
   1.122 +
   1.123 +    calls.push(rootClient.simpleReturn().then(ret => {
   1.124 +      do_check_eq(sequence, 2); // Check right return order
   1.125 +      do_check_eq(ret, sequence++); // Check request handling order
   1.126 +    }));
   1.127 +
   1.128 +    calls.push(rootClient.simpleThrow().then(() => {
   1.129 +      do_check_true(false, "simpleThrow shouldn't succeed!");
   1.130 +    }, error => {
   1.131 +      do_check_eq(sequence++, 3); // Check right return order
   1.132 +    }));
   1.133 +
   1.134 +    // While packets are sent in the correct order, rejection handlers
   1.135 +    // registered in "Promise.jsm" may be invoked later than fulfillment
   1.136 +    // handlers, meaning that we can't check the actual order with certainty.
   1.137 +    let deferAfterRejection = promise.defer();
   1.138 +
   1.139 +    calls.push(rootClient.promiseThrow().then(() => {
   1.140 +      do_check_true(false, "promiseThrow shouldn't succeed!");
   1.141 +    }, error => {
   1.142 +      do_check_eq(sequence++, 4); // Check right return order
   1.143 +      do_check_true(true, "simple throw should throw");
   1.144 +      deferAfterRejection.resolve();
   1.145 +    }));
   1.146 +
   1.147 +    calls.push(rootClient.simpleReturn().then(ret => {
   1.148 +      return deferAfterRejection.promise.then(function () {
   1.149 +        do_check_eq(sequence, 5); // Check right return order
   1.150 +        do_check_eq(ret, sequence++); // Check request handling order
   1.151 +      });
   1.152 +    }));
   1.153 +
   1.154 +    // Break up the backlog with a long request that waits
   1.155 +    // for another simpleReturn before completing
   1.156 +    calls.push(rootClient.promiseReturn(1).then(ret => {
   1.157 +      return deferAfterRejection.promise.then(function () {
   1.158 +        do_check_eq(sequence, 6); // Check right return order
   1.159 +        do_check_eq(ret, sequence++); // Check request handling order
   1.160 +      });
   1.161 +    }));
   1.162 +
   1.163 +    calls.push(rootClient.simpleReturn().then(ret => {
   1.164 +      return deferAfterRejection.promise.then(function () {
   1.165 +        do_check_eq(sequence, 7); // Check right return order
   1.166 +        do_check_eq(ret, sequence++); // Check request handling order
   1.167 +      });
   1.168 +    }));
   1.169 +
   1.170 +    promise.all(calls).then(() => {
   1.171 +      client.close(() => {
   1.172 +        do_test_finished();
   1.173 +      });
   1.174 +    })
   1.175 +  });
   1.176 +  do_test_pending();
   1.177 +}

mercurial