1 # ============LICENSE_START====================================================
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
10 # http://www.apache.org/licenses/LICENSE-2.0
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======================================================
20 unit tests for PostgreSQL password plugin
23 from __future__ import print_function
24 # pylint: disable=import-error,unused-import,wrong-import-order
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
39 sys.path.append(os.path.realpath(os.path.dirname(__file__)))
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
46 class MockKeyPair(object):
48 mock keypair for cloudify contexts
50 def __init__(self, type_hierarchy=None, target=None):
51 self._type_hierarchy = type_hierarchy
55 def type_hierarchy(self):
57 return the type hierarchy
59 return self._type_hierarchy
68 class MockInstance(object): # pylint: disable=too-few-public-methods
70 mock instance for cloudify contexts
72 def __init__(self, instance=None):
73 self._instance = instance
82 class MockRuntimeProperties(object): # pylint: disable=too-few-public-methods
84 mock runtime properties for cloudify contexts
86 def __init__(self, runtime_properties=None):
87 self._runtime_properties = runtime_properties
90 def runtime_properties(self):
94 return self._runtime_properties
96 class MockSocket(object):
102 def connect(self, host=None, port=None):
104 mock socket connection
114 def _connect(host, port): # pylint: disable=unused-argument
120 def set_mock_context(msg, monkeypatch, writerfqdn='test.bar.example.com'):
122 establish the mock context for our testing
124 print("================ %s ================" % msg)
125 # pylint: disable=bad-continuation
127 'writerfqdn': writerfqdn,
128 'use_existing': False,
129 'readerfqdn': 'test-ro.bar.example.com',
132 'initialpassword': 'test'
137 'base64private': "testpriv"
140 mock_ctx = MockCloudifyContext(node_id='test_node_id', node_name='test_node_name',
141 # pylint: disable=bad-whitespace
144 MockKeyPair(type_hierarchy =
145 [ "dcae.relationships.pgaas_cluster_uses_sshkeypair" ],
146 target= MockInstance(
147 MockRuntimeProperties(sshkeyprops)) )
149 runtime_properties = {
150 "admin": { "user": "admin_user" },
151 "user": { "user": "user_user" },
152 "viewer": { "user": "viewer_user" }
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)
162 @pytest.mark.dependency()
163 def test_start(monkeypatch): # pylint: disable=unused-argument
165 put anything in here that needs to be done
170 @pytest.mark.dependency(depends=['test_start'])
171 def test_add_pgaas_cluster(monkeypatch):
173 test add_pgaas_cluster()
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()))
185 @pytest.mark.dependency(depends=['test_add_pgaas_cluster'])
186 def test_add_database(monkeypatch):
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()))
200 @pytest.mark.dependency(depends=['test_add_pgaas_cluster'])
201 def test_bad_add_database(monkeypatch):
203 test bad_add_database()
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()))
216 @pytest.mark.dependency(depends=['test_add_database'])
217 def test_update_database(monkeypatch):
219 test update_database()
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 ########################################################
246 myctx = set_mock_context('test_update_database', monkeypatch)
247 ###########################################################
248 # Create subcontext and assign it to attribute properties #
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()))
263 @pytest.mark.dependency(depends=['test_update_database'])
264 def test_delete_database(monkeypatch):
266 test delete_database()
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()))
278 @pytest.mark.dependency(depends=['test_delete_database'])
279 def test_rm_pgaas_cluster(monkeypatch):
281 test rm_pgaas_cluster()
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()))