From 5b5cc1da4139ffeace8ea89365f1505ce6f72ab8 Mon Sep 17 00:00:00 2001
From: Christian Heimes <cheimes@redhat.com>
Date: Tue, 18 Aug 2015 11:21:01 +0200
Subject: [PATCH] Unit tests for upgraders and pki.crypto

The new unit test import files like deployment scriptlets and upgrade
scriptlets that were not executed in tests before. The basic operations
of pki.crypto are also covered.
---
 tests/python/server/test_deployment.py    | 49 +++++++++++++++++
 tests/python/server/test_serverupgrade.py | 45 ++++++++++++++++
 tests/python/test_pki.py                  |  2 +-
 tests/python/test_pkicrypto.py            | 90 +++++++++++++++++++++++++++++++
 tests/python/test_upgrade.py              | 45 ++++++++++++++++
 tox.ini                                   |  8 +++
 6 files changed, 238 insertions(+), 1 deletion(-)
 create mode 100644 tests/python/server/test_deployment.py
 create mode 100644 tests/python/server/test_serverupgrade.py
 create mode 100644 tests/python/test_pkicrypto.py
 create mode 100644 tests/python/test_upgrade.py

diff --git a/tests/python/server/test_deployment.py b/tests/python/server/test_deployment.py
new file mode 100644
index 0000000000000000000000000000000000000000..313e38f8355fe1221e5dc0ab898f0e25774e5eb3
--- /dev/null
+++ b/tests/python/server/test_deployment.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+# Authors:
+#     Christian Heimes <cheimes@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+
+import os
+import unittest
+
+from pki.server.deployment.pkiscriptlet import AbstractBasePkiScriptlet
+from pki.server.deployment import scriptlets
+
+
+class PKIDeploymentTests(unittest.TestCase):
+    scriptlet_path = os.path.dirname(os.path.abspath(scriptlets.__file__))
+
+    def find_scriptlets(self):
+        for filename in os.listdir(self.scriptlet_path):
+            if filename.endswith('.py') and not filename == '__init__.py':
+                yield filename[:-3]
+
+    def test_scriptlet_imports(self):
+        # check if all deployment scriptlets can be imported
+        for pki_scriptlet in self.find_scriptlets():
+            scriptlet = __import__(
+                "pki.server.deployment.scriptlets.%s" % pki_scriptlet,
+                fromlist=[pki_scriptlet]
+            )
+            instance = scriptlet.PkiScriptlet()
+            self.assertIsInstance(instance, AbstractBasePkiScriptlet)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/python/server/test_serverupgrade.py b/tests/python/server/test_serverupgrade.py
new file mode 100644
index 0000000000000000000000000000000000000000..14b76f288fb2e53e71a7a621a394a725e32b303d
--- /dev/null
+++ b/tests/python/server/test_serverupgrade.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+# Authors:
+#     Christian Heimes <cheimes@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+
+import os
+import sys
+import unittest
+
+from pki.server.upgrade import PKIServerUpgrader, PKIServerUpgradeScriptlet
+
+
+class PKIServerUpgradeTests(unittest.TestCase):
+    server_upgrade_dir = os.path.join(sys.prefix, 'share/pki/server/upgrade')
+
+    def test_load_scriptlets(self):
+        # test loading of server upgrade scriptlets
+        self.assertTrue(os.path.isdir(self.server_upgrade_dir))
+        upgrader = PKIServerUpgrader(upgrade_dir=self.server_upgrade_dir)
+        versions = upgrader.all_versions()
+        self.assertTrue(len(versions))
+        for version in versions:
+            scriptlets = upgrader.scriptlets(version)
+            for scriptlet in scriptlets:
+                self.assertIsInstance(scriptlet, PKIServerUpgradeScriptlet)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/python/test_pki.py b/tests/python/test_pki.py
index 606a892329b67acac7b45e0ad1b340db1e5519d8..dcab7994756801c444106951056ab6ba59a1892c 100644
--- a/tests/python/test_pki.py
+++ b/tests/python/test_pki.py
@@ -33,6 +33,7 @@ class TestHTTPError(requests.exceptions.HTTPError):
         self.response._content = body
         self.response.encoding = 'utf-8'
 
+
 class PKITests(unittest.TestCase):
     def test_handle_exceptions(self):
 
@@ -78,7 +79,6 @@ class PKITests(unittest.TestCase):
             'com.netscape.certsrv.base.BadRequestException'
         )
 
-
         with self.assertRaises(TestHTTPError) as e:
             raiser(b'no json body')
 
