Skip to content

Commit 8a54943

Browse files
committed
Add basic success case unit tests of the shared code dealing with peers.
1 parent ba904c2 commit 8a54943

File tree

5 files changed

+199
-24
lines changed

5 files changed

+199
-24
lines changed

tests/support/__init__.py

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import json
3636
import logging
3737
import os
38+
import pickle
3839
import shutil
3940
import stat
4041
import sys
@@ -257,6 +258,23 @@ def temppath(self, relative_path, **kwargs):
257258

258259
# custom assertions available for common use
259260

261+
def assertDirEmpty(self, relative_path):
262+
path_kind = self.assertPathExists(relative_path)
263+
assert path_kind == "dir", "expected a directory but found %s" % (
264+
path_kind, )
265+
absolute_path = os.path.join(TEST_OUTPUT_DIR, relative_path)
266+
entries = os.listdir(absolute_path)
267+
assert not entries, "directory is not empty"
268+
269+
def assertDirNotEmpty(self, relative_path):
270+
path_kind = self.assertPathExists(relative_path)
271+
assert path_kind == "dir", "expected a directory but found %s" % (
272+
path_kind, )
273+
absolute_path = os.path.join(TEST_OUTPUT_DIR, relative_path)
274+
entries = os.listdir(absolute_path)
275+
assert entries, "directory is empty"
276+
return [os.path.join(absolute_path, entry) for entry in entries]
277+
260278
def assertFileContentIdentical(self, file_actual, file_expected):
261279
"""Make sure file_actual and file_expected are identical"""
262280
with io.open(file_actual) as f_actual, io.open(file_expected) as f_expected:
@@ -285,9 +303,11 @@ def assertFileExists(self, relative_path):
285303

286304
def assertPathExists(self, relative_path):
287305
"""Make sure file in relative_path exists"""
288-
assert not os.path.isabs(
289-
relative_path), "expected relative path within output folder"
290-
absolute_path = os.path.join(TEST_OUTPUT_DIR, relative_path)
306+
if os.path.isabs(relative_path):
307+
self.assertPathWithin(relative_path, start=TEST_OUTPUT_DIR)
308+
absolute_path = relative_path
309+
else:
310+
absolute_path = os.path.join(TEST_OUTPUT_DIR, relative_path)
291311
return MigTestCase._absolute_path_kind(absolute_path)
292312

