Skip to content

Commit cfb7d17

Browse files
committed
Implement a test covering operation of the cat funcitonality file.
Make use of the seam that exists by virtue of the functionality files return output objects which are intrepreted by a wrapper to unit test the behaviour of cat. Specifically, we can arrange for a suitable environment plus arguments and then check the right output_objects are created. Allow doing this by exposing a variant of the cat main method which returns them rather than invoking the outer wrapper. Name this _main and call it from the original main. Note that this change is in effect a blueprint that can be used when adding coverage for other functionaity files.
1 parent 9df3ca8 commit cfb7d17

File tree

5 files changed

+295
-6
lines changed

5 files changed

+295
-6
lines changed

mig/shared/accountstate.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
from __future__ import print_function
3333
from __future__ import absolute_import
34+
from past.builtins import basestring
3435

3536
import os
3637
import time

mig/shared/functionality/cat.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ def main(client_id, user_arguments_dict, environ=None):
6161

6262
(configuration, logger, output_objects, op_name) = \
6363
initialize_main_variables(client_id)
64+
65+
return _main(configuration, logger, op_name=op_name, output_objects=output_objects, client_id=client_id, user_arguments_dict=user_arguments_dict)
66+
67+
def _main(configuration, logger, op_name='', output_objects=[], client_id=None, user_arguments_dict=None, environ=None):
68+
if logger is None:
69+
logger = configuration.logger
70+
6471
client_dir = client_id_dir(client_id)
6572
defaults = signature()[1]
6673
status = returnvalues.OK
@@ -71,6 +78,7 @@ def main(client_id, user_arguments_dict, environ=None):
7178
client_id,
7279
configuration,
7380
allow_rejects=False,
81+
environ=environ,
7482
# NOTE: path can use wildcards, dst cannot
7583
typecheck_overrides={'path': valid_path_pattern},
7684
)
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
(dp0
2+
V/C=DK/ST=NA/L=NA/O=Test Org/OU=NA/CN=b'Test User'/emailAddress=dummy-user
3+
p1
4+
(dp2
5+
Vfull_name
6+
p3
7+
Vb'Test User'
8+
p4
9+
sVorganization
10+
p5
11+
VTest Org
12+
p6
13+
sVstate
14+
p7
15+
VNA
16+
p8
17+
sVcountry
18+
p9
19+
VDK
20+
p10
21+
sVemail
22+
p11
23+
Vdummy-user
24+
p12
25+
sVcomment
26+
p13
27+
VThis is the create comment
28+
p14
29+
sVpassword
30+
p15
31+
V
32+
p16
33+
sVpassword_hash
34+
p17
35+
VPBKDF2$sha256$10000$b't0JM/JjkQ347th0Q'$b'QupJt53hA5KhESEeqDhTQTCPOrCBvZ6H'
36+
p18
37+
sVdistinguished_name
38+
p19
39+
V/C=DK/ST=NA/L=NA/O=Test Org/OU=NA/CN=b'Test User'/emailAddress=dummy-user
40+
p20
41+
sVlocality
42+
p21
43+
g16
44+
sVorganizational_unit
45+
p22
46+
g16
47+
sVexpire
48+
p23
49+
I1757925298
50+
sVcreated
51+
p24
52+
F1726233828.2676349
53+
sVunique_id
54+
p25
55+
VktyCKIRg9HvsVzXMQ22EaKS67t9atchv9JKTiJqrtBiGN3qksKrbTTYIH8mitY2K
56+
p26
57+
sVopenid_names
58+
p27
59+
(lp28
60+
sVold_password_hash
61+
p29
62+
VPBKDF2$sha256$10000$b'GL7Qq92iLe/hZXBo'$b'ZwB/5IZqgU7onP+ZqZk9zcHVZOx7jmWz'
63+
p30
64+
sVrenewed
65+
p31
66+
F1726389298.7801197
67+
ssV/C=DK/ST=NA/L=NA/O=Test Org/OU=NA/CN=Test User/emailAddress=dummy-user
68+
p32
69+
(dp33
70+
Vfull_name
71+
p34
72+
VTest User
73+
p35
74+
sVorganization
75+
p36
76+
VTest Org
77+
p37
78+
sVstate
79+
p38
80+
VNA
81+
p39
82+
sVcountry
83+
p40
84+
VDK
85+
p41
86+
sVemail
87+
p42
88+
Vdummy-user
89+
p43
90+
sVcomment
91+
p44
92+
VThis is the create comment
93+
p45
94+
sVpassword
95+
p46
96+
g16
97+
sVpassword_hash
98+
p47
99+
VPBKDF2$sha256$10000$b'kZ8WgLNH+wg3X11d'$b't1d08MV4g215WYW7S7EbkjHqDF+MCjMa'
100+
p48
101+
sVdistinguished_name
102+
p49
103+
V/C=DK/ST=NA/L=NA/O=Test Org/OU=NA/CN=Test User/emailAddress=dummy-user
104+
p50
105+
sVlocality
106+
p51
107+
g16
108+
sVorganizational_unit
109+
p52
110+
g16
111+
sVexpire
112+
p53
113+
I1759243332
114+
sVcreated
115+
p54
116+
F1726602273.7987707
117+
sVunique_id
118+
p55
119+
VKdYHJ21t37jAoHUmBq6t8Xnsnih6JWR5i0QepHoVXfDpQxz9fQGnEmegoDNrPzbe
120+
p56
121+
sVopenid_names
122+
p57
123+
(lp58
124+
sVold_password_hash
125+
p59
126+
VPBKDF2$sha256$10000$b'yObizsUepZvvJ0/r'$b'uKIt7n6Lf/7WXD6pKDGyvT30L2uowBnV'
127+
p60
128+
sVrenewed
129+
p61
130+
F1727707333.0969944
131+
ssV/C=DK/ST=NA/L=NA/O=Test Org/OU=NA/CN=Test User/emailAddress=test@example.com
132+
p62
133+
(dp63
134+
Vfull_name
135+
p64
136+
VTest User
137+
p65
138+
sVorganization
139+
p66
140+
VTest Org
141+
p67
142+
sVstate
143+
p68
144+
VNA
145+
p69
146+
sVcountry
147+
p70
148+
VDK
149+
p71
150+
sVemail
151+
p72
152+
Vtest@example.com
153+
p73
154+
sVcomment
155+
p74
156+
VThis is the create comment
157+
p75
158+
sVpassword
159+
p76
160+
g16
161+
sVpassword_hash
162+
p77
163+
VPBKDF2$sha256$10000$b'/TkhLk4yMGf6XhaY'$b'7HUeQ9iwCkE4YMQAaCd+ZdrN+y8EzkJH'
164+
p78
165+
sVdistinguished_name
166+
p79
167+
g62
168+
sVlocality
169+
p80
170+
g16
171+
sVorganizational_unit
172+
p81
173+
g16
174+
sVexpire
175+
p82
176+
I1758970812
177+
sVcreated
178+
p83
179+
F1727434813.0792377
180+
sVunique_id
181+
p84
182+
VaTza92klrnN2wfylm6HnphCy9C3PReGpQ6jklJ7zF3xjeaUDw36tW95Avx43vtba
183+
p85
184+
sVopenid_names
185+
p86
186+
(lp87
187+
ss.

tests/support/__init__.py

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,17 @@ def is_path_within(path, start=None, _msg=None):
276276
return not relative.startswith('..')
277277

278278

279-
def fixturefile(relative_path, fixture_format=None):
279+
def _ensuredirs(absolute_dir):
280+
try:
281+
os.makedirs(absolute_dir)
282+
except OSError as oserr:
283+
if oserr.errno != errno.EEXIST:
284+
raise
285+
286+
return absolute_dir
287+
288+
289+
def fixturefile(relative_path, fixture_format=None, include_path=False):
280290
"""Support function for loading fixtures from their serialised format.
281291
282292
Doing so is a little more involved than it may seem because serialisation
@@ -296,12 +306,24 @@ def fixturefile(relative_path, fixture_format=None):
296306
#_, extension = os.path.splitext(os.path.basename(tmp_path))
297307
#assert fixture_format == extension, "fixture file does not match format"
298308

299-
if fixture_format == 'json':
300-
return _fixturefile_json(tmp_path)
309+
data = None
310+
311+
if fixture_format == 'binary':
312+
with open(tmp_path, 'rb') as binfile:
313+
data = binfile.read()
314+
elif fixture_format == 'json':
315+
data = _fixturefile_json(tmp_path)
301316
else:
302317
raise AssertionError(
303318
"unsupported fixture format: %s" % (fixture_format,))
304319

320+
return (data, tmp_path) if include_path else data
321+
322+
323+
def fixturefile_normname(relative_path, prefix=None):
324+
normname, _ = relative_path.split('--')
325+
return os.path.join(prefix, normname) if prefix else normname
326+
305327

306328
_FIXTUREFILE_HINTAPPLIERS = {
307329
'array_of_tuples': lambda value: [tuple(x) for x in value]
@@ -340,12 +362,17 @@ def temppath(relative_path, test_case, ensure_dir=False, skip_clean=False):
340362
"""Get absolute temp path for relative_path"""
341363
assert isinstance(test_case, MigTestCase)
342364
tmp_path = os.path.join(TEST_OUTPUT_DIR, relative_path)
365+
return _temppath(tmp_path, test_case, ensure_dir=ensure_dir, skip_clean=skip_clean)
366+
367+
368+
def _temppath(tmp_path, test_case, ensure_dir=False, skip_clean=False):
343369
if ensure_dir:
344370
try:
345371
os.mkdir(tmp_path)
346-
except FileExistsError:
347-
raise AssertionError(
348-
"ABORT: use of unclean output path: %s" % relative_path)
372+
except OSError as oserr:
373+
if oserr.errno == errno.EEXIST:
374+
raise AssertionError(
375+
"ABORT: use of unclean output path: %s" % tmp_path)
349376
if not skip_clean:
350377
test_case._cleanup_paths.add(tmp_path)
351378
return tmp_path

tests/test_mig_cgibin_cat.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from __future__ import print_function
2+
import importlib
3+
import os
4+
import shutil
5+
import sys
6+
7+
from tests.support import MIG_BASE, MigTestCase, testmain, \
8+
fixturefile, fixturefile_normname, \
9+
_ensuredirs, _temppath
10+
11+
from mig.shared.base import client_id_dir
12+
from mig.shared.functionality.cat import _main as main
13+
14+
15+
def create_http_environ(configuration, wsgi_variables={}):
16+
"""Small helper that can create a minimum viable environ dict suitable
17+
for passing to http-facing code for the supplied configuration."""
18+
19+
environ = {}
20+
environ['MIG_CONF'] = configuration.config_file
21+
environ['HTTP_HOST'] = wsgi_variables.get('http_host', 'localhost')
22+
environ['PATH_INFO'] = wsgi_variables.get('path_info', '/')
23+
environ['REMOTE_ADDR'] = wsgi_variables.get('remote_addr', '127.0.0.1')
24+
environ['SCRIPT_URI'] = ''.join(('http://', environ['HTTP_HOST'], environ['PATH_INFO']))
25+
return environ
26+
27+
28+
class MigCgibinCat(MigTestCase):
29+
TEST_CLIENT_ID = '/C=DK/ST=NA/L=NA/O=Test Org/OU=NA/CN=Test User/emailAddress=test@example.com'
30+
31+
def _provide_configuration(self):
32+
return 'testconfig'
33+
34+
def before_each(self):
35+
# ensure a user home directory for our test user
36+
conf_user_home = self.configuration.user_home[:-1]
37+
test_client_dir = client_id_dir(self.TEST_CLIENT_ID)
38+
test_user_dir = os.path.join(conf_user_home, test_client_dir)
39+
40+
# ensure a user db that includes our test user
41+
conf_user_db_home = _ensuredirs(self.configuration.user_db_home)
42+
_temppath(conf_user_db_home, self)
43+
db_fixture, db_fixture_file = fixturefile('MiG-users.db--example', fixture_format='binary', include_path=True)
44+
test_db_file = _temppath(fixturefile_normname('MiG-users.db--example', prefix=conf_user_db_home), self)
45+
shutil.copyfile(db_fixture_file, test_db_file)
46+
47+
# create the test user home directory
48+
self.test_user_dir = _ensuredirs(test_user_dir)
49+
_temppath(self.test_user_dir, self)
50+
self.test_environ = create_http_environ(self.configuration)
51+
52+
def test_returns_file_output_with_single_file_match(self):
53+
with open(os.path.join(self.test_user_dir, 'foobar.txt'), 'w'):
54+
pass
55+
payload = {
56+
'path': ['foobar.txt'],
57+
}
58+
59+
(output_objects, status) = main(self.configuration, self.logger, client_id=self.TEST_CLIENT_ID, user_arguments_dict=payload, environ=self.test_environ)
60+
self.assertEqual(len(output_objects), 1)
61+
output_obj = output_objects[0]
62+
self.assertEqual(output_obj['object_type'], 'file_output')
63+
64+
65+
if __name__ == '__main__':
66+
testmain()

0 commit comments

Comments
 (0)