move plugins from from ccsdk to dcaegen2
[dcaegen2/platform/plugins.git] / pgaas / tests / test_plugin.py
1 # ============LICENSE_START====================================================
2 # org.onap.dcaegen2
3 # =============================================================================
4 # Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved.
5 # =============================================================================
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 #      http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 # ============LICENSE_END======================================================
18
19 """
20 unit tests for PostgreSQL password plugin
21 """
22
23 from __future__ import print_function
24 # pylint: disable=import-error,unused-import,wrong-import-order
25 import pytest
26 import socket
27 import psycopg2
28 import pgaas.pgaas_plugin
29 from cloudify.mocks import MockCloudifyContext
30 from cloudify.mocks import MockNodeContext
31 from cloudify.mocks import MockNodeInstanceContext
32 from cloudify.mocks import MockRelationshipSubjectContext
33 from cloudify.state import current_ctx
34 from cloudify.exceptions import NonRecoverableError
35 from cloudify import ctx
36
37 import sys
38 import os
39 sys.path.append(os.path.realpath(os.path.dirname(__file__)))
40 import traceback
41
42 TMPNAME = "/tmp/pgaas_plugin_tests_{}".format(os.environ["USER"] if "USER" in os.environ else
43                                               os.environ["LOGNAME"] if "LOGNAME" in os.environ else
44                                               str(os.getuid()))
45
46 class MockKeyPair(object):
47   """
48   mock keypair for cloudify contexts
49   """
50   def __init__(self, type_hierarchy=None, target=None):
51     self._type_hierarchy = type_hierarchy
52     self._target = target
53
54   @property
55   def type_hierarchy(self):
56     """
57     return the type hierarchy
58     """
59     return self._type_hierarchy
60
61   @property
62   def target(self):
63     """
64     return the target
65     """
66     return self._target
67
68 class MockInstance(object): # pylint: disable=too-few-public-methods
69   """
70   mock instance for cloudify contexts
71   """
72   def __init__(self, instance=None):
73     self._instance = instance
74
75   @property
76   def instance(self):
77     """
78     return the instance
79     """
80     return self._instance
81
82 class MockRuntimeProperties(object): # pylint: disable=too-few-public-methods
83   """
84   mock runtime properties for cloudify contexts
85   """
86   def __init__(self, runtime_properties=None):
87     self._runtime_properties = runtime_properties
88
89   @property
90   def runtime_properties(self):
91     """
92     return the properties
93     """
94     return self._runtime_properties
95
96 class MockSocket(object):
97   """
98   mock socket interface
99   """
100   def __init__(self):
101     pass
102   def connect(self, host=None, port=None):
103     """
104     mock socket connection
105     """
106     pass
107   def close(self):
108     """
109     mock socket close
110     """
111     pass
112
113
114 def _connect(host, port): # pylint: disable=unused-argument
115   """
116   mock connection
117   """
118   return {}
119
120 def set_mock_context(msg, monkeypatch, writerfqdn='test.bar.example.com'):
121   """
122   establish the mock context for our testing
123   """
124   print("================ %s ================" % msg)
125   # pylint: disable=bad-continuation
126   props = {
127     'writerfqdn': writerfqdn,
128     'use_existing': False,
129     'readerfqdn': 'test-ro.bar.example.com',
130     'name': 'testdb',
131     'port': '5432',
132     'initialpassword': 'test'
133     }
134
135   sshkeyprops = {
136     'public': "testpub",
137     'base64private': "testpriv"
138     }
139
140   mock_ctx = MockCloudifyContext(node_id='test_node_id', node_name='test_node_name',
141                                  # pylint: disable=bad-whitespace
142                                  properties=props,
143                                  relationships = [
144                                    MockKeyPair(type_hierarchy =
145                                                [ "dcae.relationships.pgaas_cluster_uses_sshkeypair" ],
146                                                target= MockInstance(
147                                                  MockRuntimeProperties(sshkeyprops)) )
148                                    ],
149                                  runtime_properties = {
150                                    "admin": { "user": "admin_user" },
151                                    "user": { "user": "user_user" },
152                                    "viewer": { "user": "viewer_user" }
153                                    }
154                                  )
155   current_ctx.set(mock_ctx)
156   monkeypatch.setattr(socket.socket, 'connect', _connect)
157   # monkeypatch.setattr(psycopg2, 'connect', _connect)
158   pgaas.pgaas_plugin.setOptManagerResources(TMPNAME)
159   return mock_ctx
160
161
162 @pytest.mark.dependency()
163 def test_start(monkeypatch): # pylint: disable=unused-argument
164   """
165   put anything in here that needs to be done
166   PRIOR to the tests
167   """
168   pass
169
170 @pytest.mark.dependency(depends=['test_start'])
171 def test_add_pgaas_cluster(monkeypatch):
172   """
173   test add_pgaas_cluster()
174   """
175   try:
176     set_mock_context('test_add_pgaas_cluster', monkeypatch)
177     pgaas.pgaas_plugin.add_pgaas_cluster(args={})
178   except Exception as e:
179     print("Error: {0}".format(e))
180     print("Stack: {0}".format(traceback.format_exc()))
181     raise
182   finally:
183     current_ctx.clear()
184
185 @pytest.mark.dependency(depends=['test_add_pgaas_cluster'])
186 def test_add_database(monkeypatch):
187   """
188   test add_database()
189   """
190   try:
191     set_mock_context('test_add_database', monkeypatch)
192     pgaas.pgaas_plugin.create_database(args={})
193   except Exception as e:
194     print("Error: {0}".format(e))
195     print("Stack: {0}".format(traceback.format_exc()))
196     raise
197   finally:
198     current_ctx.clear()
199
200 @pytest.mark.dependency(depends=['test_add_pgaas_cluster'])
201 def test_bad_add_database(monkeypatch):
202   """
203   test bad_add_database()
204   """
205   try:
206     set_mock_context('test_add_database', monkeypatch, writerfqdn="bad.bar.example.com")
207     with pytest.raises(NonRecoverableError):
208       pgaas.pgaas_plugin.create_database(args={})
209   except Exception as e:
210     print("Error: {0}".format(e))
211     print("Stack: {0}".format(traceback.format_exc()))
212     raise
213   finally:
214     current_ctx.clear()
215
216 @pytest.mark.dependency(depends=['test_add_database'])
217 def test_update_database(monkeypatch):
218   """
219   test update_database()
220   """
221   try:
222     ########################################################
223     # Subtle test implications regarding: update_database  #
224     # ---------------------------------------------------  #
225     # 1)  update_database is a workflow and the context    #
226     #     passed to it has 'nodes' attribute which is not  #
227     #     not included in MockCloudifyContext              #
228     # 2)  the 'nodes' attribute is a list of contexts so   #
229     #     we will have to create a sub-context             #
230     # 3)  update_database will iterate through each of the #
231     #     nodes contexts looking for the correct one       #
232     # 4)  To identify the correct sub-context it will first#
233     #     check each sub-context for the existence of      #
234     #     properties attribute                             #
235     # 5)  ****Mock_context internally saves properties as  #
236     #     variable _properties and 'properties' is defined #
237     #     as @property...thus it is not recognized as an   #
238     #     attribute...this will cause update_database to   #
239     #     fail so we need to explicitly create properties  #
240     #     properties attribute in the subcontext           #
241     ########################################################
242
243     ####################
244     # Main context     #
245     ####################
246     myctx = set_mock_context('test_update_database', monkeypatch)
247     ###########################################################
248     # Create subcontext and assign it to attribute properties #
249     # in main context                                         #
250     ###########################################################
251     mynode = set_mock_context('test_update_database_node', monkeypatch)
252     # pylint: disable=protected-access
253     mynode.properties = mynode._properties
254     myctx.nodes = [mynode]
255     pgaas.pgaas_plugin.update_database(refctx=myctx)
256   except Exception as e:
257     print("Error: {0}".format(e))
258     print("Stack: {0}".format(traceback.format_exc()))
259     raise
260   finally:
261     current_ctx.clear()
262
263 @pytest.mark.dependency(depends=['test_update_database'])
264 def test_delete_database(monkeypatch):
265   """
266   test delete_database()
267   """
268   try:
269     set_mock_context('test_delete_database', monkeypatch)
270     pgaas.pgaas_plugin.delete_database(args={})
271   except Exception as e:
272     print("Error: {0}".format(e))
273     print("Stack: {0}".format(traceback.format_exc()))
274     raise
275   finally:
276     current_ctx.clear()
277
278 @pytest.mark.dependency(depends=['test_delete_database'])
279 def test_rm_pgaas_cluster(monkeypatch):
280   """
281   test rm_pgaas_cluster()
282   """
283   try:
284     set_mock_context('test_rm_pgaas_cluster', monkeypatch)
285     pgaas.pgaas_plugin.rm_pgaas_cluster(args={})
286   except Exception as e:
287     print("Error: {0}".format(e))
288     print("Stack: {0}".format(traceback.format_exc()))
289     raise
290   finally:
291     current_ctx.clear()