source: mod_gnutls/test/mgstest/test_tests.py @ caffc86

Last change on this file since caffc86 was caffc86, checked in by Fiona Klute <fiona.klute@…>, 7 months ago

Fix error text in mock response

  • Property mode set to 100644
File size: 5.9 KB
Line 
1import unittest
2import unittest.mock
3import yaml
4from http import HTTPStatus
5
6from . import TestExpectationFailed
7from .tests import TestRequest
8
9
10def mock_response(status=HTTPStatus.OK, headers=dict(), body=b''):
11    response = unittest.mock.Mock()
12    response.status = status
13    response.reason = status.phrase
14    response.getheaders.return_value = [(k, v) for k, v in headers.items()]
15    response.read.return_value = body
16    return response
17
18
19class TestTestRequest(unittest.TestCase):
20    def test_run(self):
21        """Check that TestRequest matches regular response correctly."""
22        response = mock_response(
23            HTTPStatus.OK, {'X-Required-Header': 'Hi!'}, b'Hello World!\n')
24        conn = unittest.mock.Mock()
25        conn.getresponse.return_value = response
26
27        r = TestRequest(path='/test.txt',
28                        expect={'status': 200,
29                                'headers': {'X-Forbidden-Header': None,
30                                            'X-Required-Header': 'Hi!'},
31                                'body': {'contains': 'Hello'}})
32        r.run(conn)
33        conn.request.assert_called_with(
34            'GET', '/test.txt', body=None, headers={})
35
36    def test_run_unexpected_reset(self):
37        """An unexpected exception breaks out of the TestRequest run."""
38        conn = unittest.mock.Mock()
39        conn.request.side_effect = ConnectionResetError
40        r = TestRequest(path='/test.txt',
41                        expect={'status': 200})
42        with self.assertRaises(ConnectionResetError):
43            r.run(conn)
44        conn.request.assert_called_with(
45            'GET', '/test.txt', body=None, headers={})
46
47    def test_run_expected_reset(self):
48        """If the TestRequest expects an exception, it gets caught."""
49        conn = unittest.mock.Mock()
50        conn.request.side_effect = ConnectionResetError
51        r = TestRequest(path='/test.txt',
52                        expect={'reset': True})
53        r.run(conn)
54        conn.request.assert_called_with(
55            'GET', '/test.txt', body=None, headers={})
56
57    def test_check_headers(self):
58        r = TestRequest(path='/test.txt',
59                        expect={'headers': {'X-Forbidden-Header': None,
60                                            'X-Required-Header': 'Hi!'}})
61        r.check_headers({'X-Required-Header': 'Hi!'})
62
63        with self.assertRaisesRegex(TestExpectationFailed,
64                                    'Unexpected value in header'):
65            r.check_headers({'X-Required-Header': 'Hello!'})
66
67        with self.assertRaisesRegex(TestExpectationFailed,
68                                    'Unexpected value in header'):
69            r.check_headers({'X-Forbidden-Header': 'Hi!'})
70
71    def test_check_body_exact(self):
72        r = TestRequest(
73            path='/test.txt', method='GET', headers={},
74            expect={'status': 200, 'body': {'exactly': 'test\n'}})
75        r.check_body('test\n')
76
77        with self.assertRaisesRegex(
78                TestExpectationFailed,
79                r"Unexpected body: 'xyz\\n' != 'test\\n'"):
80            r.check_body('xyz\n')
81
82    def test_check_body_contains(self):
83        r1 = TestRequest(
84            path='/test.txt', method='GET', headers={},
85            expect={'status': 200, 'body': {'contains': ['tes', 'est']}})
86        r1.check_body('test\n')
87        with self.assertRaisesRegex(
88                TestExpectationFailed,
89                r"Unexpected body: 'est\\n' does not contain 'tes'"):
90            r1.check_body('est\n')
91
92        r2 = TestRequest(
93            path='/test.txt', method='GET', headers={},
94            expect={'status': 200, 'body': {'contains': 'test'}})
95        r2.check_body('test\n')
96
97    def test_expects_conn_reset(self):
98        r1 = TestRequest(path='/test.txt', method='GET', headers={},
99                         expect={'status': 200, 'body': {'contains': 'test'}})
100        self.assertFalse(r1.expects_conn_reset())
101
102        r2 = TestRequest(path='/test.txt', method='GET', headers={},
103                         expect={'reset': True})
104        self.assertTrue(r2.expects_conn_reset())
105
106
107class TestTestConnection(unittest.TestCase):
108    def test_run(self):
109        """TestConnection with a successful and a failing TestRequest."""
110
111        test = """
112        !connection
113        gnutls_params:
114          - x509cafile=authority/x509.pem
115        actions:
116          - !request
117            path: /test.txt
118            headers:
119              X-Test: mgstest
120            expect:
121              status: 200
122              headers:
123                X-Required: 'Hi!'
124              body:
125                exactly: |
126                  Hello World!
127          - !request
128            method: POST
129            path: /test.txt
130            expect:
131              status: 200
132              body:
133                exactly: |
134                  Hello World!
135        """
136        conn = yaml.load(test, Loader=yaml.Loader)
137
138        responses = [
139            mock_response(
140                HTTPStatus.OK, {'X-Required': 'Hi!'},
141                b'Hello World!\n'),
142            mock_response(
143                HTTPStatus.METHOD_NOT_ALLOWED, {}, b'Cannot POST here!\n')]
144
145        # note that this patches HTTPSubprocessConnection as imported
146        # into mgstest.tests, not in the origin package
147        with unittest.mock.patch(
148                'mgstest.tests.HTTPSubprocessConnection', spec=True) as P:
149            # the mock provided by patch acts as class, get the instance
150            instance = P.return_value
151            instance.getresponse.side_effect = responses
152            with self.assertRaisesRegex(
153                    TestExpectationFailed,
154                    r"Unexpected status: 405 != 200"):
155                conn.run()
156
157        instance.request.assert_has_calls([
158            unittest.mock.call(
159                'GET', '/test.txt', body=None, headers={'X-Test': 'mgstest'}),
160            unittest.mock.call('POST', '/test.txt', body=None, headers={})
161        ])
162        self.assertEqual(instance.request.call_count, 2)
Note: See TracBrowser for help on using the repository browser.