OLD | NEW |
| (Empty) |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 import datetime | |
6 import unittest | |
7 | |
8 from infra_libs.ts_mon.common import http_metrics | |
9 from infra_libs import instrumented_requests | |
10 from infra_libs import ts_mon | |
11 | |
12 import requests | |
13 import mock | |
14 | |
15 | |
16 class InstrumentedRequestsTest(unittest.TestCase): | |
17 def setUp(self): | |
18 ts_mon.reset_for_unittest() | |
19 | |
20 self.response = requests.Response() | |
21 self.response.elapsed = datetime.timedelta(seconds=2, milliseconds=500) | |
22 self.response.status_code = 200 | |
23 self.response.request = requests.PreparedRequest() | |
24 self.response.request.prepare_headers(None) | |
25 | |
26 self.hook = instrumented_requests.instrumentation_hook('foo') | |
27 | |
28 def tearDown(self): | |
29 super(InstrumentedRequestsTest, self).tearDown() | |
30 mock.patch.stopall() | |
31 | |
32 def test_success_status(self): | |
33 self.hook(self.response) | |
34 | |
35 self.assertEquals(1, http_metrics.response_status.get( | |
36 {'name': 'foo', 'client': 'requests', 'status': 200})) | |
37 self.assertIsNone(http_metrics.response_status.get( | |
38 {'name': 'foo', 'client': 'requests', 'status': 404})) | |
39 | |
40 def test_error_status(self): | |
41 self.response.status_code = 404 | |
42 self.hook(self.response) | |
43 | |
44 self.assertIsNone(http_metrics.response_status.get( | |
45 {'name': 'foo', 'client': 'requests', 'status': 200})) | |
46 self.assertEquals(1, http_metrics.response_status.get( | |
47 {'name': 'foo', 'client': 'requests', 'status': 404})) | |
48 | |
49 def test_response_bytes_none(self): | |
50 self.hook(self.response) | |
51 | |
52 self.assertEquals(0, http_metrics.response_bytes.get( | |
53 {'name': 'foo', 'client': 'requests'}).sum) | |
54 | |
55 def test_response_bytes(self): | |
56 self.response.headers['content-length'] = '7' | |
57 self.hook(self.response) | |
58 | |
59 self.assertEquals(7, http_metrics.response_bytes.get( | |
60 {'name': 'foo', 'client': 'requests'}).sum) | |
61 | |
62 def test_request_bytes_none(self): | |
63 self.hook(self.response) | |
64 | |
65 self.assertEquals(0, http_metrics.request_bytes.get( | |
66 {'name': 'foo', 'client': 'requests'}).sum) | |
67 | |
68 def test_request_bytes(self): | |
69 self.response.request.headers['content-length'] = '5' | |
70 self.hook(self.response) | |
71 | |
72 self.assertEquals(5, http_metrics.request_bytes.get( | |
73 {'name': 'foo', 'client': 'requests'}).sum) | |
74 | |
75 def test_durations(self): | |
76 self.hook(self.response) | |
77 | |
78 self.assertEquals(2500, http_metrics.durations.get( | |
79 {'name': 'foo', 'client': 'requests'}).sum) | |
80 | |
81 @staticmethod | |
82 def _setup_wrap(hooks=None, side_effect=None): | |
83 requests._instrumented_test = mock.Mock() | |
84 if side_effect is not None: | |
85 requests._instrumented_test.side_effect = side_effect | |
86 kwargs = {} | |
87 if hooks: | |
88 kwargs = {'hooks': hooks} | |
89 instrumented_requests._wrap( | |
90 '_instrumented_test', 'foo', 'http://example.com', **kwargs) | |
91 return requests._instrumented_test | |
92 | |
93 def test_wrap(self): | |
94 f = self._setup_wrap() | |
95 | |
96 self.assertTrue(f.called) | |
97 self.assertEquals(('http://example.com',), f.call_args[0]) | |
98 self.assertIn('hooks', f.call_args[1]) | |
99 self.assertIn('response', f.call_args[1]['hooks']) | |
100 self.assertTrue(hasattr(f.call_args[1]['hooks']['response'], '__call__')) | |
101 | |
102 def test_wrap_merges_hooks(self): | |
103 f = self._setup_wrap(hooks={'foo': lambda: 42}) | |
104 | |
105 self.assertTrue(f.called) | |
106 self.assertEquals(('http://example.com',), f.call_args[0]) | |
107 self.assertIn('hooks', f.call_args[1]) | |
108 self.assertIn('response', f.call_args[1]['hooks']) | |
109 self.assertIn('foo', f.call_args[1]['hooks']) | |
110 self.assertTrue(hasattr(f.call_args[1]['hooks']['response'], '__call__')) | |
111 self.assertEquals(42, f.call_args[1]['hooks']['foo']()) | |
112 | |
113 def test_wrap_times_out(self): | |
114 with self.assertRaises(requests.exceptions.ReadTimeout): | |
115 self._setup_wrap(side_effect=requests.exceptions.ReadTimeout) | |
116 | |
117 self.assertIsNone(http_metrics.response_status.get( | |
118 {'name': 'foo', 'client': 'requests', 'status': 200})) | |
119 self.assertEquals(1, http_metrics.response_status.get( | |
120 {'name': 'foo', 'client': 'requests', | |
121 'status': http_metrics.STATUS_TIMEOUT})) | |
122 | |
123 def test_wrap_errors_out(self): | |
124 with self.assertRaises(requests.exceptions.ConnectionError): | |
125 self._setup_wrap(side_effect=requests.exceptions.ConnectionError) | |
126 | |
127 self.assertIsNone(http_metrics.response_status.get( | |
128 {'name': 'foo', 'client': 'requests', 'status': 200})) | |
129 self.assertEquals(1, http_metrics.response_status.get( | |
130 {'name': 'foo', 'client': 'requests', | |
131 'status': http_metrics.STATUS_ERROR})) | |
132 | |
133 def test_wrap_raises_other_exception(self): | |
134 with self.assertRaises(requests.exceptions.RequestException): | |
135 self._setup_wrap(side_effect=requests.exceptions.RequestException) | |
136 | |
137 self.assertIsNone(http_metrics.response_status.get( | |
138 {'name': 'foo', 'client': 'requests', 'status': 200})) | |
139 self.assertEquals(1, http_metrics.response_status.get( | |
140 {'name': 'foo', 'client': 'requests', | |
141 'status': http_metrics.STATUS_EXCEPTION})) | |
OLD | NEW |