update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b second try
[osm/SO.git] / rwlaunchpad / ra / pytest / ns / ha / test_ha_basic.py
1 #!/usr/bin/env python3
2 """
3 #
4 # Copyright 2017 RIFT.IO Inc
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 #
18 """
19
20 import gi
21 import pytest
22 import random
23 import time
24
25 import rift.auto.mano as mano
26 import rift.auto.descriptor
27 from gi.repository.RwKeyspec import quoted_key
28
29 from gi.repository import (
30 RwProjectNsdYang,
31 RwNsrYang,
32 RwVnfrYang,
33 RwVlrYang,
34 RwCloudYang,
35 RwConmanYang,
36 )
37
38 @pytest.fixture(scope='module')
39 def test_projects():
40 projects = ['default']
41 for idx in range(1, 4):
42 projects.append('project_ha_'+str(idx))
43 return projects
44
45
46 @pytest.mark.setup('active_configuration')
47 @pytest.mark.incremental
48 class TestActiveLpConfiguration(object):
49 """sets up the configuration as per RIFT-17854"""
50 def test_create_project_users(self, rbac_user_passwd, user_domain, rw_active_user_proxy, logger,
51 rw_active_project_proxy, rw_active_rbac_int_proxy, rw_active_conman_proxy, test_projects, user_roles):
52 # Create test users
53 user_name_pfx = 'user_ha_'
54 users = []
55 for idx in range(1, 9):
56 users.append(user_name_pfx+str(idx))
57 mano.create_user(rw_active_user_proxy, user_name_pfx+str(idx), rbac_user_passwd, user_domain)
58
59 # Create projects and assign roles to users in the newly created project
60 for project_name in test_projects:
61 if project_name == 'default':
62 continue
63 logger.debug('Creating project {}'.format(project_name))
64 mano.create_project(rw_active_conman_proxy, project_name)
65
66 for project_name in test_projects:
67 for _ in range(2):
68 role = random.choice(user_roles)
69 user = users.pop()
70 logger.debug('Assinging role {} to user {} in project {}'.format(role, user, project_name))
71 mano.assign_project_role_to_user(rw_active_project_proxy, role, user, project_name, user_domain,
72 rw_active_rbac_int_proxy)
73
74 def test_create_cloud_accounts(self, cloud_account, fmt_prefixed_cloud_xpath, fmt_cloud_xpath, rw_active_cloud_pxy,
75 test_projects, logger):
76 for project_name in test_projects:
77 logger.debug('Creating cloud account {} for project {}'.format(cloud_account.name, project_name))
78 xpath = fmt_prefixed_cloud_xpath.format(project=quoted_key(project_name),
79 account_name=quoted_key(cloud_account.name))
80 rw_active_cloud_pxy.replace_config(xpath, cloud_account)
81 xpath_no_pfx = fmt_cloud_xpath.format(project=quoted_key(project_name),
82 account_name=quoted_key(cloud_account.name))
83 response = rw_active_cloud_pxy.get(xpath_no_pfx)
84 assert response.name == cloud_account.name
85 assert response.account_type == cloud_account.account_type
86
87 rw_active_cloud_pxy.wait_for(fmt_cloud_xpath.format(project=quoted_key(project_name), account_name=quoted_key(
88 cloud_account.name)) + '/connection-status/status', 'success', timeout=30, fail_on=['failure'])
89
90 def test_onboard_descriptors(self, descriptors, test_projects, active_mgmt_session, fmt_nsd_catalog_xpath, logger):
91 # Uploads the descriptors
92 for project_name in test_projects:
93 for descriptor in descriptors:
94 logger.debug('Onboarding descriptor {} for project {}'.format(descriptor, project_name))
95 rift.auto.descriptor.onboard(active_mgmt_session, descriptor, project=project_name)
96
97 # Verify whether the descriptors uploaded successfully
98 nsd_pxy = active_mgmt_session.proxy(RwProjectNsdYang)
99 for project_name in test_projects:
100 nsd_xpath = fmt_nsd_catalog_xpath.format(project=quoted_key(project_name))
101 nsd_catalog = nsd_pxy.get_config(nsd_xpath)
102 assert nsd_catalog
103
104 @pytest.mark.skipif(not pytest.config.getoption("--nsr-test"), reason="need --nsr-test option to run")
105 def test_instantiate_nsr(self, fmt_nsd_catalog_xpath, cloud_account, active_mgmt_session, logger, test_projects):
106 nsd_pxy = active_mgmt_session.proxy(RwProjectNsdYang)
107 rwnsr_pxy = active_mgmt_session.proxy(RwNsrYang)
108
109 for project_name in test_projects:
110 nsd_xpath = fmt_nsd_catalog_xpath.format(project=quoted_key(project_name))
111 nsd_catalog = nsd_pxy.get_config(nsd_xpath)
112 assert nsd_catalog
113 nsd = nsd_catalog.nsd[0]
114 nsr = rift.auto.descriptor.create_nsr(cloud_account.name, nsd.name, nsd)
115
116 logger.debug('Instantiating NS for project {}'.format(project_name))
117 rift.auto.descriptor.instantiate_nsr(nsr, rwnsr_pxy, logger, project=project_name)
118
119
120 @pytest.mark.depends('active_configuration')
121 @pytest.mark.setup('first-failover')
122 @pytest.mark.incremental
123 class TestHaFirstFailover(object):
124 def test_collect_active_lp_data(self, active_lp_node_obj, active_confd_host, standby_confd_host, logger):
125 mano.verify_hagr_endpoints(active_confd_host, standby_confd_host)
126 active_lp_node_obj.collect_data()
127
128 def test_attempt_indirect_failover(self, revertive_pref_host, active_confd_host, standby_confd_host,
129 active_site_name, standby_site_name, logger):
130 # Wait for redundancy poll interval though collecting data on active LP takes more than 5 secs
131 time.sleep(5)
132 logger.debug('Attempting first failover. Host {} will be new active'.format(standby_confd_host))
133 mano.indirect_failover(revertive_pref_host, new_active_ip=standby_confd_host, new_active_site=standby_site_name,
134 new_standby_ip=active_confd_host, new_standby_site=active_site_name)
135
136 def test_wait_for_standby_to_comeup(self, standby_mgmt_session, active_confd_host, standby_confd_host):
137 """Wait for the standby to come up; Wait for endpoint 'ha/geographic/active' to return 200"""
138 mano.wait_for_standby_to_become_active(standby_mgmt_session)
139 # mano.verify_hagr_endpoints(active_host=standby_confd_host, standby_host=active_confd_host)
140
141 def test_collect_standby_lp_data(self, standby_lp_node_obj, standby_mgmt_session, cloud_account,
142 fmt_cloud_xpath, test_projects, fmt_nsd_catalog_xpath):
143 time.sleep(180)
144 rw_new_active_cloud_pxy = standby_mgmt_session.proxy(RwCloudYang)
145 nsd_pxy = standby_mgmt_session.proxy(RwProjectNsdYang)
146 rwnsr_proxy = standby_mgmt_session.proxy(RwNsrYang)
147
148 for project_name in test_projects:
149 rw_new_active_cloud_pxy.wait_for(
150 fmt_cloud_xpath.format(project=quoted_key(project_name), account_name=quoted_key(
151 cloud_account.name)) + '/connection-status/status', 'success', timeout=60, fail_on=['failure'])
152
153 # nsd_catalog = nsd_pxy.get_config(fmt_nsd_catalog_xpath.format(project=quoted_key(project_name)))
154 # assert nsd_catalog
155
156 if pytest.config.getoption("--nsr-test"):
157 nsr_opdata = rwnsr_proxy.get(
158 '/rw-project:project[rw-project:name={project}]/ns-instance-opdata'.format(
159 project=quoted_key(project_name)))
160 assert nsr_opdata
161 nsrs = nsr_opdata.nsr
162
163 for nsr in nsrs:
164 xpath = "/rw-project:project[rw-project:name={project}]/ns-instance-opdata/nsr[ns-instance-config-ref={config_ref}]/config-status".format(
165 project=quoted_key(project_name), config_ref=quoted_key(nsr.ns_instance_config_ref))
166 rwnsr_proxy.wait_for(xpath, "configured", fail_on=['failed'], timeout=400)
167
168 standby_lp_node_obj.collect_data()
169
170 def test_match_active_standby(self, active_lp_node_obj, standby_lp_node_obj):
171 active_lp_node_obj.compare(standby_lp_node_obj)
172
173
174 @pytest.mark.depends('first-failover')
175 @pytest.mark.setup('active-teardown')
176 @pytest.mark.incremental
177 class TestHaTeardown(object):
178 """It terminates the NS & deletes descriptors, cloud accounts, projects"""
179 @pytest.mark.skipif(not pytest.config.getoption("--nsr-test"), reason="need --nsr-test option to run")
180 def test_terminate_nsr(self, test_projects, standby_mgmt_session, logger):
181 rwnsr_pxy = standby_mgmt_session.proxy(RwNsrYang)
182 rwvnfr_pxy = standby_mgmt_session.proxy(RwVnfrYang)
183 rwvlr_pxy = standby_mgmt_session.proxy(RwVlrYang)
184
185 for project_name in test_projects:
186 logger.debug("Trying to terminate NSR in project {}".format(project_name))
187 rift.auto.descriptor.terminate_nsr(rwvnfr_pxy, rwnsr_pxy, rwvlr_pxy, logger, project_name)
188
189 def test_delete_descriptors(self, standby_mgmt_session, test_projects, logger):
190 for project_name in test_projects:
191 logger.info("Trying to delete the descriptors in project {}".format(project_name))
192 rift.auto.descriptor.delete_descriptors(standby_mgmt_session, project_name)
193
194 def test_delete_cloud_accounts(self, standby_mgmt_session, logger, test_projects, cloud_account):
195 for project_name in test_projects:
196 logger.info("Trying to delete the cloud-account in project {}".format(project_name))
197 rift.auto.mano.delete_cloud_account(standby_mgmt_session, cloud_account.name, project_name)
198
199 def test_delete_projects(self, standby_mgmt_session, test_projects, logger):
200 rw_conman_proxy = standby_mgmt_session.proxy(RwConmanYang)
201 for project_name in test_projects:
202 if project_name == 'default':
203 continue
204 logger.debug('Deleting project {}'.format(project_name))
205 rift.auto.mano.delete_project(rw_conman_proxy, project_name)
206
207
208 @pytest.mark.depends('active-teardown')
209 @pytest.mark.incremental
210 class TestHaFailoverToOriginalActive(object):
211 """Does a failover to original active and verifies the config"""
212 def test_collect_current_active_lp_data(self, standby_lp_node_obj, logger):
213 time.sleep(30)
214 logger.debug('Collecting data for host {}'.format(standby_lp_node_obj.host))
215 standby_lp_node_obj.collect_data()
216
217 def test_attempt_indirect_failover(self, revertive_pref_host, active_confd_host, standby_confd_host,
218 active_site_name, standby_site_name, logger):
219 # Wait for redundancy poll interval.
220 time.sleep(5)
221 logger.debug('Attempting second failover. Host {} will be new active'.format(active_confd_host))
222 mano.indirect_failover(revertive_pref_host, new_active_ip=active_confd_host, new_active_site=active_site_name,
223 new_standby_ip=standby_confd_host, new_standby_site=standby_site_name)
224
225 def test_wait_for_standby_to_comeup(self, active_mgmt_session, active_confd_host, standby_confd_host):
226 """Wait for the standby to come up; Wait for endpoint 'ha/geographic/active' to return 200"""
227 mano.wait_for_standby_to_become_active(active_mgmt_session)
228 # mano.verify_hagr_endpoints(active_host=standby_confd_host, standby_host=active_confd_host)
229
230 def test_collect_original_active_lp_data(self, active_lp_node_obj, logger):
231 active_lp_node_obj.session = None
232 logger.debug('Collecting data for host {}'.format(active_lp_node_obj.host))
233 active_lp_node_obj.collect_data()
234
235 def test_match_active_standby(self, active_lp_node_obj, standby_lp_node_obj):
236 standby_lp_node_obj.compare(active_lp_node_obj)
237
238 def test_delete_default_project(self, rw_active_conman_proxy):
239 rift.auto.mano.delete_project(rw_active_conman_proxy, 'default')
240
241 def test_users_presence_in_active(self, rw_active_user_proxy, user_keyed_xpath, user_domain):
242 """Users were not deleted as part of Teardown; Check those users should be present and delete them"""
243 user_config = rw_active_user_proxy.get_config('/user-config')
244 current_users_list = [user.user_name for user in user_config.user]
245
246 user_name_pfx = 'user_ha_'
247 original_test_users_list = [user_name_pfx+str(idx) for idx in range(1,9)]
248
249 assert set(original_test_users_list).issubset(current_users_list)
250
251 # Delete the users
252 for idx in range(1,9):
253 rw_active_user_proxy.delete_config(
254 user_keyed_xpath.format(user=quoted_key(user_name_pfx + str(idx)), domain=quoted_key(user_domain)))
255
256 def test_projects_deleted(self, test_projects, project_keyed_xpath, rw_active_conman_proxy):
257 """There should only be the default project; all other test projects are already deleted as part of Teardown"""
258 for project_name in test_projects:
259 project_ = rw_active_conman_proxy.get_config(
260 project_keyed_xpath.format(project_name=quoted_key(project_name)) + '/name')
261 assert project_ is None