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

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

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 /* Exercise prefix-based forwarding of packets to other transports. */
     6 var gMainConnection, gMainTransport;
     7 var gSubconnection1, gSubconnection2;
     8 var gClient;
    10 function run_test()
    11 {
    12   DebuggerServer.init();
    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 }
    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   };
    43   var transport = DebuggerServer.connectPipe(aPrefix);
    45   return { conn: conn, transport: transport };
    46 }
    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 }
    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;
    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;
    83     count++;
    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);
    92                       if (--count == 0)
    93                         do_execute_soon(aCompleted, "tryActors callback " + aCompleted.name);
    94                     });
    95   }
    96 }
    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 }
   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);
   124   return { conn: conn, transport: transport };
   125 }
   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 }
   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 }
   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 }
   151 function TestForwardPrefix12OnlyRoot()
   152 {
   153   tryActors(Set(['root', 'prefix1:root', 'prefix2:root']), run_next_test);
   154 }
   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 };
   178 function TestForwardPrefix12WithActor1()
   179 {
   180   let actor = new EchoActor(gSubconnection1)
   181   actor.actorID = 'prefix1:actor';
   182   gSubconnection1.addActor(actor);
   184   tryActors(Set(['root', 'prefix1:root', 'prefix1:actor', 'prefix2:root']), run_next_test);
   185 }
   187 function TestForwardPrefix12WithActor12()
   188 {
   189   let actor = new EchoActor(gSubconnection2)
   190   actor.actorID = 'prefix2:actor';
   191   gSubconnection2.addActor(actor);
   193   tryActors(Set(['root', 'prefix1:root', 'prefix1:actor', 'prefix2:root', 'prefix2:actor']), run_next_test);
   194 }

mercurial