|
1 |
""" unit tests (mainly for code coverage)
|
|
2 |
"""
|
|
3 |
import StringIO
|
|
4 |
import os
|
|
5 |
import sys
|
|
6 |
|
|
7 |
import json
|
|
8 |
import pytest
|
|
9 |
from mock import call, patch, Mock
|
|
10 |
from requests import Response, exceptions
|
|
11 |
|
|
12 |
from hobo.agent.combo.management.commands.hobo_deploy import Command as ComboCommand
|
|
13 |
from hobo.agent.common.management.commands.hobo_deploy import (
|
|
14 |
replace_file, Command, CommandError)
|
|
15 |
from hobo.agent.hobo.management.commands.hobo_deploy import Command as HoboCommand
|
|
16 |
from hobo.environment.models import Variable, Combo, Hobo, Wcs
|
|
17 |
from hobo.multitenant.middleware import TenantNotFound
|
|
18 |
|
|
19 |
|
|
20 |
@pytest.fixture
|
|
21 |
def fake_themes(settings, tmpdir):
|
|
22 |
THEMES="""
|
|
23 |
[
|
|
24 |
{
|
|
25 |
"id": "alfortville",
|
|
26 |
"label": "Alfortville",
|
|
27 |
"variables": {
|
|
28 |
"css_variant": "alfortville",
|
|
29 |
"no_extra_js": false,
|
|
30 |
"theme_color": "#804697"
|
|
31 |
},
|
|
32 |
"overlay": "foobar"
|
|
33 |
},
|
|
34 |
{
|
|
35 |
"id": "publik",
|
|
36 |
"label": "Publik",
|
|
37 |
"variables": {
|
|
38 |
"css_variant": "publik",
|
|
39 |
"no_extra_js": false,
|
|
40 |
"theme_color": "#E80E89"
|
|
41 |
}
|
|
42 |
}
|
|
43 |
]
|
|
44 |
"""
|
|
45 |
base_dir = str(tmpdir.mkdir('themes'))
|
|
46 |
settings.THEMES_DIRECTORY = base_dir
|
|
47 |
|
|
48 |
themes_dir = os.path.join(base_dir, 'publik-base')
|
|
49 |
os.mkdir(themes_dir)
|
|
50 |
with open(os.path.join(themes_dir, 'themes.json'), 'w') as handler:
|
|
51 |
handler.write(THEMES)
|
|
52 |
|
|
53 |
# populate 'foobar' overlay
|
|
54 |
themes_dir = os.path.join(base_dir, 'foobar')
|
|
55 |
os.mkdir(themes_dir)
|
|
56 |
for part in ('static', 'templates'):
|
|
57 |
os.mkdir(os.path.join(themes_dir, part))
|
|
58 |
|
|
59 |
|
|
60 |
def test_replace_file(tmpdir):
|
|
61 |
path = str(tmpdir) + '/my_file.txt'
|
|
62 |
|
|
63 |
content = 'content of my new file'
|
|
64 |
replace_file(path, content)
|
|
65 |
with open(path, 'r') as handler:
|
|
66 |
assert handler.read() == content
|
|
67 |
|
|
68 |
content = 'new content for my file'
|
|
69 |
replace_file(path, content)
|
|
70 |
with open(path, 'r') as handler:
|
|
71 |
assert handler.read() == content
|
|
72 |
|
|
73 |
|
|
74 |
def test_handle_from_scratch():
|
|
75 |
"""API using JSON from file or from stdin"""
|
|
76 |
command = Command()
|
|
77 |
CONTENT = """
|
|
78 |
{
|
|
79 |
"services": [{
|
|
80 |
"service-id": "combo"
|
|
81 |
}]
|
|
82 |
}
|
|
83 |
"""
|
|
84 |
command.deploy = Mock()
|
|
85 |
EXPECTED = [call('https://combo.dev.publik.love/',
|
|
86 |
{'services': [{'service-id': 'combo'}]}, None)]
|
|
87 |
|
|
88 |
# handle from file
|
|
89 |
command.deploy.reset_mock()
|
|
90 |
with patch('hobo.agent.common.management.commands.hobo_deploy.file') as mocked_open:
|
|
91 |
mocked_open.side_effect = [StringIO.StringIO(CONTENT)]
|
|
92 |
command.handle('https://combo.dev.publik.love/', 'envbof.json')
|
|
93 |
assert command.deploy.mock_calls == EXPECTED
|
|
94 |
|
|
95 |
# handle using a pipe
|
|
96 |
command.deploy.reset_mock()
|
|
97 |
backup = sys.stdin
|
|
98 |
sys.stdin = StringIO.StringIO(CONTENT)
|
|
99 |
command.handle('https://combo.dev.publik.love/', '-')
|
|
100 |
sys.stdin = backup
|
|
101 |
assert command.deploy.mock_calls == EXPECTED
|
|
102 |
|
|
103 |
# JSON having syntax error
|
|
104 |
command.deploy.reset_mock()
|
|
105 |
with patch('hobo.agent.common.management.commands.hobo_deploy.file') as mocked_open:
|
|
106 |
mocked_open.side_effect = [StringIO.StringIO('malformated JSON')]
|
|
107 |
with pytest.raises(ValueError, match='No JSON object could be decoded'):
|
|
108 |
command.handle('https://combo.dev.publik.love/', 'env.json')
|
|
109 |
assert command.deploy.mock_calls == []
|
|
110 |
|
|
111 |
# missing args
|
|
112 |
with pytest.raises(CommandError, match='missing args'):
|
|
113 |
command.handle('https://combo.dev.publik.love/')
|
|
114 |
with pytest.raises(CommandError, match='missing args'):
|
|
115 |
command.handle(json_filename='env.json')
|
|
116 |
|
|
117 |
|
|
118 |
@patch('hobo.agent.common.management.commands.hobo_deploy.TenantMiddleware.get_tenants')
|
|
119 |
def test_handle_redeploy_case(mocked_get_tenants):
|
|
120 |
"""API using JSON from previous one we put on tenant"""
|
|
121 |
command = Command()
|
|
122 |
command.deploy = Mock()
|
|
123 |
tenant = Mock()
|
|
124 |
|
|
125 |
# redeploy
|
|
126 |
command.deploy.reset_mock()
|
|
127 |
ENVIRONMENT = {'services': [{'this': True,
|
|
128 |
'base_url': 'https://combo.dev.publik.love/',
|
|
129 |
'service-id': 'combo'}]}
|
|
130 |
tenant.get_hobo_json = Mock(return_value=ENVIRONMENT)
|
|
131 |
mocked_get_tenants.return_value = [tenant]
|
|
132 |
command.handle(redeploy=True)
|
|
133 |
assert command.deploy.mock_calls == [ # ignore_timestamp is set to True
|
|
134 |
call('https://combo.dev.publik.love/', ENVIRONMENT, True)]
|
|
135 |
|
|
136 |
# redeploy having wrong JSON content: no 'base_url' entry
|
|
137 |
command.deploy.reset_mock()
|
|
138 |
tenant.get_hobo_json = Mock(return_value=
|
|
139 |
{'services': [{'service-id': 'combo', 'this': True}]})
|
|
140 |
mocked_get_tenants.return_value = [tenant]
|
|
141 |
with pytest.raises(KeyError, match='base_url'):
|
|
142 |
command.handle(redeploy=True)
|
|
143 |
assert command.deploy.mock_calls == []
|
|
144 |
|
|
145 |
# redeploy having wrong JSON content: 'this' entry not found
|
|
146 |
command.deploy.reset_mock()
|
|
147 |
tenant.get_hobo_json = Mock(return_value={'services': [{'service-id': 'combo'}]})
|
|
148 |
mocked_get_tenants.return_value = [tenant]
|
|
149 |
command.handle(redeploy=True)
|
|
150 |
assert command.deploy.mock_calls == []
|
|
151 |
|
|
152 |
# IOError
|
|
153 |
command.deploy.reset_mock()
|
|
154 |
tenant.get_hobo_json = Mock(side_effect=IOError)
|
|
155 |
mocked_get_tenants.return_value = [tenant]
|
|
156 |
command.handle(redeploy=True)
|
|
157 |
assert command.deploy.mock_calls == []
|
|
158 |
|
|
159 |
|
|
160 |
@patch('hobo.agent.common.management.commands.hobo_deploy.TenantMiddleware.get_tenant_by_hostname')
|
|
161 |
def test_deploy(mocked_get_tenant_by_hostname, tmpdir):
|
|
162 |
command = Command()
|
|
163 |
command.deploy_specifics = Mock()
|
|
164 |
tenant = Mock()
|
|
165 |
tenant.get_directory = Mock(return_value=str(tmpdir))
|
|
166 |
base_url = 'https://combo.dev.publik.love/'
|
|
167 |
tenant_hobo_json = os.path.join(str(tmpdir), 'hobo.json')
|
|
168 |
ENVIRONMENT = {'services': [{'service-id': 'combo', 'base_url': base_url}],
|
|
169 |
'timestamp': '001'}
|
|
170 |
|
|
171 |
def assert_deployed():
|
|
172 |
assert mocked_get_tenant_by_hostname.mock_calls[0] == call('combo.dev.publik.love')
|
|
173 |
assert command.deploy_specifics.mock_calls == [
|
|
174 |
call({'services': [{'base_url': 'https://combo.dev.publik.love/',
|
|
175 |
'service-id': 'combo',
|
|
176 |
'this': True,}],
|
|
177 |
'timestamp': '001'},
|
|
178 |
tenant)]
|
|
179 |
with open(tenant_hobo_json, 'r') as handler: # hobo.json file
|
|
180 |
content = json.load(handler)
|
|
181 |
assert ENVIRONMENT['services'][0]['this'] is True # new entry added
|
|
182 |
assert json.dumps(content, sort_keys=True), json.dumps(ENVIRONMENT, sort_keys=True)
|
|
183 |
|
|
184 |
# create tenant first
|
|
185 |
command.deploy_specifics.reset_mock()
|
|
186 |
mocked_get_tenant_by_hostname.reset_mock()
|
|
187 |
mocked_get_tenant_by_hostname.side_effect = [TenantNotFound, tenant]
|
|
188 |
with patch('hobo.agent.common.management.commands.hobo_deploy.call_command'
|
|
189 |
) as mocked_call_command:
|
|
190 |
command.deploy(base_url, ENVIRONMENT, None)
|
|
191 |
assert mocked_call_command.mock_calls == [
|
|
192 |
call('create_tenant', 'combo.dev.publik.love')]
|
|
193 |
assert_deployed()
|
|
194 |
|
|
195 |
# already there (timestamp do not change)
|
|
196 |
command.deploy_specifics.reset_mock()
|
|
197 |
mocked_get_tenant_by_hostname.side_effect = [tenant]
|
|
198 |
command.deploy(base_url, ENVIRONMENT, None)
|
|
199 |
assert command.deploy_specifics.mock_calls == []
|
|
200 |
|
|
201 |
# force re-deploy
|
|
202 |
command.deploy_specifics.reset_mock()
|
|
203 |
mocked_get_tenant_by_hostname.reset_mock()
|
|
204 |
mocked_get_tenant_by_hostname.side_effect = [tenant]
|
|
205 |
command.deploy(base_url, ENVIRONMENT, True)
|
|
206 |
assert_deployed()
|
|
207 |
|
|
208 |
# early exit, we don't redeploy secondary services
|
|
209 |
command.deploy_specifics.reset_mock()
|
|
210 |
env = dict(ENVIRONMENT)
|
|
211 |
env['services'][0]['secondary'] = True
|
|
212 |
command.deploy(base_url, env, None)
|
|
213 |
assert command.deploy_specifics.mock_calls == []
|
|
214 |
|
|
215 |
|
|
216 |
def test_deploy_specific():
|
|
217 |
"""stupid test"""
|
|
218 |
command = Command()
|
|
219 |
command.generate_saml_keys = Mock()
|
|
220 |
command.configure_service_provider = Mock()
|
|
221 |
command.configure_theme = Mock()
|
|
222 |
command.configure_template = Mock()
|
|
223 |
|
|
224 |
command.deploy_specifics('my_hobo_env', 'my_tenant')
|
|
225 |
assert command.generate_saml_keys.mock_calls == [call('my_tenant', prefix='sp-')]
|
|
226 |
assert command.configure_service_provider.mock_calls == [call('my_hobo_env', 'my_tenant')]
|
|
227 |
assert command.configure_theme.mock_calls == [call('my_hobo_env', 'my_tenant')]
|
|
228 |
assert command.configure_template.mock_calls == [call('my_hobo_env', 'my_tenant')]
|
|
229 |
|
|
230 |
|
|
231 |
def test_generate_saml_keys(tmpdir):
|
|
232 |
"""create an RSA key and its x509 certificate"""
|
|
233 |
command = Command()
|
|
234 |
tenant = Mock()
|
|
235 |
tenant.get_directory = Mock(return_value=str(tmpdir))
|
|
236 |
tenant.domain_url = 'combo.dev.publik.love'
|
|
237 |
|
|
238 |
command.generate_saml_keys(tenant)
|
|
239 |
with open('%s/saml.key' % str(tmpdir), 'r') as handler:
|
|
240 |
key = handler.read()
|
|
241 |
with open('%s/saml.crt' % str(tmpdir), 'r') as handler:
|
|
242 |
crt = handler.read()
|
|
243 |
|
|
244 |
# if files exist don't regenerate them
|
|
245 |
command.generate_saml_keys(tenant)
|
|
246 |
with open('%s/saml.key' % str(tmpdir), 'r') as handler:
|
|
247 |
assert key == handler.read()
|
|
248 |
with open('%s/saml.crt' % str(tmpdir), 'r') as handler:
|
|
249 |
assert crt == handler.read()
|
|
250 |
|
|
251 |
|
|
252 |
@patch('hobo.agent.common.management.commands.hobo_deploy.requests.get')
|
|
253 |
def test_configure_service_provider(mocked_get, tmpdir):
|
|
254 |
"""create TENANT/idp-metadata-ID.xml file"""
|
|
255 |
command = Command()
|
|
256 |
tenant = Mock()
|
|
257 |
tenant.get_directory = Mock(return_value=str(tmpdir))
|
|
258 |
response1 = Response()
|
|
259 |
response1._content = 'my saml idp metadata (1)'
|
|
260 |
response1.status_code = 200
|
|
261 |
response2 = Response()
|
|
262 |
response2._content = 'my saml idp metadata (2)'
|
|
263 |
response2.status_code = 200
|
|
264 |
tenant_idp_metadata = '%s/idp-metadata-%s.xml' % (str(tmpdir), '1')
|
|
265 |
|
|
266 |
ENVIRONMENT = {'services': [
|
|
267 |
{'service-id': 'combo',
|
|
268 |
'saml-idp-metadata-url': 'https://combo.dev.publik.love/accounts/mellon/metadata/',
|
|
269 |
'id': 1},
|
|
270 |
{'service-id': 'wcs',
|
|
271 |
'saml-idp-metadata-url': 'https://wcs.dev.publik.love/saml/metadata',
|
|
272 |
'id': 1},
|
|
273 |
]}
|
|
274 |
|
|
275 |
# normal case (stop when configuration on a service success for this tenant)
|
|
276 |
mocked_get.side_effect = [response1]
|
|
277 |
command.configure_service_provider(ENVIRONMENT, tenant)
|
|
278 |
with open(tenant_idp_metadata, 'r') as handler:
|
|
279 |
assert handler.read() == 'my saml idp metadata (1)'
|
|
280 |
|
|
281 |
# no 'idp_url' JSON entry
|
|
282 |
env = {'services': [{'service-id': 'combo', 'id': 1}]}
|
|
283 |
os.remove(tenant_idp_metadata)
|
|
284 |
command.configure_service_provider(env, tenant)
|
|
285 |
with pytest.raises(IOError, match='No such file or directory'):
|
|
286 |
open(tenant_idp_metadata, 'r')
|
|
287 |
|
|
288 |
# idp not available
|
|
289 |
response1.status_code = 500
|
|
290 |
mocked_get.side_effect = [exceptions.RequestException, response1]
|
|
291 |
command.configure_service_provider(ENVIRONMENT, tenant)
|
|
292 |
with pytest.raises(IOError, match='No such file or directory'):
|
|
293 |
open(tenant_idp_metadata, 'r')
|
|
294 |
|
|
295 |
# case when idp is becoming available
|
|
296 |
mocked_get.side_effect = [response1, response2]
|
|
297 |
command.configure_service_provider(ENVIRONMENT, tenant)
|
|
298 |
with open(tenant_idp_metadata, 'r') as handler:
|
|
299 |
assert handler.read() == 'my saml idp metadata (2)'
|
|
300 |
|
|
301 |
|
|
302 |
def test_get_theme(fake_themes):
|
|
303 |
"""return the service's theme"""
|
|
304 |
COMBO = {'service-id': 'combo'}
|
|
305 |
WCS = {'service-id': 'hobo', 'variables': {'theme': 'alfortville'}}
|
|
306 |
HOBO = {'service-id': 'hobo', 'variables': {'theme': 'unknown_theme'}}
|
|
307 |
ENVIRONMENT = {'services': [COMBO, WCS, HOBO], 'variables': {'theme': 'publik'}}
|
|
308 |
command = Command()
|
|
309 |
|
|
310 |
# main case
|
|
311 |
command.me = COMBO
|
|
312 |
assert command.get_theme(ENVIRONMENT)['id'] == 'publik'
|
|
313 |
|
|
314 |
# service having theme overloaded
|
|
315 |
command.me = WCS
|
|
316 |
assert command.get_theme(ENVIRONMENT)['id'] == 'alfortville'
|
|
317 |
|
|
318 |
# theme not specified
|
|
319 |
command.me = COMBO
|
|
320 |
assert command.get_theme({'services': [COMBO, WCS, HOBO]}) is None
|
|
321 |
|
|
322 |
# unknown theme
|
|
323 |
command.me = HOBO
|
|
324 |
assert command.get_theme(ENVIRONMENT) is None
|
|
325 |
|
|
326 |
# can't test last return case as it could never append
|
|
327 |
# if not theme.get('module'): # TODO: dead code to remove
|
|
328 |
|
|
329 |
|
|
330 |
def test_configure_theme(fake_themes, tmpdir):
|
|
331 |
"""make symlink for TENANT/theme
|
|
332 |
and TENANT/static, TENANT/templates on overlay
|
|
333 |
"""
|
|
334 |
COMBO = {'service-id': 'combo'}
|
|
335 |
WCS = {'service-id': 'hobo', 'variables': {'theme': 'alfortville'}} # overlay on fixture
|
|
336 |
HOBO = {'service-id': 'hobo', 'variables': {'theme': 'unknown_theme'}}
|
|
337 |
ENVIRONMENT = {'services': [COMBO, WCS, HOBO], 'variables': {'theme': 'publik'}}
|
|
338 |
command = Command()
|
|
339 |
command.me = COMBO
|
|
340 |
|
|
341 |
tenant = Mock()
|
|
342 |
tenant.get_directory = Mock(return_value=str(tmpdir))
|
|
343 |
theme_path = '%s/theme' % str(tmpdir)
|
|
344 |
static_path = '%s/static' % str(tmpdir)
|
|
345 |
templates_path = '%s/templates' % str(tmpdir)
|
|
346 |
|
|
347 |
# main case: (remove 'static' and/or 'templates' links and empty directories too)
|
|
348 |
os.mkdir(static_path)
|
|
349 |
os.symlink(str(tmpdir), templates_path)
|
|
350 |
command.configure_theme(ENVIRONMENT, tenant)
|
|
351 |
assert os.path.islink(theme_path)
|
|
352 |
assert os.path.exists(static_path) is False
|
|
353 |
assert os.path.exists(templates_path) is False
|
|
354 |
|
|
355 |
# overlay provided: build links to the 'overlay' directory
|
|
356 |
os.symlink(str(tmpdir), static_path)
|
|
357 |
os.mkdir(templates_path)
|
|
358 |
command.me = WCS
|
|
359 |
command.configure_theme(ENVIRONMENT, tenant)
|
|
360 |
assert os.readlink(static_path) == '%s/themes/foobar/static' % str(tmpdir)
|
|
361 |
assert os.readlink(templates_path) == '%s/themes/foobar/templates' % str(tmpdir)
|
|
362 |
|
|
363 |
# retrieve on error (if server hangs during 'atomic_symlink')
|
|
364 |
os.unlink(theme_path)
|
|
365 |
os.symlink(str(tmpdir), theme_path + '.tmp')
|
|
366 |
command.configure_theme(ENVIRONMENT, tenant)
|
|
367 |
assert os.path.islink(theme_path)
|
|
368 |
assert os.path.islink(static_path) # to compare with result we get bellow
|
|
369 |
|
|
370 |
# do not 'overlay' non-empty 'static' and/or 'templates' true directories
|
|
371 |
os.unlink(static_path)
|
|
372 |
os.mkdir(static_path)
|
|
373 |
os.mkdir(os.path.join(static_path, 'some_dir'))
|
|
374 |
command.configure_theme(ENVIRONMENT, tenant)
|
|
375 |
assert os.path.isdir(static_path)
|
|
376 |
|
|
377 |
# no theme provided
|
|
378 |
os.unlink(theme_path)
|
|
379 |
command.me = HOBO
|
|
380 |
command.configure_theme(ENVIRONMENT, tenant)
|
|
381 |
assert os.path.exists(theme_path) is False
|
|
382 |
|
|
383 |
|
|
384 |
@patch('hobo.agent.common.management.commands.hobo_deploy.get_commands')
|
|
385 |
@patch('hobo.agent.common.management.commands.hobo_deploy.call_command')
|
|
386 |
def test_configure_template(mocked_call_command, mocked_get_commands):
|
|
387 |
command = Command()
|
|
388 |
ENVIRONMENT = {'services': [{'service-id': 'combo',
|
|
389 |
'template_name': 'my_template',
|
|
390 |
'this': True}]}
|
|
391 |
|
|
392 |
# import_template.py located into hobo/agent/common: always belongs to command object
|
|
393 |
# TODO: dead condition
|
|
394 |
mocked_get_commands.return_value = ['import_template', '...']
|
|
395 |
|
|
396 |
# main case
|
|
397 |
command.configure_template(ENVIRONMENT, 'unused') # TODO: dead tenant parameter
|
|
398 |
assert mocked_call_command.mock_calls == [call('import_template', 'my_template')]
|
|
399 |
|
|
400 |
# no template_name entry provided
|
|
401 |
mocked_call_command.reset_mock()
|
|
402 |
del ENVIRONMENT['services'][0]['template_name']
|
|
403 |
command.configure_template(ENVIRONMENT, 'unused')
|
|
404 |
assert mocked_call_command.mock_calls == []
|
|
405 |
|
|
406 |
|
|
407 |
def test_combo_get_theme(fake_themes):
|
|
408 |
# IMHO, JSON's 'this' entry can't miss
|
|
409 |
# cf: hobo/agent/common/management/commands/hobo_deploy.py::configure_template
|
|
410 |
# cf: hobo/agent/hobo/management/commands/hobo_deploy.py::deploy_specifics
|
|
411 |
# TODO: dead file (I mean it should be removed)
|
|
412 |
|
|
413 |
COMBO = {'service-id': 'combo', 'this': True}
|
|
414 |
ENVIRONMENT = {'services': [COMBO], 'variables': {'theme': 'publik'}}
|
|
415 |
command = ComboCommand()
|
|
416 |
|
|
417 |
# main case
|
|
418 |
assert command.get_theme(ENVIRONMENT)['id'] == 'publik'
|
|
419 |
|
|
420 |
|
|
421 |
@patch('hobo.agent.common.management.commands.hobo_deploy.Command.deploy_specifics')
|
|
422 |
@patch('hobo.agent.hobo.management.commands.hobo_deploy.tenant_context')
|
|
423 |
def test_hobo_deploy_specifics_alone(mocked_tenant_context, mocked_super, db):
|
|
424 |
"""build database content used later to generate hobo.json.
|
|
425 |
tests using tenants are located into tests_multipublik/test_multipublik.py
|
|
426 |
"""
|
|
427 |
command = HoboCommand()
|
|
428 |
ENVIRONMENT = {'services': [{'service-id': 'hobo',
|
|
429 |
'slug': 'hobo',
|
|
430 |
'title': 'Hobo',
|
|
431 |
'base_url': 'https://hobo.dev.publik.love/',
|
|
432 |
'this': True},
|
|
433 |
{'service-id': 'combo',
|
|
434 |
'slug': 'portal',
|
|
435 |
'title': 'Compte citoyen',
|
|
436 |
'base_url': 'https://combo.dev.publik.love/'},
|
|
437 |
{'service-id': 'wcs',
|
|
438 |
'slug': 'eservices',
|
|
439 |
'title': 'D\u00e9marches',
|
|
440 |
'base_url': 'wcs.dev.publik.love'},
|
|
441 |
{'service-id': 'wrong id',
|
|
442 |
'base_url': 'https://wrong.dev.publik.love/'}]}
|
|
443 |
|
|
444 |
command.deploy_specifics(ENVIRONMENT, 'tenant')
|
|
445 |
|
|
446 |
assert mocked_super.mock_calls == [call(ENVIRONMENT, 'tenant')]
|
|
447 |
assert len(Hobo.objects.all()) == 0
|
|
448 |
assert len(Combo.objects.all()) == 1
|
|
449 |
assert len(Wcs.objects.all()) == 1
|
|
450 |
combo = Combo.objects.all()[0]
|
|
451 |
assert combo.base_url == 'https://combo.dev.publik.love/'
|
|
452 |
assert combo.slug == '_interco_portal'
|
|
453 |
|
|
454 |
# define global variables (twice)
|
|
455 |
ou_label = Variable.objects.get(name='ou-label')
|
|
456 |
ou_slug = Variable.objects.get(name='ou-slug')
|
|
457 |
assert ou_label.value == 'Hobo'
|
|
458 |
assert ou_slug.value == 'hobo'
|
|
459 |
assert ou_label.service_pk is None
|
|
460 |
assert ou_slug.service_pk is None
|
|
461 |
|
|
462 |
|
|
463 |
@patch('hobo.agent.common.management.commands.hobo_deploy.Command.deploy_specifics')
|
|
464 |
@patch('hobo.agent.hobo.management.commands.hobo_deploy.tenant_context')
|
|
465 |
def test_hobo_deploy_specifics_primary(mocked_tenant_context, mocked_super, db):
|
|
466 |
"""first deployement: do nothing for secondary hobo-services
|
|
467 |
same behaviour as previous 'alone' test
|
|
468 |
"""
|
|
469 |
command = HoboCommand()
|
|
470 |
wcs_url = 'https://wcs.dev.publik.love/'
|
|
471 |
ENVIRONMENT = {'services': [{'service-id': 'hobo',
|
|
472 |
'slug': 'hobo',
|
|
473 |
'title': 'Hobo primary',
|
|
474 |
'base_url': 'https://hobo1.dev.publik.love/',
|
|
475 |
'this': True},
|
|
476 |
{'service-id': 'combo',
|
|
477 |
'slug': 'portal',
|
|
478 |
'title': 'Compte citoyen',
|
|
479 |
'base_url': 'https://combo.dev.publik.love/'},
|
|
480 |
{'service-id': 'wcs',
|
|
481 |
'slug': 'eservices',
|
|
482 |
'title': 'skipped as url already in use',
|
|
483 |
'base_url': wcs_url},
|
|
484 |
{'service-id': 'hobo',
|
|
485 |
'slug': 'hobo',
|
|
486 |
'title': 'Hobo secondary',
|
|
487 |
'base_url': 'https://hobo2.dev.publik.love/',
|
|
488 |
'secondary': True}]}
|
|
489 |
|
|
490 |
# make the wcs service already deployed
|
|
491 |
Wcs.objects.get_or_create(base_url=wcs_url, secondary=False)
|
|
492 |
|
|
493 |
command.deploy_specifics(ENVIRONMENT, 'tenant')
|
|
494 |
|
|
495 |
assert mocked_super.mock_calls == [call(ENVIRONMENT, 'tenant')]
|
|
496 |
assert len(Hobo.objects.all()) == 0
|
|
497 |
assert len(Combo.objects.all()) == 1
|
|
498 |
assert len(Wcs.objects.all()) == 1 # the wcs service already set upper
|
|
499 |
combo = Combo.objects.all()[0]
|
|
500 |
assert combo.base_url == 'https://combo.dev.publik.love/'
|
|
501 |
assert combo.slug == '_interco_portal'
|
|
502 |
|
|
503 |
# define global variables
|
|
504 |
ou_label = Variable.objects.get(name='ou-label')
|
|
505 |
ou_slug = Variable.objects.get(name='ou-slug')
|
|
506 |
assert ou_label.value == 'Hobo primary'
|
|
507 |
assert ou_slug.value == 'hobo'
|
|
508 |
assert ou_label.service_pk is None
|
|
509 |
assert ou_slug.service_pk is None
|
|
510 |
|
|
511 |
|
|
512 |
@patch('hobo.agent.common.management.commands.hobo_deploy.Command.deploy_specifics')
|
|
513 |
@patch('hobo.agent.hobo.management.commands.hobo_deploy.tenant_context')
|
|
514 |
def test_hobo_deploy_specifics_secondary(mocked_tenant_context, mocked_super, db):
|
|
515 |
"""next deployements: skip generic tasks and add 'ou' variables
|
|
516 |
"""
|
|
517 |
command = HoboCommand()
|
|
518 |
ENVIRONMENT = {'services': [{'service-id': 'hobo',
|
|
519 |
'slug': 'hobo',
|
|
520 |
'title': 'Hobo primary',
|
|
521 |
'base_url': 'https://hobo1.dev.publik.love/'},
|
|
522 |
{'service-id': 'combo',
|
|
523 |
'slug': 'portal',
|
|
524 |
'title': 'Compte citoyen',
|
|
525 |
'base_url': 'https://combo.dev.publik.love/'},
|
|
526 |
{'service-id': 'hobo',
|
|
527 |
'slug': 'hobo',
|
|
528 |
'title': 'Hobo secondary',
|
|
529 |
'base_url': 'https://hobo2.dev.publik.love/',
|
|
530 |
'secondary': True,
|
|
531 |
'this': True}],
|
|
532 |
'variables': {'ou-label': 'my ou-label',
|
|
533 |
'ou-slug': 'my ou-slug'}}
|
|
534 |
|
|
535 |
# assert primary hobo is wanted
|
|
536 |
command.deploy_specifics(ENVIRONMENT, 'tenant')
|
|
537 |
assert len(Combo.objects.all()) == 0
|
|
538 |
|
|
539 |
# make primary hobo already deployed
|
|
540 |
Hobo.objects.get_or_create(base_url='hobo1.dev.publik.love', secondary=False)
|
|
541 |
command.deploy_specifics(ENVIRONMENT, 'tenant')
|
|
542 |
|
|
543 |
assert mocked_super.mock_calls == []
|
|
544 |
assert len(Hobo.objects.all()) == 1 # primary hobo set upper
|
|
545 |
assert len(Combo.objects.all()) == 1
|
|
546 |
combo = Combo.objects.all()[0]
|
|
547 |
assert combo.base_url == 'https://combo.dev.publik.love/'
|
|
548 |
assert combo.slug == '_my ou-slug_portal'
|
|
549 |
|
|
550 |
# variables are added to the services
|
|
551 |
ou_label = Variable.objects.get(name='ou-label')
|
|
552 |
ou_slug = Variable.objects.get(name='ou-slug')
|
|
553 |
assert ou_label.value == 'my ou-label'
|
|
554 |
assert ou_slug.value == 'my ou-slug'
|
|
555 |
assert ou_label.service_pk == combo.id
|
|
556 |
assert ou_slug.service_pk == combo.id
|
|
557 |
|
|
558 |
|
|
559 |
# Can't write test_authentic2_deploy_specifics as cannot import A2Command here:
|
|
560 |
#from hobo.agent.authentic2.management.commands.hobo_deploy import Command as A2Command
|
|
561 |
# -> tests_authentic/test_hobo_deploy.py
|