Skip to content

Commit ffed064

Browse files
committed
Merge remote-tracking branch 'origin/master' into edge
2 parents a383c17 + 1d37a3e commit ffed064

File tree

2 files changed

+172
-7
lines changed

2 files changed

+172
-7
lines changed

mig/shared/settings.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# --- BEGIN_HEADER ---
55
#
66
# settings - helpers for handling user settings
7-
# Copyright (C) 2003-2021 The MiG Project lead by Brian Vinter
7+
# Copyright (C) 2003-2024 The MiG Project lead by Brian Vinter
88
#
99
# This file is part of MiG.
1010
#
@@ -27,6 +27,7 @@
2727

2828
from __future__ import absolute_import
2929

30+
import copy
3031
import datetime
3132
import os
3233

@@ -62,26 +63,30 @@ def parse_and_save_pickle(source, destination, keywords, client_id,
6263
client_dir = client_id_dir(client_id)
6364
result = parse(source, strip_space, strip_comments)
6465

65-
(status, parsemsg) = check_types(result, keywords, configuration)
66+
# TODO: rename or split up check_types to avoid or clarify side-effects
67+
# NOTE: check_types also fills parsed results into the given keywords dict!
68+
parsed = copy.deepcopy(keywords)
69+
(status, parsemsg) = check_types(result, parsed, configuration)
6670

6771
try:
6872
os.remove(source)
6973
except Exception as err:
7074
msg = 'Exception removing temporary file %s, %s'\
7175
% (source, err)
7276

73-
# should we exit because of this? o.reply_and_exit(o.ERROR)
74-
7577
if not status:
7678
msg = 'Parse failed (typecheck) %s' % parsemsg
7779
return (False, msg)
7880

7981
new_dict = {}
8082

81-
# move parseresult to a dictionary
83+
# copy parsed result and required default values to a new flat dictionary
8284

83-
for (key, value_dict) in keywords.iteritems():
84-
new_dict[key] = value_dict['Value']
85+
for key in keywords:
86+
if keywords[key].get('Required', True):
87+
new_dict[key] = parsed[key]['Value']
88+
elif parsed[key]['Value'] != keywords[key]['Value']:
89+
new_dict[key] = parsed[key]['Value']
8590
# apply any overrides
8691
for key in overrides:
8792
new_dict[key] = overrides[key]

tests/test_mig_shared_settings.py

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# --- BEGIN_HEADER ---
4+
#
5+
# test_mig_shared_settings - unit test of the corresponding mig shared module
6+
# Copyright (C) 2003-2024 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 os
31+
import sys
32+
33+
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__))))
34+
35+
from tests.support import TEST_OUTPUT_DIR, MigTestCase, FakeConfiguration, \
36+
cleanpath, testmain
37+
from mig.shared.settings import load_settings, update_settings, \
38+
parse_and_save_settings
39+
40+
DUMMY_USER = "dummy-user"
41+
DUMMY_SETTINGS_DIR = 'dummy_user_settings'
42+
DUMMY_SETTINGS_PATH = os.path.join(TEST_OUTPUT_DIR, DUMMY_SETTINGS_DIR)
43+
DUMMY_SYSTEM_FILES_DIR = 'dummy_system_files'
44+
DUMMY_SYSTEM_FILES_PATH = os.path.join(TEST_OUTPUT_DIR, DUMMY_SYSTEM_FILES_DIR)
45+
DUMMY_TMP_DIR = 'dummy_tmp'
46+
DUMMY_TMP_FILE = 'settings.mRSL'
47+
DUMMY_TMP_PATH = os.path.join(TEST_OUTPUT_DIR, DUMMY_TMP_DIR)
48+
DUMMY_MRSL_PATH = os.path.join(DUMMY_TMP_PATH, DUMMY_TMP_FILE)
49+
50+
DUMMY_USER_INTERFACE = ['V3', 'V42']
51+
DUMMY_DEFAULT_UI = 'V42'
52+
DUMMY_INIT_MRSL = """
53+
::EMAIL::
54+
john@doe.org
55+
56+
::SITE_USER_MENU::
57+
sharelinks
58+
people
59+
peers
60+
"""
61+
DUMMY_UPDATE_MRSL = """
62+
::EMAIL::
63+
jane@doe.org
64+
65+
::SITE_USER_MENU::
66+
people
67+
"""
68+
DUMMY_CONF = FakeConfiguration(user_settings=DUMMY_SETTINGS_PATH,
69+
mig_system_files=DUMMY_SYSTEM_FILES_PATH,
70+
user_interface=DUMMY_USER_INTERFACE,
71+
new_user_default_ui=DUMMY_DEFAULT_UI)
72+
73+
74+
class MigSharedSettings(MigTestCase):
75+
"""Wrap unit tests for the corresponding module"""
76+
77+
def test_settings_save_load(self):
78+
os.makedirs(os.path.join(DUMMY_SETTINGS_PATH, DUMMY_USER))
79+
cleanpath(DUMMY_SETTINGS_DIR, self)
80+
os.makedirs(os.path.join(DUMMY_SYSTEM_FILES_PATH, DUMMY_USER))
81+
cleanpath(DUMMY_SYSTEM_FILES_DIR, self)
82+
os.makedirs(os.path.join(DUMMY_TMP_PATH))
83+
cleanpath(DUMMY_TMP_DIR, self)
84+
85+
with open(DUMMY_MRSL_PATH, 'w') as mrsl_fd:
86+
mrsl_fd.write(DUMMY_INIT_MRSL)
87+
save_status, save_msg = parse_and_save_settings(
88+
DUMMY_MRSL_PATH, DUMMY_USER, DUMMY_CONF)
89+
self.assertTrue(save_status)
90+
self.assertFalse(save_msg)
91+
92+
saved_path = os.path.join(DUMMY_SETTINGS_PATH, DUMMY_USER, 'settings')
93+
self.assertTrue(os.path.exists(saved_path))
94+
95+
settings = load_settings(DUMMY_USER, DUMMY_CONF)
96+
# NOTE: updated should be a non-empty dict at this point
97+
self.assertTrue(isinstance(settings, dict))
98+
self.assertEqual(settings['EMAIL'], ['john@doe.org'])
99+
self.assertEqual(settings['SITE_USER_MENU'],
100+
['sharelinks', 'people', 'peers'])
101+
# NOTE: we no longer auto save default values for optional vars
102+
for key in settings.keys():
103+
self.assertTrue(key in ['EMAIL', 'SITE_USER_MENU'])
104+
# Any saved USER_INTERFACE value must match configured default if set
105+
self.assertEqual(settings.get('USER_INTERFACE', DUMMY_DEFAULT_UI),
106+
DUMMY_DEFAULT_UI)
107+
108+
def test_settings_replace(self):
109+
os.makedirs(os.path.join(DUMMY_SETTINGS_PATH, DUMMY_USER))
110+
cleanpath(DUMMY_SETTINGS_DIR, self)
111+
os.makedirs(os.path.join(DUMMY_SYSTEM_FILES_PATH, DUMMY_USER))
112+
cleanpath(DUMMY_SYSTEM_FILES_DIR, self)
113+
os.makedirs(os.path.join(DUMMY_TMP_PATH))
114+
cleanpath(DUMMY_TMP_DIR, self)
115+
116+
with open(DUMMY_MRSL_PATH, 'w') as mrsl_fd:
117+
mrsl_fd.write(DUMMY_INIT_MRSL)
118+
save_status, save_msg = parse_and_save_settings(
119+
DUMMY_MRSL_PATH, DUMMY_USER, DUMMY_CONF)
120+
self.assertTrue(save_status)
121+
self.assertFalse(save_msg)
122+
123+
with open(DUMMY_MRSL_PATH, 'w') as mrsl_fd:
124+
mrsl_fd.write(DUMMY_UPDATE_MRSL)
125+
save_status, save_msg = parse_and_save_settings(
126+
DUMMY_MRSL_PATH, DUMMY_USER, DUMMY_CONF)
127+
self.assertTrue(save_status)
128+
self.assertFalse(save_msg)
129+
130+
updated = load_settings(DUMMY_USER, DUMMY_CONF)
131+
# NOTE: updated should be a non-empty dict at this point
132+
self.assertTrue(isinstance(updated, dict))
133+
self.assertEqual(updated['EMAIL'], ['jane@doe.org'])
134+
self.assertEqual(updated['SITE_USER_MENU'], ['people'])
135+
136+
def test_update_settings(self):
137+
os.makedirs(os.path.join(DUMMY_SETTINGS_PATH, DUMMY_USER))
138+
cleanpath(DUMMY_SETTINGS_DIR, self)
139+
os.makedirs(os.path.join(DUMMY_SYSTEM_FILES_PATH, DUMMY_USER))
140+
cleanpath(DUMMY_SYSTEM_FILES_DIR, self)
141+
os.makedirs(os.path.join(DUMMY_TMP_PATH))
142+
cleanpath(DUMMY_TMP_DIR, self)
143+
144+
with open(DUMMY_MRSL_PATH, 'w') as mrsl_fd:
145+
mrsl_fd.write(DUMMY_INIT_MRSL)
146+
save_status, save_msg = parse_and_save_settings(
147+
DUMMY_MRSL_PATH, DUMMY_USER, DUMMY_CONF)
148+
self.assertTrue(save_status)
149+
self.assertFalse(save_msg)
150+
151+
changes = {'EMAIL': ['john@doe.org', 'jane@doe.org']}
152+
defaults = {}
153+
updated = update_settings(DUMMY_USER, DUMMY_CONF, changes, defaults)
154+
# NOTE: updated should be a non-empty dict at this point
155+
self.assertTrue(isinstance(updated, dict))
156+
self.assertEqual(updated['EMAIL'], ['john@doe.org', 'jane@doe.org'])
157+
158+
159+
if __name__ == '__main__':
160+
testmain()

0 commit comments

Comments
 (0)