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 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_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 testMissingOp(self): request = {api.TARGET: 'expose', api.DATA: {api.OPERATION: 'foo'}} # Suppress exception log with util.log_level(logging.CRITICAL, 'bll'): reply = SvcBase.spawn_service(BllRequest(request)) self.assertEqual(reply[api.STATUS], api.STATUS_ERROR) self.assertIn('Unsupported', reply[api.DATA][0][api.DATA])
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 test_spawn_long(self): """ This function is nearly identical to test_spawn_long in test_service_collection.py, with the only difference being the target and operation in the request. This illustrates that the behavior of the new @expose method is the same as the old handle/complete for asynchronous calls. """ pauses = 5 pause_sec = 0.1 bll_request = { api.TARGET: 'expose', api.DATA: { api.OPERATION: 'progress', 'pause_sec': pause_sec, 'num_pauses': pauses, } } reply = SvcBase.spawn_service(BllRequest(bll_request)) txn_id = reply.get(api.TXN_ID) # test the incomplete reply self.assertIn(api.TXN_ID, reply) self.assertIn(api.PROGRESS, reply) self.assertIn(api.POLLING_INTERVAL, reply) self.assertIn(api.STARTTIME, reply) self.assertIn(api.STATUS, reply) self.assertEqual(api.STATUS_INPROGRESS, reply[api.STATUS]) # wait a little extra before the first poll time.sleep(0.1 + pause_sec) # read the job status update reply = get_job_status(txn_id) self.assertEqual(reply[api.TXN_ID], txn_id) self.assertIn(api.STARTTIME, reply) self.assertIn(api.STATUS, reply) self.assertEqual(api.STATUS_INPROGRESS, reply[api.STATUS]) percent = reply[api.PROGRESS][api.PERCENT_COMPLETE] self.assertGreater(percent, 0) self.assertLess(percent, 100) while reply.get(api.STATUS) != api.COMPLETE: time.sleep(pause_sec) reply = get_job_status(txn_id) self.assertEqual(reply[api.TXN_ID], txn_id) self.assertIn(api.DURATION, reply) self.assertIn(api.ENDTIME, reply) self.assertIn(api.STARTTIME, reply) self.assertIn(api.STATUS, reply) self.assertEqual(reply[api.STATUS], api.COMPLETE) self.assertEqual(reply[api.PROGRESS][api.PERCENT_COMPLETE], 100)
def testAction(self): request = { api.TARGET: 'expose', api.ACTION: 'act', } reply = SvcBase.spawn_service(BllRequest(request)) self.assertEqual(reply[api.STATUS], api.COMPLETE) self.assertEqual(reply[api.DATA], 'action')
def test_returned_data(self): request = { api.TARGET: 'expose', api.DATA: { api.OPERATION: 'data_in_response' } } reply = SvcBase.spawn_service(BllRequest(request)) # even though the data_in_response method doesn't return anything, # we should still see data self.assertEqual(reply[api.DATA], 'blah')
def handle(self, action, user='******', prefs=None): req_dict = { api.TARGET: 'preferences', api.AUTH_TOKEN: get_mock_token(), api.ACTION: action } req_dict[api.DATA] = {"user": user} if prefs: req_dict[api.DATA]["prefs"] = prefs return SvcBase.spawn_service(BllRequest(req_dict))
def test_call_service_fail(self): # Test an sync service that calls another sync service via # SvcBase.call_service, and fails bll_request = { api.TARGET: 'composite', api.DATA: {api.OPERATION: 'fail'} } # load the composite plugin reply = SvcBase.spawn_service(BllRequest(bll_request)) self.assertEqual(api.STATUS_ERROR, reply[api.STATUS])
def test_spawn_short(self): bll_request = { api.TARGET: 'general', api.DATA: { api.OPERATION: 'null' } } reply = SvcBase.spawn_service(BllRequest(bll_request)) self.assertEqual(reply[api.STATUS], api.COMPLETE) self.assertIsNotNone(reply.get(api.TXN_ID)) self.assertIn(api.DURATION, reply) self.assertIn(api.ENDTIME, reply) self.assertIn(api.STARTTIME, reply)
def test_spawn_long(self): pauses = 5 pause_sec = 0.1 bll_request = { api.TARGET: 'general', api.DATA: { api.OPERATION: 'progress', 'pause_sec': pause_sec, 'num_pauses': pauses, } } reply = SvcBase.spawn_service(BllRequest(bll_request)) txn_id = reply.get(api.TXN_ID) # test the incomplete reply self.assertIn(api.TXN_ID, reply) self.assertIn(api.PROGRESS, reply) self.assertIn(api.POLLING_INTERVAL, reply) self.assertIn(api.STARTTIME, reply) self.assertIn(api.STATUS, reply) self.assertEqual(api.STATUS_INPROGRESS, reply[api.STATUS]) # wait a little extra before the first poll time.sleep(0.1 + pause_sec) # read the job status update reply = get_job_status(txn_id) self.assertEqual(reply[api.TXN_ID], txn_id) self.assertIn(api.STARTTIME, reply) self.assertIn(api.STATUS, reply) self.assertEqual(api.STATUS_INPROGRESS, reply[api.STATUS]) percent = reply[api.PROGRESS][api.PERCENT_COMPLETE] self.assertGreater(percent, 0) self.assertLess(percent, 100) while reply.get(api.STATUS) != api.COMPLETE: time.sleep(pause_sec) reply = get_job_status(txn_id) self.assertEqual(reply[api.TXN_ID], txn_id) self.assertIn(api.DURATION, reply) self.assertIn(api.ENDTIME, reply) self.assertIn(api.STARTTIME, reply) self.assertIn(api.STATUS, reply) self.assertEqual(reply[api.STATUS], api.COMPLETE) self.assertEqual(reply[api.PROGRESS][api.PERCENT_COMPLETE], 100)
def testSlowOp(self): request = {api.TARGET: 'expose', api.DATA: {api.OPERATION: 'slow_op'}} # Suppress exception log txn_id = None with util.log_level(logging.CRITICAL, 'bll'): reply = SvcBase.spawn_service(BllRequest(request)) txn_id = reply.get(api.TXN_ID) self.assertEqual(reply[api.PROGRESS]['percentComplete'], 0) self.assertEqual(api.STATUS_INPROGRESS, reply[api.STATUS]) time.sleep(0.1) reply = get_job_status(txn_id) self.assertEqual(reply[api.PROGRESS]['percentComplete'], 100)
def test_call_service_async_indirect_fail(self): # Test an async service that calls another async service via # SvcBase.call_async, and which fails pause_sec = 0.1 request = BllRequest(target='composite-async', operation='fail') reply = SvcBase.spawn_service(request) txn_id = reply.get(api.TXN_ID) while reply.get(api.STATUS) in (api.STATUS_INPROGRESS, api.STATUS_NOT_FOUND): time.sleep(pause_sec) reply = get_job_status(txn_id) self.assertIn(api.TXN_ID, reply) self.assertIsNotNone(reply.get(api.TXN_ID)) self.assertEqual(api.STATUS_ERROR, reply[api.STATUS])
def test_call_service(self): # Test an sync service that calls another sync service via # SvcBase.call_service, and fails bll_request = { api.TARGET: 'composite', api.DATA: {api.OPERATION: 'composite'} } # load the composite plugin reply = SvcBase.spawn_service(BllRequest(bll_request)) 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]) self.assertEqual(len(reply[api.DATA]), 2)
def test_spawn_service(target, operation=None, action=None, token=None, data=None): """ Variant of spawn_service intended for testing -- the keystone token will be faked if not passed """ payload = {} if operation: payload[api.OPERATION] = operation if data: payload.update(data) req = { api.TARGET: target, api.ACTION: action or "GET", api.AUTH_TOKEN: token or get_mock_token(), api.DATA: payload } return SvcBase.spawn_service(BllRequest(req))
def testNull(self): request = {api.TARGET: 'general', api.DATA: {api.OPERATION: 'null'}} reply = SvcBase.spawn_service(BllRequest(request)) self.assertEqual(reply[api.STATUS], api.COMPLETE)