From 585debcb34f3344e1a673eacc7cbd13fcf8c3751 Mon Sep 17 00:00:00 2001 From: Mark Seaborn Date: Mon, 23 Mar 2009 22:37:52 +0000 Subject: [PATCH] imcplugin: Add automated tests --- imcplugin/imcplugin.c | 5 +- imcplugin/make.sh | 7 ++ imcplugin/test.py | 202 ++++++++++++++++++++++++++++++++++++++++++++ imcplugin/tests/imc-read.c | 41 +++++++++ imcplugin/tests/imc-send.c | 30 +++++++ imcplugin/tests/printargs.c | 14 +++ 6 files changed, 295 insertions(+), 4 deletions(-) create mode 100644 imcplugin/test.py create mode 100644 imcplugin/tests/imc-read.c create mode 100644 imcplugin/tests/imc-send.c create mode 100644 imcplugin/tests/printargs.c diff --git a/imcplugin/imcplugin.c b/imcplugin/imcplugin.c index c8e95c7b..58dab945 100644 --- a/imcplugin/imcplugin.c +++ b/imcplugin/imcplugin.c @@ -20,7 +20,7 @@ #include "native_client/service_runtime/nrd_xfer_lib/nrd_xfer_effector.h" -#define print(x) printf x +#define print(x) static NPNetscapeFuncs g_funcs; @@ -179,7 +179,6 @@ ConvertDescArray(NPP plugin, NPObject *array, struct NaClImcTypedMsgHdr *header) struct NaClDesc **descs = malloc(sizeof(struct NaClDesc *) * length); if(descs == NULL) return false; - printf("ConvertDescArray %i\n", length); int i; for(i = 0; i < length; i++) { NPIdentifier index_id = NPN_GetIntIdentifier(i); @@ -333,7 +332,6 @@ ReceiveThread(void *handle) int got_bytes = NaClImcRecvTypedMessage(args->desc, (struct NaClDescEffector *) &effector, &header, 0); - printf("ReceiveThread %i\n", got_bytes); if(got_bytes < 0) { free(call); break; @@ -485,7 +483,6 @@ LauncherObj_Invoke(NPObject *npobj, NPIdentifier methodName, if(IsType(file_npobj, &FileObj_Vtable) && ConvertArgvArray(obj->plugin, argv_obj, &argv, &argv_size)) { struct FileObj *file_obj = (struct FileObj *) file_npobj; - printf("launch %s\n", file_obj->filename); struct NaClDesc *desc = LaunchProcess(obj->plugin, file_obj->filename, argv, argv_size, receive_callback); diff --git a/imcplugin/make.sh b/imcplugin/make.sh index 4ae807e8..17ae33f9 100755 --- a/imcplugin/make.sh +++ b/imcplugin/make.sh @@ -7,6 +7,13 @@ libdir=scons-out/dbg-linux/lib ./tools_bin/linux/sdk/nacl-sdk/bin/nacl-gcc \ -static -Wall imcplugin/imcread.c -o imcplugin/imcread +./tools_bin/linux/sdk/nacl-sdk/bin/nacl-gcc \ + -static -Wall imcplugin/tests/printargs.c -o imcplugin/tests/printargs +./tools_bin/linux/sdk/nacl-sdk/bin/nacl-gcc \ + -static -Wall imcplugin/tests/imc-read.c -o imcplugin/tests/imc-read +./tools_bin/linux/sdk/nacl-sdk/bin/nacl-gcc \ + -static -Wall imcplugin/tests/imc-send.c -o imcplugin/tests/imc-send + # Needs xulrunner-1.9-dev rather than libxul-dev on hardy gcc $(pkg-config mozilla-plugin --cflags --libs) \ -DNACL_LINUX -I.. \ diff --git a/imcplugin/test.py b/imcplugin/test.py new file mode 100644 index 00000000..d75f1b47 --- /dev/null +++ b/imcplugin/test.py @@ -0,0 +1,202 @@ + +import os +import shutil +import signal +import subprocess +import tempfile +import unittest + + +HEREDIR = os.path.dirname(__file__) + + +def write_file(filename, data): + fh = open(filename, "w") + try: + fh.write(data) + finally: + fh.close() + + +class TempDirTestCase(unittest.TestCase): + + def setUp(self): + self._on_teardown = [] + + def make_temp_dir(self): + temp_dir = tempfile.mkdtemp(prefix="tmp-%s-" % self.__class__.__name__) + def tear_down(): + shutil.rmtree(temp_dir) + self._on_teardown.append(tear_down) + return temp_dir + + def tearDown(self): + for func in reversed(self._on_teardown): + func() + + +class ImcPluginTests(TempDirTestCase): + + def _run_firefox(self, html_file, expect): + home_dir = self.make_temp_dir() + os.makedirs(os.path.join(home_dir, ".mozilla/plugins")) + os.makedirs(os.path.join(home_dir, ".mozilla/firefox/default")) + # This profiles.ini file tells Mozilla to use the "default" + # profile with our user.js file, rather than making up a new + # profile name. + write_file(os.path.join(home_dir, ".mozilla/firefox/profiles.ini"), + """ +[General] +StartWithLastProfile=0 + +[Profile0] +Name=default +IsRelative=1 +Path=default +""") + write_file(os.path.join(home_dir, ".mozilla/firefox/default/user.js"), + 'user_pref("browser.dom.window.dump.enabled", true);\n') + shutil.copy(os.path.join(HEREDIR, "plugin.so"), + os.path.join(home_dir, ".mozilla/plugins/plugin.so")) + env = os.environ.copy() + # Reusing current X display. TODO: launch a scratch Xvfb. + if "XAUTHORITY" not in env: + env["XAUTHORITY"] = os.path.expanduser("~/.Xauthority") + env["HOME"] = home_dir + + proc = subprocess.Popen(["firefox", html_file], + env=env, stdout=subprocess.PIPE) + try: + while len(expect) > 0: + # TODO: add a timeout. Unfortunately we can't really + # tell if the test has failed. + line = proc.stdout.readline() + if line == "": + raise AssertionError("Output ended too soon") + # Ignore noise from Mozilla. + if line.startswith("*** e = [Exception"): + continue + self.assertEquals(line.rstrip("\n"), expect.pop(0)) + finally: + os.kill(proc.pid, signal.SIGKILL) + proc.wait() + + def test_getting_file(self): + html_dir = self.make_temp_dir() + write_file(os.path.join(html_dir, "test-file"), "blah blah") + write_file(os.path.join(html_dir, "test.html"), r""" +Testing plugin... +Plugin not working + +""") + self._run_firefox(os.path.join(html_dir, "test.html"), + ["got file"]) + + def test_launching_nacl_process(self): + html_dir = self.make_temp_dir() + shutil.copy(os.path.join(HEREDIR, "tests/printargs"), + os.path.join(html_dir, "printargs")) + write_file(os.path.join(html_dir, "test.html"), r""" +Testing plugin... +Plugin not working + +""") + expect = ["NaCl module started", + "argc = 3", + 'argv[0] = "NaClMain"', + 'argv[1] = "arg 1 foo"', + 'argv[2] = "arg 2 baz"', + "PASS"] + self._run_firefox(os.path.join(html_dir, "test.html"), expect) + + def test_sending_to_nacl(self): + html_dir = self.make_temp_dir() + shutil.copy(os.path.join(HEREDIR, "tests/imc-read"), + os.path.join(html_dir, "imc-read")) + write_file(os.path.join(html_dir, "test.html"), r""" +Testing plugin... +Plugin not working + +""") + expect = ["NaCl got message: Hello from Javascript to NaCl", + "NaCl received 0 FDs", + "NaCl got message: Second message", + "NaCl received 0 FDs"] + self._run_firefox(os.path.join(html_dir, "test.html"), expect) + + def test_receiving_from_nacl(self): + html_dir = self.make_temp_dir() + shutil.copy(os.path.join(HEREDIR, "tests/imc-send"), + os.path.join(html_dir, "imc-send")) + write_file(os.path.join(html_dir, "test.html"), r""" +Testing plugin... +Plugin not working + +""") + expect = ["Javascript got message: Hello from NaCl to Javascript!", + "Javascript got message: Message 2"] + self._run_firefox(os.path.join(html_dir, "test.html"), expect) + + +if __name__ == "__main__": + unittest.main() diff --git a/imcplugin/tests/imc-read.c b/imcplugin/tests/imc-read.c new file mode 100644 index 00000000..3e5378f8 --- /dev/null +++ b/imcplugin/tests/imc-read.c @@ -0,0 +1,41 @@ + +#include + +#include +#include + + +int read_message(int desc) +{ + char buf[2000]; + int fds[8]; + struct NaClImcMsgIoVec iov; + struct NaClImcMsgHdr msg; + iov.base = buf; + iov.length = sizeof(buf); + msg.iov = &iov; + msg.iov_length = 1; + msg.descv = fds; + msg.desc_length = 8; + + int result = imc_recvmsg(desc, &msg, 0); + if(result <= 0) { + printf("failed, result=%i\n", result); + return 0; + } + else { + int i; + printf("NaCl got message: "); + for(i = 0; i < result; i++) + printf("%c", buf[i]); + printf("NaCl received %i FDs\n", msg.desc_length); + return 1; + } +} + +int main(int argc, char* argv[]) +{ + while(read_message(3)) + ; + return 0; +} diff --git a/imcplugin/tests/imc-send.c b/imcplugin/tests/imc-send.c new file mode 100644 index 00000000..96a3418f --- /dev/null +++ b/imcplugin/tests/imc-send.c @@ -0,0 +1,30 @@ + +#include +#include + +#include +#include + + +void send_message(int desc, char *data) +{ + struct NaClImcMsgIoVec iov; + struct NaClImcMsgHdr msg; + iov.base = data; + iov.length = strlen(data); + msg.iov = &iov; + msg.iov_length = 1; + msg.descv = NULL; + msg.desc_length = 0; + + int result = imc_sendmsg(desc, &msg, 0); + if(result < 0) + perror("sendmsg"); +} + +int main(int argc, char* argv[]) +{ + send_message(3, "Hello from NaCl to Javascript!"); + send_message(3, "Message 2"); + return 0; +} diff --git a/imcplugin/tests/printargs.c b/imcplugin/tests/printargs.c new file mode 100644 index 00000000..484c4344 --- /dev/null +++ b/imcplugin/tests/printargs.c @@ -0,0 +1,14 @@ + +#include + + +int main(int argc, char* argv[]) +{ + int i; + printf("NaCl module started\n"); + printf("argc = %i\n", argc); + for(i = 0; i < argc; i++) + printf("argv[%i] = \"%s\"\n", i, argv[i]); + printf("PASS\n"); + return 0; +} -- 2.11.4.GIT