293313
@staticmethod
@@ -368,6 +388,31 @@ def _fixture_copy_as_temp(testcase, fixture_format, fixture_data, fixture_path,
368388
shutil.copyfile(fixture_path, copied_fixture_file)
369389
return copied_fixture_file
370390

391+
@staticmethod
392+
def _provision_test_user(self, distinguished_name):
393+
# ensure a user home directory for our test user
394+
conf_user_home = self.configuration.user_home[:-1]
395+
from mig.shared.base import client_id_dir
396+
test_client_dir_name = client_id_dir(distinguished_name)
397+
test_user_dir = os.path.join(conf_user_home, test_client_dir_name)
398+
399+
# ensure a user db that includes our test user
400+
conf_user_db_home = ensure_dirs_exist(self.configuration.user_db_home)
401+
prepared_fixture = self.prepareFixtureAssert(
402+
'MiG-users.db--example',
403+
fixture_format='pickle',
404+
)
405+
406+
test_db_file = prepared_fixture.copy_as_temp(prefix=conf_user_db_home)
407+
408+
# create the test user home directory
409+
ensure_dirs_exist(test_user_dir)
410+
# create the test user settings directory
411+
user_settings_dir = os.path.join(self.configuration.user_settings, test_client_dir_name)
412+
ensure_dirs_exist(user_settings_dir)
413+
414+
return test_user_dir
415+
371416

372417
def _to_display_path(value):
373418
"""Convert a relative path to one to be shown as part of test output."""
@@ -419,7 +464,7 @@ def fixturefile(relative_path, fixture_format=None):
419464

420465
data = None
421466

422-
if fixture_format == 'binary':
467+
if fixture_format == 'binary' or fixture_format == 'pickle':
423468
with open(tmp_path, 'rb') as binfile:
424469
data = binfile.read()
425470
elif fixture_format == 'json':
@@ -428,6 +473,9 @@ def fixturefile(relative_path, fixture_format=None):
428473
raise AssertionError(
429474
"unsupported fixture format: %s" % (fixture_format,))
430475

476+
if fixture_format == 'pickle':
477+
data = pickle.loads(data)
478+
431479
return data, tmp_path
432480

433481

tests/test_mig_shared_accountreq.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# --- BEGIN_HEADER ---
4+
#
5+
# test_mig_shared_accountreq - unit test of the corresponding mig lib module
6+
# Copyright (C) 2003-2025 The MiG Project by the Science HPC Center at UCPH
7+
#
8+
# This file is part of MiG.
9+
#
10+
# MiG is free software: you can redistribute it and/or modify
11+
# it under the terms of the GNU General Public License as published by
12+
# the Free Software Foundation; either version 2 of the License, or
13+
# (at your option) any later version.
14+
#
15+
# MiG is distributed in the hope that it will be useful,
16+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
# GNU General Public License for more details.
19+
#
20+
# You should have received a copy of the GNU General Public License
21+
# along with this program; if not, write to the Free Software
22+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
23+
# USA.
24+
#
25+
# --- END_HEADER ---
26+
#
27+
28+
"""Unit tests for the migrid module pointed to in the filename"""
29+
30+
import datetime
31+
import os
32+
import pickle
33+
import sys
34+
import unittest
35+
36+
from tests.support import MigTestCase, testmain, fixturefile, ensure_dirs_exist
37+
38+
import mig.shared.accountreq as accountreq
39+
from mig.shared.base import canonical_user, fill_distinguished_name
40+
from mig.shared.defaults import keyword_auto
41+
42+
43+
class MigSharedAccountreq__peers(MigTestCase):
44+
45+
TEST_PEER_DN = '/C=DK/ST=NA/L=NA/O=Test Org/OU=NA/CN=Test User/[email protected]'
46+
TEST_USER_DN = '/C=DK/ST=NA/L=NA/O=Test Org/OU=NA/CN=Test User/[email protected]'
47+
48+
@property
49+
def user_pending_dir(self):
50+
return self.configuration.user_pending
51+
52+
def _load_pickled_peer(self, absolute_path):
53+
self.assertPathWithin(absolute_path, start=self.user_pending_dir)
54+
with open(absolute_path, 'rb') as pickle_file:
55+
value = pickle.load(pickle_file)
56+
57+
def _string_if_bytes(value):
58+
if isinstance(value, bytes):
59+
return str(value, 'utf8')
60+
else:
61+
return value
62+
return {_string_if_bytes(x): _string_if_bytes(y) for x, y in value.items()}
63+
64+
def _peer_dict_from_fixture(self):
65+
fixture_data, fixture_path = fixturefile(
66+
"MiG-users.db--example",
67+
fixture_format="pickle"
68+
)
69+
raw_user = dict(fixture_data[self.TEST_USER_DN])
70+
del raw_user["distinguished_name"]
71+
del raw_user["unique_id"]
72+
del raw_user["password"]
73+
del raw_user["password_hash"]
74+
raw_user["email"] = "[email protected]"
75+
76+
# avoid the need for the 'site_peers_explicit_fields' config option..
77+
raw_user['comment'] = fixture_data[self.TEST_USER_DN]["email"]
78+
79+
user_dict = canonical_user(self.configuration, raw_user, raw_user.keys())
80+
fill_distinguished_name(user_dict)
81+
return user_dict
82+
83+
def _record_peer_acceptance(self, test_client_dir_name, peer_distinguished_name):
84+
test_user_accepted_peers_file = os.path.join(self.configuration.user_settings, test_client_dir_name, "peers")
85+
expire_tomorrow = datetime.date.today() + datetime.timedelta(days=1)
86+
with open(test_user_accepted_peers_file, "wb") as test_user_accepted_peers:
87+
pickle.dump({peer_distinguished_name:{'expire': str(expire_tomorrow) }}, test_user_accepted_peers)
88+
89+
def _settings_dir_for_user(self, distinguished_name):
90+
return os.path.join(self.configuration.user_settings, distinguished_name)
91+
92+
def _provide_configuration(self):
93+
return 'testconfig'
94+
95+
def before_each(self):
96+
ensure_dirs_exist(self.configuration.user_cache)
97+
ensure_dirs_exist(self.configuration.user_pending)
98+
ensure_dirs_exist(self.configuration.user_settings)
99+
ensure_dirs_exist(self.configuration.mrsl_files_dir)
100+
ensure_dirs_exist(self.configuration.resource_pending)
101+
102+
def test_a_new_peer(self):
103+
# precondition
104+
self.assertDirEmpty(self.configuration.user_pending)
105+
request_dict = self._peer_dict_from_fixture()
106+
107+
success, _ = accountreq.save_account_request(self.configuration, request_dict)
108+
109+
# check that we have an output directory now
110+
absolute_files = self.assertDirNotEmpty(self.user_pending_dir)
111+
self.assertEqual(len(absolute_files), 1)
112+
# check the saved peer
113+
peer_user_dict = self._load_pickled_peer(absolute_files[0])
114+
self.assertEqual(peer_user_dict, request_dict)
115+
116+
def test_listing_peers(self):
117+
# precondition
118+
self.assertDirEmpty(self.configuration.user_pending)
119+
request_dict = self._peer_dict_from_fixture()
120+
success, _ = accountreq.save_account_request(self.configuration, request_dict)
121+
122+
success, listing = accountreq.list_account_reqs(self.configuration)
123+
124+
self.assertTrue(success)
125+
self.assertEqual(len(listing), 1)
126+
peer_pickle_file = os.path.join(self.user_pending_dir, listing[0])
127+
peer_pickle = self._load_pickled_peer(peer_pickle_file)
128+
self.assertEqual(peer_pickle['distinguished_name'], self.TEST_PEER_DN)
129+
130+
def test_peer_acceptance(self):
131+
test_client_dir = self._provision_test_user(self, self.TEST_USER_DN)
132+
test_client_dir_name = os.path.basename(test_client_dir)
133+
self._record_peer_acceptance(test_client_dir_name, self.TEST_PEER_DN)
134+
self.assertDirEmpty(self.configuration.user_pending)
135+
request_dict = self._peer_dict_from_fixture()
136+
success, req_path = accountreq.save_account_request(self.configuration, request_dict)
137+
arranged_req_id = os.path.basename(req_path)
138+
139+
success, message = accountreq.accept_account_req(arranged_req_id, self.configuration, keyword_auto)
140+
141+
self.assertTrue(success)
142+
143+
144+
if __name__ == '__main__':
145+
testmain()

tests/test_mig_shared_functionality_cat.py

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -69,25 +69,7 @@ def _provide_configuration(self):
6969
return 'testconfig'
7070

7171
def before_each(self):
72-
# ensure a user home directory for our test user
73-
conf_user_home = self.configuration.user_home[:-1]
74-
test_client_dir = client_id_dir(self.TEST_CLIENT_ID)
75-
test_user_dir = os.path.join(conf_user_home, test_client_dir)
76-
77-
# ensure a user db that includes our test user
78-
79-
conf_user_db_home = ensure_dirs_exist(self.configuration.user_db_home)
80-
temppath(conf_user_db_home, self)
81-
prepared_fixture = self.prepareFixtureAssert(
82-
'MiG-users.db--example',
83-
fixture_format='binary',
84-
)
85-
86-
test_db_file = prepared_fixture.copy_as_temp(prefix=conf_user_db_home)
87-
88-
# create the test user home directory
89-
self.test_user_dir = ensure_dirs_exist(test_user_dir)
90-
temppath(self.test_user_dir, self)
72+
self.test_user_dir = self._provision_test_user(self, self.TEST_CLIENT_ID)
9173
self.test_environ = create_http_environ(self.configuration)
9274

9375
def assertSingleOutputObject(self, output_objects, with_object_type=None):

tests/test_mig_shared_functionality_datatransfer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def before_each(self):
8484
temppath(conf_user_db_home, self)
8585
prepared_fixture = self.prepareFixtureAssert(
8686
"MiG-users.db--example",
87-
fixture_format="binary",
87+
fixture_format="pickle",
8888
)
8989

9090
prepared_fixture.copy_as_temp(prefix=conf_user_db_home)

0 commit comments

Comments
 (0)