changeset 16:5d9d2ae0d995 default tip

added really basic plugin support
author Atul Varma <avarma@mozilla.com>
date Mon, 31 May 2010 19:29:37 -0700
parents 745b985ee84a
children
files run_tests.py sjsbox/box.py sjsbox/js.py tests/test_box.py tests/testplugins/__init__.py tests/testplugins/printer.py
diffstat 5 files changed, 58 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/run_tests.py	Mon May 31 19:29:37 2010 -0700
@@ -0,0 +1,5 @@
+if __name__ == '__main__':
+    import nose
+
+    nose.run(env={'NOSE_WITH_DOCTEST': 1,
+                  'NOSE_DOCTEST_TESTS': 1})
--- a/sjsbox/box.py	Mon May 31 18:25:10 2010 -0700
+++ b/sjsbox/box.py	Mon May 31 19:29:37 2010 -0700
@@ -3,6 +3,15 @@
 import subprocess
 import multiprocessing as mproc
 
+DEFAULT_PLUGINS = []
+
+def get_plugin(name):
+    parts = name.split('.')
+    module = __import__(name, fromlist=parts[:-1])
+    if not hasattr(module, '__sjsbox_plugin_version__'):
+        raise ValueError('module %s is not a plugin' % name)
+    return module
+
 def get_pid_statuses(pids):
     keywords = ["pid", "%cpu", "%mem", "rss", "utime", "cputime"]
     cmdline = ["ps"]
@@ -34,13 +43,17 @@
         #resource.RLIMIT_NOFILE: (10, 20)
         }
 
-    def __init__(self, f, pipe):
+    def __init__(self, f, pipe, plugins):
+        self.pipe = pipe
+        self.globals = {}
+        for pluginname in plugins:
+            plugin = get_plugin(pluginname)
+            plugin.init(self)
         if f.name.endswith('.js'):
             import sjsbox.js
-            self.__impl = sjsbox.js.JsBox(f.contents, f.name)
+            self.__impl = sjsbox.js.JsBox(self, f.contents, f.name)
         else:
             raise ValueError('unknown box type: %s' % f)
-        self.pipe = pipe
 
     def run(self):
         while True:
@@ -61,8 +74,9 @@
 class BoxParent(object):
     TIMEOUT = 3.0
 
-    def __init__(self, sourcefile, logger):
+    def __init__(self, sourcefile, logger, plugins=DEFAULT_PLUGINS):
         self.file = sourcefile
+        self.plugins = plugins
         self.logger = logger
         self.child = None
         self.child_pipe = None
@@ -72,7 +86,8 @@
         if self.child:
             self.shutdown()
         self.child_pipe, pipe = mproc.Pipe()
-        kwargs = dict(f=self.file, pipe=pipe)
+        kwargs = dict(f=self.file, pipe=pipe,
+                      plugins=self.plugins)
         self.child = mproc.Process(target=BoxChild.start,
                                    kwargs=kwargs)
         self.child.start()
--- a/sjsbox/js.py	Mon May 31 18:25:10 2010 -0700
+++ b/sjsbox/js.py	Mon May 31 19:29:37 2010 -0700
@@ -11,14 +11,15 @@
 from pydertron import jsexposed, JsExposedObject
 
 class JsBox(object):
-    def __init__(self, code, filename):
+    def __init__(self, box, code, filename):
         self.sandbox = pydertron.JsSandbox(pydertron.NullFileSystem())
-        self.sandbox.set_globals()
+        self.sandbox.set_globals(**box.globals)
         self.stderr = StringIO()
         retval = self.sandbox.run_script(code, filename=filename,
                                          stderr=self.stderr)
         if retval:
-            print self.stderr.getvalue()
+            box.logger.error(self.stderr.getvalue())
+            raise ValueError('code did not execute successfully')
 
     def handle(self, method, path):
         request = json.dumps(dict(method=method, path=path))
--- a/tests/test_box.py	Mon May 31 18:25:10 2010 -0700
+++ b/tests/test_box.py	Mon May 31 19:29:37 2010 -0700
@@ -1,8 +1,28 @@
 import unittest
+import logging
 
 import sjsbox.box
 from sjsbox.bunch import Bunch
 
+class PluginTests(unittest.TestCase):
+    def setUp(self):
+        self.foo = Bunch(
+            mtime = 0,
+            name = 'foo.js',
+            contents = """function handle(request) {
+              printer("hi " + request.path); return "woot"; }"""
+            )
+        self.box = sjsbox.box.BoxParent(self.foo,
+                                        logging.getLogger(),
+                                        ['testplugins.printer'])
+
+    def tearDown(self):
+        self.box.shutdown()
+
+    def test_printer(self):
+        self.assertEqual(self.box.handle('GET', '/'),
+                         "woot")
+
 class BoxesTests(unittest.TestCase):
     def setUp(self):
         self.foo = Bunch(
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/testplugins/printer.py	Mon May 31 19:29:37 2010 -0700
@@ -0,0 +1,9 @@
+__sjsbox_plugin_version__ = 1
+
+def init(box):
+    def printer(msg):
+        print msg
+
+    printer.__jsexposed__ = True
+
+    box.globals['printer'] = printer