~andrewjbeach/juju-ci-tools/make-local-patcher

« back to all changes in this revision

Viewing changes to tests/__init__.py

  • Committer: Aaron Bentley
  • Date: 2015-01-19 15:32:33 UTC
  • mto: This revision was merged to the branch mainline in revision 804.
  • Revision ID: aaron.bentley@canonical.com-20150119153233-jjcvikwiw1dx2lak
Print error on missing environment.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
"""Testing helpers and base classes for better isolation."""
2
 
 
3
 
from contextlib import contextmanager
4
 
import logging
5
 
import os
6
 
import StringIO
7
 
import subprocess
8
 
import unittest
9
 
 
10
 
from mock import patch
11
 
 
12
 
import utility
13
 
 
14
 
 
15
 
@contextmanager
16
 
def stdout_guard():
17
 
    stdout = StringIO.StringIO()
18
 
    with patch('sys.stdout', stdout):
19
 
        yield
20
 
    if stdout.getvalue() != '':
21
 
        raise AssertionError(
22
 
            'Value written to stdout: {}'.format(stdout.getvalue()))
23
 
 
24
 
 
25
 
def use_context(test_case, context):
26
 
    result = context.__enter__()
27
 
    test_case.addCleanup(context.__exit__, None, None, None)
28
 
    return result
29
 
 
30
 
 
31
 
class TestCase(unittest.TestCase):
32
 
    """TestCase provides a better isolated version of unittest.TestCase."""
33
 
 
34
 
    log_level = logging.INFO
35
 
    test_environ = {}
36
 
 
37
 
    def setUp(self):
38
 
        super(TestCase, self).setUp()
39
 
 
40
 
        def _must_not_Popen(*args, **kwargs):
41
 
            """Tests may patch Popen but should never call it."""
42
 
            self.fail("subprocess.Popen(*{!r}, **{!r}) called".format(
43
 
                args, kwargs))
44
 
 
45
 
        self.addCleanup(setattr, subprocess, "Popen", subprocess.Popen)
46
 
        subprocess.Popen = _must_not_Popen
47
 
 
48
 
        self.addCleanup(setattr, os, "environ", os.environ)
49
 
        os.environ = dict(self.test_environ)
50
 
 
51
 
        setup_test_logging(self, self.log_level)
52
 
 
53
 
 
54
 
class FakeHomeTestCase(TestCase):
55
 
    """FakeHomeTestCase creates an isolated home dir for Juju to use."""
56
 
 
57
 
    def setUp(self):
58
 
        super(FakeHomeTestCase, self).setUp()
59
 
        self.home_dir = use_context(self, utility.temp_dir())
60
 
        os.environ["HOME"] = self.home_dir
61
 
        os.environ["PATH"] = os.path.join(self.home_dir, ".local", "bin")
62
 
        os.mkdir(os.path.join(self.home_dir, ".juju"))
63
 
 
64
 
 
65
 
def setup_test_logging(testcase, level=None):
66
 
    log = logging.getLogger()
67
 
    testcase.addCleanup(setattr, log, 'handlers', log.handlers)
68
 
    log.handlers = []
69
 
    testcase.log_stream = StringIO.StringIO()
70
 
    handler = logging.StreamHandler(testcase.log_stream)
71
 
    handler.setFormatter(logging.Formatter("%(levelname)s %(message)s"))
72
 
    log.addHandler(handler)
73
 
    if level is not None:
74
 
        testcase.addCleanup(log.setLevel, log.level)
75
 
        log.setLevel(level)
76
 
 
77
 
 
78
 
# suppress nosetests
79
 
setup_test_logging.__test__ = False
80
 
 
81
 
 
82
 
@contextmanager
83
 
def parse_error(test_case):
84
 
    stderr = StringIO.StringIO()
85
 
    with test_case.assertRaises(SystemExit):
86
 
        with patch('sys.stderr', stderr):
87
 
            yield stderr
88
 
 
89
 
 
90
 
@contextmanager
91
 
def temp_os_env(key, value):
92
 
    org_value = os.environ.get(key, '')
93
 
    os.environ[key] = value
94
 
    try:
95
 
        yield
96
 
    finally:
97
 
        os.environ[key] = org_value