Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
4 /**
5 * Make sure we get replies in the same order that we sent their
6 * requests even when earlier requests take several event ticks to
7 * complete.
8 */
10 let protocol = devtools.require("devtools/server/protocol");
11 let {method, Arg, Option, RetVal} = protocol;
12 let events = devtools.require("sdk/event/core");
14 function simpleHello() {
15 return {
16 from: "root",
17 applicationType: "xpcshell-tests",
18 traits: [],
19 }
20 }
22 let RootActor = protocol.ActorClass({
23 typeName: "root",
24 initialize: function(conn) {
25 protocol.Actor.prototype.initialize.call(this, conn);
26 // Root actor owns itself.
27 this.manage(this);
28 this.actorID = "root";
29 this.sequence = 0;
30 },
32 sayHello: simpleHello,
34 simpleReturn: method(function() {
35 return this.sequence++;
36 }, {
37 response: { value: RetVal() },
38 }),
40 promiseReturn: method(function(toWait) {
41 // Guarantee that this resolves after simpleReturn returns.
42 let deferred = promise.defer();
43 let sequence = this.sequence++;
45 // Wait until the number of requests specified by toWait have
46 // happened, to test queuing.
47 let check = () => {
48 if ((this.sequence - sequence) < toWait) {
49 do_execute_soon(check);
50 return;
51 }
52 deferred.resolve(sequence);
53 }
54 do_execute_soon(check);
56 return deferred.promise;
57 }, {
58 request: { toWait: Arg(0, "number") },
59 response: { value: RetVal("number") },
60 }),
62 simpleThrow: method(function() {
63 throw new Error(this.sequence++);
64 }, {
65 response: { value: RetVal("number") }
66 }),
68 promiseThrow: method(function() {
69 // Guarantee that this resolves after simpleReturn returns.
70 let deferred = promise.defer();
71 let sequence = this.sequence++;
72 // This should be enough to force a failure if the code is broken.
73 do_timeout(150, () => {
74 deferred.reject(sequence++);
75 });
76 return deferred.promise;
77 }, {
78 response: { value: RetVal("number") },
79 })
80 });
82 let RootFront = protocol.FrontClass(RootActor, {
83 initialize: function(client) {
84 this.actorID = "root";
85 protocol.Front.prototype.initialize.call(this, client);
86 // Root owns itself.
87 this.manage(this);
88 }
89 });
91 function run_test()
92 {
93 DebuggerServer.createRootActor = RootActor;
94 DebuggerServer.init(() => true);
96 let trace = connectPipeTracing();
97 let client = new DebuggerClient(trace);
98 let rootClient;
100 client.connect((applicationType, traits) => {
101 rootClient = RootFront(client);
103 let calls = [];
104 let sequence = 0;
106 // Execute a call that won't finish processing until 2
107 // more calls have happened
108 calls.push(rootClient.promiseReturn(2).then(ret => {
109 do_check_eq(sequence, 0); // Check right return order
110 do_check_eq(ret, sequence++); // Check request handling order
111 }));
113 // Put a few requests into the backlog
115 calls.push(rootClient.simpleReturn().then(ret => {
116 do_check_eq(sequence, 1); // Check right return order
117 do_check_eq(ret, sequence++); // Check request handling order
118 }));
120 calls.push(rootClient.simpleReturn().then(ret => {
121 do_check_eq(sequence, 2); // Check right return order
122 do_check_eq(ret, sequence++); // Check request handling order
123 }));
125 calls.push(rootClient.simpleThrow().then(() => {
126 do_check_true(false, "simpleThrow shouldn't succeed!");
127 }, error => {
128 do_check_eq(sequence++, 3); // Check right return order
129 }));
131 // While packets are sent in the correct order, rejection handlers
132 // registered in "Promise.jsm" may be invoked later than fulfillment
133 // handlers, meaning that we can't check the actual order with certainty.
134 let deferAfterRejection = promise.defer();
136 calls.push(rootClient.promiseThrow().then(() => {
137 do_check_true(false, "promiseThrow shouldn't succeed!");
138 }, error => {
139 do_check_eq(sequence++, 4); // Check right return order
140 do_check_true(true, "simple throw should throw");
141 deferAfterRejection.resolve();
142 }));
144 calls.push(rootClient.simpleReturn().then(ret => {
145 return deferAfterRejection.promise.then(function () {
146 do_check_eq(sequence, 5); // Check right return order
147 do_check_eq(ret, sequence++); // Check request handling order
148 });
149 }));
151 // Break up the backlog with a long request that waits
152 // for another simpleReturn before completing
153 calls.push(rootClient.promiseReturn(1).then(ret => {
154 return deferAfterRejection.promise.then(function () {
155 do_check_eq(sequence, 6); // Check right return order
156 do_check_eq(ret, sequence++); // Check request handling order
157 });
158 }));
160 calls.push(rootClient.simpleReturn().then(ret => {
161 return deferAfterRejection.promise.then(function () {
162 do_check_eq(sequence, 7); // Check right return order
163 do_check_eq(ret, sequence++); // Check request handling order
164 });
165 }));
167 promise.all(calls).then(() => {
168 client.close(() => {
169 do_test_finished();
170 });
171 })
172 });
173 do_test_pending();
174 }