diff options
author | 2019-08-07 02:58:48 +0000 | |
---|---|---|
committer | 2019-08-07 15:54:09 +0000 | |
commit | 85b8365c69b25191ba53390ba8ae9c7ad8e9f18b (patch) | |
tree | 1e454665559eac962f00e200704fac60c0336494 /pgaas/tests/test_plugin.py | |
parent | 556b233513db587f5d3982628dbca200fd3a9e2a (diff) |
PGaaS plugin -- modify code to support python3
add code to work on both python2 and python3
lots of pylinting
remove debug logging of a password
improve error message when given an invalid cluster name, simplify some code
password changing capability for a database
tox tests improvements
NOTE . . .
The PGaaS plugin uses several Cloudify mock libraries, one of which
is not compatible with Python3.
Until we get an updated version of that Cloudify mock libraries,
we will have to leave out py3X from the tox tests.
We cannot use py37 yet because Jenkins returns:
InterpreterNotFound: python3.7
So tox.ini is using envlist = py27
Change-Id: I795b71cc8a1fdea043e2ff3a0d66bb95e3f93a89
Signed-off-by: Hansen, Tony (th1395) <th1395@att.com>
Issue: CCSDK-1599
Signed-off-by: Hansen, Tony (th1395) <th1395@att.com>
Diffstat (limited to 'pgaas/tests/test_plugin.py')
-rw-r--r-- | pgaas/tests/test_plugin.py | 170 |
1 files changed, 146 insertions, 24 deletions
diff --git a/pgaas/tests/test_plugin.py b/pgaas/tests/test_plugin.py index d3c29b9..0071499 100644 --- a/pgaas/tests/test_plugin.py +++ b/pgaas/tests/test_plugin.py @@ -16,6 +16,12 @@ # limitations under the License. # ============LICENSE_END====================================================== +""" +unit tests for PostgreSQL password plugin +""" + +from __future__ import print_function +# pylint: disable=import-error,unused-import,wrong-import-order import pytest import socket import psycopg2 @@ -28,70 +34,111 @@ from cloudify.state import current_ctx from cloudify.exceptions import NonRecoverableError from cloudify import ctx -import sys, os +import sys +import os sys.path.append(os.path.realpath(os.path.dirname(__file__))) +import traceback -TMPNAME = "/tmp/pgaas_plugin_tests" +TMPNAME = "/tmp/pgaas_plugin_tests_{}".format(os.environ["USER"] if "USER" in os.environ else + os.environ["LOGNAME"] if "LOGNAME" in os.environ else + str(os.getuid())) class MockKeyPair(object): + """ + mock keypair for cloudify contexts + """ def __init__(self, type_hierarchy=None, target=None): self._type_hierarchy = type_hierarchy self._target = target @property def type_hierarchy(self): + """ + return the type hierarchy + """ return self._type_hierarchy @property def target(self): + """ + return the target + """ return self._target -class MockInstance(object): +class MockInstance(object): # pylint: disable=too-few-public-methods + """ + mock instance for cloudify contexts + """ def __init__(self, instance=None): self._instance = instance @property def instance(self): + """ + return the instance + """ return self._instance -class MockRuntimeProperties(object): +class MockRuntimeProperties(object): # pylint: disable=too-few-public-methods + """ + mock runtime properties for cloudify contexts + """ def __init__(self, runtime_properties=None): self._runtime_properties = runtime_properties @property def runtime_properties(self): + """ + return the properties + """ return self._runtime_properties class MockSocket(object): + """ + mock socket interface + """ def __init__(self): pass - def connect(self,host=None,port=None): + def connect(self, host=None, port=None): + """ + mock socket connection + """ pass def close(self): - pass + """ + mock socket close + """ + pass + +def _connect(host, port): # pylint: disable=unused-argument + """ + mock connection + """ + return {} -def _connect(h,p): - return { } - -def set_mock_context(msg, monkeypatch): +def set_mock_context(msg, monkeypatch, writerfqdn='test.bar.example.com'): + """ + establish the mock context for our testing + """ print("================ %s ================" % msg) - os.system("exec >> {0}.out 2>&1; echo Before test".format(TMPNAME)) #### DELETE + # pylint: disable=bad-continuation props = { - 'writerfqdn': 'test.bar.example.com', + 'writerfqdn': writerfqdn, 'use_existing': False, 'readerfqdn': 'test-ro.bar.example.com', 'name': 'testdb', 'port': '5432', 'initialpassword': 'test' } - + sshkeyprops = { 'public': "testpub", 'base64private': "testpriv" } mock_ctx = MockCloudifyContext(node_id='test_node_id', node_name='test_node_name', + # pylint: disable=bad-whitespace properties=props, relationships = [ MockKeyPair(type_hierarchy = @@ -109,55 +156,130 @@ def set_mock_context(msg, monkeypatch): monkeypatch.setattr(socket.socket, 'connect', _connect) # monkeypatch.setattr(psycopg2, 'connect', _connect) pgaas.pgaas_plugin.setOptManagerResources(TMPNAME) - + return mock_ctx @pytest.mark.dependency() -def test_start(monkeypatch): - os.system("exec > {0}.out 2>&1; echo Before any test; rm -rf {0}; mkdir -p {0}".format(TMPNAME)) #### DELETE +def test_start(monkeypatch): # pylint: disable=unused-argument + """ + put anything in here that needs to be done + PRIOR to the tests + """ + pass @pytest.mark.dependency(depends=['test_start']) def test_add_pgaas_cluster(monkeypatch): + """ + test add_pgaas_cluster() + """ try: set_mock_context('test_add_pgaas_cluster', monkeypatch) pgaas.pgaas_plugin.add_pgaas_cluster(args={}) + except Exception as e: + print("Error: {0}".format(e)) + print("Stack: {0}".format(traceback.format_exc())) finally: current_ctx.clear() - os.system("exec >> {0}.out 2>&1; echo After add_pgaas_cluster test; ls -lR {0}; head -1000 /dev/null {0}/pgaas/*;echo".format(TMPNAME)) #### DELETE @pytest.mark.dependency(depends=['test_add_pgaas_cluster']) def test_add_database(monkeypatch): + """ + test add_database() + """ try: set_mock_context('test_add_database', monkeypatch) pgaas.pgaas_plugin.create_database(args={}) + except Exception as e: + print("Error: {0}".format(e)) + print("Stack: {0}".format(traceback.format_exc())) + finally: + current_ctx.clear() + +@pytest.mark.dependency(depends=['test_add_pgaas_cluster']) +def test_bad_add_database(monkeypatch): + """ + test bad_add_database() + """ + try: + set_mock_context('test_add_database', monkeypatch, writerfqdn="bad.bar.example.com") + with pytest.raises(NonRecoverableError): + pgaas.pgaas_plugin.create_database(args={}) + except Exception as e: + print("Error: {0}".format(e)) + print("Stack: {0}".format(traceback.format_exc())) finally: current_ctx.clear() - os.system("exec >> {0}.out 2>&1; echo After add_database test; ls -lR {0}; head -1000 /dev/null {0}/pgaas/*;echo".format(TMPNAME)) #### DELETE @pytest.mark.dependency(depends=['test_add_database']) def test_update_database(monkeypatch): + """ + test update_database() + """ try: - set_mock_context('test_update_database', monkeypatch) - pgaas.pgaas_plugin.update_database(args={}) + ######################################################## + # Subtle test implications regarding: update_database # + # --------------------------------------------------- # + # 1) update_database is a workflow and the context # + # passed to it has 'nodes' attribute which is not # + # not included in MockCloudifyContext # + # 2) the 'nodes' attribute is a list of contexts so # + # we will have to create a sub-context # + # 3) update_database will iterate through each of the # + # nodes contexts looking for the correct one # + # 4) To identify the correct sub-context it will first# + # check each sub-context for the existence of # + # properties attribute # + # 5) ****Mock_context internally saves properties as # + # variable _properties and 'properties' is defined # + # as @property...thus it is not recognized as an # + # attribute...this will cause update_database to # + # fail so we need to explicitly create properties # + # properties attribute in the subcontext # + ######################################################## + + #################### + # Main context # + #################### + myctx = set_mock_context('test_update_database', monkeypatch) + ########################################################### + # Create subcontext and assign it to attribute properties # + # in main context # + ########################################################### + mynode = set_mock_context('test_update_database_node', monkeypatch) + # pylint: disable=protected-access + mynode.properties = mynode._properties + myctx.nodes = [mynode] + pgaas.pgaas_plugin.update_database(ctx=myctx, args={}) + except Exception as e: + print("Error: {0}".format(e)) + print("Stack: {0}".format(traceback.format_exc())) finally: current_ctx.clear() - os.system("exec >> {0}.out 2>&1; echo After update_database test; ls -lR {0}; head -1000 /dev/null {0}/pgaas/*;echo".format(TMPNAME)) #### DELETE @pytest.mark.dependency(depends=['test_update_database']) def test_delete_database(monkeypatch): + """ + test delete_database() + """ try: set_mock_context('test_delete_database', monkeypatch) pgaas.pgaas_plugin.delete_database(args={}) + except Exception as e: + print("Error: {0}".format(e)) + print("Stack: {0}".format(traceback.format_exc())) finally: current_ctx.clear() - os.system("exec >> {0}.out 2>&1; echo After delete_database test; ls -lR {0}; head -1000 /dev/null {0}/pgaas/*;echo".format(TMPNAME)) #### DELETE @pytest.mark.dependency(depends=['test_delete_database']) def test_rm_pgaas_cluster(monkeypatch): + """ + test rm_pgaas_cluster() + """ try: set_mock_context('test_rm_pgaas_cluster', monkeypatch) pgaas.pgaas_plugin.rm_pgaas_cluster(args={}) + except Exception as e: + print("Error: {0}".format(e)) + print("Stack: {0}".format(traceback.format_exc())) finally: current_ctx.clear() - os.system("exec >> {0}.out 2>&1; echo After delete_database test; ls -lR {0}; head -1000 /dev/null {0}/pgaas/*;echo".format(TMPNAME)) #### DELETE - |