diff --git a/tests/python/test_pkicrypto.py b/tests/python/test_pkicrypto.py
new file mode 100644
index 0000000000000000000000000000000000000000..3638c23e57c9c5857e23321d618cba54434a8195
--- /dev/null
+++ b/tests/python/test_pkicrypto.py
@@ -0,0 +1,90 @@
+# -*- coding: utf-8 -*-
+# Authors:
+#     Christian Heimes <cheimes@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+
+import os
+import shutil
+import tempfile
+import unittest
+
+from nss import nss
+from nss.error import NSPRError
+
+from pki.crypto import NSSCryptoProvider
+
+
+class PKICryptoTests(unittest.TestCase):
+    password = b'random password'
+
+    @classmethod
+    def setUpClass(cls):
+        cls.tempdir = tempfile.mkdtemp()
+        cls.dbdir = os.path.join(cls.tempdir, 'nssdb')
+        NSSCryptoProvider.setup_database(cls.dbdir, cls.password)
+        cls.provider = NSSCryptoProvider(cls.dbdir, cls.password)
+        cls.provider.initialize()
+
+    @classmethod
+    def tearDownClass(cls):
+        nss.nss_shutdown()
+        shutil.rmtree(cls.tempdir)
+
+    def test_generate_nounce_iv(self):
+        iv = self.provider.generate_nonce_iv()
+        self.assertIsInstance(iv, bytes)
+        self.assertEqual(len(iv), 8)
+
+        iv = self.provider.generate_nonce_iv(nss.CKM_AES_CBC_PAD)
+        self.assertIsInstance(iv, bytes)
+        self.assertEqual(len(iv), 16)
+
+    def test_generate_symmentric_key(self):
+        key = self.provider.generate_symmetric_key()
+        self.assertIsInstance(key, nss.PK11SymKey)
+        self.assertEqual(key.key_length, 24)
+
+        key = self.provider.generate_symmetric_key(nss.CKM_AES_CBC_PAD)
+        self.assertIsInstance(key, nss.PK11SymKey)
+        self.assertEqual(key.key_length, 32)
+
+    def test_generate_session_key(self):
+        key = self.provider.generate_session_key()
+        self.assertIsInstance(key, nss.PK11SymKey)
+        self.assertEqual(key.key_length, 24)
+
+    def test_symmentric_wrap(self):
+        key = self.provider.generate_symmetric_key()
+        data = b'some private data'
+        wrapped = self.provider.symmetric_wrap(data, key)
+        self.assertNotEqual(data, wrapped)
+        unwrapped = self.provider.symmetric_unwrap(wrapped, key)
+        self.assertEqual(data, unwrapped)
+
+        otherkey = self.provider.generate_symmetric_key()
+        with self.assertRaises(NSPRError) as e:
+            self.provider.symmetric_unwrap(wrapped, otherkey)
+        self.assertEqual(
+            e.exception.error_desc,
+            '(SEC_ERROR_BAD_DATA) security library: received bad data.'
+        )
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/python/test_upgrade.py b/tests/python/test_upgrade.py
new file mode 100644
index 0000000000000000000000000000000000000000..74bdd0e74ac9a8d1ec56f7c93d02cb377d87f192
--- /dev/null
+++ b/tests/python/test_upgrade.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+# Authors:
+#     Christian Heimes <cheimes@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+
+import os
+import sys
+import unittest
+
+from pki.upgrade import PKIUpgrader, PKIUpgradeScriptlet
+
+
+class PKIUpgradeTests(unittest.TestCase):
+    upgrade_dir = os.path.join(sys.prefix, 'share/pki/upgrade')
+
+    def test_load_scriptlets(self):
+        # test loading of upgrade scriptlets
+        self.assertTrue(os.path.isdir(self.upgrade_dir))
+        upgrader = PKIUpgrader(upgrade_dir=self.upgrade_dir)
+        versions = upgrader.all_versions()
+        self.assertTrue(len(versions))
+        for version in versions:
+            scriptlets = upgrader.scriptlets(version)
+            for scriptlet in scriptlets:
+                self.assertIsInstance(scriptlet, PKIUpgradeScriptlet)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tox.ini b/tox.ini
index 748e3d0dbb5da7268aeb4ef385f349e1765d95c5..cbdc92dcddfe84407c2f24b3e8383567a1831b5c 100644
--- a/tox.ini
+++ b/tox.ini
@@ -36,6 +36,12 @@ commands =
     {envpython} {envbindir}/pki-upgrade --help
     py.test --capture=no --strict {posargs}
 
+[testenv:py34]
+deps =
+    {[testenv]deps}
+    pyldap
+    hg+https://fedorapeople.org/~jdennis/python-nss/repo/python-nss/
+
 [testenv:lint]
 basepython = python2.7
 deps =
@@ -54,6 +60,8 @@ commands =
 basepython = python3.4
 deps =
     pylint
+    pyldap
+    hg+https://fedorapeople.org/~jdennis/python-nss/repo/python-nss/
 commands =
     {envpython} {toxinidir}/scripts/pylint-build-scan.py tox
 
-- 
2.4.3

