def reassign_node_with_empty_body(self): """Test reassign node with empty body Scenario: 1. Revert snapshot "upgrade_ha_ceph_for_all_ubuntu_neutron_vlan" 2. Clone cluster 3. Reassign node with empty POST body 4. Check status code: 400 """ if not self.env.d_env.has_snapshot(self.snapshot): raise SkipTest('Snapshot {} not found'.format(self.snapshot)) self.env.revert_snapshot(self.snapshot) cluster_id = self.fuel_web.get_last_created_cluster() cluster = self.fuel_web.client.get_cluster(cluster_id) release_id = self.fuel_web.get_next_deployable_release_id( cluster["release_id"] ) data = { "name": "new_test_cluster", "release_id": release_id } cloned_cluster = self.fuel_web.client.clone_environment( cluster_id, data) try: self.fuel_web.client.reassign_node(cloned_cluster["id"], None) except HTTPError as e: assert_equal(400, e.code) else: fail("Doesn't raise HTTP 400 error on request" "to reassigning node with empty body")
def test_node_get_obm_invalid_node_id(self): """Test that PUT:/api/2.0/:id/obm returns 404 with invalid node ID""" try: Api().nodes_get_obms_by_node_id(identifier='invalid_ID') fail(message='did not raise exception') except rest.ApiException as e: assert_equal(404, e.status, message='unexpected response {0}, expected 404'.format(e.status))
def reassign_node_to_nonexistent_cluster(self): """Test reassign node to nonexistent cluster Scenario: 1. Revert snapshot "upgrade_ha_ceph_for_all_ubuntu_neutron_vlan" 2. Reassign node to nonexistent cluster 3. Check status code: 404 """ if not self.env.d_env.has_snapshot(self.snapshot): raise SkipTest('Snapshot {} not found'.format(self.snapshot)) self.env.revert_snapshot(self.snapshot) cluster_id = self.fuel_web.get_last_created_cluster() controller_node = self.fuel_web.get_nailgun_cluster_nodes_by_roles( cluster_id, ['controller'])[0] data = { "node_id": controller_node["id"] } try: self.fuel_web.client.reassign_node(123456, data) except HTTPError as e: assert_equal(404, e.code) else: fail("Doesn't rise HTTP 404 error" "while reassigning" "the node with id {0}" "to non-existing" "cluster 123456".format(controller_node["id"]))
def test_delete(self): if do_not_delete_instance(): CONFIG.get_report().log("TESTS_DO_NOT_DELETE_INSTANCE=True was " "specified, skipping delete...") raise SkipTest("TESTS_DO_NOT_DELETE_INSTANCE was specified.") global dbaas if not hasattr(instance_info, "initial_result"): raise SkipTest("Instance was never created, skipping test...") # Update the report so the logs inside the instance will be saved. CONFIG.get_report().update() dbaas.instances.delete(instance_info.id) instance_info.deleted_at = timeutils.utcnow().isoformat() attempts = 0 try: time.sleep(1) result = True while result is not None: attempts += 1 time.sleep(1) result = dbaas.instances.get(instance_info.id) assert_equal(200, dbaas.last_http_code) assert_equal("SHUTDOWN", result.status) except exceptions.NotFound: pass except Exception as ex: fail("A failure occured when trying to GET instance %s for the %d" " time: %s" % (str(instance_info.id), attempts, str(ex)))
def install_windowsServer2012(self, version, nodes=[], options=None): graph_name = 'Graph.InstallWindowsServer' os_repo = defaults.get('RACKHD_SMB_WINDOWS_REPO_PATH', None) if None == os_repo: fail('user must set RACKHD_SMB_WINDOWS_REPO_PATH') body = options if body == None: # The value of the productkey below is not a valid product key. It is a KMS client key that was generated to run the workflows without requiring a real product key. This key is # available to public on the Microsoft site. body = { 'options': { 'defaults': { 'productkey': 'D2N9P-3P6X9-2R39C-7RTCD-MDVJX', 'smbUser': defaults.get('RACKHD_SMB_USER' , 'onrack'), 'smbPassword': defaults.get('RACKHD_SMB_PASSWORD' , 'onrack'), 'completionUri': 'winpe-kickstart.ps1', 'smbRepo': os_repo, 'repo' : defaults.get('RACKHD_WINPE_REPO_PATH', \ self.__base + '/repo/winpe') }, 'firstboot-callback-uri-wait':{ 'completionUri': 'renasar-ansible.pub' } } } self.__post_workflow(graph_name, nodes, body)
def test_clone_with_incorrect_release_id(self): """Test clone with incorrect release id in POST body Scenario: 1. Revert snapshot "upgrade_ha_ceph_for_all_ubuntu_neutron_vlan" 2. Try to clone environment with incorrect release id in POST body 3. Check status code """ if not self.env.d_env.has_snapshot(self.snapshot): raise SkipTest('Snapshot {} not found'.format(self.snapshot)) self.env.revert_snapshot(self.snapshot, skip_timesync=True) cluster_id = self.fuel_web.get_last_created_cluster() data = { "name": "new_test_cluster", "release_id": "djigurda" } try: self.fuel_web.client.clone_environment(cluster_id, data) except HTTPError as e: assert_equal(400, e.code) else: fail("Doesn't raise needed error")
def _delete_instance(self): """Deletes an instance. This call polls the REST API until NotFound is raised. The entire time it also makes sure that the API returns SHUTDOWN. """ # Update the report so the logs inside the instance will be saved. report.update() self.dbaas.instances.delete(self.id) attempts = 0 try: time.sleep(1) result = True while result is not None: time.sleep(2) attempts += 1 result = None result = self.dbaas.instances.get(self.id) assert_equal(dbaas_mapping[power_state.SHUTDOWN], result.status) except exception.NotFound: pass except NotFound404: pass except Exception as ex: fail("A failure occured when trying to GET instance %s" " for the %d time: %s" % (str(self.id), attempts, str(ex))) self._check_vifs_cleaned()
def install_windowsServer2012(self, version, payloadFile, nodes=[]): graph_name = 'Graph.InstallWindowsServer' os_repo = defaults.get('RACKHD_SMB_WINDOWS_REPO_PATH', None) if None == os_repo: fail('user must set RACKHD_SMB_WINDOWS_REPO_PATH') # load the payload from the specified file body = {} body = self.__get_os_install_payload(payloadFile) # The value of the productkey below is not a valid product key. It is a KMS client # key that was generated to run the workflows without requiring a real product key. # This key is available to public on the Microsoft site. extra_options = { 'options': { 'defaults': { 'productkey': 'D2N9P-3P6X9-2R39C-7RTCD-MDVJX', 'smbUser': defaults.get('RACKHD_SMB_USER' , 'onrack'), 'smbPassword': defaults.get('RACKHD_SMB_PASSWORD' , 'onrack'), 'smbRepo': os_repo, 'repo' : defaults.get('RACKHD_WINPE_REPO_PATH', \ self.__base + '/repo/winpe') } } } self.__update_body(body, extra_options) new_body = dumps(body) self.__post_workflow(graph_name, nodes, body) if 'networkDevices' in body['options']['defaults']: self.__test_link_up(body['options']['defaults']['networkDevices'])
def _send(self): original_queue_count = self.rabbit.get_queue_items() @time_out(5) def send_msg_with_timeout(): self.rabbit.declare_queue(topic_name()) version = rpc.call(context.get_admin_context(), topic_name(), {"method": "version", "args": {"package_name": "dpkg"} }) return { "status":"good", "version": version } try: return send_msg_with_timeout() except Exception as e: # If the Python side works, we should at least see an item waiting # in the queue. # Whether we see this determines if the failure to send is Nova's # fault or Sneaky Petes. print("Error making RPC call: %s" % e) print("Original queue count = %d, " "current count = %d" % (original_queue_count, self.rabbit.get_queue_items())) # In the Kombu driver there is a bug where after restarting rabbit # the first message to be sent fails with a broken pipe. So here we # tolerate one such bug but no more. if not isinstance(e, TimeoutError): self.send_after_reconnect_errors += 1 if self.send_after_reconnect_errors > self.tolerated_send_errors: fail("Exception while making RPC call: %s" % e) if self.rabbit.get_queue_items() > original_queue_count: return { "status":"bad", "blame":"agent"} else: return { "status":"bad", "blame":"host"}
def _send_unsuccessfully(self): original_queue_count = self.rabbit.get_queue_items(topic_name()) or 0 try: self._send_msg_with_timeout() fail("Expected the message to fail, but it succeeded.") except Exception as e: # If the Python side works, we should at least see an item waiting # in the queue. # Whether we see this determines if the failure to send is Nova's # fault or Sneaky Petes. print("Error making RPC call: %s" % e) print("Original queue count = %d, " "current count = %d" % (original_queue_count, self.rabbit.get_queue_items(topic_name()) or 0)) #TODO: Erase the commented section below: # In the Kombu driver there is a bug where after restarting rabbit # the first message to be sent fails with a broken pipe. So here we # tolerate one such bug but no more. if not isinstance(e, TimeoutError): self.send_after_reconnect_errors += 1 errors = self.send_after_reconnect_errors if errors > self.tolerated_send_errors: fail("Exception while making RPC call: %s" % e) if ((self.rabbit.get_queue_items(topic_name()) or 0) > original_queue_count): return {"status": "bad", "blame": "agent"} else: return {"status": "bad", "blame": "host"}
def test_database_restored_incremental(self): try: self._poll(incremental_restore_instance_id, incremental_db) assert_equal(total_num_dbs, len(instance_info.dbaas.databases.list( incremental_restore_instance_id))) except exception.PollTimeOut: fail('Timed out')
def test_delete(self): if do_not_delete_instance(): report.log("TESTS_DO_NOT_DELETE_INSTANCE=True was specified, " "skipping delete...") raise SkipTest("TESTS_DO_NOT_DELETE_INSTANCE was specified.") global dbaas if not hasattr(instance_info, "initial_result"): raise SkipTest("Instance was never created, skipping test...") if WHITE_BOX: # Change this code to get the volume using the API. # That way we can keep it while keeping it black box. admin_context = context.get_admin_context() volumes = db.volume_get_all_by_instance(admin_context(), instance_info.local_id) instance_info.volume_id = volumes[0].id # Update the report so the logs inside the instance will be saved. report.update() dbaas.instances.delete(instance_info.id) attempts = 0 try: time.sleep(1) result = True while result is not None: attempts += 1 result = dbaas.instances.get(instance_info.id) assert_equal(200, dbaas.last_http_code) assert_equal("SHUTDOWN", result.status) except exceptions.NotFound: pass except Exception as ex: fail("A failure occured when trying to GET instance %s for the %d " "time: %s" % (str(instance_info.id), attempts, str(ex)))
def assert_mysql_connection_fails(user_name, password, ip): engine = init_engine(user_name, password, ip) try: engine.connect() fail("Should have failed to connect.") except OperationalError as oe: assert_mysql_failure_msg_was_permissions_issue(oe.message)
def test_double_clone_environment(self): """Test double clone environment Scenario: 1. Revert snapshot "upgrade_ha_ceph_for_all_ubuntu_neutron_vlan" 2. Clone cluster 3. Clone cluster again 4. Check status code """ if not self.env.d_env.has_snapshot(self.snapshot): raise SkipTest('Snapshot {} not found'.format(self.snapshot)) self.env.revert_snapshot(self.snapshot, skip_timesync=True) cluster_id = self.fuel_web.get_last_created_cluster() cluster = self.fuel_web.client.get_cluster(cluster_id) release_id = self.fuel_web.get_next_deployable_release_id( cluster["release_id"]) data = { "name": "new_test_cluster", "release_id": release_id } self.fuel_web.client.clone_environment(cluster_id, data) try: self.fuel_web.client.clone_environment(cluster_id, data) except HTTPError as e: assert_equal(400, e.code) else: fail("Doesn't raise needed error")
def reassign_node_to_nonexistent_cluster(self): """Test reassign node to nonexistent cluster Scenario: 1. Revert snapshot "upgrade_ceph_ha_restore" 2. Reassign node to nonexistent cluster 3. Check status code: 404 """ if not self.env.d_env.has_snapshot(self.snapshot): raise SkipTest('Snapshot {} not found'.format(self.snapshot)) self.env.revert_snapshot(self.snapshot) cluster_id = self.fuel_web.get_last_created_cluster() controller_node = self.fuel_web.get_nailgun_cluster_nodes_by_roles( cluster_id, ['controller'])[0] data = { "nodes_ids": [controller_node["id"]] } try: self.fuel_web.client.reassign_node(123456, data) except NotFound: logger.debug('Got NotFound error as expected') else: fail("Doesn't rise HTTP 404 error" "while reassigning" "the node with id {0}" "to non-existing" "cluster 123456".format(controller_node["id"]))
def test_single_failure_is_presented(self): try: with Check() as check: check.equal(4, 6) fail("Expected an assertion!") except ASSERTION_ERROR as ae: assert_true("4 != 6" in str(ae), str(ae))
def __call__(self, mgmt_instance): """ Given an instance ID and ip address, confirm that the proper DNS record was stored in Designate or some other DNS system. """ entry = FakeDnsInstanceEntryFactory().create_entry(mgmt_instance.id) # Confirm DNS entry shown to user is what we expect. assert_equal(entry.name, mgmt_instance.hostname) hostname = entry.name for i in ENTRIES: print(i) print("\t%s" % ENTRIES[i]) assert_true(hostname in ENTRIES, "Hostname %s not found in DNS entries!" % hostname) entry = ENTRIES[hostname] # See if the ip address assigned to the record is what we expect. # This isn't perfect, but for Fake Mode its good enough. If we # really want to know exactly what it should be then we should restore # the ability to return the IP from the API as well as a hostname, # since that lines up to the DnsEntry's content field. ip_addresses = mgmt_instance.server['addresses'] for network_name, ip_list in ip_addresses.items(): for ip in ip_list: if entry.content == ip['addr']: return fail("Couldn't find IP address %s among these values: %s" % (entry.content, ip_addresses))
def test_clone_with_nonexistent_release_id(self): """Test clone with nonexistent release id in POST body Scenario: 1. Revert snapshot "upgrade_ha_ceph_for_all_ubuntu_neutron_vlan" 2. Try to clone environment with nonexistent release id in POST body 3. Check status code """ if not self.env.d_env.has_snapshot( "upgrade_ha_ceph_for_all_ubuntu_neutron_vlan"): raise SkipTest() self.env.revert_snapshot("upgrade_ha_ceph_for_all_ubuntu_neutron_vlan", skip_timesync=True) cluster_id = self.fuel_web.get_last_created_cluster() data = { "name": "new_test_cluster", "release_id": 123456 } try: self.fuel_web.client.clone_environment(cluster_id, data) except urllib2.HTTPError as e: assert_equal(404, e.code) else: fail("Doesn't raise needed error")
def test_clone_wo_name_in_body(self): """Test clone without name in POST body Scenario: 1. Revert snapshot "upgrade_ha_ceph_for_all_ubuntu_neutron_vlan" 2. Try to clone environment without name in POST body 3. Check status code """ if not self.env.d_env.has_snapshot( "upgrade_ha_ceph_for_all_ubuntu_neutron_vlan"): raise SkipTest() self.env.revert_snapshot("upgrade_ha_ceph_for_all_ubuntu_neutron_vlan", skip_timesync=True) cluster_id = self.fuel_web.get_last_created_cluster() cluster = self.fuel_web.client.get_cluster(cluster_id) release_id = self.fuel_web.get_next_deployable_release_id( cluster["release_id"]) data = { "release_id": release_id } try: self.fuel_web.client.clone_environment(cluster_id, data) except urllib2.HTTPError as e: assert_equal(400, e.code) else: fail("Doesn't raise needed error")
def test_double_clone_environment(self): """Test double clone environment Scenario: 1. Revert snapshot "upgrade_ceph_ha_restore" 2. Clone cluster 3. Clone cluster again 4. Check status code """ if not self.env.d_env.has_snapshot(self.snapshot): raise SkipTest('Snapshot {} not found'.format(self.snapshot)) self.env.revert_snapshot(self.snapshot) cluster_id = self.fuel_web.get_last_created_cluster() cluster = self.fuel_web.client.get_cluster(cluster_id) release_id = self.fuel_web.get_next_deployable_release_id( cluster["release_id"]) data = { "name": "new_test_cluster", "release_id": release_id } self.fuel_web.client.clone_environment(cluster_id, data) try: self.fuel_web.client.clone_environment(cluster_id, data) except BadRequest: logger.debug('exceptions.BadRequest received as expected') else: fail("Doesn't raise needed error")
def test_clone_with_incorrect_release_id(self): """Test clone with incorrect release id in POST body Scenario: 1. Revert snapshot "upgrade_ceph_ha_restore" 2. Try to clone environment with incorrect release id in POST body 3. Check status code """ if not self.env.d_env.has_snapshot(self.snapshot): raise SkipTest('Snapshot {} not found'.format(self.snapshot)) self.env.revert_snapshot(self.snapshot) cluster_id = self.fuel_web.get_last_created_cluster() data = { "name": "new_test_cluster", "release_id": "djigurda" } try: self.fuel_web.client.clone_environment(cluster_id, data) except BadRequest: logger.debug('exceptions.BadRequest received as expected') else: fail("Doesn't raise needed error")
def _check_connection(self, username, password): if not FAKE: util.assert_mysql_connection_fails(username, password, instance_info.user_ip) # Also determine the db is gone via API. result = self.dbaas.users.list(instance_info.id) for item in result: if item.name == username: fail("User %s was not deleted." % user)
def test_instance_status_deleted_in_db(self): mgmt_details = dbaas_admin.management.index(deleted=True) for instance in mgmt_details: if instance.id == instance_info.id: assert_equal(instance.service_status, 'DELETED') break else: fail("Could not find instance %s" % instance_info.id)
def check_resize_status(): instance = instance_info.dbaas.instances.get(instance_info.id) if instance.status == "ACTIVE": return True elif instance.status == "RESIZE": return False else: fail("Status should not be %s" % instance.status)
def _send_allow_for_host_bug(self): while True: result = self._send() if result["status"] == "good": return result["version"] else: if result["blame"] == "agent": fail("Nova Host put a message on the queue but the agent " "never responded.")
def test_instance_status_after_double_migrate(self): """ This test is to verify that instance status returned is more informative than 'Status is {}'. There are several ways to replicate this error. A double migration is just one of them but since this is a known way to recreate that error we will use it here to be sure that the error is fixed. The actual code lives in trove/instance/models.py in _validate_can_perform_action() """ # TODO(imsplitbit): test other instances where this issue could be # replicated. Resizing a resized instance awaiting confirmation # can be used as another case. This all boils back to the same # piece of code so I'm not sure if it's relevant or not but could # be done. size = None if VOLUME_SUPPORT: size = {'size': 5} result = self.client.instances.create('testbox', instance_info.dbaas_flavor_href, size) id = result.id self.instances.append(id) def verify_instance_is_active(): result = self.client.instances.get(id) print(result.status) return result.status == 'ACTIVE' def attempt_migrate(): print('attempting migration') try: self.mgmt.migrate(id) except exceptions.UnprocessableEntity: return False return True # Timing necessary to make the error occur poll_until(verify_instance_is_active, time_out=120, sleep_time=1) try: poll_until(attempt_migrate, time_out=10, sleep_time=1) except rd_exceptions.PollTimeOut: fail('Initial migration timed out') try: self.mgmt.migrate(id) except exceptions.UnprocessableEntity as err: assert('status was {}' not in err.message) else: # If we are trying to test what status is returned when an # instance is in a confirm_resize state and another # migration is attempted then we also need to # assert that an exception is raised when running migrate. # If one is not then we aren't able to test what the # returned status is in the exception message. fail('UnprocessableEntity was not thrown')
def test_volume_resize_success_databases(self): databases = instance_info.dbaas.databases.list(instance_info.id) db_list = [] for database in databases: db_list.append(database.name) for name in self.expected_dbs: if not name in db_list: fail("Database %s was not found after the volume resize. " "Returned list: %s" % (name, databases))
def assert_user_delete(self, instance_id, user_name, expected_http_code): self.rd_client.users.delete(instance_id, user_name) self.assert_client_code(expected_http_code) self.assert_raises(exceptions.NotFound, 404, self.rd_client.users.get, instance_id, user_name, "%") for user in self.rd_client.users.list(instance_id): if user.name == user_name: asserts.fail("User still listed after delete: %s" % user_name)
def _check_connection(self, username, password): if not FAKE: util.mysql_connection().assert_fails(username, password, instance_info.get_address()) # Also determine the db is gone via API. result = self.dbaas.users.list(instance_info.id) assert_equal(200, self.dbaas.last_http_code) for item in result: if item.name == username: fail("User %s was not deleted." % username)
def assert_file_matches(original): expected = original.split('\n') # Remove the last item which will look like a duplicated # file ending newline expected.pop() diff = '\n'.join(goofy_diff(expected, actual)) if diff: fail('Error: output files differ for %s:\n%s' % (filename, diff))
def assert_fails(self, ip, user_name, password): from trove.tests.util import mysql try: with mysql.create_mysql_connection(ip, user_name, password): pass fail("Should have failed to connect: mysql --host %s -u %s -p%s" % (ip, user_name, password)) except mysql.MySqlPermissionsFailure: return # Good, this is what we wanted. except mysql.MySqlConnectionFailure as mcf: fail("Expected to see permissions failure. Instead got message:" "%s" % mcf.message)
def test_remove_user(self): """ Testing DELETE user """ Api().remove_user(name='funtest-name') Api().list_users() users = self.__get_data() LOG.debug(users, json=True) found = False for user in users: if user.get('username') == 'funtest-name': found = True if found: fail(message='newly created user was not removed')
def _get_user_count(server_info): cmd = ( 'docker exec -e MYSQL_PWD=$(sudo cat /var/lib/mysql/conf.d/root.cnf | ' 'grep password | awk "{print \$3}") database mysql -uroot -N -e ' '"select count(*) from mysql.user where user like \\"slave_%\\""') server = create_server_connection(server_info.id) try: stdout = server.execute(cmd) return int(stdout.rstrip()) except Exception as e: fail("Failed to execute command: %s, error: %s" % (cmd, str(e)))
def assert_unprocessable(func, *args): try: func(*args) # If the exception didn't get raised, but the instance is still in # the BUILDING state, that's a bug. result = dbaas.instances.get(instance_info.id) if result.status == "BUILD": fail("When an instance is being built, this function should " "always raise UnprocessableEntity.") except exceptions.UnprocessableEntity: assert_equal(422, dbaas.last_http_code) pass # Good
def test_node_put_obm_invalid_node_id(self): """Test that PUT:/api/2.0/:id/obm returns 404 with invalid node ID""" try: Api().nodes_put_obms_by_node_id(identifier='invalid_ID', body=self.__test_obm) fail(message='did not raise exception') except rest.ApiException as e: assert_equal( 404, e.status, message='unexpected response {0}, expected 404'.format( e.status))
def run_workflow_tasks(self, tasks, timeout_sec): def thread_func(worker, id): worker.start() tasks = self.__tasks if tasks is None else tasks worker_tasks = WorkerTasks(tasks=self.__tasks, func=thread_func) worker_tasks.run() worker_tasks.wait_for_completion(timeout_sec=timeout_sec) for task in tasks: if task.timeout: LOG.error('Timeout for {0}, node {1}'.format(self.__graph_name, task.id)) self.__graph_status.append('failed') if 'failed' in self.__graph_status: fail('Failure running {0}'.format(self.__graph_name))
def test_multiple_failures_are_presented(self): try: with Check() as c: c.equal(2, 27) c.equal("BEE", "BEE") c.equal(39, 37) c.equal("CAT", "RAT") fail("Expected an assertion!") except ASSERTION_ERROR as ae: msg = str(ae) assert_true("2 != 27" in msg, msg) assert_true("39 != 37" in msg, msg) assert_true("'CAT' != 'RAT'" in msg, msg)
def test_get_registry_file_invalid(self): """ Testing GET /Registries/{identifier} 404s properly """ self.__membersList = self.__registryList.get('Members') assert_not_equal(None, self.__membersList) for member in self.__membersList: dataId = member.get('@odata.id') assert_not_equal(None,dataId) dataId = dataId.split('/redfish/v1/Registries/')[1] try: redfish().get_registry_file(dataId + '-invalid') fail(message='did not raise exception') except rest.ApiException as e: assert_equal(404, e.status, message='unexpected response {0}, expected 404'.format(e.status))
def check_slave_is_running(): server = create_server_connection(slave_instance.id) cmd = ("mysqladmin extended-status " "| awk '/Slave_running/{print $4}'") try: stdout = server.execute(cmd) stdout = stdout.rstrip() except Exception as e: fail("Failed to execute command %s, error: %s" % (cmd, str(e))) expected = b"ON" if running else b"OFF" return stdout == expected
def test_instance_status_after_double_migrate(self): """ This test is to verify that instance status returned is more informative than 'Status is {}'. There are several ways to replicate this error. A double migration is just one of them but since this is a known way to recreate that error we will use it here to be sure that the error is fixed. The actual code lives in reddwarf/instance/models.py in _validate_can_perform_action() """ # TODO(imsplitbit): test other instances where this issue could be # replicated. Resizing a resized instance awaiting confirmation # can be used as another case. This all boils back to the same # piece of code so I'm not sure if it's relevant or not but could # be done. result = self.client.instances.create('testbox', 1, {'size': 5}) id = result.id self.instances.append(id) def verify_instance_is_active(): result = self.client.instances.get(id) print result.status return result.status == 'ACTIVE' def attempt_migrate(): print 'attempting migration' try: self.mgmt.migrate(id) except exceptions.UnprocessableEntity: return False return True # Timing necessary to make the error occur poll_until(verify_instance_is_active, time_out=120, sleep_time=1) try: poll_until(attempt_migrate, time_out=10, sleep_time=1) except rd_exceptions.PollTimeOut: fail('Initial migration timed out') try: self.mgmt.migrate(id) except exceptions.UnprocessableEntity as err: assert('status was {}' not in err.message) else: # If we are trying to test what status is returned when an # instance is in a confirm_resize state and another # migration is attempted then we also need to # assert that an exception is raised when running migrate. # If one is not then we aren't able to test what the # returned status is in the exception message. fail('UnprocessableEntity was not thrown')
def test_post_systems_actions_reset(self): """ Testing POST /Systems/{identifier}/Actions/ComputerSystem.Reset """ self.__membersList = self.__systemsList.get('Members') assert_is_not_none(self.__membersList) assert_is_not_none(self.__resetActionTypes) for member in self.__membersList: actionsCompleted = 0 dataId = member.get('@odata.id') assert_not_equal(0, len(dataId)) dataId = dataId.split('/redfish/v1/Systems/')[1] for action in self.__resetActionTypes: if action == 'PushPowerButton': # skip manual test LOG.warning('skipping \"PushPowerButton\" reset action') continue LOG.info('testing reset action {0}'.format(action)) try: redfish().do_reset(dataId, {'reset_type': action}) except rest.ApiException as err: message = loads(err.body)['message'] if message == 'value not found in map': LOG.warning('{0} for \"{1}\", skipping..'.format( message, action)) continue else: raise (err) task = self.__get_data() taskId = task.get('@odata.id') assert_is_not_none(taskId) taskId = taskId.split('/redfish/v1/TaskService/Tasks/')[1] timeout = 20 while timeout > 0: redfish().get_task(taskId) taskInfo = self.__get_data() taskState = taskInfo.get('TaskState') taskStatus = taskInfo.get('TaskStatus') assert_is_not_none(taskState) assert_is_not_none(taskStatus) if taskState == "Completed" and \ taskStatus == "OK": actionsCompleted += 1 break LOG.warning('waiting for reset action {0} (state={1},status={2})' \ .format(action, taskState, taskStatus)) timeout -= 1 time.sleep(1) if timeout == 0: fail('timed out waiting for reset action {0}'.format( action)) if actionsCompleted == 0: fail('no reset actions were completed for id {0}'.format( dataId))
def mess_up_mysql(self): """Ruin MySQL's ability to restart.""" server = create_server_connection(self.instance_id, self.instance_mgmt_address) cmd_template = "sudo cp /dev/null /var/lib/mysql/data/ib_logfile%d" instance_info.dbaas_admin.management.stop(self.instance_id) for index in range(2): cmd = cmd_template % index try: server.execute(cmd) except Exception as e: asserts.fail("Failed to execute command %s, error: %s" % (cmd, str(e)))
def disable_master(self): if CONFIG.fake_mode: raise SkipTest("eject_replica_source not supported in fake mode") cmd = "sudo service trove-guestagent stop" server = create_server_connection(self._third_slave.id) try: stdout = server.execute(cmd) stdout = int(stdout.rstrip()) except Exception as e: fail("Failed to execute command %s, error: %s" % (cmd, str(e))) assert_equal(stdout, 1)
def test_modify_user(self): """ Testing modifying user information """ newuser = {'password': '******', 'role': 'ReadOnly'} Api().modify_user(name='funtest-name', body=newuser) Api().list_users() users = self.__get_data() LOG.debug(users, json=True) found = False for user in users: if 'funtest-name' == user.get('username'): found = True assert_equal(newuser.get('role'), user.get('role')) if not found: fail(message='newly modified user was not found')
def find_mysql_proc_on_instance(self): server = create_server_connection( self.instance_id, ip_address=self.instance_mgmt_address) cmd = "sudo ps acux | grep mysqld " \ "| grep -v mysqld_safe | awk '{print $2}'" try: stdout = server.execute(cmd) return int(stdout) except ValueError: return None except Exception as e: asserts.fail("Failed to execute command: %s, error: %s" % (cmd, str(e)))
def cpu_pinning_allocation(self): """Check errors for allocation of CPU for nova Scenario: 1. Revert snapshot "basic_env_for_numa_cpu_pinning" 2. Pin all node CPU and twice of it for the nova 3. Check status code: 400 Snapshot: cpu_pinning_allocation """ self.show_step(1) self.env.revert_snapshot("basic_env_for_numa_cpu_pinning") cluster_id = self.fuel_web.get_last_created_cluster() self.show_step(2) self.show_step(3) target_nodes = self.fuel_web.get_nailgun_cluster_nodes_by_roles( cluster_id, ['compute'], role_status='pending_roles') for compute in target_nodes: compute_cpu = compute['meta']['cpu']['total'] compute_config = self.fuel_web.client.get_node_attributes( compute['id']) compute_config['cpu_pinning']['nova']['value'] = compute_cpu try: self.fuel_web.client.upload_node_attributes( compute_config, compute['id']) except BadRequest: logger.debug('BadRequest received as expected') else: asserts.fail("Pinned all CPU on {0}, while expecting HTTP " "error on CPU value {1}".format( compute['ip'], compute_cpu)) compute_config['cpu_pinning']['nova']['value'] = compute_cpu * 2 try: self.fuel_web.client.upload_node_attributes( compute_config, compute['id']) except BadRequest: logger.debug('BadRequest received as expected') else: asserts.fail("Pinned all CPU on {0}, while expecting HTTP " "400 error on CPU value {1}".format( compute['ip'], compute_cpu * 2)) self.env.make_snapshot('cpu_pinning_allocation')
def test_slave_is_read_only(self): """test_slave_is_read_only""" cmd = ('docker exec -e MYSQL_PWD=$(sudo cat ' '/var/lib/mysql/conf.d/root.cnf | grep password | ' 'awk "{print \$3}") database mysql -uroot -NBq -e ' '"select @@read_only"') server = create_server_connection(slave_instance.id) try: stdout = server.execute(cmd) stdout = int(stdout.rstrip()) except Exception as e: fail("Failed to execute command %s, error: %s" % (cmd, str(e))) assert_equal(stdout, 1)
def resize_should_not_delete_users(self): """Resize should not delete users.""" # Resize has an incredibly weird bug where users are deleted after # a resize. The code below is an attempt to catch this while proceeding # with the rest of the test (note the use of runs_after). if USE_IP: self.connection.connect() if not self.connection.is_connected(): # Ok, this is def. a failure, but before we toss up an error # lets recreate to see how far we can get. report.log("Having to recreate the test_user! Resizing " "somehow killed it!") self.log_current_users() self.create_user() fail("Somehow, the resize made the test user disappear.")
def test_list_manager_ethernet_interfaces_invalid(self): """ Testing GET /Managers/{identifier}/EthernetInterfaces 404s properly """ for member in self.__managersList: dataId = member.get('@odata.id') assert_is_not_none(dataId) dataId = dataId.split('/redfish/v1/Managers/')[1] try: redfish().list_manager_ethernet_interfaces(dataId + '1') fail(message='did not raise exception') except rest.ApiException as e: assert_equal( 404, e.status, message='unexpected response {0}, expected 404'.format( e.status))
def find_nessus_address(self, nessus_net_name='admin', nessus_port=8834): admin_net_cidr = \ self.env.d_env.get_network(name=nessus_net_name).ip_network logger.info( "Scanning network '%s' (%s) for nessus service on port %d", nessus_net_name, admin_net_cidr, nessus_port) for address in netaddr.IPNetwork(admin_net_cidr).iter_hosts(): if tcp_ping(address.format(), nessus_port, timeout=1): return address.format() fail("No running nessus service found!")
def check_database_for_user(self, user, password, dbs): if not FAKE: # Make the real call to the database to check things. dblist = self.show_databases(user, password) for db in dbs: default_db = re.compile("[\w\n]*%s[\w\n]*" % db) if not default_db.match(dblist): fail("No match for db %s in dblist. %s :(" % (db, dblist)) # Confirm via API. result = self.dbaas.users.list(instance_info.id) for item in result: if item.name == user: break else: fail("User %s not added to collection." % user)
def _get_current_step(self): step_name = settings.UPGRADE_CUSTOM_STEP_NAME target_field = { 'backup': 'backup_snapshot_name', 'restore': 'restore_snapshot_name' } for item in self.upgrade_data: if not step_name == item['name']: continue if self.env.d_env.has_snapshot(item[target_field[item['action']]]): raise SkipTest("Step {!r} already executed".format(step_name)) else: return item fail("Can not find step {!r} in config file {!r}".format( step_name, settings.UPGRADE_TEST_TEMPLATE))
def __init__(self, instance_id): self.instance_id = instance_id req_admin = Requirements(is_admin=True) self.user = util.test_config.users.find_user(req_admin) self.dbaas_admin = util.create_dbaas_client(self.user) self.instance = self.dbaas_admin.management.show(self.instance_id) try: self.ip_address = [str(ip) for ip in self.instance.ip if netaddr.valid_ipv4(ip)][0] except Exception: fail("No IPV4 ip found") TROVE_TEST_SSH_USER = os.environ.get('TROVE_TEST_SSH_USER') if TROVE_TEST_SSH_USER and '@' not in self.ip_address: self.ip_address = TROVE_TEST_SSH_USER + '@' + self.ip_address
def check_slave_is_running(): server = create_server_connection(slave_instance.id) cmd = ('docker exec -e MYSQL_PWD=$(sudo cat ' '/var/lib/mysql/conf.d/root.cnf | grep password ' '| awk "{print \$3}") database mysql -uroot -N -e ' '"SELECT SERVICE_STATE FROM ' 'performance_schema.replication_connection_status"') try: stdout = server.execute(cmd) stdout = stdout.rstrip() except Exception as e: fail("Failed to execute command %s, error: %s" % (cmd, str(e))) expected = b"ON" if running else b"" return stdout == expected
def assert_output_matches(): if os.path.isfile(filename): with open(filename, 'r') as original_file: original = original_file.read() if empty: fail('Error: output missing in new snippet generation ' 'for %s. Old content follows:\n"""%s"""' % (filename, original)) elif filename.endswith('.json'): assert_json_matches(original) else: assert_file_matches(original) elif not empty: fail('Error: new file necessary where there was no file ' 'before. Filename=%s\nContent follows:\n"""%s"""' % (filename, output))
def test_if_set_then_func_should_not_inherit(self): from proboscis import test @test(enabled=False) class ExampleTest(object): @test(enabled=False) def test_1(self): pass for t in self.registry.tests: if t.home is ExampleTest: assert_false(t.info.enabled) elif t.home is get_method_function(ExampleTest.test_1): assert_false(t.info.enabled) else: fail("Unexpected test seen in iteration: %s" % t)
def test_get_schema_content_invalid(self): """ Testing GET /Schemas/en/{identifier} 404s properly """ assert_not_equal([], self.__locationUri) for member in self.__locationUri: assert_not_equal(None, member) dataId = member.split('/redfish/v1/SchemaStore/en/')[1] try: redfish().get_schema_content(dataId + '-invalid') fail(message='did not raise exception') except rest.ApiException as e: assert_equal( 404, e.status, message='unexpected response {0}, expected 404'.format( e.status)) break
def check_database_for_user(self, user, password, dbs): if not FAKE: # Make the real call to the database to check things. actual_list = self.show_databases(user, password) for db in dbs: assert_true( db in actual_list, "No match for db %s in dblist. %s :(" % (db, actual_list)) # Confirm via API. result = self.dbaas.users.list(instance_info.id) assert_equal(200, self.dbaas.last_http_code) for item in result: if item.name == user: break else: fail("User %s not added to collection." % user)
def test_get_session_info_invalid(self): """ Testing GET /SessionService/Sessions/{identifier} 404s properly""" assert_not_equal(None, self.__sessionList) for member in self.__sessionList: dataId = member.get('@odata.id') assert_not_equal(None, dataId) dataId = dataId.split('/redfish/v1/SessionService/Sessions/')[1] try: redfish().get_session_info(dataId + 'invalid') fail(message='did not raise exception') except rest.ApiException as e: assert_equal( 404, e.status, message='unexpected response {0}, expected 404'.format( e.status)) break
def test_if_not_set_on_parent_func_is_unaffected(self): from proboscis import test @test class ExampleTest(object): @test(runs_after_groups=["other_test"]) def test_1(self): pass for t in self.registry.tests: if t.home == ExampleTest: assert_equal(0, len(t.info.runs_after_groups)) elif t.home == get_method_function(ExampleTest.test_1): assert_equal(1, len(t.info.runs_after_groups)) assert_true("other_test" in t.info.runs_after_groups) else: fail("Unexpected test seen in iteration: %s" % t)