def test_workflow_gets_triggered_with_isstarted_check_turned_off(self): self.launch_deployment('dsl/isstarted_check_turned_off.yaml') execute_workflow('uninstall', self.deployment.id) self._publish_heart_beat_event() self._wait_for_event_expiration() self.wait_for_executions(self.NUM_OF_INITIAL_WORKFLOWS + 2) self._wait_for_terminated_execution(workflow_id='auto_heal_workflow')
def test_script_mapping(self): dsl_path = resource('dsl/test_script_mapping.yaml') deployment, _ = deploy(dsl_path) execute_workflow('workflow', deployment.id) data = self.get_plugin_data(plugin_name='script', deployment_id=deployment.id) self.assertEqual(data['op1_called_with_property'], 'op2_called') self.assertEqual(data['op2_prop'], 'op2_value')
def _test_custom_workflow(self, workflow, error_expected=False): deployment = deploy(resource("dsl/basic_task_not_exist.yaml")) try: execute_workflow(workflow, deployment.id) if error_expected: self.fail('RuntimeError expected') except RuntimeError as e: if not error_expected: self.fail('Success expected. error message: {0}'.format(e)) self.assertIn(self.AGENT_ALIVE_FAIL, str(e))
def test_modification_operations(self): dsl_path = resource("dsl/deployment_modification_operations.yaml") deployment, _ = deploy(dsl_path) deployment_id = deployment.id execute_workflow('deployment_modification', deployment_id) invocations = self.get_plugin_data( 'testmockoperations', deployment_id)['mock_operation_invocation'] self.assertEqual(1, len([i for i in invocations if i['operation'] == 'create'])) self.assertEqual(2, len([i for i in invocations if i['operation'] == 'preconfigure'])) self.assertEqual(2, len([i for i in invocations if i['operation'] == 'preconfigure'])) configure_invocations = [i for i in invocations if i['operation'] == 'configure'] self.assertEqual(1, len(configure_invocations)) self.assertEqual(1, len(configure_invocations[0]['target_ids'])) start_invocations = [i for i in invocations if i['operation'] == 'start'] self.assertEqual(1, len(start_invocations)) self.assertEqual(2, len(start_invocations[0]['target_ids']))
def test_script_mapping_to_deployment_resource(self): dsl_path = resource('dsl/test_script_mapping.yaml') deployment, _ = deploy(dsl_path) workflow_script_path = resource('dsl/scripts/workflows/workflow.py') with open(workflow_script_path, 'r') as f: workflow_script_content = f.read() deployment_folder = ('/opt/manager/resources/deployments/{0}'.format( deployment.id)) workflow_folder = os.path.join(deployment_folder, 'scripts/workflows') try: self.execute_on_manager('mkdir -p {0}'.format(workflow_folder)) deployment_workflow_script_path = os.path.join( workflow_folder, 'workflow.py') self.logger.info('Writing workflow.py to: {0}'.format( deployment_workflow_script_path)) with tempfile.NamedTemporaryFile() as f: f.write(workflow_script_content) f.write(os.linesep) f.write("instance.execute_operation('test.op3')") f.write(os.linesep) f.flush() self.copy_file_to_manager( source=f.name, target=deployment_workflow_script_path) self.execute_on_manager( 'chmod 644 {0}'.format(deployment_workflow_script_path)) execute_workflow('workflow', deployment.id) data = self.get_plugin_data(plugin_name='script', deployment_id=deployment.id) self.assertEqual(data['op1_called_with_property'], 'op2_called') self.assertEqual(data['op2_prop'], 'op2_value') self.assertIn('op3_called', data) finally: self.execute_on_manager('rm -rf {0}'.format(deployment_folder))
def test_executions_sort(self): deployment = deploy(resource('dsl/sort.yaml')) for i in range(5): execute_workflow('install', deployment.id) execute_workflow('uninstall', deployment.id) self._test_sort('executions', ['deployment_id', '-status'])
def _test_deployment_modification(self, modified_nodes, expected_compute, expected_db, expected_webserver, modification_type, expected_total, deployment_id=None, rollback=False): if not deployment_id: dsl_path = resource("dsl/deployment_modification.yaml") test_id = str(uuid.uuid4()) deployment, _ = deploy(dsl_path, deployment_id=test_id, blueprint_id='b_{0}'.format(test_id)) deployment_id = deployment.id nodes_before_modification = { node.id: node for node in self.client.nodes.list(deployment_id) } before_modifications = self.client.deployment_modifications.list( deployment_id) workflow_id = 'deployment_modification_{0}'.format( 'rollback' if rollback else 'finish') execution = execute_workflow( workflow_id, deployment_id, parameters={'nodes': modified_nodes}) after_modifications = self.client.deployment_modifications.list( deployment_id) new_modifications = [ m for m in after_modifications if m.id not in [m2.id for m2 in before_modifications]] self.assertEqual(len(new_modifications), 1) modification = list(new_modifications)[0] self.assertEqual(self.client.deployment_modifications.get( modification.id), modification) expected_status = DeploymentModification.ROLLEDBACK if rollback \ else DeploymentModification.FINISHED self.assertEqual(modification.status, expected_status) self.assertEqual(modification.deployment_id, deployment_id) self.assertEqual(modification.modified_nodes, modified_nodes) self.assertDictContainsSubset({ 'workflow_id': workflow_id, 'execution_id': execution.id, 'deployment_id': deployment_id, 'blueprint_id': 'b_{0}'.format(deployment_id)}, modification.context) created_at = dateutil.parser.parse(modification.created_at) ended_at = dateutil.parser.parse(modification.ended_at) self.assertTrue(created_at <= ended_at) for node_id, modified_node in modified_nodes.items(): node = self.client.nodes.get(deployment_id, node_id) if rollback: self.assertEqual( node.planned_number_of_instances, nodes_before_modification[ node.id].planned_number_of_instances) self.assertEqual( node.number_of_instances, nodes_before_modification[ node.id].number_of_instances) else: self.assertEqual(node.planned_number_of_instances, modified_node['instances']) self.assertEqual(node.number_of_instances, modified_node['instances']) state = self.get_plugin_data('testmockoperations', deployment_id)['state'] compute_instances = self._get_instances(state, 'compute') db_instances = self._get_instances(state, 'db') webserver_instances = self._get_instances(state, 'webserver') # existence self.assertEqual(expected_compute['existence'], len(compute_instances)) self.assertEqual(expected_db['existence'], len(db_instances)) self.assertEqual(expected_webserver['existence'], len(webserver_instances)) # modification self.assertEqual(expected_compute['modification'], len([i for i in compute_instances if i['modification'] == modification_type])) self.assertEqual(expected_db['modification'], len([i for i in db_instances if i['modification'] == modification_type])) self.assertEqual(expected_webserver['modification'], len([i for i in webserver_instances if i['modification'] == modification_type])) # relationships if compute_instances: self.assertEqual(expected_compute['relationships'], len(compute_instances[0]['relationships'])) if db_instances: self.assertEqual(expected_db['relationships'], len(db_instances[0]['relationships'])) if webserver_instances: self.assertEqual(expected_webserver['relationships'], len(webserver_instances[0]['relationships'])) node_instances = self.client.node_instances.list(deployment_id) self.assertEqual(expected_total, len(node_instances)) for node_id, modification in modified_nodes.items(): if rollback: self.assertEqual( nodes_before_modification[ node_id].number_of_instances, self.client.nodes.get( deployment_id, node_id).number_of_instances) else: self.assertEqual( modification['instances'], self.client.nodes.get( deployment_id, node_id).number_of_instances) for node_instance in node_instances: relationships_count = len(node_instance.relationships) if node_instance.node_id == 'compute': self.assertEqual(relationships_count, expected_compute['total_relationships']) if node_instance.node_id == 'db': self.assertEqual(relationships_count, expected_db['total_relationships']) if node_instance.node_id == 'webserver': self.assertEqual(relationships_count, expected_webserver['total_relationships']) return deployment_id
def scale(self, parameters): execute_workflow('scale', self.deployment_id, parameters=parameters) return self.expectations()
def test_autoheal_doesnt_get_triggered_after_regular_uninstall(self): self.launch_deployment(self.SIMPLE_AUTOHEAL_POLICY_YAML) execute_workflow('uninstall', self.deployment.id) self._publish_heart_beat_event() self._wait_for_event_expiration() self.wait_for_executions(self.NUM_OF_INITIAL_WORKFLOWS + 1)
def test_execution_logging(self): blueprint_path = resource('dsl/execution_logging.yaml') deployment, _ = deploy(blueprint_path) for user_cause in [False, True]: with self.assertRaises(RuntimeError): execute_workflow( 'execute_operation', deployment_id=deployment.id, parameters={'operation': 'test.op', 'operation_kwargs': {'user_cause': user_cause}} ) executions = self.client.executions.list( deployment_id=deployment.id, workflow_id='execute_operation').items no_user_cause_ex_id = [ e for e in executions if not e.parameters['operation_kwargs'].get('user_cause')][0].id user_cause_ex_id = [ e for e in executions if e.parameters['operation_kwargs'].get('user_cause')][0].id self.do_assertions(self._wait_for_end_events, execution_ids=[no_user_cause_ex_id, user_cause_ex_id], timeout=120) def assert_output(verbosity, expect_debug, expect_traceback, expect_rest_logs): events = self.cfy.events.list( verbosity, execution_id=no_user_cause_ex_id).stdout # When running tests locally (not CI), events returned by the CLI # maybe colored, depending on his configuration so we strip ansi # escape sequences from retrieved events. events = ansi_escape.sub('', events) assert_in = self.assertIn assert_not_in = self.assertNotIn assert_in('INFO: INFO_MESSAGE', events) assert_in('Task failed', events) assert_in('ERROR_MESSAGE', events) debug_assert = assert_in if expect_debug else assert_not_in debug_assert('DEBUG: DEBUG_MESSAGE', events) trace_assert = assert_in if expect_traceback else assert_not_in trace_assert('NonRecoverableError: ERROR_MESSAGE', events) assert_not_in('Causes', events) assert_not_in('RuntimeError: ERROR_MESSAGE', events) rest_assert = assert_in if expect_rest_logs else assert_not_in rest_assert('Sending request:', events) user_cause_events = self.cfy.events.list( verbosity, execution_id=user_cause_ex_id, ) causes_assert = assert_in if expect_traceback else assert_not_in causes_assert('Causes', user_cause_events) causes_assert('RuntimeError: ERROR_MESSAGE', user_cause_events) assert_output(verbosity=[], # sh handles '' as an argument, but not [] expect_traceback=False, expect_debug=False, expect_rest_logs=False) assert_output(verbosity='-v', expect_traceback=True, expect_debug=False, expect_rest_logs=False) assert_output(verbosity='-vv', expect_traceback=True, expect_debug=True, expect_rest_logs=False) assert_output(verbosity='-vvv', expect_traceback=True, expect_debug=True, expect_rest_logs=True)