def test_process_lots_failed(bot, logger, mocker): result = bot.process_lots(None) assert result is None lots = [{'data': { 'status': 'dissolved', 'id': 'fd122ba678174a19affcb3a0edc96e0e', 'assets': ["a107b69548b54eb293ad82b36c6936a1"] } }] mock_assets_available = mocker.patch.object(bot, 'check_lot_assets', autospec=True) mock_assets_available.side_effect = RequestFailed() bot.process_lots(lots) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[0] == "Could not get any lots" assert log_strings[1] == "Got lots" assert log_strings[2] == "Processing lot fd122ba678174a19affcb3a0edc96e0e" assert log_strings[3] == "Due to fail in getting assets, lot fd122ba678174a19affcb3a0edc96e0e is skipped"
def check_assets(self, lot, status='pending'): """ Makes GET request to openregistry for every asset id in assets list from lot object, passed as parameter, with client specified in configuration file. Args: lot: dictionary which contains some fields of lot document from db: id, rev, status, assets, lotID. status (str): status, in which assets are considered as available. Defaults to 'pending'. Returns: bool: True if request was successful and conditions were satisfied, False otherwise. Raises: RequestFailed: if RequestFailed was raised during request. """ for asset_id in lot['assets']: try: asset = self.assets_client.get_asset(asset_id).data logger.info('Successfully got asset {}'.format(asset_id)) except ResourceNotFound as e: logger.error('Failed to get asset {0}: {1}'.format( asset_id, e.message)) return False except RequestFailed as e: logger.error( 'Failed to get asset {0}. Status code: {1}'.format( asset_id, e.status_code)) raise RequestFailed('Failed to get assets') if asset.assetType not in self.allowed_asset_types: return False related_lot_check = 'relatedLot' in asset and asset.relatedLot != lot[ 'id'] if related_lot_check or asset.status != status: return False return True
def test_patch_assets_failed(bot, logger, mock_client): lot = {'data': { 'status': 'waiting', 'id': 'dd36079db10f4b77b8dd77ca64299e95', 'assets': [ "137738e77e1c4a968a2f1c4226639854", # status: pending "b30136280e2a4d8f8c3572d52b155741", # status: pending ] } } with open(ROOT + 'assets.json') as assets_data: assets = munchify(load(assets_data)) asset = assets['137738e77e1c4a968a2f1c4226639854'] asset.data.status = 'active' bot.assets_client.patch_asset.side_effect = [ str(asset), RequestFailed() ] result = bot.patch_assets(lot, 'active', lot['data']['id']) assert result is False bot.assets_client.patch_asset.side_effect = InvalidResponse() result = bot.patch_assets(lot, 'active', lot['data']['id']) assert result is False bot.assets_client.patch_asset.side_effect = Forbidden() result = bot.patch_assets(lot, 'active', lot['data']['id']) assert result is False log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[0] == "Successfully patched asset 137738e77e1c4a968a2f1c4226639854 to active" assert log_strings[1] == "Failed to patch asset b30136280e2a4d8f8c3572d52b155741 to active (Not described error yet.)" assert log_strings[2] == "Failed to patch asset 137738e77e1c4a968a2f1c4226639854 to active (Not described error yet.)" assert log_strings[3] == "Failed to patch asset 137738e77e1c4a968a2f1c4226639854 to active (Not described error yet.)"
def test_check_lot_asset_request_failed(bot, logger, mock_client): lot = {'data': { 'status': 'waiting', 'id': 'dd36079db10f4b77b8dd77ca64299e95', 'assets': [ "137738e77e1c4a968a2f1c4226639854", # status: pending ] } } with open(ROOT + 'assets.json') as assets_data: assets = munchify(load(assets_data)) bot.assets_client.get_asset.side_effect = [ RequestFailed() ] with pytest.raises(RequestFailed): bot.check_lot_assets(lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[0] == "Falied to get asset: Not described error yet."
def test__get_resource_item_from_public(self, mock_api_client): item = { 'id': uuid.uuid4().hex, 'dateModified': datetime.datetime.utcnow().isoformat() } api_clients_queue = Queue() client_dict = { 'id': uuid.uuid4().hex, 'request_interval': 0.02, 'client': mock_api_client } api_clients_queue.put(client_dict) api_clients_info =\ {client_dict['id']: {'destroy': False, 'request_durations': {}}} retry_queue = Queue() return_dict = { 'data': { 'id': item['id'], 'dateModified': datetime.datetime.utcnow().isoformat() } } mock_api_client.get_resource_item.return_value = return_dict worker = ResourceItemWorker(api_clients_queue=api_clients_queue, config_dict=self.worker_config, retry_resource_items_queue=retry_queue, api_clients_info=api_clients_info) # Success test self.assertEqual(worker.api_clients_queue.qsize(), 1) api_client = worker._get_api_client_dict() self.assertEqual(api_client['request_interval'], 0.02) self.assertEqual(worker.api_clients_queue.qsize(), 0) public_item = worker._get_resource_item_from_public(api_client, item) self.assertEqual(worker.retry_resource_items_queue.qsize(), 0) self.assertEqual(public_item, return_dict['data']) # Not actual document form public item['dateModified'] = datetime.datetime.utcnow().isoformat() api_client = worker._get_api_client_dict() self.assertEqual(worker.api_clients_queue.qsize(), 0) self.assertEqual(api_client['request_interval'], 0) public_item = worker._get_resource_item_from_public(api_client, item) self.assertEqual(public_item, None) sleep(worker.config['retry_default_timeout'] * 2) self.assertEqual(worker.retry_resource_items_queue.qsize(), 1) self.assertEqual(worker.api_clients_queue.qsize(), 1) # InvalidResponse mock_api_client.get_resource_item.side_effect =\ InvalidResponse('invalid response') self.assertEqual(worker.retry_resource_items_queue.qsize(), 1) api_client = worker._get_api_client_dict() self.assertEqual(worker.api_clients_queue.qsize(), 0) public_item = worker._get_resource_item_from_public(api_client, item) self.assertEqual(public_item, None) sleep(worker.config['retry_default_timeout'] * 2) self.assertEqual(worker.retry_resource_items_queue.qsize(), 2) self.assertEqual(worker.api_clients_queue.qsize(), 1) # RequestFailed status_code=429 mock_api_client.get_resource_item.side_effect = RequestFailed( munchify({'status_code': 429})) api_client = worker._get_api_client_dict() self.assertEqual(worker.api_clients_queue.qsize(), 0) self.assertEqual(api_client['request_interval'], 0) public_item = worker._get_resource_item_from_public(api_client, item) self.assertEqual(public_item, None) sleep(worker.config['retry_default_timeout'] * 2) self.assertEqual(worker.retry_resource_items_queue.qsize(), 3) self.assertEqual(worker.api_clients_queue.qsize(), 1) api_client = worker._get_api_client_dict() self.assertEqual(worker.api_clients_queue.qsize(), 0) self.assertEqual(api_client['request_interval'], worker.config['client_inc_step_timeout']) # RequestFailed status_code=429 with drop cookies api_client['request_interval'] = 2 public_item = worker._get_resource_item_from_public(api_client, item) sleep(api_client['request_interval']) self.assertEqual(worker.api_clients_queue.qsize(), 1) self.assertEqual(public_item, None) self.assertEqual(api_client['request_interval'], 0) sleep(worker.config['retry_default_timeout'] * 2) self.assertEqual(worker.retry_resource_items_queue.qsize(), 4) # RequestFailed with status_code not equal 429 mock_api_client.get_resource_item.side_effect = RequestFailed( munchify({'status_code': 404})) api_client = worker._get_api_client_dict() self.assertEqual(worker.api_clients_queue.qsize(), 0) public_item = worker._get_resource_item_from_public(api_client, item) self.assertEqual(public_item, None) self.assertEqual(worker.api_clients_queue.qsize(), 1) self.assertEqual(api_client['request_interval'], 0) sleep(worker.config['retry_default_timeout'] * 2) self.assertEqual(worker.retry_resource_items_queue.qsize(), 5) # ResourceNotFound mock_api_client.get_resource_item.side_effect = RNF( munchify({'status_code': 404})) api_client = worker._get_api_client_dict() self.assertEqual(worker.api_clients_queue.qsize(), 0) public_item = worker._get_resource_item_from_public(api_client, item) self.assertEqual(public_item, None) self.assertEqual(worker.api_clients_queue.qsize(), 1) self.assertEqual(api_client['request_interval'], 0) sleep(worker.config['retry_default_timeout'] * 2) self.assertEqual(worker.retry_resource_items_queue.qsize(), 6) # Exception api_client = worker._get_api_client_dict() mock_api_client.get_resource_item.side_effect =\ Exception('text except') public_item = worker._get_resource_item_from_public(api_client, item) self.assertEqual(public_item, None) self.assertEqual(api_client['request_interval'], 0) sleep(worker.config['retry_default_timeout'] * 2) self.assertEqual(worker.retry_resource_items_queue.qsize(), 7) del worker
def test_check_assets(bot, logger, mocker): with open(ROOT + 'assets.json') as assets: assets = load(assets) with open(ROOT + 'lots.json') as lots: lots = load(lots) verification_lot = deepcopy(lots[0]['data']) verification_lot['assets'] = ['e519404fd0b94305b3b19ec60add05e7'] dissolved_lot = deepcopy(lots[1]['data']) dissolved_lot['assets'] = ["0a7eba27b22a454180d3a49b02a1842f"] mock_get_asset = mocker.MagicMock() mock_get_asset.side_effect = [ RequestFailed(response=munchify({ "text": "Request failed.", "status_code": 502 })), ResourceNotFound( response=munchify({"text": "Asset could not be found."})), munchify(assets[0]), munchify(assets[7]) ] bot.assets_client.get_asset = mock_get_asset with pytest.raises(RequestFailed): bot.check_assets(verification_lot) result = bot.check_assets(verification_lot) assert result is False result = bot.check_assets(verification_lot) assert result is True result = bot.check_assets(dissolved_lot) assert result is False verification_lot = deepcopy(lots[5]['data']) basic_asset = deepcopy(assets[7]) basic_asset['data']['status'] = 'pending' basic_asset['data']['relatedLot'] = verification_lot['id'] basic_asset['data']['assetType'] = 'basic' wrong_asset = deepcopy(assets[9]) wrong_asset['data']['status'] = 'pending' wrong_asset['data']['assetType'] = 'wrong' wrong_asset['data']['relatedLot'] = verification_lot['id'] mock_get_asset.side_effect = [munchify(wrong_asset), munchify(basic_asset)] verification_lot['assets'] = [wrong_asset['data']['id']] result = bot.check_assets(verification_lot) assert result is False verification_lot['assets'] = [basic_asset['data']['id']] result = bot.check_assets(verification_lot) assert result is True log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 0] == "Failed to get asset e519404fd0b94305b3b19ec60add05e7. Status code: 502" assert log_strings[ 1] == "Failed to get asset e519404fd0b94305b3b19ec60add05e7: Asset could not be found." assert log_strings[ 2] == "Successfully got asset e519404fd0b94305b3b19ec60add05e7" assert log_strings[ 3] == "Successfully got asset 0a7eba27b22a454180d3a49b02a1842f" assert log_strings[4] == "Successfully got asset {}".format( wrong_asset['data']['id']) assert log_strings[5] == "Successfully got asset {}".format( basic_asset['data']['id'])
def test_process_lots(bot, logger, mocker): mock_get_asset = mocker.MagicMock() bot.assets_client.get_asset = mock_get_asset mock_check_lot = mocker.patch.object(bot, 'check_lot', autospec=True) # mock_check_lot.side_effect = iter([ # True, # True, # True, # True, # True, # False, # True, # True, # True, # True, # True, # ]) mock_check_assets = mocker.patch.object(bot, 'check_assets', autospec=True) # mock_check_assets.side_effect = iter([ # True, # True, # False, # RequestFailed(response=munchify({"text": "Request failed."})), # True, # True, # ]) mock_patch_assets = mocker.patch.object(bot, 'patch_assets', autospec=True) # mock_patch_assets.side_effect = iter([ # (False, []), # (True, []), # (True, ['all_assets']), # (True, ['all_assets']), # (False, []), # (True, ['all_assets']), # (False, []), # (True, ['all_assets']), # (False, []) # ]) mock_patch_lot = mocker.patch.object(bot, 'patch_lot', autospec=True) mock_patch_lot.return_value = True with open(ROOT + 'lots.json') as lots: lots = load(lots) with open(ROOT + 'assets.json') as assets: assets = load(assets) verification_lot = lots[0]['data'] pending_dissolution_lot = lots[1]['data'] # status == 'verification' mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([ (False, []), (True, ['all_assets']), ]) bot.process_lots( verification_lot ) # assets_available: True; patch_assets: [(False, []), (True, []]; check_lot: True log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 0] == 'Processing lot 9ee8f769438e403ebfb17b2240aedcf1 in status verification' assert mock_check_assets.call_count == 1 assert mock_check_assets.call_args[0] == (verification_lot, ) assert mock_check_lot.call_count == 1 assert mock_check_lot.call_args[0] == (verification_lot, ) assert mock_patch_assets.call_count == 1 assert mock_patch_assets.call_args_list[0][0] == (verification_lot, 'verification', verification_lot['id']) mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([ (True, ['all_assets']), (True, ['all_assets']), ]) bot.process_lots( verification_lot ) # assets_available: True; patch_assets: [(True, []), (True, [])]; check_lot: True log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 1] == 'Processing lot 9ee8f769438e403ebfb17b2240aedcf1 in status verification' assert mock_check_assets.call_count == 2 assert mock_check_assets.call_args[0] == (verification_lot, ) assert mock_check_lot.call_count == 2 assert mock_check_lot.call_args[0] == (verification_lot, ) assert mock_patch_assets.call_count == 3 assert mock_patch_assets.call_args_list[1][0] == (verification_lot, 'verification', verification_lot['id']) assert mock_patch_assets.call_args_list[2][0] == (verification_lot, 'active', verification_lot['id']) assert mock_patch_lot.call_count == 1 assert mock_patch_lot.call_args[0] == (verification_lot, 'active.salable') mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([False]) mock_patch_assets.side_effect = iter([]) bot.process_lots( verification_lot ) # assets_available: False; patch_assets: None; check_lot: True log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 2] == 'Processing lot 9ee8f769438e403ebfb17b2240aedcf1 in status verification' assert mock_check_assets.call_count == 3 assert mock_check_assets.call_args[0] == (verification_lot, ) assert mock_check_lot.call_count == 3 assert mock_check_lot.call_args[0] == (verification_lot, ) assert mock_patch_lot.call_count == 2 assert mock_patch_lot.call_args[0] == (verification_lot, 'pending') mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter( [RequestFailed(response=munchify({"text": "Request failed."}))]) mock_patch_assets.side_effect = iter([]) bot.process_lots( verification_lot ) # assets_available: raises exception; patch_assets: None; check_lot: True log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 3] == 'Processing lot 9ee8f769438e403ebfb17b2240aedcf1 in status verification' assert log_strings[ 4] == 'Due to fail in getting assets, lot 9ee8f769438e403ebfb17b2240aedcf1 is skipped' assert mock_check_assets.call_count == 4 assert mock_check_assets.call_args[0] == (verification_lot, ) assert mock_check_lot.call_count == 4 assert mock_check_lot.call_args[0] == (verification_lot, ) # status == 'pending.dissolution' mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([None]) mock_patch_assets.side_effect = iter([(True, ['all_assets'])]) bot.process_lots( pending_dissolution_lot ) # assets_available: None; patch_assets: (True, []); check_lot: True log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 5] == 'Processing lot b844573afaa24e4fb098f3027e605c87 in status pending.dissolution' assert log_strings[ 6] == "Assets {} from lot {} will be patched to 'pending'".format( pending_dissolution_lot['assets'], pending_dissolution_lot['id']) assert mock_check_lot.call_count == 5 assert mock_check_lot.call_args[0] == (pending_dissolution_lot, ) # lot is not available mock_check_lot.side_effect = iter([False]) mock_check_assets.side_effect = iter([]) mock_patch_assets.side_effect = iter([]) bot.process_lots( pending_dissolution_lot ) # assets_available: None; patch_assets: None; check_lot: False log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[7] == 'Skipping lot {}'.format( pending_dissolution_lot['id']) assert mock_check_lot.call_count == 6 assert mock_check_lot.call_args[0] == (pending_dissolution_lot, ) pending_dissolution_lot = lots[2]['data'] mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([False]) mock_patch_assets.side_effect = iter([(False, []), (True, ['all_assets'])]) bot.process_lots(pending_dissolution_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[9] == 'Not valid assets {} in lot {}'.format( pending_dissolution_lot['assets'], pending_dissolution_lot['id']) assert mock_check_lot.call_count == 7 assert mock_check_lot.call_args[0] == (pending_dissolution_lot, ) assert mock_check_assets.call_count == 4 assert mock_patch_assets.call_args[0] == (pending_dissolution_lot, 'pending') recomposed_lot = lots[3]['data'] mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([ (True, ['all_assets']), ]) bot.process_lots(recomposed_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[10] == 'Processing lot {} in status recomposed'.format( recomposed_lot['id']) assert log_strings[ 11] == "Assets {} from lot {} will be patched to 'pending'".format( recomposed_lot['assets'], recomposed_lot['id']) assert mock_check_lot.call_count == 8 assert mock_check_lot.call_args[0] == (recomposed_lot, ) assert mock_patch_lot.call_args[0] == (recomposed_lot, 'pending') assert mock_check_assets.call_count == 4 assert mock_patch_assets.call_args[0] == (recomposed_lot, 'pending') mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([ (False, []), (True, ['all_assets']), ]) bot.process_lots(recomposed_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[12] == 'Processing lot {} in status recomposed'.format( recomposed_lot['id']) assert log_strings[13] == 'Not valid assets {} in lot {}'.format( recomposed_lot['assets'], recomposed_lot['id']) assert mock_check_lot.call_count == 9 assert mock_check_lot.call_args[0] == (recomposed_lot, ) assert mock_patch_lot.call_args[0] == (recomposed_lot, 'pending') assert mock_check_assets.call_count == 4 assert mock_patch_assets.call_args[0] == (recomposed_lot, 'pending') mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([ (True, ['all_assets']), ]) pending_sold_lot = lots[4]['data'] bot.process_lots(pending_sold_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 14] == 'Processing lot {} in status pending.sold'.format( pending_sold_lot['id']) assert log_strings[ 15] == "Assets {} from lot {} will be patched to 'complete'".format( pending_sold_lot['assets'], pending_sold_lot['id']) assert mock_check_lot.call_count == 10 assert mock_check_lot.call_args[0] == (pending_sold_lot, ) assert mock_patch_lot.call_args[0] == (pending_sold_lot, 'sold') assert mock_check_assets.call_count == 4 assert mock_patch_assets.call_args[0] == (pending_sold_lot, 'complete') mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([ (False, []), (True, ['all_assets']), ]) bot.process_lots(pending_sold_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 16] == 'Processing lot {} in status pending.sold'.format( pending_sold_lot['id']) assert log_strings[17] == 'Not valid assets {} in lot {}'.format( pending_sold_lot['assets'], pending_sold_lot['id']) assert mock_check_lot.call_count == 11 assert mock_check_lot.call_args[0] == (pending_sold_lot, ) assert mock_patch_lot.call_args[0] == (pending_sold_lot, 'sold') assert mock_check_assets.call_count == 4 assert mock_patch_assets.call_args[0] == (pending_sold_lot, 'complete') # Test pending.deleted lot pending_deleted_lot = lots[6]['data'] pending_deleted_lot['assets'] = [assets[9]] mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([ (True, ['all_assets']), (True, ['all_assets']), ]) mock_get_asset.side_effect = iter([munchify(assets[9])]) bot.process_lots(pending_deleted_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 18] == 'Processing lot {} in status pending.deleted'.format( pending_deleted_lot['id']) assert mock_check_lot.call_count == 12 assert mock_check_lot.call_args[0] == (pending_deleted_lot, ) assert mock_patch_lot.call_args[0] == (pending_deleted_lot, 'deleted') assert mock_check_assets.call_count == 4 assert mock_patch_assets.call_args[0] == (pending_deleted_lot, 'pending')
def test_patch_assets_pending_fail(bot, logger, mocker): mock_patch_asset = mocker.MagicMock() bot.assets_client.patch_asset = mock_patch_asset with open(ROOT + 'lots.json') as lots: lots = load(lots) with open(ROOT + 'assets.json') as assets: assets = load(assets) lot = lots[1]['data'] status = 'pending' mock_patch_asset.side_effect = [ munchify(assets[4]), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), munchify(assets[6]), munchify(assets[7]) ] result, patched_assets = bot.patch_assets(lot=lot, status=status) assert result is False assert patched_assets == [ '8034c43e2d764006ad6e655e339e5fec', '0a7eba27b22a454180d3a49b02a1842f', '660cbb6e83c94c80baf47691732fd1b2' ] log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 0] == 'Successfully patched asset 8034c43e2d764006ad6e655e339e5fec to pending' assert log_strings[ 2] == 'Successfully patched asset 0a7eba27b22a454180d3a49b02a1842f to pending' assert log_strings[ 3] == 'Successfully patched asset 660cbb6e83c94c80baf47691732fd1b2 to pending' assert log_strings[ 1] == 'Failed to patch asset 5545b519045a4637ab880f032960e034 to pending (Server error: 502)' assert bot.assets_client.patch_asset.call_count == 8 mock_patch_asset.side_effect = [ Forbidden(response=munchify({"text": "Operation is forbidden."})), munchify(assets[5]), munchify(assets[6]), munchify(assets[7]) ] result, patched_assets = bot.patch_assets(lot=lot, status=status) assert result is False assert patched_assets == [ '5545b519045a4637ab880f032960e034', '0a7eba27b22a454180d3a49b02a1842f', '660cbb6e83c94c80baf47691732fd1b2' ] log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 4] == 'Failed to patch asset 8034c43e2d764006ad6e655e339e5fec to pending (Operation is forbidden.)' assert bot.assets_client.patch_asset.call_count == 12
def test__run(self, mocked_logger, mock_get_from_public, mock_registry): self.queue = Queue() self.retry_queue = Queue() self.api_clients_queue = Queue() queue_item = (1, { 'id': uuid.uuid4().hex, 'procurementMethodType': 'closeFrameworkAgreementUA' }) doc = { 'id': queue_item[1], '_rev': '1-{}'.format(uuid.uuid4().hex), 'dateModified': datetime.datetime.utcnow().isoformat(), 'doc_type': 'Tender' } client = MagicMock() api_client_dict = { 'id': uuid.uuid4().hex, 'client': client, 'request_interval': 0 } client.session.headers = {'User-Agent': 'Test-Agent'} self.api_clients_info = { api_client_dict['id']: { 'drop_cookies': False, 'request_durations': [] } } self.db = MagicMock() worker = AgreementWorker(api_clients_queue=self.api_clients_queue, resource_items_queue=self.queue, retry_resource_items_queue=self.retry_queue, db=self.db, api_clients_info=self.api_clients_info, config_dict=self.worker_config) worker.exit = MagicMock() worker.exit.__nonzero__.side_effect = [False, True] # Try get api client from clients queue self.assertEqual(self.queue.qsize(), 0) worker._run() self.assertEqual(self.queue.qsize(), 0) mocked_logger.critical.assert_called_once_with( 'API clients queue is empty.') # Try get item from resource items queue with no handler self.api_clients_queue.put(api_client_dict) worker.exit.__nonzero__.side_effect = [False, True] mock_registry.get.return_value = '' self.queue.put(queue_item) mock_get_from_public.return_value = doc worker._run() self.assertEqual(mocked_logger.critical.call_args_list, [ call('API clients queue is empty.'), call('Not found handler for procurementMethodType: {}, {} {}'. format(doc['id']['procurementMethodType'], self.worker_config['resource'][:-1], doc['id']['id']), extra={ 'JOURNAL_TENDER_ID': doc['id']['id'], 'MESSAGE_ID': 'bridge_worker_exception' }) ]) # Try get item from resource items queue self.api_clients_queue.put(api_client_dict) worker.exit.__nonzero__.side_effect = [False, True] handler_mock = MagicMock() handler_mock.process_resource.return_value = None mock_registry.return_value = { 'closeFrameworkAgreementUA': handler_mock } worker._run() self.assertEqual(mocked_logger.debug.call_args_list[2:], [ call('GET API CLIENT: {} {} with requests interval: {}'.format( api_client_dict['id'], api_client_dict['client'].session.headers['User-Agent'], api_client_dict['request_interval']), extra={ 'REQUESTS_TIMEOUT': 0, 'MESSAGE_ID': 'get_client' }), call('PUT API CLIENT: {}'.format(api_client_dict['id']), extra={'MESSAGE_ID': 'put_client'}), call('Resource items queue is empty.') ]) # Try get resource item from local storage self.queue.put(queue_item) mock_get_from_public.return_value = doc worker.exit.__nonzero__.side_effect = [False, True] worker._run() self.assertEqual(mocked_logger.debug.call_args_list[5:], [ call('GET API CLIENT: {} {} with requests interval: {}'.format( api_client_dict['id'], api_client_dict['client'].session.headers['User-Agent'], api_client_dict['request_interval']), extra={ 'REQUESTS_TIMEOUT': 0, 'MESSAGE_ID': 'get_client' }), call('Get tender {} from main queue.'.format(doc['id']['id'])) ]) # Try get local_resource_item with Exception self.api_clients_queue.put(api_client_dict) self.queue.put(queue_item) mock_get_from_public.return_value = doc self.db.get.side_effect = [Exception('Database Error')] worker.exit.__nonzero__.side_effect = [False, True] worker._run() self.assertEqual(mocked_logger.debug.call_args_list[7:], [ call('GET API CLIENT: {} {} with requests interval: {}'.format( api_client_dict['id'], api_client_dict['client'].session.headers['User-Agent'], api_client_dict['request_interval']), extra={ 'REQUESTS_TIMEOUT': 0, 'MESSAGE_ID': 'get_client' }), call('Get tender {} from main queue.'.format(doc['id']['id'])) ]) # Try process resource with Exception self.api_clients_queue.put(api_client_dict) self.queue.put(queue_item) mock_get_from_public.return_value = doc worker.exit.__nonzero__.side_effect = [False, True] mock_handler = MagicMock() mock_handler.process_resource.side_effect = (RequestFailed(), ) mock_registry.get.return_value = mock_handler worker._run() self.assertEqual(mocked_logger.error.call_args_list, [ call('Error while processing {} {}: {}'.format( self.worker_config['resource'][:-1], doc['id']['id'], 'Not described error yet.'), extra={ 'JOURNAL_TENDER_ID': doc['id']['id'], 'MESSAGE_ID': 'bridge_worker_exception' }) ]) check_queue_item = (queue_item[0] + 1, queue_item[1] ) # priority is increased self.assertEquals(self.retry_queue.get(), check_queue_item) # Try process resource with Exception self.api_clients_queue.put(api_client_dict) self.queue.put(queue_item) mock_get_from_public.return_value = doc worker.exit.__nonzero__.side_effect = [False, True] mock_handler = MagicMock() mock_handler.process_resource.side_effect = (Exception(), ) mock_registry.get.return_value = mock_handler worker._run() self.assertEqual(mocked_logger.error.call_args_list[1:], [ call('Error while processing {} {}: {}'.format( self.worker_config['resource'][:-1], doc['id']['id'], ''), extra={ 'JOURNAL_TENDER_ID': doc['id']['id'], 'MESSAGE_ID': 'bridge_worker_exception' }) ]) check_queue_item = (queue_item[0] + 1, queue_item[1] ) # priority is increased self.assertEquals(self.retry_queue.get(), check_queue_item) # No resource item self.api_clients_queue.put(api_client_dict) self.queue.put(queue_item) mock_get_from_public.return_value = None worker.exit.__nonzero__.side_effect = [False, True] mock_handler = MagicMock() mock_handler.process_resource.side_effect = (Exception(), ) mock_registry.get.return_value = mock_handler worker._run() self.assertEquals(self.queue.empty(), True) self.assertEquals(self.retry_queue.empty(), True)
def test__action_resource_item_from_cdb(self, mock_api_client): item = { 'id': uuid.uuid4().hex, 'dateModified': datetime.datetime.utcnow().isoformat(), 'resource': 'tenders' } api_clients_queue = Queue() api_clients_queue.put({ 'client': mock_api_client, 'request_interval': 0.02}) retry_queue = Queue() return_dict = { 'data': { 'id': item['id'], 'dateModified': datetime.datetime.utcnow().isoformat() } } mock_api_client.get_resource_dump.return_value = return_dict worker = ArchiveWorker(api_clients_queue=api_clients_queue, config_dict=self.worker_config, retry_resource_items_queue=retry_queue, log_dict=self.log_dict) # Success test self.assertEqual(worker.api_clients_queue.qsize(), 1) api_client = worker._get_api_client_dict() self.assertEqual(api_client['request_interval'], 0.02) self.assertEqual(worker.api_clients_queue.qsize(), 0) public_item = worker._action_resource_item_from_cdb(api_client, item) self.assertEqual(worker.retry_resource_items_queue.qsize(), 0) self.assertEqual(public_item, return_dict['data']) # InvalidResponse mock_api_client.get_resource_dump.side_effect = InvalidResponse('invalid response') self.assertEqual(self.log_dict['exceptions_count'], 0) self.assertEqual(worker.retry_resource_items_queue.qsize(), 0) api_client = worker._get_api_client_dict() self.assertEqual(worker.api_clients_queue.qsize(), 0) public_item = worker._action_resource_item_from_cdb(api_client, item) self.assertEqual(public_item, None) self.assertEqual(worker.log_dict['exceptions_count'], 1) self.assertEqual(worker.log_dict['add_to_retry'], 1) sleep(worker.config['retry_default_timeout'] * 2) self.assertEqual(worker.retry_resource_items_queue.qsize(), 1) self.assertEqual(worker.api_clients_queue.qsize(), 1) # RequestFailed status_code=429 mock_api_client.get_resource_dump.side_effect = RequestFailed( munchify({'status_code': 429})) api_client = worker._get_api_client_dict() self.assertEqual(worker.api_clients_queue.qsize(), 0) self.assertEqual(api_client['request_interval'], 0) public_item = worker._action_resource_item_from_cdb(api_client, item) self.assertEqual(public_item, None) self.assertEqual(worker.log_dict['exceptions_count'], 2) self.assertEqual(worker.log_dict['add_to_retry'], 2) sleep(worker.config['retry_default_timeout'] * 2) self.assertEqual(worker.retry_resource_items_queue.qsize(), 2) self.assertEqual(worker.api_clients_queue.qsize(), 1) api_client = worker._get_api_client_dict() self.assertEqual(worker.api_clients_queue.qsize(), 0) self.assertEqual(api_client['request_interval'], worker.config['client_inc_step_timeout']) # RequestFailed status_code=429 with drop cookies api_client['request_interval'] = 2 public_item = worker._action_resource_item_from_cdb(api_client, item) sleep(api_client['request_interval']) self.assertEqual(worker.api_clients_queue.qsize(), 1) self.assertEqual(public_item, None) self.assertEqual(api_client['request_interval'], 0) self.assertEqual(worker.log_dict['exceptions_count'], 3) self.assertEqual(worker.log_dict['add_to_retry'], 3) sleep(worker.config['retry_default_timeout'] * 2) self.assertEqual(worker.retry_resource_items_queue.qsize(), 3) # RequestFailed with status_code not equal 429 mock_api_client.get_resource_dump.side_effect = RequestFailed( munchify({'status_code': 404})) api_client = worker._get_api_client_dict() self.assertEqual(worker.api_clients_queue.qsize(), 0) public_item = worker._action_resource_item_from_cdb(api_client, item) self.assertEqual(public_item, None) self.assertEqual(worker.api_clients_queue.qsize(), 1) self.assertEqual(api_client['request_interval'], 0) self.assertEqual(worker.log_dict['exceptions_count'], 4) self.assertEqual(worker.log_dict['add_to_retry'], 4) sleep(worker.config['retry_default_timeout'] * 2) self.assertEqual(worker.retry_resource_items_queue.qsize(), 4) # ResourceNotFound mock_api_client.get_resource_dump.side_effect = RNF( munchify({'status_code': 404})) api_client = worker._get_api_client_dict() self.assertEqual(worker.api_clients_queue.qsize(), 0) public_item = worker._action_resource_item_from_cdb(api_client, item) self.assertEqual(public_item, None) self.assertEqual(worker.api_clients_queue.qsize(), 1) self.assertEqual(api_client['request_interval'], 0) self.assertEqual(worker.log_dict['exceptions_count'], 4) self.assertEqual(worker.log_dict['add_to_retry'], 4) self.assertEqual(worker.log_dict['not_found_count'], 1) sleep(worker.config['retry_default_timeout'] * 2) self.assertEqual(worker.retry_resource_items_queue.qsize(), 4) # Exception api_client = worker._get_api_client_dict() mock_api_client.get_resource_dump.side_effect = Exception('text except') public_item = worker._action_resource_item_from_cdb(api_client, item) self.assertEqual(public_item, None) self.assertEqual(api_client['request_interval'], 0) self.assertEqual(worker.log_dict['exceptions_count'], 5) self.assertEqual(worker.log_dict['add_to_retry'], 5) sleep(worker.config['retry_default_timeout'] * 2) self.assertEqual(worker.retry_resource_items_queue.qsize(), 5) del worker
def test_create_auction(bot, logger, mocker): mock_dict_from_object = mocker.patch.object(bot, '_dict_from_object', autospec=True) mock_get_next_auction = mocker.patch.object(bot, 'get_next_auction', autospec=True) mock_post_auction = mocker.patch.object(bot, '_post_auction', autospec=True) dict_with_value = {'value': 'value'} mock_dict_from_object.return_value = dict_with_value auction_obj = 'auction' with open(ROOT + 'lots.json') as lots: lots = load(lots) active_salable_lot = lots[7]['data'] # With first auction mock_post_auction.side_effect = iter([auction_obj]) auction = active_salable_lot['auctions'][0] mock_get_next_auction.side_effect = iter([auction]) result = bot._create_auction(active_salable_lot) assert result == (auction_obj, auction['id']) assert mock_dict_from_object.call_count == 1 mock_dict_from_object.assert_called_with(KEYS_FOR_AUCTION_CREATE, active_salable_lot, auction['tenderAttempts'] - 1) assert mock_get_next_auction.call_count == 1 mock_get_next_auction.assert_called_with(active_salable_lot) assert mock_post_auction.call_count == 1 mock_post_auction.assert_called_with(dict_with_value, active_salable_lot['id']) # Tender attempts more than 1 mock_post_auction.side_effect = iter([auction_obj]) data_with_tender_period = deepcopy(dict_with_value) auction = active_salable_lot['auctions'][1] mock_datetime = mocker.patch( 'openregistry.concierge.loki.processing.datetime', autospec=True) mock_get_next_auction.side_effect = iter([auction]) start_date = datetime.now() end_date = start_date + parse_duration( active_salable_lot['auctions'][1]['tenderingDuration']) data_with_tender_period['tenderPeriod'] = { 'startDate': start_date, 'endDate': end_date } mock_datetime.now.return_value = start_date result = bot._create_auction(active_salable_lot) assert result == (auction_obj, auction['id']) assert mock_dict_from_object.call_count == 2 mock_dict_from_object.assert_called_with(KEYS_FOR_AUCTION_CREATE, active_salable_lot, auction['tenderAttempts'] - 1) assert mock_get_next_auction.call_count == 2 mock_get_next_auction.assert_called_with(active_salable_lot) assert mock_post_auction.call_count == 2 mock_post_auction.assert_called_with(data_with_tender_period, active_salable_lot['id']) # When you get error auction = active_salable_lot['auctions'][0] mock_get_next_auction.side_effect = iter([auction]) mock_post_auction.side_effect = iter([ RequestFailed(response=munchify({ "text": "Request failed.", "status_code": 502 })), ]) result = bot._create_auction(active_salable_lot) assert result is None assert mock_dict_from_object.call_count == 3 mock_dict_from_object.assert_called_with(KEYS_FOR_AUCTION_CREATE, active_salable_lot, auction['tenderAttempts'] - 1) assert mock_get_next_auction.call_count == 3 mock_get_next_auction.assert_called_with(active_salable_lot) assert mock_post_auction.call_count == 3 mock_post_auction.assert_called_with(data_with_tender_period, active_salable_lot['id']) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 0] == 'Failed to create auction from lot {} (Server error: 502)'.format( active_salable_lot['id'])
def test_process_lots(bot, logger, mocker): mock_get_asset = mocker.MagicMock() bot.assets_client.get_asset = mock_get_asset mock_check_lot = mocker.patch.object(bot, 'check_lot', autospec=True) mock_patch_auction = mocker.patch.object(bot, '_patch_auction', autospec=True) # mock_check_lot.side_effect = iter([ # True, # True, # True, # True, # True, # False, # True, # True, # True, # True, # True, # ]) mock_check_assets = mocker.patch.object(bot, 'check_assets', autospec=True) # mock_check_assets.side_effect = iter([ # True, # True, # False, # RequestFailed(response=munchify({"text": "Request failed."})), # True, # True, # ]) mock_patch_assets = mocker.patch.object(bot, 'patch_assets', autospec=True) # mock_patch_assets.side_effect = iter([ # (False, []), # (True, []), # (True, ['all_assets']), # (True, ['all_assets']), # (False, []), # (True, ['all_assets']), # (False, []), # (True, ['all_assets']), # (False, []) # ]) mock_patch_lot = mocker.patch.object(bot, 'patch_lot', autospec=True) mock_patch_lot.return_value = True with open(ROOT + 'lots.json') as lots: lots = load(lots) with open(ROOT + 'assets.json') as assets: assets = load(assets) verification_lot = lots[0]['data'] pending_dissolution_lot = lots[1]['data'] # status == 'verification' mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([ (False, []), (True, ['all_assets']), ]) bot.process_lots( verification_lot ) # assets_available: True; patch_assets: [(False, []), (True, []]; check_lot: True log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 0] == 'Processing lot 9ee8f769438e403ebfb17b2240aedcf1 in status verification' assert mock_check_assets.call_count == 1 assert mock_check_assets.call_args[0] == (verification_lot, ) assert mock_check_lot.call_count == 1 assert mock_check_lot.call_args[0] == (verification_lot, ) assert mock_patch_assets.call_count == 1 assert mock_patch_assets.call_args_list[0][0] == (verification_lot, 'verification', verification_lot['id']) mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([ (True, ['all_assets']), (True, ['all_assets']), ]) mock_get_asset.side_effect = iter([munchify(assets[9])]) to_compare = { l_key: assets[9]['data'].get(a_key, None) for a_key, l_key in KEYS_FOR_LOKI_PATCH.items() } asset_decision = deepcopy(assets[9]['data']['decisions'][0]) asset_decision['relatedItem'] = assets[9]['data']['id'] to_compare['decisions'] = [ verification_lot['decisions'][0], asset_decision ] bot.process_lots( verification_lot ) # assets_available: True; patch_assets: [(True, []), (True, [])]; check_lot: True log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 1] == 'Processing lot 9ee8f769438e403ebfb17b2240aedcf1 in status verification' assert mock_check_assets.call_count == 2 assert mock_check_assets.call_args[0] == (verification_lot, ) assert mock_check_lot.call_count == 2 assert mock_check_lot.call_args[0] == (verification_lot, ) assert mock_patch_assets.call_count == 3 assert mock_patch_assets.call_args_list[1][0] == (verification_lot, 'verification', verification_lot['id']) assert mock_patch_assets.call_args_list[2][0] == (verification_lot, 'active', verification_lot['id']) assert mock_patch_lot.call_count == 1 assert mock_patch_lot.call_args[0] == (verification_lot, 'pending', to_compare) mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([False]) mock_patch_assets.side_effect = iter([]) bot.process_lots( verification_lot ) # assets_available: False; patch_assets: None; check_lot: True log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 2] == 'Processing lot 9ee8f769438e403ebfb17b2240aedcf1 in status verification' assert mock_check_assets.call_count == 3 assert mock_check_assets.call_args[0] == (verification_lot, ) assert mock_check_lot.call_count == 3 assert mock_check_lot.call_args[0] == (verification_lot, ) assert mock_patch_lot.call_count == 2 assert mock_patch_lot.call_args[0] == (verification_lot, 'invalid') mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter( [RequestFailed(response=munchify({"text": "Request failed."}))]) mock_patch_assets.side_effect = iter([]) bot.process_lots( verification_lot ) # assets_available: raises exception; patch_assets: None; check_lot: True log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 3] == 'Processing lot 9ee8f769438e403ebfb17b2240aedcf1 in status verification' assert log_strings[ 4] == 'Due to fail in getting assets, lot 9ee8f769438e403ebfb17b2240aedcf1 is skipped' assert mock_check_assets.call_count == 4 assert mock_check_assets.call_args[0] == (verification_lot, ) assert mock_patch_lot.call_count == 2 assert mock_check_lot.call_count == 4 assert mock_check_lot.call_args[0] == (verification_lot, ) # status == 'pending.dissolution' mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([None]) mock_patch_assets.side_effect = iter([(True, ['all_assets'])]) bot.process_lots( pending_dissolution_lot ) # assets_available: None; patch_assets: (True, []); check_lot: True log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 5] == 'Processing lot b844573afaa24e4fb098f3027e605c87 in status pending.dissolution' assert log_strings[ 6] == "Assets {} from lot {} will be patched to 'pending'".format( pending_dissolution_lot['assets'], pending_dissolution_lot['id']) assert mock_patch_lot.call_count == 3 assert mock_patch_lot.call_args[0] == (pending_dissolution_lot, 'dissolved') assert mock_check_lot.call_count == 5 assert mock_check_lot.call_args[0] == (pending_dissolution_lot, ) # lot is not available mock_check_lot.side_effect = iter([False]) mock_check_assets.side_effect = iter([]) mock_patch_assets.side_effect = iter([]) bot.process_lots( pending_dissolution_lot ) # assets_available: None; patch_assets: None; check_lot: False log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[7] == 'Skipping lot {}'.format( pending_dissolution_lot['id']) assert mock_patch_lot.call_count == 3 assert mock_check_lot.call_count == 6 assert mock_check_lot.call_args[0] == (pending_dissolution_lot, ) # Pending dissolution pending_dissolution_lot = lots[2]['data'] mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([False]) mock_patch_assets.side_effect = iter([(False, []), (True, ['all_assets'])]) bot.process_lots(pending_dissolution_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[9] == 'Not valid assets {} in lot {}'.format( pending_dissolution_lot['assets'], pending_dissolution_lot['id']) assert mock_check_lot.call_count == 7 assert mock_check_lot.call_args[0] == (pending_dissolution_lot, ) assert mock_patch_lot.call_count == 4 assert mock_check_assets.call_count == 4 assert mock_patch_assets.call_args[0] == (pending_dissolution_lot, 'pending') # Pending sold lot mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([ (True, ['all_assets']), ]) pending_sold_lot = lots[4]['data'] bot.process_lots(pending_sold_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 10] == 'Processing lot {} in status pending.sold'.format( pending_sold_lot['id']) assert log_strings[ 11] == "Assets {} from lot {} will be patched to 'complete'".format( pending_sold_lot['assets'], pending_sold_lot['id']) assert mock_check_lot.call_count == 8 assert mock_check_lot.call_args[0] == (pending_sold_lot, ) assert mock_patch_lot.call_count == 5 assert mock_patch_lot.call_args[0] == (pending_sold_lot, 'sold') assert mock_check_assets.call_count == 4 assert mock_patch_assets.call_args[0] == (pending_sold_lot, 'complete') mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([ (False, []), (True, ['all_assets']), ]) bot.process_lots(pending_sold_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 12] == 'Processing lot {} in status pending.sold'.format( pending_sold_lot['id']) assert log_strings[13] == 'Not valid assets {} in lot {}'.format( pending_sold_lot['assets'], pending_sold_lot['id']) assert mock_check_lot.call_count == 9 assert mock_check_lot.call_args[0] == (pending_sold_lot, ) assert mock_patch_lot.call_count == 6 assert mock_patch_lot.call_args[0] == (pending_sold_lot, 'sold') assert mock_check_assets.call_count == 4 assert mock_patch_assets.call_args[0] == (pending_sold_lot, 'complete') # Verification lot loki_verfication_lot = lots[5]['data'] mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([ (True, ['all_assets']), (True, ['all_assets']), ]) mock_get_asset.side_effect = iter([munchify(assets[9])]) asset_decision = assets[9]['data']['decisions'][0] asset_decision['relatedItem'] = assets[9]['data']['id'] to_compare = { l_key: assets[9]['data'].get(a_key, None) for a_key, l_key in KEYS_FOR_LOKI_PATCH.items() } to_compare['decisions'] = [ loki_verfication_lot['decisions'][0], assets[9]['data']['decisions'][0], ] bot.process_lots(loki_verfication_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 14] == 'Processing lot {} in status verification'.format( loki_verfication_lot['id']) assert mock_check_lot.call_count == 10 assert mock_check_lot.call_args[0] == (loki_verfication_lot, ) assert mock_patch_lot.call_count == 7 assert mock_patch_lot.call_args[0] == (loki_verfication_lot, 'pending', to_compare) assert mock_check_assets.call_count == 5 assert mock_patch_assets.call_args[0] == (loki_verfication_lot, 'active', loki_verfication_lot['id']) # When something wrong loki_verfication_lot = lots[5]['data'] mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([False]) mock_patch_assets.side_effect = iter([(False, [])]) mock_get_asset.side_effect = iter([munchify(assets[9])]) bot.process_lots(loki_verfication_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 15] == 'Processing lot {} in status verification'.format( loki_verfication_lot['id']) assert mock_check_lot.call_count == 11 assert mock_check_lot.call_args[0] == (loki_verfication_lot, ) assert mock_patch_lot.call_count == 8 assert mock_patch_lot.call_args[0] == (loki_verfication_lot, 'invalid') assert mock_check_assets.call_count == 6 assert mock_patch_assets.call_args[0] == (loki_verfication_lot, 'active', loki_verfication_lot['id']) # Test pending.deleted lot pending_deleted_lot = lots[6]['data'] pending_deleted_lot['assets'] = [assets[9]] mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([ (True, ['all_assets']), (True, ['all_assets']), ]) mock_get_asset.side_effect = iter([munchify(assets[9])]) bot.process_lots(pending_deleted_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 16] == 'Processing lot {} in status pending.deleted'.format( pending_deleted_lot['id']) assert mock_check_lot.call_count == 12 assert mock_check_lot.call_args[0] == (pending_deleted_lot, ) assert mock_patch_lot.call_count == 9 assert mock_patch_lot.call_args[0] == (pending_deleted_lot, 'deleted') assert mock_check_assets.call_count == 6 assert mock_patch_assets.call_args[0] == (pending_deleted_lot, 'pending') # Test active.salable lot mock_create_auction = mocker.patch.object(bot, '_create_auction', autospec=True) mock_check_previous_auction = mocker.patch.object(bot, 'check_previous_auction', autospec=True) active_salable_lot = lots[7]['data'] active_salable_lot['assets'] = [assets[9]] created_auction = munchify( {'data': deepcopy(active_salable_lot['auctions'][0])}) auction_id = 'id_of_auction' internal_id = '1' * 32 created_auction.data.auctionID = auction_id lot_auction_id = '2' * 32 created_auction.data.id = internal_id mock_create_auction.return_value = (created_auction, lot_auction_id) mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([]) mock_get_asset.side_effect = iter([munchify(assets[9])]) bot.process_lots(active_salable_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 18] == 'Processing lot {} in status active.salable'.format( active_salable_lot['id']) assert mock_check_lot.call_count == 13 assert mock_check_lot.call_args[0] == (active_salable_lot, ) patched_data = {'auctionID': created_auction.data.id, 'status': 'active'} assert mock_patch_lot.call_count == 9 assert mock_patch_auction.call_count == 1 mock_patch_auction.assert_called_with(patched_data, active_salable_lot['id'], lot_auction_id) assert mock_create_auction.call_count == 1 mock_create_auction.assert_called_with(active_salable_lot) assert mock_check_assets.call_count == 7 assert mock_check_assets.call_args[0] == (active_salable_lot, 'active') assert mock_check_previous_auction.call_count == 1 mock_check_previous_auction.assert_called_with(active_salable_lot) # Test active.salable lot when it contain not valid auctions active_salable_lot['auctions'][0]['status'] = 'cancelled' active_salable_lot = lots[7]['data'] active_salable_lot['assets'] = [assets[9]] mock_check_lot.side_effect = iter([True]) mock_check_assets.side_effect = iter([True]) mock_patch_assets.side_effect = iter([]) mock_get_asset.side_effect = iter([munchify(assets[9])]) bot.process_lots(active_salable_lot) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 19] == 'Processing lot {} in status active.salable'.format( active_salable_lot['id']) assert mock_check_lot.call_count == 14 assert mock_check_lot.call_args[0] == (active_salable_lot, ) assert mock_patch_lot.call_count == 9 assert mock_create_auction.call_count == 1 mock_create_auction.assert_called_with(active_salable_lot) assert mock_check_assets.call_count == 8 assert mock_check_assets.call_args[0] == (active_salable_lot, 'active') assert mock_check_previous_auction.call_count == 1 mock_check_previous_auction.assert_called_with(active_salable_lot)
def test_patch_auction(bot, logger, mocker): with open(ROOT + 'lots.json') as lots: lots = load(lots) lot = lots[7]['data'] mock_lots_client = bot.lots_client auction = 'auction' auction_id = '1' * 32 # Test when patch is success patched_data = {'auctionID': auction_id, 'status': 'active'} mock_lots_client.patch_resource_item_subitem.side_effect = iter([auction]) result = bot._patch_auction(patched_data, lot['id'], auction_id) assert result == auction assert mock_lots_client.patch_resource_item_subitem.call_count == 1 mock_lots_client.patch_resource_item_subitem.assert_called_with( resource_item_id=lot['id'], patch_data={'data': patched_data}, subitem_name='auctions', subitem_id=auction_id) log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 0] == "Successfully patched auction {} from lot {})".format( auction_id, lot['id']) # Test when post is failed mock_lots_client.patch_resource_item_subitem.side_effect = iter([ RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), ]) try: bot._patch_auction(patched_data, lot['id'], auction_id) except RequestFailed as ex: pass assert isinstance(ex, RequestFailed) is True assert mock_lots_client.patch_resource_item_subitem.call_count == 6 mock_lots_client.patch_resource_item_subitem.assert_called_with( resource_item_id=lot['id'], patch_data={'data': patched_data}, subitem_name='auctions', subitem_id='1' * 32)
def test_patch_assets_pending_fail(bot, logger, mocker): mock_patch_asset = mocker.MagicMock() bot.assets_client.patch_asset = mock_patch_asset with open(ROOT + 'lots.json') as lots: lots = load(lots) with open(ROOT + 'assets.json') as assets: assets = load(assets) lot = lots[1]['data'] status = 'pending' mock_patch_asset.side_effect = [ munchify(assets[4]), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), RequestFailed(response=munchify({ "text": "Bad Gateway", "status_code": 502 })), ] result, patched_assets = bot.patch_assets(lot=lot, status=status) assert result is True assert patched_assets == ['8034c43e2d764006ad6e655e339e5fec'] log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 0] == 'Successfully patched asset 8034c43e2d764006ad6e655e339e5fec to pending' result, patched_assets = bot.patch_assets(lot=lot, status=status) assert result is False assert patched_assets == [] log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 1] == 'Failed to patch asset 8034c43e2d764006ad6e655e339e5fec to pending (Server error: 502)' assert bot.assets_client.patch_asset.call_count == 6 mock_patch_asset.side_effect = [ Forbidden(response=munchify({"text": "Operation is forbidden."})), munchify(assets[4]), ] result, patched_assets = bot.patch_assets(lot=lot, status=status) assert result is False assert patched_assets == [] log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 2] == 'Failed to patch asset 8034c43e2d764006ad6e655e339e5fec to pending (Operation is forbidden.)' result, patched_assets = bot.patch_assets(lot=lot, status=status) assert result is True assert patched_assets == ['8034c43e2d764006ad6e655e339e5fec'] log_strings = logger.log_capture_string.getvalue().split('\n') assert log_strings[ 3] == 'Successfully patched asset 8034c43e2d764006ad6e655e339e5fec to pending' assert bot.assets_client.patch_asset.call_count == 8