Merge branch 'cnfline-templates' into cnfvar-deprecations
[pyi2ncommon] / test / test_simple_cnf.py
CommitLineData
f49f6323
PD
1#!/usr/bin/env python
2# This Python file uses the following encoding: utf-8
3
11cbb815
PD
4# The software in this package is distributed under the GNU General
5# Public License version 2 (with a special exception described below).
6#
7# A copy of GNU General Public License (GPL) is included in this distribution,
8# in the file COPYING.GPL.
9#
10# As a special exception, if other files instantiate templates or use macros
11# or inline functions from this file, or you compile this file and link it
12# with other works to produce a work based on this file, this file
13# does not by itself cause the resulting work to be covered
14# by the GNU General Public License.
15#
16# However the source code for this file must still be made available
17# in accordance with section (3) of the GNU General Public License.
18#
19# This exception does not invalidate any other reasons why a work based
20# on this file might be covered by the GNU General Public License.
21#
22# Copyright (c) 2016-2018 Intra2net AG <info@intra2net.com>
23
f49f6323
PD
24import unittest
25from traceback import print_exc
26from tempfile import mkstemp
27import os
0ba9936c 28import sys
f49f6323
PD
29
30from src.simple_cnf import SimpleCnf
ce20f5b6 31from src.simple_cnf import InvalidCnf
f49f6323
PD
32
33TEST_SET = """
341 USER,1: "admin"
352 (1) USER_DISABLED,0: "0"
363 (1) USER_FULLNAME,0: "Administrator"
374 (1) USER_GROUPWARE_FOLDER_CALENDAR,0: "INBOX/Kalender"
385 (1) USER_GROUPWARE_FOLDER_CONTACTS,0: "INBOX/Kontakte"
396 (1) USER_GROUPWARE_FOLDER_DRAFTS,0: "INBOX/Entwürfe"
407 (1) USER_GROUPWARE_FOLDER_NOTES,0: "INBOX/Notizen"
418 (1) USER_GROUPWARE_FOLDER_OUTBOX,0: "INBOX/Gesendete Elemente"
429 (1) USER_GROUPWARE_FOLDER_TASKS,0: "INBOX/Aufgaben"
4310 (1) USER_GROUPWARE_FOLDER_TRASH,0: "INBOX/Gelöschte Elemente"
4411 (1) USER_GROUP_MEMBER_REF,0: "1"
4512 (1) USER_GROUP_MEMBER_REF,1: "2"
4613 (1) USER_LOCALE,0: ""
4714 (1) USER_PASSWORD,0: "test1234"
4815 (1) USER_TRASH_DELETEDAYS,0: "30"
4916 USER,2: "test"
5017 (16) USER_DISABLED,0: "0"
5118 (16) USER_EMAIL_VACATION,0: "ON"
5219 (16) USER_EMAIL_VACATION_AUTOMATIC_END,0: ""
5320 (16) USER_EMAIL_VACATION_AUTOMATIC_START,0: ""
5421 (16) USER_EMAIL_VACATION_AUTOMATIC_STATE,0: "UNKNOWN"
5522 (16) USER_EMAIL_VACATION_REPLYDAYS,0: "1"
5623 (16) USER_EMAIL_VACATION_TEXT,0: "Bin im Urlaub"
5724 (16) USER_FULLNAME,0: "testnutzer"
5825 (16) USER_GROUPWARE_FOLDER_CALENDAR,0: "INBOX/Kalender"
5926 (16) USER_GROUPWARE_FOLDER_CONTACTS,0: "INBOX/Kontakte"
6027 (16) USER_GROUPWARE_FOLDER_DRAFTS,0: "INBOX/Entwürfe"
6128 (16) USER_GROUPWARE_FOLDER_NOTES,0: "INBOX/Notizen"
6229 (16) USER_GROUPWARE_FOLDER_OUTBOX,0: "INBOX/Gesendete Elemente"
6330 (16) USER_GROUPWARE_FOLDER_TASKS,0: "INBOX/Aufgaben"
6431 (16) USER_GROUPWARE_FOLDER_TRASH,0: "INBOX/Gelöschte Elemente"
6532 (16) USER_GROUP_MEMBER_REF,0: "2"
6633 (16) USER_GROUP_MEMBER_REF,1: "3"
6734 (16) USER_LOCALE,0: ""
6835 (16) USER_PASSWORD,0: "test1234"
6936 (16) USER_TRASH_DELETEDAYS,0: "30"
7037 (16) USER_WEBMAIL_MESSAGES_PER_PAGE,0: "25"
7138 (16) USER_WEBMAIL_SIGNATURE,0: ""
7239 USER,3: "mueller"
7340 (39) USER_DISABLED,0: "0"
7441 (39) USER_FULLNAME,0: "Kärößü"
7542 (39) USER_GROUPWARE_FOLDER_CALENDAR,0: "INBOX/Kalender"
7643 (39) USER_GROUPWARE_FOLDER_CONTACTS,0: "INBOX/Kontakte"
7744 (39) USER_GROUPWARE_FOLDER_DRAFTS,0: "INBOX/Entwürfe"
7845 (39) USER_GROUPWARE_FOLDER_NOTES,0: "INBOX/Notizen"
7946 (39) USER_GROUPWARE_FOLDER_OUTBOX,0: "INBOX/Gesendete Elemente"
8047 (39) USER_GROUPWARE_FOLDER_TASKS,0: "INBOX/Aufgaben"
8148 (39) USER_GROUPWARE_FOLDER_TRASH,0: "INBOX/Gelöschte Elemente"
8249 (39) USER_GROUP_MEMBER_REF,0: "2"
8350 (39) USER_GROUP_MEMBER_REF,1: "3"
8451 (39) USER_LOCALE,0: ""
8552 (39) USER_PASSWORD,0: "grmpfl"
8653 (39) USER_TRASH_DELETEDAYS,0: "30"
8754 (39) USER_WEBMAIL_MESSAGES_PER_PAGE,0: "25"
8855 (39) USER_WEBMAIL_SIGNATURE,0: ""
8956 BACKUP_COMPRESS_ENABLE,0: "1"
9057 BACKUP_CRON,0: "0123456"
9158 (57) BACKUP_CRON_BEGIN,0: "7200"
9259 BACKUP_ENCRYPT_ENABLE,0: "0"
9360 BACKUP_ENCRYPT_PASSWORD,0: ""
9461 TESTVAR,0: "test"
95"""
96
0ba9936c
CH
97#: encoding for text files, set in :py:func:`setUpModule`
98ENCODING = None
99
100
101def setUpModule():
102 """Called once before all tests; determines encoding
103
104 This test might run in very limited build environments without locale, so
105 auto-selection of temp-file text encoding may return 'ASCII'.
106 Therefore, do the encoding "manually".
107 """
108 global ENCODING
109 ENCODING = sys.getfilesystemencoding()
110 if ENCODING.lower() in ('ascii', 'ansi_x3.4-1968'):
111 ENCODING = 'utf8'
8468f520 112 print('\nWARNING: Using fallback encoding {} for temp file creation'
0ba9936c
CH
113 .format(ENCODING))
114
f49f6323
PD
115
116class SimpleCnfTest(unittest.TestCase):
117 """ The one and only test case in this module `-->` see module doc """
118
119 # setup and cleanup
120
121 import_file = None
122 cnf = None
123
124 @classmethod
125 def _import_cnf(cls):
126 """ import conf var data from temp file """
127 cls.cnf = SimpleCnf()
128 cls.cnf.append_file(cls.import_file)
129
130 @classmethod
131 def setUpClass(cls):
132 """ before running tests: write conf var string to temp file """
133 try:
0ba9936c 134 sys_file_descriptor, cls.import_file = mkstemp()
f49f6323 135 os.close(sys_file_descriptor)
0ba9936c
CH
136 with open(cls.import_file, 'wb') as file_handle:
137 file_handle.write(TEST_SET.encode(ENCODING))
f49f6323 138 except Exception:
8468f520 139 print('\nWARNING: exception creating temp file:')
f49f6323
PD
140 print_exc()
141
142 # clean up
143 cls.tearDownClass()
144
145 # re-raise
146 raise
147
148 cls._import_cnf()
149
150 @classmethod
151 def tearDownClass(cls):
152 """ after all tests have run, delete temp file """
153 if cls.import_file is not None:
154 try:
155 os.unlink(cls.import_file)
f49f6323 156 except Exception:
8468f520 157 print('\nWARNING: exception deleting temp file:')
f49f6323
PD
158 print_exc()
159
160 # tests
161
ce20f5b6
PG
162 def test_ctor_ok (self):
163 """
164 Test initializer :py:meth:`SimpleCnf.__init__` must succeed on sane
165 inputs.
166 """
167 self.assertNotEqual (SimpleCnf ({"cnf": []}), None)
168 self.assertNotEqual (SimpleCnf ([]), None)
169 self.assertNotEqual (SimpleCnf (), None)
170
171 def test_ctor_fail (self):
172 """
173 Test initializer :py:meth:`SimpleCnf.__init__` must reject inputs that
174 ``cnfvar.py`` does not handle.
175 """
176 with self.assertRaises (InvalidCnf):
177 _void = SimpleCnf (b"junk")
178 with self.assertRaises (InvalidCnf):
179 _void = SimpleCnf (42)
180 with self.assertRaises (InvalidCnf):
181 _void = SimpleCnf (tuple ([1701, 1337]))
182 with self.assertRaises (InvalidCnf):
183 _void = SimpleCnf (set (["one", "two"]))
184
f49f6323
PD
185 def test_eq(self):
186 """ test method :py:meth:`SimpleCnf.__eq__` """
187 self.assertEqual(self.cnf[61], self.cnf[61])
188 self.assertEqual(self.cnf['testvar'], self.cnf[61])
189 self.assertEqual(self.cnf, self.cnf)
190 self.assertNotEqual(self.cnf[56], self.cnf[57])
ee39385c
PG
191 self.assertNotEqual(SimpleCnf ({"cnf": []}), None)
192 self.assertNotEqual(SimpleCnf ({"cnf": []}), 42)
193 self.assertNotEqual(SimpleCnf ({"cnf": []}), "got wood?")
194 self.assertEqual(SimpleCnf (), SimpleCnf ({"cnf": []}))
f49f6323
PD
195
196 def test_len(self):
197 """ test method :py:meth:`SimpleCnf.__len__` """
198 self.assertEqual(len(self.cnf), 8)
199
200 def test_getitem(self):
201 """ test method :py:meth:`SimpleCnf.__item__` """
202 self.assertEqual(len(self.cnf['user']), 3)
203 self.assertEqual(self.cnf['USER'], self.cnf['user'])
204 self.assertEqual(len(self.cnf['backup_encrypt_password']), 1)
205 self.assertEqual(len(self.cnf[12232]), 0)
206 self.assertEqual(len(self.cnf[55]), 0)
207 self.assertEqual(len(self.cnf[61]), 1)
208 self.assertEqual(len(self.cnf['user_webmail_signature']), 0)
209
210 def test_get(self):
211 """ test method :py:meth:`SimpleCnf.get` """
212 self.assertEqual(len(self.cnf.get()), 8)
213 self.assertEqual(len(self.cnf.get(name='user')), 3)
214
215 def test_get_value(self):
216 """ test method :py:meth:`SimpleCnf.get_value` """
217
218 with self.assertRaises(ValueError):
219 self.cnf.get_value()
220
221 self.assertEqual(self.cnf[56].get_value(), '1')
222 self.assertEqual(self.cnf[61].get_value(), 'test')
223
224 def test_get_children(self):
225 """ test method :py:meth:`SimpleCnf.get_children` """
226 with self.assertRaises(ValueError):
227 self.cnf.get_children()
f49f6323
PD
228 self.assertEqual(len(self.cnf.get(name='user', value='mueller')
229 .get_children()), 16)
cfcef185
PG
230 self.assertEqual(self.cnf.get(name='user'),
231 self.cnf.get(name='USER'))
232 self.assertEqual(self.cnf.get(name='user', value='mueller'),
233 self.cnf.get(name='USER', value='mueller'))
f49f6323
PD
234 self.assertEqual(len(self.cnf[57].get_children()), 1)
235 self.assertEqual(self.cnf[57].get_children().get_value(), '7200')
236
237 def test_add_alone(self):
238 """ test method :py:meth:`SimpleCnf.add` on empty conf """
239 # do not use self.cnf since that would void other test methods
240 cnf = SimpleCnf()
241 self.assertEqual(len(cnf), 0)
242 cnf.add('new_var', 'new_value')
243 self.assertEqual(len(cnf), 1)
244 cnf_var = cnf.get(name='new_var').get_single_dict()
245 self.assertEqual(cnf_var['data'], 'new_value')
246 self.assertIsInstance(cnf_var['data'], str)
247 self.assertEqual(cnf_var['number'], 1)
248
249 def test_add_on_top(self):
250 """ test method :py:meth:`SimpleCnf.add` on regular conf """
251 cnf = SimpleCnf()
252 self.assertEqual(len(cnf), 0)
253 cnf.append_file(self.import_file)
254 self.assertEqual(len(cnf), 8)
255
256 cnf.add('new_var', 'new_value')
257 self.assertEqual(len(cnf), 9)
258 cnf_var = cnf.get(name='new_var').get_single_dict()
259 self.assertEqual(cnf_var['data'], 'new_value')
260 self.assertIsInstance(cnf_var['data'], str)
261 self.assertEqual(cnf_var['number'], 62)
262
263 def test_add_with_children(self):
264 """ test method :py:meth:`SimpleCnf.add` by adding var with children"""
265 # load config
266 cnf = SimpleCnf()
267 cnf.append_file(self.import_file)
268 self.assertEqual(len(cnf['user']), 3)
269
270 # get a certain user with all its sub config
271 user_cnf = cnf.get(name='user', value='admin')
272 self.assertEqual(len(user_cnf), 1)
273
274 # copy as new user with different name but same children
275 cnf.add('user', 'admin2', children=user_cnf.get_children())
276 self.assertEqual(len(cnf['user']), 4)
277 self.assertEqual(len(cnf.get(name='user', value='admin2')), 1)
278 self.assertEqual(len(cnf.get(name='user', value='admin2').get_children()), 14)
279
280
281if __name__ == '__main__':
282 unittest.main()