4 # Copyright 2017 RIFT.IO Inc
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.
25 import rift
.auto
.mano
as mano
26 import rift
.auto
.descriptor
27 from gi
.repository
.RwKeyspec
import quoted_key
29 from gi
.repository
import (
38 @pytest.fixture(scope
='module')
40 projects
= ['default']
41 for idx
in range(1, 4):
42 projects
.append('project_ha_'+str(idx
))
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
):
53 user_name_pfx
= 'user_ha_'
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
)
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':
63 logger
.debug('Creating project {}'.format(project_name
))
64 mano
.create_project(rw_active_conman_proxy
, project_name
)
66 for project_name
in test_projects
:
68 role
= random
.choice(user_roles
)
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
)
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
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'])
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
)
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
)
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
)
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
)
113 nsd
= nsd_catalog
.nsd
[0]
114 nsr
= rift
.auto
.descriptor
.create_nsr(cloud_account
.name
, nsd
.name
, nsd
)
116 logger
.debug('Instantiating NS for project {}'.format(project_name
))
117 rift
.auto
.descriptor
.instantiate_nsr(nsr
, rwnsr_pxy
, logger
, project
=project_name
)
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()
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
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
)
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)
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
):
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
)
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'])
153 # nsd_catalog = nsd_pxy.get_config(fmt_nsd_catalog_xpath.format(project=quoted_key(project_name)))
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
)))
161 nsrs
= nsr_opdata
.nsr
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)
168 standby_lp_node_obj
.collect_data()
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
)
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
)
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
)
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
)
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
)
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':
204 logger
.debug('Deleting project {}'.format(project_name
))
205 rift
.auto
.mano
.delete_project(rw_conman_proxy
, project_name
)
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
):
214 logger
.debug('Collecting data for host {}'.format(standby_lp_node_obj
.host
))
215 standby_lp_node_obj
.collect_data()
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.
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
)
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)
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()
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
)
238 def test_delete_default_project(self
, rw_active_conman_proxy
):
239 rift
.auto
.mano
.delete_project(rw_active_conman_proxy
, 'default')
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
]
246 user_name_pfx
= 'user_ha_'
247 original_test_users_list
= [user_name_pfx
+str(idx
) for idx
in range(1,9)]
249 assert set(original_test_users_list
).issubset(current_users_list
)
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
)))
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