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

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:104b5f63f289
1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
3
4 /* Exercise prefix-based forwarding of packets to other transports. */
5
6 var gMainConnection, gMainTransport;
7 var gSubconnection1, gSubconnection2;
8 var gClient;
9
10 function run_test()
11 {
12 DebuggerServer.init();
13
14 add_test(createMainConnection);
15 add_test(TestNoForwardingYet);
16 add_test(createSubconnection1);
17 add_test(TestForwardPrefix1OnlyRoot);
18 add_test(createSubconnection2);
19 add_test(TestForwardPrefix12OnlyRoot);
20 add_test(TestForwardPrefix12WithActor1);
21 add_test(TestForwardPrefix12WithActor12);
22 run_next_test();
23 }
24
25 /*
26 * Create a pipe connection, and return an object |{ conn, transport }|,
27 * where |conn| is the new DebuggerServerConnection instance, and
28 * |transport| is the client side of the transport on which it communicates
29 * (that is, packets sent on |transport| go to the new connection, and
30 * |transport|'s hooks receive replies).
31 *
32 * |aPrefix| is optional; if present, it's the prefix (minus the ':') for
33 * actors in the new connection.
34 */
35 function newConnection(aPrefix)
36 {
37 var conn;
38 DebuggerServer.createRootActor = function (aConn) {
39 conn = aConn;
40 return new DebuggerServer.RootActor(aConn, {});
41 };
42
43 var transport = DebuggerServer.connectPipe(aPrefix);
44
45 return { conn: conn, transport: transport };
46 }
47
48 /* Create the main connection for these tests. */
49 function createMainConnection()
50 {
51 ({ conn: gMainConnection, transport: gMainTransport }) = newConnection();
52 gClient = new DebuggerClient(gMainTransport);
53 gClient.connect((aType, aTraits) => run_next_test());
54 }
55
56 /*
57 * Exchange 'echo' messages with five actors:
58 * - root
59 * - prefix1:root
60 * - prefix1:actor
61 * - prefix2:root
62 * - prefix2:actor
63 *
64 * Expect proper echos from those named in |aReachables|, and 'noSuchActor'
65 * errors from the others. When we've gotten all our replies (errors or
66 * otherwise), call |aCompleted|.
67 *
68 * To avoid deep stacks, we call aCompleted from the next tick.
69 */
70 function tryActors(aReachables, aCompleted) {
71 let count = 0;
72
73 let outerActor;
74 for (outerActor of [ 'root',
75 'prefix1:root', 'prefix1:actor',
76 'prefix2:root', 'prefix2:actor' ]) {
77 /*
78 * Let each callback capture its own iteration's value; outerActor is
79 * local to the whole loop, not to a single iteration.
80 */
81 let actor = outerActor;
82
83 count++;
84
85 gClient.request({ to: actor, type: 'echo', value: 'tango'}, // phone home
86 (aResponse) => {
87 if (aReachables.has(actor))
88 do_check_matches({ from: actor, type: 'echo', value: 'tango' }, aResponse);
89 else
90 do_check_matches({ from: actor, error: 'noSuchActor' }, aResponse);
91
92 if (--count == 0)
93 do_execute_soon(aCompleted, "tryActors callback " + aCompleted.name);
94 });
95 }
96 }
97
98 /*
99 * With no forwarding established, sending messages to root should work,
100 * but sending messages to prefixed actor names, or anyone else, should get
101 * an error.
102 */
103 function TestNoForwardingYet()
104 {
105 tryActors(Set(['root']), run_next_test);
106 }
107
108 /*
109 * Create a new pipe connection which forwards its reply packets to
110 * gMainConnection's client, and to which gMainConnection forwards packets
111 * directed to actors whose names begin with |aPrefix + ':'|, and.
112 *
113 * Return an object { conn, transport }, as for newConnection.
114 */
115 function newSubconnection(aPrefix)
116 {
117 let { conn, transport } = newConnection(aPrefix);
118 transport.hooks = {
119 onPacket: (aPacket) => gMainConnection.send(aPacket),
120 onClosed: () => {}
121 }
122 gMainConnection.setForwarding(aPrefix, transport);
123
124 return { conn: conn, transport: transport };
125 }
126
127 /* Create a second root actor, to which we can forward things. */
128 function createSubconnection1()
129 {
130 let { conn, transport } = newSubconnection('prefix1');
131 gSubconnection1 = conn;
132 transport.ready();
133 gClient.expectReply('prefix1:root', (aReply) => run_next_test());
134 }
135
136 // Establish forwarding, but don't put any actors in that server.
137 function TestForwardPrefix1OnlyRoot()
138 {
139 tryActors(Set(['root', 'prefix1:root']), run_next_test);
140 }
141
142 /* Create a third root actor, to which we can forward things. */
143 function createSubconnection2()
144 {
145 let { conn, transport } = newSubconnection('prefix2');
146 gSubconnection2 = conn;
147 transport.ready();
148 gClient.expectReply('prefix2:root', (aReply) => run_next_test());
149 }
150
151 function TestForwardPrefix12OnlyRoot()
152 {
153 tryActors(Set(['root', 'prefix1:root', 'prefix2:root']), run_next_test);
154 }
155
156 // A dumb actor that implements 'echo'.
157 //
158 // It's okay that both subconnections' actors behave identically, because
159 // the reply-sending code attaches the replying actor's name to the packet,
160 // so simply matching the 'from' field in the reply ensures that we heard
161 // from the right actor.
162 function EchoActor(aConnection)
163 {
164 this.conn = aConnection;
165 }
166 EchoActor.prototype.actorPrefix = "EchoActor";
167 EchoActor.prototype.onEcho = function (aRequest) {
168 /*
169 * Request packets are frozen. Copy aRequest, so that
170 * DebuggerServerConnection.onPacket can attach a 'from' property.
171 */
172 return JSON.parse(JSON.stringify(aRequest));
173 };
174 EchoActor.prototype.requestTypes = {
175 "echo": EchoActor.prototype.onEcho
176 };
177
178 function TestForwardPrefix12WithActor1()
179 {
180 let actor = new EchoActor(gSubconnection1)
181 actor.actorID = 'prefix1:actor';
182 gSubconnection1.addActor(actor);
183
184 tryActors(Set(['root', 'prefix1:root', 'prefix1:actor', 'prefix2:root']), run_next_test);
185 }
186
187 function TestForwardPrefix12WithActor12()
188 {
189 let actor = new EchoActor(gSubconnection2)
190 actor.actorID = 'prefix2:actor';
191 gSubconnection2.addActor(actor);
192
193 tryActors(Set(['root', 'prefix1:root', 'prefix1:actor', 'prefix2:root', 'prefix2:actor']), run_next_test);
194 }

mercurial