Skip to content
This repository has been archived by the owner on Nov 8, 2024. It is now read-only.

Commit

Permalink
modules loading inside VM (just stdlib http://nodejs.org/api/)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tully committed Sep 2, 2014
1 parent eb38d60 commit f0d7cac
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 16 deletions.
8 changes: 6 additions & 2 deletions src/forkable.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ run = (msg) ->
unless script
error "No code to run"
return false
if msg?.context?.debug is true
msg.context.console = console

msg.context ?= {}

if msg?.libraries
for lib in msg?.libraries
msg.context[lib] = eval lib
try
res =
result: script.runInNewContext(msg.context || {}) || null # script can return undefined, ensure it's null
Expand Down
9 changes: 5 additions & 4 deletions src/pitboss.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ exports.Pitboss = class Pitboss extends EventEmitter
@next()
@q = []

run: (context, callback) ->
@q.push({context:context,callback:callback})
run: ({context, libraries}, callback) ->
@q.push({context: context, libraries: libraries, callback: callback})
@next()

next: ->
return false if @runner.running
c = @q.shift()
if c
@runner.run(c.context, c.callback)
@runner.run({context: c.context, libraries: c.libraries}, c.callback)

# Can only run one at a time due to the blocking nature of VM
# Need to queue this up outside of the process since it's over an async channel
Expand All @@ -34,11 +34,12 @@ exports.Runner = class Runner extends EventEmitter
@proc.on 'exit', @failedForkHandler
@proc.send {code:@code}

run: (context, callback) ->
run: ({context, libraries}, callback) ->
return false if @running
id = Date.now().toString() + Math.floor(Math.random() * 1000)
msg =
context: context
libraries: libraries
id: id
@callback = callback || false
@startTimer()
Expand Down
42 changes: 32 additions & 10 deletions test/pitboss_test.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,34 @@ describe "Pitboss running code", ->

it "should take a JSON encodable message", (done) ->
pitboss = new Pitboss(@code)
pitboss.run {data: "test"}, (err, result) ->
pitboss.run context: {data: "test"}, (err, result) ->
assert.equal "test", result
pitboss.run {data: 456}, (err, result) ->
pitboss.run context: {data: 456}, (err, result) ->
assert.equal 456, result
done()


describe "Pitboss modules loading code", ->
beforeEach ->
@code = """
console.error(data);
data;
"""

it "should not return an error when loaded module is used", (done) ->
pitboss = new Pitboss(@code)
pitboss.run context: {data: "test"}, libraries: ['console'], (err, result) ->
assert.equal "test", result
assert.equal undefined, err
done()

it "should return an error when unknown module is used", (done) ->
pitboss = new Pitboss(@code)
pitboss.run context: {data: "test"}, libraries: [], (err, result) ->
assert.equal undefined, result
assert.equal 'VM Runtime Error: ReferenceError: console is not defined', err
done()

describe "Running dubius code", ->
beforeEach ->
@code = """
Expand All @@ -32,7 +54,7 @@ describe "Running dubius code", ->

it "should take a JSON encodable message", (done) ->
pitboss = new Runner(@code)
pitboss.run {data: 123}, (err, result) ->
pitboss.run context: {data: 123}, (err, result) ->
assert.equal 123, result
done()

Expand All @@ -44,7 +66,7 @@ describe "Running shitty code", ->

it "should return the error", (done) ->
pitboss = new Runner(@code)
pitboss.run {data: 123}, (err, result) ->
pitboss.run context: {data: 123}, (err, result) ->
assert.equal "VM Syntax Error: SyntaxError: Unexpected identifier", err
assert.equal null, result
done()
Expand All @@ -60,19 +82,19 @@ describe "Running infinite loop code", ->

it "should timeout and restart fork", (done) ->
pitboss = new Runner @code,
timeout: 100
pitboss.run {infinite: true}, (err, result) ->
timeout: 200
pitboss.run context: {infinite: true}, (err, result) ->
assert.equal "Timedout", err
pitboss.run {infinite: false}, (err, result) ->
pitboss.run context: {infinite: false}, (err, result) ->
assert.equal "OK", result
done()

it "should happily allow for process failure (e.g. ulimit kills)", (done) ->
pitboss = new Runner @code,
timeout: 100
pitboss.run {infinite: true}, (err, result) ->
timeout: 200
pitboss.run context: {infinite: true}, (err, result) ->
assert.equal "Process Failed", err
pitboss.run {infinite: false}, (err, result) ->
pitboss.run context: {infinite: false}, (err, result) ->
assert.equal "OK", result
done()
pitboss.proc.kill()

0 comments on commit f0d7cac

Please sign in to comment.