diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
commit | 09911bf300f1a419907a9412154760efd0b7abc3 (patch) | |
tree | f131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/test/debugger | |
parent | 586acc5fe142f498261f52c66862fa417c3d52d2 (diff) | |
download | chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2 |
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/debugger')
-rw-r--r-- | chrome/test/debugger/debugger_unittests.py | 50 | ||||
-rwxr-xr-x | chrome/test/debugger/debugger_unittests.sh | 9 | ||||
-rw-r--r-- | chrome/test/debugger/test_protocol.js | 293 |
3 files changed, 352 insertions, 0 deletions
diff --git a/chrome/test/debugger/debugger_unittests.py b/chrome/test/debugger/debugger_unittests.py new file mode 100644 index 0000000..bacaa00 --- /dev/null +++ b/chrome/test/debugger/debugger_unittests.py @@ -0,0 +1,50 @@ +# debugger_unittests.py +# +# Run chrome debugger front-end tests. +# see also chrome/test/debugger/test_protocol.js + +import optparse +import os.path +import subprocess +import sys +import time + +import google.path_utils +import google.process_utils + +def RunTests(build_dir=None): + '''This is just a simple wrapper for running the test through v8_shell. + Since v8_shell always returns 0 whether the test passes or fails, buildbot + looks at stdout to test for failure. + ''' + script_dir = google.path_utils.ScriptDir() + chrome_dir = google.path_utils.FindUpward(script_dir, "chrome") + v8_dir = google.path_utils.FindUpward(script_dir, "v8") + if build_dir: + v8_shell = os.path.join(build_dir, "v8_shell.exe") + else: + v8_shell = os.path.join(chrome_dir, "Debug", "v8_shell.exe") + # look for Debug version first + if not os.path.isfile(v8_shell): + v8_shell = os.path.join(chrome_dir, "Release", "v8_shell.exe") + cmd = [v8_shell, + "--allow-natives-syntax", + "--expose-debug-as", "debugContext", # these two are together + os.path.join(chrome_dir, "browser", "resources", "debugger_shell.js"), + os.path.join(v8_dir, "tests", "mjsunit.js"), + os.path.join(chrome_dir, "test", "debugger", "test_protocol.js") + ] + (retcode, output) = google.process_utils.RunCommandFull(cmd, + collect_output=True) + if "Success" in output: + return 0 + else: + return 1 + +if __name__ == "__main__": + parser = optparse.OptionParser("usage: %prog [--build_dir=dir]") + parser.add_option("", "--build_dir", + help="directory where v8_shell.exe was built") + (options, args) = parser.parse_args() + ret = RunTests(options.build_dir) + sys.exit(ret) diff --git a/chrome/test/debugger/debugger_unittests.sh b/chrome/test/debugger/debugger_unittests.sh new file mode 100755 index 0000000..443488d --- /dev/null +++ b/chrome/test/debugger/debugger_unittests.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +system_root=`cygpath "$SYSTEMROOT"` +export PATH="/usr/bin:$system_root/system32:$system_root:$system_root/system32/WBEM" + +exec_dir=$(dirname $0) + +"$exec_dir/../../../third_party/python_24/python.exe" \ + "$exec_dir/debugger_unittests.py" "$@" diff --git a/chrome/test/debugger/test_protocol.js b/chrome/test/debugger/test_protocol.js new file mode 100644 index 0000000..6ca0835 --- /dev/null +++ b/chrome/test/debugger/test_protocol.js @@ -0,0 +1,293 @@ +// Copyright 2008 Google Inc. All Rights Reserved. +// test_protocol.js + +/** + * @fileoverview Unit tests for testing debugger protocol betweeen front-end JS + * and back-end. + * Run with the following command line: + * v8_shell.exe --allow-natives-syntax --expose-debug-as debugContext + * chrome/browser/resources/shell.js + * v8/tests/mjsunit.js + * chrome/test/debugger/test_protocol.js + */ + + +/** + * shell() is normally a native function exposed to shell.js in Chrome that + * sets the global DebugShell (shell_) object used for the debugger front-end. + */ +function shell(sh) { + shell_ = sh; + shell_.response("{type: 'event', event: 'attach'}"); +}; + + +/** + * @class The global chrome object has some functions to control some status UI + * in the debugger window. Stub them out here. + */ +function chrome() { +}; +chrome.setDebuggerReady = function(ready) {}; +chrome.setDebuggerBreak = function(brk) {}; + + +/** + * @constructor a pseudo namespace to wrap the various functions and data for + * the test + */ +function DebuggerTest() { +}; + +/** + * initialize the member + */ +DebuggerTest.initialize = function() { + DebuggerTest.pendingCommand = null; + DebuggerTest.output = []; + + // swap out the built-in print with our own so that we can verify output + DebuggerTest.realPrint = print; + print = DebuggerTest.print; + // uncomment this to see more verbose information + //dprint = DebuggerTest.realPrint; + + debugContext.Debug.addListener(DebuggerTest.listener); +}; + +/** + * Collects calls to print() in an array for test verification. + */ +DebuggerTest.print = function(str) { + DebuggerTest.output.push(str); + // uncomment this if you need to trace what's happening while it's happening + // rather than waiting for the end + //DebuggerTest.realPrint(str); +}; + +/** + * Processes pendingCommand and sends response to shell_. Since that may in + * turn generate a new pendingCommand, repeat this until there is no + * pendingCommand. + */ +DebuggerTest.processCommands = function(dcp) { + while (DebuggerTest.pendingCommand) { + var json = DebuggerTest.pendingCommand; + DebuggerTest.pendingCommand = null; + var result = dcp.processDebugJSONRequest(json); + shell_.response(result); + } +}; + +/** + * Handles DebugEvents from the Debug object. Hooked in via addListener above. + */ +DebuggerTest.listener = function(event, exec_state, event_data, data) { + try { + if (event == debugContext.Debug.DebugEvent.Break) { + var dcp = exec_state.debugCommandProcessor(); + // process any pending commands prior to handling the breakpoint + DebuggerTest.processCommands(dcp); + var json = event_data.toJSONProtocol(); + shell_.response(json); + // response() may have added another command to process + DebuggerTest.processCommands(dcp); + } + } catch(e) { + print(e); + } +}; + +/** + * Send the next command from the command-list. + */ +DebuggerTest.sendNextCommand = function() { + var cmd = DebuggerTest.commandList.shift(); + print("$ " + cmd); + shell_.command(cmd); +}; + +/** + * Verify that the actual output matches the expected output + * depends on mjsunit + */ +DebuggerTest.verifyOutput = function() { + // restore print since mjsunit depends on it + print = DebuggerTest.realPrint; + + var out = DebuggerTest.output; + var expected = DebuggerTest.expectedOutput; + if (out.length != expected.length) { + assertTrue(out.length == expected.length, + "length mismatch: " + out.length + " == " + expected.length); + } else { + var succeeded = true; + for (var i in out) { + // match the front of the string so we can avoid testing changes in frames + // that are in the test harness + if (out[i].indexOf(expected[i]) != 0) { + assertTrue(out[i] == expected[i], + "actual '" + out[i] + "' == " + "expected '" + expected[i] + "'"); + succeeded = false; + break; + } + } + if (succeeded) + print("Success"); + } + + // useful for generating a new version of DebuggerTest.expectedOutput + for (var i in DebuggerTest.output) { + //print(" \"" + DebuggerTest.output[i] + "\","); + } +}; + + + +/** + * @class DebugShell is passed a "Tab" object that it uses to communicate with + * the debugger. This mock simulates that. + * @param {string} title + */ +DebuggerTest.TabMock = function(title) { + this.title = title; + this.attach = function() {}; + this.debugBreak = function() { + // TODO(erikkay) + }; + this.sendToDebugger = function(str) { + DebuggerTest.pendingCommand = str; + }; +}; + + +/** + * @class Uses prototype chaining to allow DebugShell methods to be overridden + * selectively. + */ +function DebugShellOverrides() { + this._origPrototype = DebugShell.prototype; +}; +DebugShellOverrides.prototype = DebugShell.prototype; +DebugShell.prototype = new DebugShellOverrides; + +/** + * Overrides DebugShell.prototype.response so that we can log the responses + * and trigger the next command to be processed. + */ +DebugShell.prototype.response = function(str) { + var msg = eval('(' + str + ')'); + print("< " + msg.type + ":" + (msg.command || msg.event)); + var sendAnother = (msg.type == "event"); + if (!sendAnother && shell_.current_command) { + sendAnother = (shell_.current_command.from_user && + msg.type == "response" && msg.command != "continue") + } + this._origPrototype.response.call(this, str) + + // Send the next command, but only if the program is paused (a continue + // command response means that we're about to be running again) and the + // command we just processed isn't a continue + if (!this.running && sendAnother) + DebuggerTest.sendNextCommand(); +}; + + +// The list of commands to be processed +// TODO(erikkay): this doesn't test the full set of debugger commands yet, +// but it should be enough to verify that the protocol is still working. +DebuggerTest.commandList = [ +"next", "step", "backtrace", "source", "print x", "args", "locals", "frame 1", +"stepout", "continue" +]; + +DebuggerTest.expectedOutput = [ + "< event:attach", + "attached to testing", + "< response:scripts", + "< event:break", + "g(), foo.html", + "60: debugger;", + "$ next", + "< response:continue", + "< event:break", + "61: f(1);", + "$ step", + "< response:continue", + "< event:break", + "f(x=1, y=undefined), foo.html", + "29: return a;", + "$ backtrace", + "< response:backtrace", + "Frames #0 to #3 of 4:", + "#00 f(x=1, y=undefined) foo.html line 29 column 3 (position 62)", + "#01 g() foo.html line 61 column 3 (position 30)", + "#02 function DebuggerTest()", // prefix + "#03 [anonymous]()", // prefix + "$ source", + "< response:source", + "24: function f(x, y) {", + "25: var a=1;", + "26: if (x == 1) {", + "27: a++;", + "28: }", + ">>>> return a;", + "30: };", + "$ print x", + "< response:evaluate", + "1", + "$ args", + "< response:frame", + "x = 1", + "y = undefined", + "$ locals", + "< response:frame", + "a = 2", + "$ frame 1", + "< response:frame", + "#1 g, foo.html", + "61: f(1);", + "$ stepout", + "< response:continue", + "< event:break", + "g(), foo.html", + "62: };", + "$ continue", + "< response:continue" +]; + + +/** + * Tests the debugger and protocol for a couple of simple scripts. + */ +DebuggerTest.testProtocol = function() { + DebuggerTest.initialize(); + + // Startup the front-end. + debug(new DebuggerTest.TabMock("testing")); + + script1 = + "function f(x, y) {\n" + // line 23 + " var a=1;\n" + // line 24 + " if (x == 1) {\n" + // line 25 + " a++;\n }\n" + // line 26 + " return a;\n" + // line 27 + "};"; // line 28 + script2 = + "function g() {\n" + // line 58 + " debugger;\n" + // line 59 + " f(1);\n" + // line 60 + "};"; // line 61 + %CompileScript(script1, "foo.html", 23, 0)(); + %CompileScript(script2, "foo.html", 58, 0)(); + + try { + g(); + } catch(e) { + print(e); + } + + DebuggerTest.verifyOutput(); +} + +DebuggerTest.testProtocol(); |