config/mozunit.py

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 # This Source Code Form is subject to the terms of the Mozilla Public
     2 # License, v. 2.0. If a copy of the MPL was not distributed with this
     3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
     5 from unittest import TextTestRunner as _TestRunner, TestResult as _TestResult
     6 import unittest
     7 import inspect
     8 from StringIO import StringIO
     9 import os
    11 '''Helper to make python unit tests report the way that the Mozilla
    12 unit test infrastructure expects tests to report.
    14 Usage:
    16 import unittest
    17 import mozunit
    19 if __name__ == '__main__':
    20     mozunit.main()
    21 '''
    23 class _MozTestResult(_TestResult):
    24     def __init__(self, stream, descriptions):
    25         _TestResult.__init__(self)
    26         self.stream = stream
    27         self.descriptions = descriptions
    29     def getDescription(self, test):
    30         if self.descriptions:
    31             return test.shortDescription() or str(test)
    32         else:
    33             return str(test)
    35     def addSuccess(self, test):
    36         _TestResult.addSuccess(self, test)
    37         filename = inspect.getfile(test.__class__)
    38         testname = test._testMethodName
    39         self.stream.writeln("TEST-PASS | {0} | {1}".format(filename, testname))
    41     def addError(self, test, err):
    42         _TestResult.addError(self, test, err)
    43         self.printFail(test, err)
    45     def addFailure(self, test, err):
    46         _TestResult.addFailure(self, test, err)
    47         self.printFail(test,err)
    49     def printFail(self, test, err):
    50         exctype, value, tb = err
    51         # Skip test runner traceback levels
    52         while tb and self._is_relevant_tb_level(tb):
    53             tb = tb.tb_next
    54         if not tb:
    55             self.stream.writeln("TEST-UNEXPECTED-FAIL | NO TRACEBACK |")
    56         _f, _ln, _t = inspect.getframeinfo(tb)[:3]
    57         self.stream.writeln("TEST-UNEXPECTED-FAIL | {0} | line {1}, {2}: {3}" 
    58                             .format(_f, _ln, _t, value.message))
    60     def printErrorList(self):
    61         for test, err in self.errors:
    62             self.stream.writeln("ERROR: {0}".format(self.getDescription(test)))
    63             self.stream.writeln("{0}".format(err))
    66 class MozTestRunner(_TestRunner):
    67     def _makeResult(self):
    68         return _MozTestResult(self.stream, self.descriptions)
    69     def run(self, test):
    70         result = self._makeResult()
    71         test(result)
    72         result.printErrorList()
    73         return result
    75 class MockedFile(StringIO):
    76     def __init__(self, context, filename, content = ''):
    77         self.context = context
    78         self.name = filename
    79         StringIO.__init__(self, content)
    81     def close(self):
    82         self.context.files[self.name] = self.getvalue()
    83         StringIO.close(self)
    85     def __enter__(self):
    86         return self
    88     def __exit__(self, type, value, traceback):
    89         self.close()
    91 class MockedOpen(object):
    92     '''
    93     Context manager diverting the open builtin such that opening files
    94     can open "virtual" file instances given when creating a MockedOpen.
    96     with MockedOpen({'foo': 'foo', 'bar': 'bar'}):
    97         f = open('foo', 'r')
    99     will thus open the virtual file instance for the file 'foo' to f.
   101     MockedOpen also masks writes, so that creating or replacing files
   102     doesn't touch the file system, while subsequently opening the file
   103     will return the recorded content.
   105     with MockedOpen():
   106         f = open('foo', 'w')
   107         f.write('foo')
   108     self.assertRaises(Exception,f.open('foo', 'r'))
   109     '''
   110     def __init__(self, files = {}):
   111         self.files = {}
   112         for name, content in files.iteritems():
   113             self.files[os.path.abspath(name)] = content
   115     def __call__(self, name, mode = 'r'):
   116         absname = os.path.abspath(name)
   117         if 'w' in mode:
   118             file = MockedFile(self, absname)
   119         elif absname in self.files:
   120             file = MockedFile(self, absname, self.files[absname])
   121         elif 'a' in mode:
   122             file = MockedFile(self, absname, self.open(name, 'r').read())
   123         else:
   124             file = self.open(name, mode)
   125         if 'a' in mode:
   126             file.seek(0, os.SEEK_END)
   127         return file
   129     def __enter__(self):
   130         import __builtin__
   131         self.open = __builtin__.open
   132         self._orig_path_exists = os.path.exists
   133         __builtin__.open = self
   134         os.path.exists = self._wrapped_exists
   136     def __exit__(self, type, value, traceback):
   137         import __builtin__
   138         __builtin__.open = self.open
   139         os.path.exists = self._orig_path_exists
   141     def _wrapped_exists(self, p):
   142         if p in self.files:
   143             return True
   145         abspath = os.path.abspath(p)
   146         if abspath in self.files:
   147             return True
   149         return self._orig_path_exists(p)
   151 def main(*args):
   152     unittest.main(testRunner=MozTestRunner(),*args)

mercurial