commit a3ffb115308a21c423b32cfd47456d417aede3a4
parent 91e5da36959712f9f1de3fda4ca5474d80eb1756
Author: nolash <dev@holbrook.no>
Date: Mon, 12 Jul 2021 09:38:14 +0200
Add missing test files and pgp crypt files
Diffstat:
20 files changed, 460 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,6 @@
+build/
+*.egg-info/
+dist/
+__pycache__
+*.pyc
+gmon.out
diff --git a/confini/crypt/pgp.py b/confini/crypt/pgp.py
@@ -0,0 +1,53 @@
+# standard imports
+import logging
+import re
+import os
+
+# external imports
+import gnupg
+
+# local imports
+from confini.error import DecryptError
+
+
+logg = logging.getLogger(__name__)
+
+gpg = gnupg.GPG(
+ verbose=False,
+ use_agent=True,
+ )
+gpg.encoding = 'utf-8'
+
+
+
+class PGPDecrypter:
+
+ def __init__(self, base_dir='.'):
+ self.base_dir = base_dir
+
+
+ def decrypt(self, k, v, src_dir=None):
+ if src_dir == None:
+ src_dir = self.base_dir
+
+ if type(v).__name__ != 'str':
+ logg.debug('entry {} is not type str'.format(k))
+ return (v, False)
+
+ m = re.match(r'^\!gpg\((.*)\)', v)
+ if m != None:
+ filename = m.group(1)
+ if filename[0] != '/':
+ filename = os.path.join(src_dir, filename)
+ f = open(filename, 'rb')
+ logg.debug('decrypting entry {} in file {}'.format(k, f))
+ d = gpg.decrypt_file(f)
+ if not d.ok:
+ raise DecryptError()
+ v = str(d)
+ f.close()
+
+ return (v, m != None)
+
+ def __str__(self):
+ return 'gpg decrypter'
diff --git a/run_tests.sh b/run_tests.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+set -e
+set -x
+export PYTHONPATH=$PYTHONPATH:.
+for f in `ls tests/*.py`; do
+ python $f
+done
+set +x
+set +e
diff --git a/setup.py b/setup.py
@@ -19,6 +19,7 @@ setup(
packages=[
'confini',
'confini.runnable',
+ 'confini.crypt',
],
url='https://gitlab.com/nolash/python-confini',
)
diff --git a/tests/files/bar.ini b/tests/files/bar.ini
@@ -0,0 +1,5 @@
+[BAR]
+foo = oof
+
+[XYZZY]
+bert = ernie
diff --git a/tests/files/crypt/baz.asc b/tests/files/crypt/baz.asc
@@ -0,0 +1,14 @@
+-----BEGIN PGP MESSAGE-----
+
+hQGMA8Ll7MXhlLGLAQv/Skj9eYN9MuR2JLIFJ7V2BYgpdakukamW6dCEwr1dyWbq
+Uj0UurqSCJBg3qvDQvK2K/UU1ez2+Sot8i/rQY5Q7t9Daxlzp4PombtYw0R3dxLE
+bcNCEv7tIr1VjW8cRvkgKc9CamcI2zcUDt2DGq+c9w8Hxn+N7KRF1ZZLGvb7nnTU
+ugMyrQb8ILJDyw7ifjgjQFSeh5Kfg+tQAKaPTk7ydCqCXaODd1dCNE1IK/ebl8kT
+gGm0db20lcNG9MOmmumD22hTovlouv1WcybpQGzNsogkiJxMRgCQ2DRRAxWOLyam
+71iEcCb3w/xf+YISUSWkD+H1W0+2i0X6RTIVNYs/tEnI9/DypKV4wPWcsWbLsVqO
+u8wodH5Kk3f/gwVd90wjmpYMrRCIL0/GOfMn8IglN58lOMEtopRtll/CbM8XcRUc
+5vsCIcrBiZiwq6bfQxyPSVmpOsxz24BMvU537bVf5qI7KpFn5L5Gjo/Sy1Xq4rpT
+avEBM1lXrRbEqXz/fd2J0j4BInKLK3yaAkBq0pFYvCFsHOB/7n0SUkOZcFBXxGGb
+sDj+VuQr5hdhJbgyl0ZhsUvHaJQzKFn2N4cW8RQwmw==
+=qkyQ
+-----END PGP MESSAGE-----
diff --git a/tests/files/crypt/foo.ini b/tests/files/crypt/foo.ini
@@ -0,0 +1,4 @@
+[FOO]
+bar = 42
+baz = !gpg(baz.asc)
+xyzzy =
diff --git a/tests/files/default/foo.ini b/tests/files/default/foo.ini
@@ -0,0 +1,3 @@
+[FOO]
+bar = xyzzy
+baz =
diff --git a/tests/files/foo.ini b/tests/files/foo.ini
@@ -0,0 +1,3 @@
+[FOO]
+bar = 42
+baz = 029a
diff --git a/tests/files/multi/one/bar.ini b/tests/files/multi/one/bar.ini
@@ -0,0 +1,2 @@
+[bar]
+one = two
diff --git a/tests/files/multi/one/foo.ini b/tests/files/multi/one/foo.ini
@@ -0,0 +1,4 @@
+[FOO]
+bar = xyzzy
+baz =
+bah =
diff --git a/tests/files/multi/three/foo.ini b/tests/files/multi/three/foo.ini
@@ -0,0 +1,5 @@
+[FOO]
+bar = plugh
+baz = 42
+bah =
+mah = nah
diff --git a/tests/files/multi/two/bar.ini b/tests/files/multi/two/bar.ini
@@ -0,0 +1,2 @@
+[bar]
+one = three
diff --git a/tests/files/multi/two/foo.ini b/tests/files/multi/two/foo.ini
@@ -0,0 +1,4 @@
+[FOO]
+bar = plugh
+baz = 42
+bah =
diff --git a/tests/files/translate/foo.ini b/tests/files/translate/foo.ini
@@ -0,0 +1,10 @@
+[true]
+a = true
+b = True
+c = 1
+
+[false]
+a = false
+b = False
+c = 0
+d =
diff --git a/tests/test_basic.py b/tests/test_basic.py
@@ -0,0 +1,95 @@
+#!/usr/bin/python
+
+import os
+import unittest
+import logging
+
+from confini import Config
+
+logging.basicConfig(level=logging.DEBUG)
+logg = logging.getLogger()
+
+class TestBasic(unittest.TestCase):
+
+ wd = os.path.dirname(__file__)
+
+ def setUp(self):
+ pass
+
+
+ def tearDown(self):
+ pass
+
+
+ def test_parse_default(self):
+ inidir = os.path.join(self.wd, 'files/default')
+ c = Config(inidir)
+ c.process()
+ r = c.get('FOO_BAR', 'plugh')
+ self.assertEqual(r, 'xyzzy')
+ r = c.get('FOO_BAZ', 'plugh')
+ self.assertEqual(r, 'plugh')
+ r = c.get('FOO_BAZ')
+ self.assertEqual(r, None)
+ with self.assertRaises(KeyError):
+ r = c.get('FOO_BAZBAZ')
+
+
+ def test_parse_two(self):
+ inidir = os.path.join(self.wd, 'files/default')
+ c = Config(inidir, override_dirs=[inidir])
+ c.process()
+ r = c.get('FOO_BAR', 'plugh')
+ self.assertEqual(r, 'xyzzy')
+ r = c.get('FOO_BAZ', 'plugh')
+ self.assertEqual(r, 'plugh')
+ r = c.get('FOO_BAZ')
+ self.assertEqual(r, None)
+ with self.assertRaises(KeyError):
+ r = c.get('FOO_BAZBAZ')
+
+
+ def test_overwrite_guard(self):
+ inidir = os.path.join(self.wd, 'files/default')
+ c = Config(inidir)
+ c.process()
+ with self.assertRaises(AttributeError):
+ c.add('xxx', 'FOO_BAR')
+ c.add('xxx', 'FOO_BAR', exists_ok=True)
+ r = c.get('FOO_BAR')
+ self.assertEqual(r, 'xxx')
+
+
+ def test_parse_two_files(self):
+ inidir = os.path.join(self.wd, 'files')
+ c = Config(inidir)
+ c.process()
+ c.require('BERT', 'XYZZY')
+ expect = {
+ 'FOO_BAR': '42',
+ 'FOO_BAZ': '029a',
+ 'BAR_FOO': 'oof',
+ 'XYZZY_BERT': 'ernie',
+ }
+ self.assertDictEqual(expect, c.store)
+
+
+ def test_require(self):
+ inidir = os.path.join(self.wd, 'files')
+ c = Config(inidir)
+ c.require('BERT', 'XYZZY')
+ self.assertTrue(c.validate())
+ c.require('ERNIE', 'XYZZY')
+ self.assertFalse(c.validate())
+ logg.debug(c)
+
+
+ def test_all(self):
+ inidir = os.path.join(self.wd, 'files')
+ c = Config(inidir)
+ a = c.all()
+ self.assertEqual(a, list(c.store.keys()))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_enc.py b/tests/test_enc.py
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+
+import os
+import unittest
+import logging
+
+from confini import Config
+from confini.error import DecryptError
+from confini.crypt.pgp import PGPDecrypter
+
+logging.basicConfig(level=logging.DEBUG)
+logg = logging.getLogger()
+
+script_dir = os.path.dirname(os.path.realpath(__file__))
+gnupg_dir = os.path.join(script_dir, 'gnupg')
+
+class TestBasic(unittest.TestCase):
+
+ wd = os.path.dirname(__file__)
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_enc(self):
+ inidir = os.path.join(self.wd, 'files/crypt')
+ c = Config(inidir)
+ decrypter = PGPDecrypter()
+ c.add_decrypt(decrypter)
+ c.process()
+ with self.assertRaises(DecryptError):
+ c.get('FOO_BAZ')
+ os.environ['GNUPGHOME'] = gnupg_dir
+ c.get('FOO_BAZ')
+
+
+ def test_decrypt_with_non_string(self):
+ inidir = os.path.join(self.wd, 'files/crypt')
+ c = Config(inidir)
+ decrypter = PGPDecrypter()
+ c.add_decrypt(decrypter)
+ c.process()
+ override = {
+ 'FOO_XYZZY': False,
+ }
+ c.dict_override(override, 'test')
+ c.get('FOO_XYZZY')
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_env.py b/tests/test_env.py
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+
+import os
+import unittest
+import logging
+
+from confini import Config
+
+logging.basicConfig(level=logging.DEBUG)
+logg = logging.getLogger()
+
+class TestEnv(unittest.TestCase):
+
+ wd = os.path.dirname(__file__)
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_dict_override(self):
+ inidir = os.path.join(self.wd, 'files')
+ c = Config(inidir)
+ c.process()
+
+ override_dict = {
+ 'FOO_BAR': '666',
+ 'XYZZY_BERT': 'oscar',
+ 'BAR_FOO': None,
+ }
+ c.dict_override(override_dict, 'arbitrary dict')
+
+ expect = {
+ 'FOO_BAR': '666',
+ 'FOO_BAZ': '029a',
+ 'BAR_FOO': 'oof',
+ 'XYZZY_BERT': 'oscar',
+ }
+ self.assertDictEqual(expect, c.store)
+
+ override_dict = {
+ 'BAR_FOO': 'barbarbar',
+ }
+ c.dict_override(override_dict, 'arbitrary dict')
+
+ expect = {
+ 'FOO_BAR': '666',
+ 'FOO_BAZ': '029a',
+ 'BAR_FOO': 'barbarbar',
+ 'XYZZY_BERT': 'oscar',
+ }
+ self.assertDictEqual(expect, c.store)
+
+
+
+ def test_env_a_override(self):
+ os.environ['FOO_BAR'] = '43'
+ inidir = os.path.join(self.wd, 'files')
+ c = Config(inidir)
+ c.process()
+
+ os.environ['ZZZ_FOO_BAR'] = '44'
+ inidir = os.path.join(self.wd, 'files')
+ c = Config(inidir, env_prefix='ZZZ')
+ c.process()
+ expect = {
+ 'FOO_BAR': '44',
+ 'FOO_BAZ': '029a',
+ 'BAR_FOO': 'oof',
+ 'XYZZY_BERT': 'ernie',
+ }
+ self.assertDictEqual(expect, c.store)
+
+ os.environ['ZZZ_FOO_BAR'] = ''
+ inidir = os.path.join(self.wd, 'files')
+ c = Config(inidir, env_prefix='ZZZ')
+ c.process()
+ expect = {
+ 'FOO_BAR': '42',
+ 'FOO_BAZ': '029a',
+ 'BAR_FOO': 'oof',
+ 'XYZZY_BERT': 'ernie',
+ }
+ self.assertDictEqual(expect, c.store)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_multi.py b/tests/test_multi.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+
+import os
+import unittest
+import logging
+
+from confini import Config
+
+logging.basicConfig(level=logging.DEBUG)
+logg = logging.getLogger()
+
+
+class TestBasic(unittest.TestCase):
+
+ wd = os.path.dirname(__file__)
+
+ def setUp(self):
+ pass
+
+
+ def tearDown(self):
+ pass
+
+
+ def test_parse_two(self):
+ inidir_one = os.path.join(self.wd, 'files', 'multi', 'one')
+ inidir_two = os.path.join(self.wd, 'files', 'multi', 'two')
+ c = Config(inidir_one, override_dirs=[inidir_two])
+ c.process()
+ r = c.get('FOO_BAR')
+ self.assertEqual(r, 'plugh')
+ r = c.get('FOO_BAZ')
+ self.assertEqual(r, '42')
+ r = c.get('FOO_BAH')
+ self.assertEqual(r, None)
+ r = c.get('BAR_ONE')
+ self.assertEqual(r, 'three')
+
+
+ def test_parse_two_schema_error(self):
+ inidir_one = os.path.join(self.wd, 'files', 'multi', 'one')
+ inidir_two = os.path.join(self.wd, 'files', 'multi', 'three')
+ c = Config(inidir_one, override_dirs=[inidir_two])
+ with self.assertRaises(KeyError):
+ c.process()
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_translate.py b/tests/test_translate.py
@@ -0,0 +1,49 @@
+# standard imports
+import os
+import unittest
+import logging
+
+# local imports
+from confini import Config
+
+logging.basicConfig(level=logging.DEBUG)
+logg = logging.getLogger()
+
+
+class TestTranslate(unittest.TestCase):
+
+ wd = os.path.dirname(__file__)
+
+ def setUp(self):
+ pass
+
+
+ def tearDown(self):
+ pass
+
+
+ def test_parse_default(self):
+ inidir = os.path.join(self.wd, 'files/translate')
+ c = Config(inidir)
+ c.process()
+
+ self.assertTrue(c.get('TRUE_A'))
+ self.assertTrue(c.get('TRUE_B'))
+ self.assertTrue(c.get('TRUE_C'))
+
+ self.assertFalse(c.true('FALSE_A'))
+ self.assertFalse(c.true('FALSE_B'))
+ self.assertFalse(c.true('FALSE_C'))
+ self.assertIsNone(c.get('FALSE_D'))
+
+ o = {
+ 'TRUE_A': True,
+ 'FALSE_A': False,
+ }
+ c.dict_override(o, 'test')
+ self.assertTrue(c.true('TRUE_A'))
+ self.assertFalse(c.true('FALSE_A'))
+
+
+if __name__ == '__main__':
+ unittest.main()