doctest and unittest with pysandbox

200 Views Asked by At

I want to test student submissions in a save environment. That's the reason why I use pysandbox. For testing the student submission I want to use doctest and unittest.

Here is the studentSubmission.py

def factorial(n):
import math

if not n >= 0:
   raise ValueError("n must be >= 0")
if math.floor(n) != n:
   raise ValueError("n must be exact integer")
if n+1 == n:  # catch a value like 1e300
   raise OverflowError("n too large")
resulto = 1
factor = 2
while factor <= n:
   resulto *= factor
   factor += 1
return resulto

Here is a regular unittest by a possible tutor: tutor_tester.py

import unittest
from studentSubmission import factorial
class TestSequenceFunctions(unittest.TestCase):

    def test_equal(self):
        res = factorial(4)
        self.assertEqual(res, 24)

    def test_error(self):
        self.assertRaises(ValueError, factorial, -1)
if __name__ == '__main__':
    unittest.main()

And now the script for the sandbox: sandbox_test.py

import os
from sandbox import Sandbox, SandboxConfig

#sandbox config
sandbox = Sandbox(SandboxConfig('traceback','math','stdout','stderr','exit' ))
sandbox.config.allowModule('unittest','student_submission')


fo = open("./tutor_tester.py", "r")
code = fo.read();
fo.close()

sandbox.execute(code)

When I run this on my ubuntu lts 12.04.3 with Python 2.7.3 version and the latest Pysandbox. Running sandbox_test.py I got following error:

Traceback (most recent call last):
  File "sandbox_test.py", line 17, in <module>
    sandbox.execute(code)
  File "/usr/local/lib/python2.7/dist-packages/sandbox/sandbox_class.py", line 97, in execute
    return self.execute_subprocess(self, code, globals, locals)
  File "/usr/local/lib/python2.7/dist-packages/sandbox/subprocess_parent.py", line 185, in execute_subprocess
    raise output_data['error']
ImportError: Import "result" blocked by the sandbox

When I try doctest : doctest_sandbox.py

def testing():
  """testing student
  >>> from studentSubmission import factorial
  >>> [factorial(n) for n in range(6)]
  [1, 1, 2, 6, 24, 120]
  >>> [factorial(long(n)) for n in range(6)]
  [1, 1, 2, 6, 24, 120]
  >>> factorial(30)
  265252859812191058636308480000000L
  >>> factorial(-1)
  Traceback (most recent call last):
  ...
  ValueError: n must be >= 0
  """

if __name__ == "__main__":
  import doctest
  from sandbox import Sandbox, SandboxConfig
  sandbox = Sandbox(SandboxConfig('math','stdout','stderr','exit' ))
  sandbox.config.allowModule('studentSubmission')
  sandbox.execute(doctest.testmod())

Doctest worked quite well, but also in the end the sandbox gave me an error:

python doctest_sandbox.py -v

    Trying:
        from studentSubmission import factorial
    Expecting nothing
    ok
    Trying:
        [factorial(n) for n in range(6)]
    Expecting:
        [1, 1, 2, 6, 24, 120]
    ok
    Trying:
        [factorial(long(n)) for n in range(6)]
    Expecting:
        [1, 1, 2, 6, 24, 120]
    ok
    Trying:
        factorial(30)
    Expecting:
        265252859812191058636308480000000L
    ok
    Trying:
        factorial(-1)
    Expecting:
        Traceback (most recent call last):
        ...
        ValueError: n must be >= 0
    ok
    1 items had no tests:
    __main__
    1 items passed all tests:
       5 tests in __main__.testing
    5 tests in 2 items.
    5 passed and 0 failed.
    Test passed.
    Traceback (most recent call last):
      File "doctest_sandbox.py", line 21, in <module>
        sandbox.execute(doctest.testmod())
      File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sandbox/sandbox_class.py", line 97, in execute
        return self.execute_subprocess(self, code, globals, locals)
      File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sandbox/subprocess_parent.py", line 185, in execute_subprocess
        raise output_data['error']
    TypeError: exec: arg 1 must be a string, file, or code object

Thanks for your help;)

0

There are 0 best solutions below