def test_flattening(self): # Verify that we get the same result whether creating from a # dictionary, individual fields, or a nested data element txn_id = util.randomhex() target = util.randomword() op = util.randomword() d = util.randomdict() req1 = BllRequest( dict(target=target, foo="baz", txn_id=txn_id, operation=op, bar=d)) req2 = BllRequest(target=target, foo="baz", txn_id=txn_id, operation=op, bar=d) req3 = BllRequest(target=target, txn_id=txn_id, data={ 'operation': op, 'foo': 'baz', 'bar': d }) self.assertDictEqual(req1, req2) self.assertDictEqual(req2, req3) self.assertIn("operation", req1['data']) self.assertIn("foo", req1['data']) self.assertIn("bar", req1['data']) self.assertNotIn("target", req1['data']) self.assertNotIn("txn_id", req1['data'])
def test_data_remains_gone_when_none_supplied(self): # Verify that when neither 'operation' nor 'data' are supplied, that # the resulting request has no 'data' key req1 = BllRequest(target=util.randomword(), action=util.randomword()) self.assertFalse(req1.get('data'))
def test_overrides(self): # Test that explicitly supplied values override those in the # request parameter of the BllRequest constructor req1 = BllRequest(target=util.randomword(), auth_token=util.randomword(), operation=util.randomword(), action=util.randomword(), data=util.randomdict()) target = util.randomword() operation = util.randomword() action = util.randomword() auth_token = util.randomword() req2 = BllRequest(request=req1, target=target, operation=operation, action=action, auth_token=auth_token) self.assertEquals(req2['action'], action) self.assertEquals(req2['target'], target) self.assertEquals(req2['auth_token'], auth_token) self.assertEquals(req2['data']['operation'], operation)
def post(self, **kwargs): # generate a uniq id solely for the purpose of more # easily matching up request/responses in the log try: bll_request = BllRequest(json.loads(request.body)) # Add to thread local storage for logging context.txn_id = bll_request.txn_id if 'X-Auth-Token' in request.headers: bll_request[api.AUTH_TOKEN] = request.headers['X-Auth-Token'] bll_request[api.LANGUAGE] = self.get_language( request.headers.get('Accept-Language')) LOG.info("Received %s", bll_request) # initial service request? if bll_request.is_service_request(): ret = SvcBase.spawn_service(bll_request) else: # Poll to retrieve async response ret = get_job_status(bll_request.txn_id) response.status = 201 if isinstance(ret, dict): logstr = response_to_string(ret) LOG.info("Response %s", logstr) except ValueError as info: # json.loads was unable to convert the request to json LOG.error("Error converting request body to json: %s. " "Request body: %s", info, request.body) response.status = 400 ret = { api.STATUS: api.STATUS_ERROR, api.DATA: [{api.DATA: str(info)}] } LOG.info("Response ValueError: %s", scrub_passwords(ret)) except Exception as info: response.status = 400 ret = { api.STATUS: api.STATUS_ERROR, api.DATA: [{api.DATA: str(info)}] } LOG.info("Response Exception: %s", scrub_passwords(ret)) # Clear out txn_id as it leaves the system context.txn_id = '' return ret
def go(self, validate): if validate: return if self.operation == 'progress': request = BllRequest(target="general", operation='progress', data={'num_pauses': 2}) elif self.operation == 'fail': request = BllRequest(target="general", operation="failcomplete") return self.call_service_async(request, polling_interval=0.1)
def testMultiDecorator(self): request = {api.TARGET: 'expose', api.DATA: {api.OPERATION: 'op1'}} reply = SvcBase.spawn_service(BllRequest(request)) self.assertEqual(reply[api.STATUS], api.COMPLETE) self.assertEqual(reply[api.DATA], 'multi') request[api.DATA][api.OPERATION] = 'op2' reply = SvcBase.spawn_service(BllRequest(request)) self.assertEqual(reply[api.STATUS], api.COMPLETE) self.assertEqual(reply[api.DATA], 'multi')
def test_volume_crud(self): volume_type = "test_" + randomidentifier() # Add the volume type and grab its id svc = CinderSvc( BllRequest(target="cinder", operation="volume_type_add", auth_token=self.token, volume_type=volume_type)) reply = svc.handle() self.assertEqual(api.COMPLETE, reply[api.STATUS]) svc = CinderSvc( BllRequest(target="cinder", auth_token=self.token, operation="volume_type_list")) reply = svc.handle() volume_types = reply[api.DATA] for id, vol_type in volume_types.iteritems(): if vol_type == volume_type: new_id = id break else: self.fail("Newly created volume does not appear in list") svc = CinderSvc( BllRequest(target="cinder", operation="map_volume_backend", auth_token=self.token, volume_type_id=new_id, backend_name=randomidentifier())) reply = svc.handle() self.assertEqual(api.COMPLETE, reply[api.STATUS]) # Now delete it and verify it is gone svc = CinderSvc( BllRequest(target="cinder", operation="volume_type_delete", auth_token=self.token, volume_type_id=new_id)) reply = svc.handle() self.assertEqual(api.COMPLETE, reply[api.STATUS]) svc = CinderSvc( BllRequest(target="cinder", operation="volume_type_list", auth_token=self.token)) reply = svc.handle() self.assertNotIn(new_id, reply[api.DATA])
def test_activate_resource_success_esx(self, *_): body = { "type": "esxcluster", "network_config": { 'mgmt_trunk': [{ 'nics': 'vmnic0', 'name': 'MGMT-DVS-SH', 'mtu': '1500' }], 'cloud_trunks': [{ 'nics': 'vmnic1', 'network_name': 'VxLAN-R1', 'name': 'DATA-DVS', 'mtu': '1500' }] }, "id": "12345" } svc = EONSvc( BllRequest(operation="activate_resource", action="POST", auth_token=get_mock_token(), data={'data': body})) svc.handle() reply = svc.complete() self.assertEqual(reply[api.STATUS], api.COMPLETE)
def common_handler(self, mock_get_token_for_project, mock_get_service_endpoint, mock_get_measurement_list, mock_get_statistics_list, mock_get_list, mock_get_alarm_count, mock_get_alarm_definition_get, mock_get_alarm_get, mock_get_alarm_list, mock_call_service, operation, data, expected_output): mock_get_token_for_project.return_value = "admin" mock_get_service_endpoint.return_value = "http://localhost:8070/v2.0" mock_get_measurement_list.return_value = MEASUREMENT_OUPUT mock_get_statistics_list.return_value = STATISTICS_OUTPUT mock_get_list.return_value = METRIC_LIST_OUTPUT mock_get_alarm_count.return_value = ALARM_COUNT_OUTPUT mock_get_alarm_definition_get.return_value = \ ALARM_DEFINITION_SHOW_OUTPUT mock_get_alarm_get.return_value = ALARM_SHOW_OUTPUT mock_get_alarm_list.return_value = ALARM_LIST_OUTPUT mock_call_service.return_value = CALL_SERVICE_OUTPUT request = { api.TARGET: 'objectstorage_summary_service', api.ACTION: 'GET', api.AUTH_TOKEN: 'unused', api.DATA: { api.OPERATION: operation, api.DATA: data } } svc = objectstorage_summary_service.ObjectStorageSummarySvc( bll_request=BllRequest(request)) reply = svc.handle() expected = expected_output self.assertEqual(reply[api.DATA], expected)
def test_health_focused(self, mock_get_token_for_project, mock_get_service_endpoint, mock_call_service, mock_alarm_count): mock_get_token_for_project.return_value = "admin" mock_get_service_endpoint.return_value = "http://localhost:8070/v2.0" mock_call_service.return_value = { 'ccp:cluster1': [ 'standard-ccp-c1-m1-mgmt', 'standard-ccp-c1-m2-mgmt', 'standard-ccp-c1-m3-mgmt' ], 'ccp:cluster2': [ 'standard-ccp-c1-m1-mgmt', 'standard-ccp-c1-m2-mgmt', 'standard-ccp-c1-m3-mgmt' ] } mock_alarm_count.return_value = { "counts": [[5, "OK", "LOW"], [6, "OK", "HIGH"]] } request = { api.TARGET: 'objectstorage_summary_service', api.ACTION: 'GET', api.AUTH_TOKEN: 'unused', api.DATA: { api.OPERATION: "health_focused", api.DATA: None } } svc = objectstorage_summary_service.ObjectStorageSummarySvc( bll_request=BllRequest(request)) reply = svc.handle() self.assertEqual(reply['status'], api.STATUS_INPROGRESS)
def complete(self): """ Async call that calls async calls in other plugins """ if self.operation == 'progress': request = BllRequest(target="general", operation='progress', data={'num_pauses': 2}) elif self.operation == 'fail': request = BllRequest(target="general", operation="failcomplete") self.response[api.DATA] = self.call_service_async(request, polling_interval=0.1) self.response[api.PERCENT_COMPLETE] = dict(percentComplete=100) self.response.complete() return self.response
def test_update_eon_with_stats(self, *_): # example of what comes back from eon compute_list = [ { "cluster_moid": "domain-c84", "id": "ebe3e327-1e02-4feb-bfed-7eaa410bb5c9", "ip_address": "UNSET", "meta_data": [ { "id": "311c3abc-15c6-4156-bf61-38ea304e8675", "name": "hypervisor_id", "value": "1" }, { "id": "7063a114-469f-4591-8315-e042801235ca", "name": "network_properties", "value": "network_properties_blah" }, { "id": "7173ccad-c4c7-4b76-b1e9-91b6da330af6", "name": "cluster_moid", "value": "domain-c3135" }, { "id": "ca70eaac-8bd9-411d-9c98-d90d7812b5a1", "name": "ardana_properties", "value": "ardana_properties_blah" } ], "hypervisor_hostname": "domain-c84.68bb08ca-07ed-4b9d-835f-1815a5f15a85", "name": "Compute-08A", "password": "******", "port": "UNSET", "region": "my_region", "resource_mgr_id": "68bb08ca-07ed-4b9d-835f-1815a5f15a85", "state": "activated", "type": "esxcluster", "username": "******" } ] request = { api.TARGET: 'compute', api.ACTION: 'GET', api.AUTH_TOKEN: 'blah', api.DATA: { api.OPERATION: 'get_compute_list' } } svc = compute_service.ComputeSvc(bll_request=BllRequest(request)) svc._filter_eon_compute_node = mock.Mock(return_value=compute_list) reply = svc.handle() self.assertEqual(api.COMPLETE, reply[api.STATUS]) self.assertFalse('meta_data' in reply[api.DATA][0]) self.assertEquals(reply[api.DATA][0]['network_properties'], 'network_properties_blah') self.assertEquals(reply[api.DATA][0]['ping_status'], 'up')
def test_handle_status_in_progress(self, *_): svc = IntegratedToolsSvc( BllRequest(action='GET', operation='vcenters', auth_token=get_mock_token())) output = svc.handle() self.assertEqual(output['status'], 'complete')
def test_query_parameters(self, _token_helper): base_url = randomurl() data = randomdict() path = "my/path" # The token_helper constructor returns an object with # a get_service_endpoint function that we want to override _token_helper.return_value.get_service_endpoint.return_value = base_url svc = ArdSvc( BllRequest(operation="do_path_operation", auth_token=get_mock_token(), action="GET", data={ 'path': path, 'request_data': data, 'request_parameters': ['key=value'] })) svc._request = mock.Mock() svc.handle() # Verify that the proper values are going to be passed to the requests # library svc._request.assert_called_once_with(path, {"key": "value"}, data, action='GET')
def test_default_project(self): bll_request = { api.AUTH_TOKEN: self.token, 'target': 'user_group', 'data': { 'operation': 'unused' } } app_svc = UserGroupSvc(bll_request=BllRequest(bll_request)) svc = get_service_tenant_name() # Tests a a bunch of tuples with input, and expect output as items tests = [ (["admin", svc], None), (["admin"], None), ([svc], None), (["admin", svc, "demo"], "demo"), (["demo"], "demo"), (["demo", "foo"], "demo"), (["admin", svc, "foo"], "foo"), (["admin", svc, "demo"], "demo"), (["foo"], "foo"), ] # Test all of the above scenarios for vals, expected in tests: self.assertEquals(expected, app_svc._select_default_project(vals), ",".join(vals))
def test_call_service_async_with_progress(self): class Foo(SvcBase): @expose(is_long=True) def bar(self): req = BllRequest(target="general", operation="progress", pause_sec=.1, num_pauses=5) self.call_service_async(req, polling_interval=0.05, offset=50, scale=0.5) self.response.complete() return self.response svc = Foo(BllRequest(operation="bar")) svc.update_job_status = mock.Mock() reply = svc.complete() self.assertEquals(api.COMPLETE, reply[api.STATUS]) # Note that any_order permits extra calls to have been made, which # will happen since there may be multiple calls in a row with the # same percentage_complete svc.update_job_status.assert_has_calls([ mock.call(percentage_complete=60.0), mock.call(percentage_complete=70.0), mock.call(percentage_complete=80.0), mock.call(percentage_complete=90.0), mock.call(percentage_complete=100.0)], any_order=True)
def test_playbook_cycle(self, *_): svc = ArdSvc( BllRequest(operation='run_playbook', auth_token=get_mock_token(), action='POST', data={ 'playbook_name': 'some_playbook', })) # Kick off the playbook resp = svc.handle() txn_id = resp[api.TXN_ID] # We now should be busy running the playbook status = get_job_status(txn_id) self.assertTrue(status['status'], api.STATUS_INPROGRESS) svc.update_job_status() self.assertTrue(status['status'], api.STATUS_INPROGRESS) # Now pretend we are done svc.update_job_status('done', percentage_complete=100, txn_id=txn_id) svc.sc_complete() self.assertTrue(status['status'], api.COMPLETE) self.assertFalse(status[api.DATA]['alive']) self.assertEquals(status[api.DATA]['code'], 0)
def test_generic_get(self, _mock_endpoints, _mock_get_func): mock_client = mock.MagicMock() mock_client.node = mock.create_autospec(NodeManager) _mock_endpoints.return_value = [{ 'region': randomword(), 'url': randomurl() }] nodeid = randomhex() res = self.MockResource({ 'instance_uuid': randomhex(), 'uuid': nodeid, 'driver': 'agent_ilo', 'name': randomword(), 'power_state': 'power on', 'provision_state': 'active', }) mock_client.node.get.return_value = res _mock_get_func.return_value = mock_client svc = IronicSvc( BllRequest(operation='node.get', auth_token=get_mock_token(), data={'node_id': randomhex})) data = svc.handle()[api.DATA] self.assertIsInstance(data, dict) self.assertEqual(data['driver'], 'agent_ilo') self.assertEqual(data['uuid'], nodeid)
def test_scrub_token_from_bll_request(self): test_data = {'auth_token': '4d038a60-2409-4636-b99f-280e4dc3c6fe', 'txn_id': '8582cdc0-c09a-4bd6-a1a8-67c5af78a1cf', 'target': 'deploy', 'data': {'operation': 'some_operation'}} result = scrub_passwords(BllRequest(test_data)) self.assertNotIn('4d038a60', result)
def test_call_service_async_indirect(self): # Test an async service that calls another async service via # SvcBase.call_service_async pauses = 2 pause_sec = 0.1 request = BllRequest(target='composite-async', operation='progress', data={ 'pause_sec': pause_sec, 'num_pauses': pauses, }) reply = SvcBase.spawn_service(request) txn_id = reply.get(api.TXN_ID) while reply.get(api.STATUS) != api.COMPLETE: time.sleep(pause_sec) reply = get_job_status(txn_id) self.assertIn(api.TXN_ID, reply) self.assertIsNotNone(reply.get(api.TXN_ID)) self.assertIn(api.DURATION, reply) self.assertIn(api.ENDTIME, reply) self.assertIn(api.STARTTIME, reply) self.assertIn(api.STATUS, reply) self.assertEqual(api.COMPLETE, reply[api.STATUS])
def test_hypervisor_list(self, _mock_nova_client, _mock_endpoints, _mock_serv_end, _mock_ks_client): _mock_nova_client.return_value = self.mock_novaclient _mock_serv_end.return_value = None _mock_ks_client.return_value = self.mock_ksclient _mock_endpoints.return_value = self.mock_get_endpoints svc = NovaSvc( BllRequest(auth_token=get_mock_token(), data={api.OPERATION: 'hypervisor-list'})) # build up a list of ping statuses statuses = {} for hyp in self.hyp_list: statuses[hyp.hypervisor_hostname] = 'up' with patch('bll.plugins.service.SvcBase.call_service', return_value=statuses): reply = svc.handle() self.assertEqual(api.COMPLETE, reply[api.STATUS]) # 4 hypervisors hyp_list = reply[api.DATA] self.assertEqual(len(self.hyp_list), len(hyp_list)) known_id_list = [x.id for x in self.hyp_list] for hyp in hyp_list: self.assertTrue(hyp['hypervisor_id'] in known_id_list) self.assertEqual(hyp['ping_status'], 'up')
def test_service_inc_metrics_statistics(self, _mock_nova_client, _mock_monasca_client, _mock_endpoints, _mock_serv_end, _mock_ks_client): _mock_nova_client.return_value = self.mock_novaclient _mock_serv_end.return_value = None _mock_ks_client.return_value = self.mock_ksclient _mock_monasca_client.return_value = self.mock_monasca_client _mock_endpoints.return_value = self.mock_get_endpoints req_data = { api.OPERATION: 'instance-list', 'monasca_metrics': ['some.metric'], 'monasca_data': { 'operation': 'metric_statistics' } } svc = NovaSvc(BllRequest(auth_token=get_mock_token(), data=req_data)) reply = svc.handle() self.assertEqual(reply[api.STATUS], api.COMPLETE) self.mock_monasca_client.metrics.list_statistics.assert_called_with( name='some.metric') self.assertIn(api.DATA, reply) data = reply[api.DATA] self.assertIn('instances', data) self.assertIsInstance(data['instances'], list) self.assertTrue(len(data['instances']) > 0) self.assertIn('metrics', data['instances'][0]) self.assertIn('some.metric', data['instances'][0]['metrics']) some_metric = data['instances'][0]['metrics']['some.metric'] self.assertEquals(some_metric[0]['statistics'][0][1], 31)
def testOp(self): request = {api.TARGET: 'expose', api.DATA: {api.OPERATION: 'valid_op'}} reply = SvcBase.spawn_service(BllRequest(request)) self.assertEqual(reply[api.STATUS], api.COMPLETE) self.assertEqual(reply[api.DATA], 'ok')
def test_get_enterprise_app_endpoints(self, mock_get_service_endpoint): svc = CatalogSvc( BllRequest(operation='get_enterprise_app_endpoints', auth_token=get_mock_token())) output = svc.handle() self.assertGreater(len(output['data']), 0)
def test_get_vcenter_count(self, *_): svc = IntegratedToolsSvc( BllRequest(action='GET', operation='count_vcenters', auth_token=get_mock_token())) output = svc.handle() self.assertEqual(output['data'], 1)
def test_del_user_list(self): users_before = self._get_user_list() user1 = self._add_user(self.newuser(), '*****@*****.**') user2 = self._add_user(self.newuser(), '*****@*****.**') user_id_list = [user1, user2] project_id = None for user in self._get_user_list(): if user1 == user['user_id']: project_id = user['project_id'] break bll_request = { api.AUTH_TOKEN: self.token, 'target': 'user_group', 'data': { 'operation': 'users_remove', 'user_ids': user_id_list, 'project_id': project_id, 'api_version': 'v1', } } app_svc = UserGroupSvc(bll_request=BllRequest(bll_request)) app_svc.handle() users_after = self._get_user_list() self.assertEqual(len(users_before), len(users_after))
def test_no_playbook(self, *_): svc = ArdSvc( BllRequest(operation='run_playbook', auth_token=get_mock_token(), action='POST', data={})) with self.assertRaises(InvalidBllRequestException): svc.handle()
def test_doubly_nested_data(self): target = util.randomword() d = util.randomdict() req = BllRequest(target=target, data={'data': d}) # Make sure that the doubly nested data got populated correctly self.assertDictEqual(d, req['data']['data'])
def _build_request(self, request=None, target=None, auth_token=None, operation=None, action=None, data=None, region=None, **kwargs): """ Construct a request object using the following, in priority order ( highest priority first): 1. Function arguments (e.g. operation) 2. Values in the ``request`` argument 3. Values from the service making the request for fields that are commonly inherited (txn, region, auth_token) For example, if the auth_token is passed as a parameter, it will be used; otherwise, the auth_token will be taken from any request object passes as a parameter; otherwise it will be copied from the calling service. """ txn_id = new_txn_id(self.txn_id) language = self.request.get(api.LANGUAGE) if not region: if request: region = request.get(api.REGION) region = region or self.region req = BllRequest(request=request, target=target, auth_token=auth_token, operation=operation, action=action, data=data, txn_id=txn_id, region=region, language=language, **kwargs) if not req.get(api.AUTH_TOKEN) and getattr(self, 'token_helper', None): req[api.AUTH_TOKEN] = self.token_helper.get_user_token() return req
def test_unregister_vcenter_error_missing_ids(self, *_): svc = IntegratedToolsSvc( BllRequest(action='DELETE', operation='vcenters', auth_token=get_mock_token())) output = svc.complete() self.assertEqual('error', output['status']) self.assertEqual(REGISTERED_STATE, get_vcenter_state(id))