5
from os.path import dirname
7
from testtools import TestCase
8
from testtools.matchers import AfterPreprocessing, Contains
12
from charmhelpers.core.hookenv import Serializable
15
def normalize_whitespace(data):
16
return ' '.join(chunk for chunk in data.split())
19
@patch.dict(os.environ, {"CHARM_DIR": dirname(dirname(dirname(__file__)))})
20
class SquidConfigTest(TestCase):
22
def _assert_contents(self, *expected):
24
for chunk in expected:
25
self.assertThat(got, AfterPreprocessing(
27
Contains(normalize_whitespace(chunk))))
30
def _apply_patch(self, name):
32
mocked_name = p.start()
33
self.addCleanup(p.stop)
37
super(SquidConfigTest, self).setUp()
38
self.get_reverse_sites = self._apply_patch('hooks.get_reverse_sites')
39
self.get_forward_sites = self._apply_patch('hooks.get_forward_sites')
40
self.config_get = self._apply_patch('hooks.config_get')
41
self.write_squid3_config = self._apply_patch(
42
'hooks.write_squid3_config')
44
self.get_forward_sites.return_value = {}
46
def test_squid_config_no_sites(self):
47
self.config_get.return_value = Serializable({
48
"refresh_patterns": "",
49
"cache_size_mb": 1024,
50
"target_objs_per_dir": 1024,
51
"avg_obj_size_kb": 1024,
54
self.get_reverse_sites.return_value = None
55
self.write_squid3_config.side_effect = self._assert_contents(
57
always_direct deny all
63
hooks.construct_squid3_config()
65
def test_squid_config_via_off(self):
66
self.config_get.return_value = Serializable({
67
"refresh_patterns": "",
68
"cache_size_mb": 1024,
69
"target_objs_per_dir": 1024,
70
"avg_obj_size_kb": 1024,
73
self.get_reverse_sites.return_value = None
74
self.write_squid3_config.side_effect = self._assert_contents(
79
hooks.construct_squid3_config()
81
def test_squid_config_refresh_pattern_json(self):
82
self.config_get.return_value = Serializable({
83
"refresh_patterns": json.dumps(
84
{"http://www.ubuntu.com":
85
{"min": 0, "percent": 20, "max": 60}}),
86
"cache_size_mb": 1024,
87
"target_objs_per_dir": 1024,
88
"avg_obj_size_kb": 1024,
90
self.get_reverse_sites.return_value = None
91
self.write_squid3_config.side_effect = self._assert_contents(
93
refresh_pattern http://www.ubuntu.com 0 20% 60
96
hooks.construct_squid3_config()
98
def test_squid_config_refresh_pattern_yaml(self):
99
self.config_get.return_value = Serializable({
100
"refresh_patterns": yaml.dump(
101
{"http://www.ubuntu.com":
102
{"min": 0, "percent": 20, "max": 60}}),
103
"cache_size_mb": 1024,
104
"target_objs_per_dir": 1024,
105
"avg_obj_size_kb": 1024,
107
self.get_reverse_sites.return_value = None
108
self.write_squid3_config.side_effect = self._assert_contents(
110
refresh_pattern http://www.ubuntu.com 0 20% 60
113
hooks.construct_squid3_config()
115
def test_squid_config_refresh_pattern_options(self):
116
self.config_get.return_value = Serializable({
117
"refresh_patterns": yaml.dump(
118
{"http://www.ubuntu.com":
119
{"min": 0, "percent": 20, "max": 60,
120
"options": ["override-lastmod",
121
"reload-into-ims"]}}),
122
"cache_size_mb": 1024,
123
"target_objs_per_dir": 1024,
124
"avg_obj_size_kb": 1024,
126
self.get_reverse_sites.return_value = None
127
self.write_squid3_config.side_effect = self._assert_contents(
129
refresh_pattern http://www.ubuntu.com 0 20% 60
130
override-lastmod reload-into-ims
131
refresh_pattern . 30 20% 4320
134
hooks.construct_squid3_config()
136
def test_squid_config_refresh_pattern_default(self):
137
self.config_get.return_value = Serializable({
138
"refresh_patterns": yaml.dump(
140
{"min": 0, "percent": 20, "max": 60,
141
"options": ["override-lastmod",
142
"reload-into-ims"]}}),
143
"cache_size_mb": 1024,
144
"target_objs_per_dir": 1024,
145
"avg_obj_size_kb": 1024,
147
self.get_reverse_sites.return_value = None
148
self.write_squid3_config.side_effect = self._assert_contents(
150
refresh_pattern . 0 20% 60
151
override-lastmod reload-into-ims
154
hooks.construct_squid3_config()
156
def test_squid_config_no_sitenames(self):
157
self.config_get.return_value = Serializable({
158
"refresh_patterns": "",
159
"cache_size_mb": 1024,
160
"target_objs_per_dir": 1024,
161
"avg_obj_size_kb": 1024,
163
self.get_reverse_sites.return_value = {
165
hooks.Server("website_1__foo_1", "1.2.3.4", 4242, ''),
166
hooks.Server("website_1__foo_2", "1.2.3.5", 4242, ''),
169
self.write_squid3_config.side_effect = self._assert_contents(
171
acl no_sitename_acl myport
172
http_access allow accel_ports no_sitename_acl
173
never_direct allow no_sitename_acl
176
cache_peer 1.2.3.4 parent 4242 0 name=website_1__foo_1 no-query
177
no-digest originserver round-robin login=PASS
178
cache_peer_access website_1__foo_1 allow no_sitename_acl
179
cache_peer_access website_1__foo_1 deny all
182
cache_peer 1.2.3.5 parent 4242 0 name=website_1__foo_2 no-query
183
no-digest originserver round-robin login=PASS
184
cache_peer_access website_1__foo_2 allow no_sitename_acl
185
cache_peer_access website_1__foo_2 deny all
188
hooks.construct_squid3_config()
190
def test_squid_config_with_domain(self):
191
self.config_get.return_value = Serializable({
192
"refresh_patterns": "",
193
"cache_size_mb": 1024,
194
"target_objs_per_dir": 1024,
195
"avg_obj_size_kb": 1024,
197
self.get_reverse_sites.return_value = {
199
hooks.Server("foo_com__website_1__foo_1",
200
"1.2.3.4", 4242, "forceddomain=example.com"),
201
hooks.Server("foo_com__website_1__foo_2",
202
"1.2.3.5", 4242, "forceddomain=example.com"),
205
self.write_squid3_config.side_effect = self._assert_contents(
207
acl s_1_acl dstdomain foo.com
208
http_access allow accel_ports s_1_acl
209
http_access allow CONNECT SSL_ports s_1_acl
210
always_direct allow CONNECT SSL_ports s_1_acl
211
always_direct deny s_1_acl
214
cache_peer 1.2.3.4 parent 4242 0 name=foo_com__website_1__foo_1
215
no-query no-digest originserver round-robin login=PASS
216
forceddomain=example.com
217
cache_peer_access foo_com__website_1__foo_1 allow s_1_acl
218
cache_peer_access foo_com__website_1__foo_1 deny all
221
cache_peer 1.2.3.5 parent 4242 0 name=foo_com__website_1__foo_2
222
no-query no-digest originserver round-robin login=PASS
223
forceddomain=example.com
224
cache_peer_access foo_com__website_1__foo_2 allow s_1_acl
225
cache_peer_access foo_com__website_1__foo_2 deny all
228
hooks.construct_squid3_config()
230
def test_with_domain_no_servers_only_direct(self):
231
self.config_get.return_value = Serializable({
232
"refresh_patterns": "",
233
"cache_size_mb": 1024,
234
"target_objs_per_dir": 1024,
235
"avg_obj_size_kb": 1024,
237
self.get_reverse_sites.return_value = {
241
self.write_squid3_config.side_effect = self._assert_contents(
243
acl s_1_acl dstdomain foo.com
244
http_access allow accel_ports s_1_acl
245
http_access allow CONNECT SSL_ports s_1_acl
246
always_direct allow s_1_acl
249
hooks.construct_squid3_config()
251
def test_with_balancer_no_servers_only_direct(self):
252
self.config_get.return_value = Serializable({
253
"refresh_patterns": "",
254
"cache_size_mb": 1024,
255
"target_objs_per_dir": 1024,
256
"avg_obj_size_kb": 1024,
257
"x_balancer_name_allowed": True,
259
self.get_reverse_sites.return_value = {
262
self.write_squid3_config.side_effect = self._assert_contents(
264
acl s_1_acl dstdomain foo.com
265
http_access allow accel_ports s_1_acl
266
http_access allow CONNECT SSL_ports s_1_acl
267
always_direct allow s_1_acl
270
acl s_1_balancer req_header X-Balancer-Name foo\.com
271
http_access allow accel_ports s_1_balancer
272
http_access allow CONNECT SSL_ports s_1_balancer
273
always_direct allow s_1_balancer
276
hooks.construct_squid3_config()
278
def test_with_balancer_name(self):
279
self.config_get.return_value = Serializable({
280
"refresh_patterns": "",
281
"cache_size_mb": 1024,
282
"target_objs_per_dir": 1024,
283
"avg_obj_size_kb": 1024,
284
"x_balancer_name_allowed": True,
286
self.get_reverse_sites.return_value = {
288
hooks.Server("foo_com__website_1__foo_1",
289
"1.2.3.4", 4242, ''),
290
hooks.Server("foo_com__website_1__foo_2",
291
"1.2.3.5", 4242, ''),
294
self.write_squid3_config.side_effect = self._assert_contents(
296
acl s_1_acl dstdomain foo.com
297
http_access allow accel_ports s_1_acl
298
http_access allow CONNECT SSL_ports s_1_acl
299
always_direct allow CONNECT SSL_ports s_1_acl
300
always_direct deny s_1_acl
303
acl s_1_balancer req_header X-Balancer-Name foo\.com
304
http_access allow accel_ports s_1_balancer
305
http_access allow CONNECT SSL_ports s_1_balancer
306
always_direct allow CONNECT SSL_ports s_1_balancer
307
always_direct deny s_1_balancer
310
cache_peer 1.2.3.4 parent 4242 0 name=foo_com__website_1__foo_1
311
no-query no-digest originserver round-robin login=PASS
312
cache_peer_access foo_com__website_1__foo_1 allow s_1_acl
313
cache_peer_access foo_com__website_1__foo_1 allow s_1_balancer
314
cache_peer_access foo_com__website_1__foo_1 deny all
317
cache_peer 1.2.3.5 parent 4242 0 name=foo_com__website_1__foo_2
318
no-query no-digest originserver round-robin login=PASS
319
cache_peer_access foo_com__website_1__foo_2 allow s_1_acl
322
hooks.construct_squid3_config()
324
def test_forward_enabled(self):
325
self.config_get.return_value = Serializable({
326
"enable_forward_proxy": True,
327
"refresh_patterns": "",
328
"cache_size_mb": 1024,
329
"target_objs_per_dir": 1024,
330
"avg_obj_size_kb": 1024,
332
self.get_reverse_sites.return_value = {
335
self.get_forward_sites.return_value = [
336
{'private-address': '1.2.3.4', 'name': 'service_unit_0'},
337
{'private-address': '2.3.4.5', 'name': 'service_unit_1'},
339
self.write_squid3_config.side_effect = self._assert_contents(
341
acl fwd_service_unit_0 src 1.2.3.4
342
http_access allow fwd_service_unit_0
343
http_access allow CONNECT SSL_ports fwd_service_unit_0
344
always_direct allow fwd_service_unit_0
345
always_direct allow CONNECT SSL_ports fwd_service_unit_0
346
acl fwd_service_unit_1 src 2.3.4.5
347
http_access allow fwd_service_unit_1
348
http_access allow CONNECT SSL_ports fwd_service_unit_1
349
always_direct allow fwd_service_unit_1
350
always_direct allow CONNECT SSL_ports fwd_service_unit_1
353
acl s_1_acl dstdomain foo.com
354
http_access allow accel_ports s_1_acl
355
http_access allow CONNECT SSL_ports s_1_acl
356
always_direct allow s_1_acl
359
hooks.construct_squid3_config()
361
def test_squid_config_cache_enabled(self):
362
self.config_get.return_value = Serializable({
363
"refresh_patterns": "",
364
"cache_size_mb": 1024,
366
"cache_dir": "/var/run/squid3",
367
"target_objs_per_dir": 16,
368
"avg_obj_size_kb": 4,
370
self.get_reverse_sites.return_value = None
371
self.write_squid3_config.side_effect = self._assert_contents(
373
cache_dir aufs /var/run/squid3 1024 32 512
377
hooks.construct_squid3_config()
379
def test_squid_config_cache_disabled(self):
380
self.config_get.return_value = Serializable({
381
"refresh_patterns": "",
383
"target_objs_per_dir": 1024,
384
"avg_obj_size_kb": 1024,
386
self.get_reverse_sites.return_value = None
387
self.write_squid3_config.side_effect = self._assert_contents(
392
hooks.construct_squid3_config()
395
class HelpersTest(TestCase):
396
def test_gets_config(self):
397
json_string = '{"foo": "BAR"}'
398
with patch('subprocess.check_output') as check_output:
399
check_output.return_value = json_string
401
result = hooks.config_get()
403
self.assertEqual(result['foo'], 'BAR')
404
check_output.assert_called_with(['config-get', '--format=json'])
406
def test_gets_config_with_scope(self):
407
json_string = '{"foo": "BAR"}'
408
with patch('subprocess.check_output') as check_output:
409
check_output.return_value = json_string
411
result = hooks.config_get(scope='baz')
413
self.assertEqual(result['foo'], 'BAR')
414
check_output.assert_called_with(['config-get', 'baz',