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

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* Any copyright is dedicated to the Public Domain.
     2    http://creativecommons.org/publicdomain/zero/1.0/ */
     4 "use strict";
     5 const Cc = Components.classes;
     6 const Ci = Components.interfaces;
     7 const Cu = Components.utils;
     8 const Cr = Components.results;
    10 const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
    11 const Services = devtools.require("Services");
    12 const { ActorPool, createExtraActors, appendExtraActors } = devtools.require("devtools/server/actors/common");
    13 const DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils.js");
    14 const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
    16 // Always log packets when running tests. runxpcshelltests.py will throw
    17 // the output away anyway, unless you give it the --verbose flag.
    18 Services.prefs.setBoolPref("devtools.debugger.log", true);
    19 // Enable remote debugging for the relevant tests.
    20 Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
    22 function tryImport(url) {
    23   try {
    24     Cu.import(url);
    25   } catch (e) {
    26     dump("Error importing " + url + "\n");
    27     dump(DevToolsUtils.safeErrorString(e) + "\n");
    28     throw e;
    29   }
    30 }
    32 tryImport("resource://gre/modules/devtools/dbg-server.jsm");
    33 tryImport("resource://gre/modules/devtools/dbg-client.jsm");
    34 tryImport("resource://gre/modules/devtools/Loader.jsm");
    35 tryImport("resource://gre/modules/devtools/Console.jsm");
    37 function testExceptionHook(ex) {
    38   try {
    39     do_report_unexpected_exception(ex);
    40   } catch(ex) {
    41     return {throw: ex}
    42   }
    43   return undefined;
    44 }
    46 // Convert an nsIScriptError 'aFlags' value into an appropriate string.
    47 function scriptErrorFlagsToKind(aFlags) {
    48   var kind;
    49   if (aFlags & Ci.nsIScriptError.warningFlag)
    50     kind = "warning";
    51   if (aFlags & Ci.nsIScriptError.exceptionFlag)
    52     kind = "exception";
    53   else
    54     kind = "error";
    56   if (aFlags & Ci.nsIScriptError.strictFlag)
    57     kind = "strict " + kind;
    59   return kind;
    60 }
    62 // Redeclare dbg_assert with a fatal behavior.
    63 function dbg_assert(cond, e) {
    64   if (!cond) {
    65     throw e;
    66   }
    67 }
    69 // Register a console listener, so console messages don't just disappear
    70 // into the ether.
    71 let errorCount = 0;
    72 let listener = {
    73   observe: function (aMessage) {
    74     errorCount++;
    75     try {
    76       // If we've been given an nsIScriptError, then we can print out
    77       // something nicely formatted, for tools like Emacs to pick up.
    78       var scriptError = aMessage.QueryInterface(Ci.nsIScriptError);
    79       dump(aMessage.sourceName + ":" + aMessage.lineNumber + ": " +
    80            scriptErrorFlagsToKind(aMessage.flags) + ": " +
    81            aMessage.errorMessage + "\n");
    82       var string = aMessage.errorMessage;
    83     } catch (x) {
    84       // Be a little paranoid with message, as the whole goal here is to lose
    85       // no information.
    86       try {
    87         var string = "" + aMessage.message;
    88       } catch (x) {
    89         var string = "<error converting error message to string>";
    90       }
    91     }
    93     // Make sure we exit all nested event loops so that the test can finish.
    94     while (DebuggerServer.xpcInspector.eventLoopNestLevel > 0) {
    95       DebuggerServer.xpcInspector.exitNestedEventLoop();
    96     }
    97     do_throw("head_dbg.js got console message: " + string + "\n");
    98   }
    99 };
   101 let consoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
   102 consoleService.registerListener(listener);
   104 function check_except(func)
   105 {
   106   try {
   107     func();
   108   } catch (e) {
   109     do_check_true(true);
   110     return;
   111   }
   112   dump("Should have thrown an exception: " + func.toString());
   113   do_check_true(false);
   114 }
   116 function testGlobal(aName) {
   117   let systemPrincipal = Cc["@mozilla.org/systemprincipal;1"]
   118     .createInstance(Ci.nsIPrincipal);
   120   let sandbox = Cu.Sandbox(systemPrincipal);
   121   sandbox.__name = aName;
   122   return sandbox;
   123 }
   125 function addTestGlobal(aName)
   126 {
   127   let global = testGlobal(aName);
   128   DebuggerServer.addTestGlobal(global);
   129   return global;
   130 }
   132 // List the DebuggerClient |aClient|'s tabs, look for one whose title is
   133 // |aTitle|, and apply |aCallback| to the packet's entry for that tab.
   134 function getTestTab(aClient, aTitle, aCallback) {
   135   aClient.listTabs(function (aResponse) {
   136     for (let tab of aResponse.tabs) {
   137       if (tab.title === aTitle) {
   138         aCallback(tab);
   139         return;
   140       }
   141     }
   142     aCallback(null);
   143   });
   144 }
   146 // Attach to |aClient|'s tab whose title is |aTitle|; pass |aCallback| the
   147 // response packet and a TabClient instance referring to that tab.
   148 function attachTestTab(aClient, aTitle, aCallback) {
   149   getTestTab(aClient, aTitle, function (aTab) {
   150     aClient.attachTab(aTab.actor, aCallback);
   151   });
   152 }
   154 // Attach to |aClient|'s tab whose title is |aTitle|, and then attach to
   155 // that tab's thread. Pass |aCallback| the thread attach response packet, a
   156 // TabClient referring to the tab, and a ThreadClient referring to the
   157 // thread.
   158 function attachTestThread(aClient, aTitle, aCallback) {
   159   attachTestTab(aClient, aTitle, function (aResponse, aTabClient) {
   160     function onAttach(aResponse, aThreadClient) {
   161       aCallback(aResponse, aTabClient, aThreadClient);
   162     }
   163     aTabClient.attachThread({ useSourceMaps: true }, onAttach);
   164   });
   165 }
   167 // Attach to |aClient|'s tab whose title is |aTitle|, attach to the tab's
   168 // thread, and then resume it. Pass |aCallback| the thread's response to
   169 // the 'resume' packet, a TabClient for the tab, and a ThreadClient for the
   170 // thread.
   171 function attachTestTabAndResume(aClient, aTitle, aCallback) {
   172   attachTestThread(aClient, aTitle, function(aResponse, aTabClient, aThreadClient) {
   173     aThreadClient.resume(function (aResponse) {
   174       aCallback(aResponse, aTabClient, aThreadClient);
   175     });
   176   });
   177 }
   179 /**
   180  * Initialize the testing debugger server.
   181  */
   182 function initTestDebuggerServer()
   183 {
   184   DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/root.js");
   185   DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/script.js");
   186   DebuggerServer.addActors("resource://test/testactors.js");
   187   // Allow incoming connections.
   188   DebuggerServer.init(function () { return true; });
   189 }
   191 function initTestTracerServer()
   192 {
   193   DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/root.js");
   194   DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/script.js");
   195   DebuggerServer.addActors("resource://test/testactors.js");
   196   DebuggerServer.registerModule("devtools/server/actors/tracer");
   197   // Allow incoming connections.
   198   DebuggerServer.init(function () { return true; });
   199 }
   201 function finishClient(aClient)
   202 {
   203   aClient.close(function() {
   204     do_test_finished();
   205   });
   206 }
   208 /**
   209  * Takes a relative file path and returns the absolute file url for it.
   210  */
   211 function getFileUrl(aName, aAllowMissing=false) {
   212   let file = do_get_file(aName, aAllowMissing);
   213   return Services.io.newFileURI(file).spec;
   214 }
   216 /**
   217  * Returns the full path of the file with the specified name in a
   218  * platform-independent and URL-like form.
   219  */
   220 function getFilePath(aName, aAllowMissing=false)
   221 {
   222   let file = do_get_file(aName, aAllowMissing);
   223   let path = Services.io.newFileURI(file).spec;
   224   let filePrePath = "file://";
   225   if ("nsILocalFileWin" in Ci &&
   226       file instanceof Ci.nsILocalFileWin) {
   227     filePrePath += "/";
   228   }
   229   return path.slice(filePrePath.length);
   230 }
   232 Cu.import("resource://gre/modules/NetUtil.jsm");
   234 /**
   235  * Returns the full text contents of the given file.
   236  */
   237 function readFile(aFileName) {
   238   let f = do_get_file(aFileName);
   239   let s = Cc["@mozilla.org/network/file-input-stream;1"]
   240     .createInstance(Ci.nsIFileInputStream);
   241   s.init(f, -1, -1, false);
   242   try {
   243     return NetUtil.readInputStreamToString(s, s.available());
   244   } finally {
   245     s.close();
   246   }
   247 }
   249 function writeFile(aFileName, aContent) {
   250   let file = do_get_file(aFileName, true);
   251   let stream = Cc["@mozilla.org/network/file-output-stream;1"]
   252     .createInstance(Ci.nsIFileOutputStream);
   253   stream.init(file, -1, -1, 0);
   254   try {
   255     do {
   256       let numWritten = stream.write(aContent, aContent.length);
   257       aContent = aContent.slice(numWritten);
   258     } while (aContent.length > 0);
   259   } finally {
   260     stream.close();
   261   }
   262 }
   264 function connectPipeTracing() {
   265   return new TracingTransport(DebuggerServer.connectPipe());
   266 }
   268 function TracingTransport(childTransport) {
   269   this.hooks = null;
   270   this.child = childTransport;
   271   this.child.hooks = this;
   273   this.expectations = [];
   274   this.packets = [];
   275   this.checkIndex = 0;
   276 }
   278 function deepEqual(a, b) {
   279   if (a === b)
   280     return true;
   281   if (typeof a != "object" || typeof b != "object")
   282     return false;
   283   if (a === null || b === null)
   284     return false;
   285   if (Object.keys(a).length != Object.keys(b).length)
   286     return false;
   287   for (let k in a) {
   288     if (!deepEqual(a[k], b[k]))
   289       return false;
   290   }
   291   return true;
   292 }
   294 TracingTransport.prototype = {
   295   // Remove actor names
   296   normalize: function(packet) {
   297     return JSON.parse(JSON.stringify(packet, (key, value) => {
   298       if (key === "to" || key === "from" || key === "actor") {
   299         return "<actorid>";
   300       }
   301       return value;
   302     }));
   303   },
   304   send: function(packet) {
   305     this.packets.push({
   306       type: "sent",
   307       packet: this.normalize(packet)
   308     });
   309     return this.child.send(packet);
   310   },
   311   close: function() {
   312     return this.child.close();
   313   },
   314   ready: function() {
   315     return this.child.ready();
   316   },
   317   onPacket: function(packet) {
   318     this.packets.push({
   319       type: "received",
   320       packet: this.normalize(packet)
   321     });
   322     this.hooks.onPacket(packet);
   323   },
   324   onClosed: function() {
   325     this.hooks.onClosed();
   326   },
   328   expectSend: function(expected) {
   329     let packet = this.packets[this.checkIndex++];
   330     do_check_eq(packet.type, "sent");
   331     do_check_true(deepEqual(packet.packet, this.normalize(expected)));
   332   },
   334   expectReceive: function(expected) {
   335     let packet = this.packets[this.checkIndex++];
   336     do_check_eq(packet.type, "received");
   337     do_check_true(deepEqual(packet.packet, this.normalize(expected)));
   338   },
   340   // Write your tests, call dumpLog at the end, inspect the output,
   341   // then sprinkle the calls through the right places in your test.
   342   dumpLog: function() {
   343     for (let entry of this.packets) {
   344       if (entry.type === "sent") {
   345         dump("trace.expectSend(" + entry.packet + ");\n");
   346       } else {
   347         dump("trace.expectReceive(" + entry.packet + ");\n");
   348       }
   349     }
   350   }
   351 };
   353 function StubTransport() { }
   354 StubTransport.prototype.ready = function () {};
   355 StubTransport.prototype.send  = function () {};
   356 StubTransport.prototype.close = function () {};
   358 function executeSoon(aFunc) {
   359   Services.tm.mainThread.dispatch({
   360     run: DevToolsUtils.makeInfallible(aFunc)
   361   }, Ci.nsIThread.DISPATCH_NORMAL);
   362 }

mercurial