def test_simulate_policy_errors(self): def check_err(params, context, request, emsg): try: self.policy_model.simulate_action(params, context, request) self.assertFail() except webservice.DataModelException as e: self.assertIn(emsg, str(e)) context = {'policy_id': self.action_policy['name']} # Missing query body = { 'action_policy': self.action_policy['name'], 'sequence': 'q(1)' } check_err({}, context, helper.FakeRequest(body), 'Simulate requires parameters') # Invalid query body = { 'query': 'p(x', 'action_policy': self.action_policy['name'], 'sequence': 'q(1)' } check_err({}, context, helper.FakeRequest(body), 'Parse failure') # Multiple querys body = { 'query': 'p(x) q(x)', 'action_policy': self.action_policy['name'], 'sequence': 'q(1)' } check_err({}, context, helper.FakeRequest(body), 'more than 1 rule') # Missing action_policy body = {'query': 'p(x)', 'sequence': 'q(1)'} check_err({}, context, helper.FakeRequest(body), 'Simulate requires parameters') # Missing sequence body = {'query': 'p(x)', 'action_policy': self.action_policy['name']} check_err({}, context, helper.FakeRequest(body), 'Simulate requires parameters') # Syntactically invalid sequence body = { 'query': 'p(x)', 'action_policy': self.action_policy['name'], 'sequence': 'q(1' } check_err({}, context, helper.FakeRequest(body), 'Parse failure') # Semantically invalid sequence body = { 'query': 'p(x)', 'action_policy': self.action_policy['name'], 'sequence': 'r(1)' } # r is not an action check_err({}, context, helper.FakeRequest(body), 'non-action, non-update')
def test_simulate_invalid_policy(self): context = {'policy_id': 'invalid-policy'} request_body = { 'query': 'p(x)', 'action_policy': self.action_policy['name'], 'sequence': 'q(1)' } request = helper.FakeRequest(request_body) self.assertRaises(webservice.DataModelException, self.policy_model.simulate_action, {}, context, request)
def test_simulate_invalid_sequence(self): context = {'policy_id': self.action_policy['name']} action_rule = { 'rule': 'w(x):-z(x)', } self.rule_api.add_item(action_rule, {}, context=context) request_body = { 'query': 'w(x)', 'action_policy': self.action_policy['name'], 'sequence': 'z(1)' } request = helper.FakeRequest(request_body) self.assertRaises(webservice.DataModelException, self.policy_model.simulate_action, {}, context, request)
def test_simulate_action(self): context = {'policy_id': self.action_policy['name']} action_rule1 = { 'rule': 'action("q")', } action_rule2 = {'rule': 'p+(x):- q(x)'} self.rule_api.add_item(action_rule1, {}, context=context) self.rule_api.add_item(action_rule2, {}, context=context) request_body = { 'query': 'p(x)', 'action_policy': self.action_policy['name'], 'sequence': 'q(1)' } request = helper.FakeRequest(request_body) expected_ret = {'result': ["p(1)"]} ret = self.policy_model.simulate_action({}, context, request) self.assertEqual(expected_ret, ret)
def test_policy_api_model_execute(self): def _execute_api(client, action, action_args): positional_args = action_args['positional'] named_args = action_args['named'] method = reduce(getattr, action.split('.'), client) method(*positional_args, **named_args) class NovaClient(object): def __init__(self, testkey): self.testkey = testkey def _get_testkey(self): return self.testkey def disconnectNetwork(self, arg1, arg2, arg3): self.testkey = "arg1=%s arg2=%s arg3=%s" % (arg1, arg2, arg3) nova_client = NovaClient("testing") cservices = self.cage.services cservices['nova']['object']._execute_api = _execute_api cservices['nova']['object'].nova_client = nova_client api = self.api body = { 'name': 'nova:disconnectNetwork', 'args': { 'positional': ['value1', 'value2'], 'named': { 'arg3': 'value3' } } } request = helper.FakeRequest(body) result = api['policy'].execute_action({}, {}, request) self.assertEqual(result, {}) expected_result = "arg1=value1 arg2=value2 arg3=value3" f = cservices['nova']['object'].nova_client._get_testkey helper.retry_check_function_return_value(f, expected_result)
def test_simulate_with_delta_and_trace(self): context = {'policy_id': self.action_policy['name']} action_rule1 = { 'rule': 'action("q")', } action_rule2 = {'rule': 'p+(x):- q(x)'} self.rule_api.add_item(action_rule1, {}, context=context) self.rule_api.add_item(action_rule2, {}, context=context) request_body = { 'query': 'p(x)', 'action_policy': self.action_policy['name'], 'sequence': 'q(1)' } request = helper.FakeRequest(request_body) params = {'trace': 'true', 'delta': 'true'} expected_ret = {'result': ["p+(1)"], 'trace': "trace strings"} ret = self.policy_model.simulate_action(params, context, request) # check response's keys equal expected_ret's key self.assertTrue(all(key in expected_ret.keys() for key in ret.keys())) self.assertEqual(expected_ret['result'], ret['result']) self.assertGreater(len(ret['trace']), 10)
def test_policy_api_model_simulate_errors(self): def check_err(params, context, request, emsg, msg): try: api['policy'].simulate_action(params, context, request) self.fail(msg + ":: Error should have been thrown: " + emsg) except webservice.DataModelException as e: if emsg not in str(e): emsg = "Expected error: {}. Actual error: {}".format( emsg, str(e)) self.fail(msg + ":: " + emsg) api = self.api engine = self.engine context = {'policy_id': engine.ACTION_THEORY} # Missing query body = {'action_policy': engine.ACTION_THEORY, 'sequence': 'q(1)'} check_err({}, context, helper.FakeRequest(body), 'Simulate requires parameters', 'Missing query') # Invalid query body = { 'query': 'p(x', 'action_policy': engine.ACTION_THEORY, 'sequence': 'q(1)' } check_err({}, context, helper.FakeRequest(body), 'Syntax error for rule', 'Invalid query') # Multiple querys body = { 'query': 'p(x) q(x)', 'action_policy': engine.ACTION_THEORY, 'sequence': 'q(1)' } check_err({}, context, helper.FakeRequest(body), 'more than 1 rule', 'Multiple queries') # Missing action_policy body = {'query': 'p(x)', 'sequence': 'q(1)'} check_err({}, context, helper.FakeRequest(body), 'Simulate requires parameters', 'Missing action policy') # Invalid action_policy body = { 'query': 'p(x)', 'action_policy': "nonexistent", 'sequence': 'q(1)' } check_err({}, context, helper.FakeRequest(body), 'Unknown policy', 'Invalid action policy') # Missing sequence body = {'query': 'p(x)', 'action_policy': engine.ACTION_THEORY} check_err({}, context, helper.FakeRequest(body), 'Simulate requires parameters', 'Missing sequence') # Syntactically invalid sequence body = { 'query': 'p(x)', 'action_policy': engine.ACTION_THEORY, 'sequence': 'q(1' } check_err({}, context, helper.FakeRequest(body), 'Syntax error for rule', 'Syntactically invalid sequence') # Semantically invalid sequence body = { 'query': 'p(x)', 'action_policy': engine.ACTION_THEORY, 'sequence': 'r(1)' } # r is not an action check_err({}, context, helper.FakeRequest(body), 'non-action, non-update', 'Semantically invalid sequence')
def test_policy_api_model_simulate(self): def check_err(params, context, emsg, msg): try: api['policy'].simulate_action(params, context, None) self.fail(msg + ":: Error should have been thrown: " + emsg) except webservice.DataModelException as e: if emsg not in str(e): emsg = "Expected error: {}. Actual error: {}".format( emsg, str(e)) self.fail(msg + ":: " + emsg) api = self.api engine = self.engine context = {'policy_id': engine.ACTION_THEORY} # add actions to the action theory api['rule'].add_item({'rule': 'action("q")'}, {}, context=context) api['rule'].add_item({'rule': 'p+(x) :- q(x)'}, {}, context=context) # run simulation body = { 'query': 'p(x)', 'action_policy': engine.ACTION_THEORY, 'sequence': 'q(1)' } request = helper.FakeRequest(body) result = api['policy'].simulate_action({}, context, request)['result'] self.assertEqual(len(result), 1) self.assertEqual(result[0], "p(1)") # run simulation with delta body = { 'query': 'p(x)', 'action_policy': engine.ACTION_THEORY, 'sequence': 'q(1)' } params = {'delta': 'true'} request = helper.FakeRequest(body) result = api['policy'].simulate_action(params, context, request)['result'] self.assertEqual(len(result), 1) self.assertEqual(result[0], "p+(1)") # run simulation with trace body = { 'query': 'p(x)', 'action_policy': engine.ACTION_THEORY, 'sequence': 'q(1)' } params = {'trace': 'true'} request = helper.FakeRequest(body) dresult = api['policy'].simulate_action(params, context, request) result = dresult['result'] trace = dresult['trace'] self.assertEqual(len(result), 1) self.assertEqual(result[0], "p(1)") self.assertTrue(len(trace) > 10) # run simulation with delta and trace body = { 'query': 'p(x)', 'action_policy': engine.ACTION_THEORY, 'sequence': 'q(1)' } params = {'trace': 'true', 'delta': 'true'} request = helper.FakeRequest(body) dresult = api['policy'].simulate_action(params, context, request) result = dresult['result'] trace = dresult['trace'] self.assertEqual(len(result), 1) self.assertEqual(result[0], "p+(1)") self.assertTrue(len(trace) > 10)
def test_datasource_api_model_execute(self): def _execute_api(client, action, action_args): positional_args = action_args.get('positional', []) named_args = action_args.get('named', {}) method = reduce(getattr, action.split('.'), client) method(*positional_args, **named_args) class NovaClient(object): def __init__(self, testkey): self.testkey = testkey def _get_testkey(self): return self.testkey def disconnect(self, arg1, arg2, arg3): self.testkey = "arg1=%s arg2=%s arg3=%s" % (arg1, arg2, arg3) def disconnect_all(self): self.testkey = "action_has_no_args" nova_client = NovaClient("testing") args = helper.datasource_openstack_args() nova = nova_driver.NovaDriver('nova', args=args) nova.nova_client = nova_client nova.update_from_datasource = mock.MagicMock() nova._execute_api = _execute_api self.node.register_service(nova) execute_action = self.datasource_model.execute_action # Positive test: valid body args, ds_id context = {'ds_id': 'nova'} body = { 'name': 'disconnect', 'args': { 'positional': ['value1', 'value2'], 'named': { 'arg3': 'value3' } } } request = helper.FakeRequest(body) result = execute_action({}, context, request) self.assertEqual(result, {}) expected_result = "arg1=value1 arg2=value2 arg3=value3" f = nova.nova_client._get_testkey helper.retry_check_function_return_value(f, expected_result) # Positive test: no body args context = {'ds_id': 'nova'} body = {'name': 'disconnect_all'} request = helper.FakeRequest(body) result = execute_action({}, context, request) self.assertEqual(result, {}) expected_result = "action_has_no_args" f = nova.nova_client._get_testkey helper.retry_check_function_return_value(f, expected_result) # Negative test: invalid ds_id context = {'ds_id': 'unknown_ds'} self.assertRaises(webservice.DataModelException, execute_action, {}, context, request) # Negative test: no ds_id context = {} self.assertRaises(webservice.DataModelException, execute_action, {}, context, request) # Negative test: empty body context = {'ds_id': 'nova'} bad_request = helper.FakeRequest({}) self.assertRaises(webservice.DataModelException, execute_action, {}, context, bad_request) # Negative test: no body name/action context = {'ds_id': 'nova'} body = { 'args': { 'positional': ['value1', 'value2'], 'named': { 'arg3': 'value3' } } } bad_request = helper.FakeRequest(body) self.assertRaises(webservice.DataModelException, execute_action, {}, context, bad_request) # Positive test with retry: no body args cfg.CONF.dse.execute_action_retry = True context = {'ds_id': 'nova'} body = {'name': 'disconnect_all'} request = helper.FakeRequest(body) result = execute_action({}, context, request) self.assertEqual(result, {}) expected_result = "action_has_no_args" f = nova.nova_client._get_testkey helper.retry_check_function_return_value(f, expected_result)