async def do_data(self): """ Read new lines from the log file and enqueue any new actions""" while True: try: line = self.file_obj.readline() except ValueError: break if line is None: await asyncio.sleep(1) else: try: action = parse.handle_line(line, self.active_items) if action is not None: print('enqueued a line', line) self.queue.put(('', action)) if action['action'] == 'AUCTION_START': self.active_items.add(action['item_name']) if action['action'] in ['AUCTION_CLOSE', 'AUCTION_CANCEL', 'AUCTION_AWARD']: self.active_items.discard(action['item_name']) except Exception: print('PARSE ERROR') print('LINE', line) print(traceback.format_exc()) print('') print('thread completed')
def test_failed_bid_case(): auc = auction.AuctionState() lines = [ "[Wed Jun 23 23:24:33 2019] You tell your raid, '!Bids open !2 Cloak of Flames'", "[Wed Jun 23 23:07:49 2019] Foo -> Quaff: Cloak of Flames 35", "[Wed Jun 23 23:07:49 2019] Bar -> Quaff: Cloak of Flames 56", "[Wed Jun 23 23:07:49 2019] Bar -> Quaff: I don't understand the rules, help?", ] for line in lines: action = parse.handle_line(line, set(['Cloak of Flames'])) # we assume that every action was parsed properly. parse failures will cause a type error here update = auc.update(action) assert update.status_messages[ 0] == "Failed to parse bid: Bar -> Quaff: I don't understand the rules, help?"
def test_whole_auction_case_4(): auc = auction.AuctionState() lines = [ "[Wed Jun 23 23:24:33 2019] You tell your raid, '!Bids open !2 Cloak of Flames'", "[Wed Jun 23 23:07:49 2019] Foo -> Quaff: Cloak of Flames 35", "[Wed Jun 23 23:07:49 2019] Bar -> Quaff: Cloak of Flames 56", "[Wed Jun 23 23:24:33 2019] You tell your raid, '!Bids closed Cloak of Flames '", "[Wed Jun 23 23:24:34 2019] You tell your raid, '!correction !award Cloak of Flames !to Baz 30'", ] for line in lines: action = parse.handle_line(line, set(['Cloak of Flames'])) # we assume that every action was parsed properly. parse failures will cause a type error here update = auc.update(action) assert len(auc.concluded_auctions) == 1 assert update.update_rows[0].winner == 'Baz' assert update.update_rows[0].price == '30'
def test_whole_auction_case_1(): auc = auction.AuctionState() lines = [ "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids open Cloak of Flames'", "[Wed Jun 12 23:07:49 2019] Foobar -> Quaff: Cloak of Flames 10", "[Wed Jun 12 23:07:49 2019] Playerone -> Quaff: Cloak of Flames 10", "[Wed Jun 12 23:07:49 2019] Playerone -> Quaff: Cloak of Flames 11", "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids closed Cloak of Flames '", ] for line in lines: # we assume that every action was parsed properly. parse failures will cause a type error here action = parse.handle_line(line, set(['Cloak of Flames'])) auc.update(action) finished_auction = auc.concluded_auctions[0] assert finished_auction['item'] == 'Cloak of Flames' assert len(finished_auction['bids']) == 2
def test_failed_bid_case(): auc = auction.AuctionState("Tester") lines = [ "[Wed Jun 23 23:24:33 2019] You tell your raid, '!Bids open !2 Cloak of Flames'", "[Wed Jun 23 23:07:49 2019] Foo tells you, 'Cloak of Flames 35'", "[Wed Jun 23 23:07:49 2019] Bar tells you, 'Cloak of Flames 56'", "[Wed Jun 23 23:07:49 2019] Bar tells you, 'I don't understand the rules, help?", ] for line in lines: actions = parse.handle_line(line, set(['Cloak of Flames'])) # we assume that every action was parsed properly. parse failures will cause a type error here if not isinstance(actions, list): actions = [actions] for action in actions: update = auc.update(action) assert update.status_messages[ 0] == "Failed to parse bid: Bar tells you, 'I don't understand the rules, help?"
def test_preregister_bid_alt(): auc = auction.AuctionState("Tester") lines = [ "[Wed Jun 12 23:24:32 2019] You told Grunt, '!preregister Cloak of Flames 20 alt'", "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids open Cloak of Flames'", "[Wed Jun 12 23:07:49 2019] Foobar tells you, 'Cloak of Flames 5'", "[Wed Jun 12 23:07:49 2019] Playerone tells you, 'Cloak of Flames 5'", "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids closed Cloak of Flames '", ] body = { 'message': 'Cloak of Flames awarded to - Tester for 1', 'warnings': [] } responses.add(responses.POST, 'http://padkp.net/api/resolve_auction/', json=body) for line in lines: # we assume that every action was parsed properly. parse failures will cause a type error here actions = parse.handle_line(line, set(['Cloak of Flames'])) if not isinstance(actions, list): actions = [actions] for action in actions: update = auc.update(action) data = json.loads(responses.calls[0].request.body) finished_auction = auc.concluded_auctions['Cloak of Flames'] assert finished_auction['item'] == 'Cloak of Flames' assert len(finished_auction['bids']) == 6 assert update.update_rows[ 0].winner == 'Cloak of Flames awarded to - Tester for 1' assert data['bids'] == [{ 'name': 'Tester', 'bid': 20, 'tag': 'ALT' }, { 'name': "Foobar", 'bid': 5, 'tag': '' }, { 'name': 'Playerone', 'bid': 5, 'tag': '' }]
def test_preregister_bid(): auc = auction.AuctionState() auc.my_name = "Tester" lines = [ "[Wed Jun 12 23:24:32 2019] You told Grunt, '!preregister Cloak of Flames 20'", "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids open Cloak of Flames'", "[Wed Jun 12 23:07:49 2019] Foobar -> Quaff: Cloak of Flames 10", "[Wed Jun 12 23:07:49 2019] Playerone -> Quaff: Cloak of Flames 10", "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids closed Cloak of Flames '", ] for line in lines: # we assume that every action was parsed properly. parse failures will cause a type error here action = parse.handle_line(line, set(['Cloak of Flames'])) update = auc.update(action) finished_auction = auc.concluded_auctions[0] assert finished_auction['item'] == 'Cloak of Flames' assert len(finished_auction['bids']) == 3 assert update.update_rows[0].winner == 'Tester' assert update.update_rows[0].price == '20'
def test_whole_auction_correction_after_close_multibid_case(): auc = auction.AuctionState("Tester") lines = [ "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids open !2 Cloak of Flames'", "[Wed Jun 12 23:07:49 2019] Foobar tells you, 'Cloak of Flames 10'", "[Wed Jun 12 23:07:49 2019] Playerone tells you, 'Cloak of Flames 10'", "[Wed Jun 12 23:07:49 2019] Playerone tells you, 'Cloak of Flames 11, 15 alt'", "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids closed Cloak of Flames '", "[Wed Jun 23 23:24:34 2019] You tell your raid, '!correction !award Cloak of Flames !to Baz 30, Foobar 15'", ] body = { 'message': 'Cloak of Flames awarded to - Tester for 1', 'warnings': [] } responses.add(responses.POST, 'http://padkp.net/api/resolve_auction/', json=body) responses.add(responses.POST, 'http://padkp.net/api/correct_auction/', json=body) for line in lines: # we assume that every action was parsed properly. parse failures will cause a type error here actions = parse.handle_line(line, set(['Cloak of Flames'])) if not isinstance(actions, list): actions = [actions] for action in actions: update = auc.update(action) close_finger = json.loads(responses.calls[0].request.body)['fingerprint'] correct_finger = json.loads(responses.calls[1].request.body)['fingerprint'] data = json.loads(responses.calls[1].request.body) assert len(auc.concluded_auctions) == 1 assert close_finger == correct_finger assert data['bids'] == [{ 'name': 'Baz', 'bid': '30' }, { 'name': 'Foobar', 'bid': '15' }]
def test_whole_auction_cancel_pre_close_case(): auc = auction.AuctionState("Tester") lines = [ "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids open Cloak of Flames'", "[Wed Jun 12 23:07:49 2019] Foobar tells you, 'Cloak of Flames 10'", "[Wed Jun 12 23:07:49 2019] Playerone tells you, 'Cloak of Flames 10'", "[Wed Jun 12 23:07:49 2019] Playerone tells you, 'Cloak of Flames 11, 15 alt'", "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Cancel Cloak of Flames '", ] for line in lines: # we assume that every action was parsed properly. parse failures will cause a type error here actions = parse.handle_line(line, set(['Cloak of Flames'])) if not isinstance(actions, list): actions = [actions] for action in actions: update = auc.update(action) assert len(auc.concluded_auctions) == 0 assert auc.active_auctions == {}
def test_whole_auction_case_2(): auc = auction.AuctionState() lines = [ "[Wed Jun 12 23:01:33 2019] You tell your raid, '!Bids open Green Dragon Scale'", "[Wed Jun 12 23:02:49 2019] Foobar -> Quaff: Cloak of Flames 10", "[Wed Jun 12 23:03:49 2019] Foobar -> Quaff: Green Dragon Scale 10", "[Wed Jun 12 23:04:49 2019] Grunt -> Quaff: Green Dragon Scale 4", "[Wed Jun 12 23:05:49 2019] Papapa -> Quaff: Green Dragon Scale 5", "[Wed Jun 12 23:06:49 2019] Baz -> Quaff: Green Dragon Scale 10", "[Wed Jun 12 23:07:33 2019] You tell your raid, '!Bids closed Green Dragon Scale'", ] for line in lines: action = parse.handle_line( line, set(['Cloak of Flames', 'Green Dragon Scale'])) auc.update(action) assert len( auc.concluded_auctions) == 0 # bids are tied, auction wasn't completed tied_auction = list(auc.active_auctions.values())[0] assert tied_auction['item'] == 'Green Dragon Scale' assert len(tied_auction['bids']) == 4
def test_whole_auction_case_3(): auc = auction.AuctionState() lines = [ "[Wed Jun 12 23:01:33 2019] You tell your raid, '!Bids open Amulet of Necropotence'", "[Wed Jun 12 23:07:49 2019] Foo -> Quaff: Amulet of Necropotence 90", "[Wed Jun 12 23:07:49 2019] Bar -> Quaff: Amulet of Necropotence 112 ALT", "[Wed Jun 12 23:07:49 2019] Baz -> Quaff: Amulet of Necropotence 75", "[Wed Jun 12 23:07:49 2019] Qux -> Quaff: Amulet of Necropotence 40", "[Wed Jun 12 23:07:49 2019] Quux -> Quaff: Amulet of Necropotence 2", "[Wed Jun 12 23:07:49 2019] Thud -> Quaff: Amulet of Necropotence 89", "[Wed Jun 12 23:07:49 2019] Waldo -> Quaff: Amulet of Necropotence 13", "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids closed Amulet of Necropotence'", ] for line in lines: action = parse.handle_line(line, set(['Amulet of Necropotence'])) # we assume that every action was parsed properly. parse failures will cause a type error here update = auc.update(action) assert len(auc.concluded_auctions) == 1 assert len(update.update_rows) == 1 assert update.update_rows[0].winner == 'Foo'
def test_whole_auction_case_1(): auc = auction.AuctionState("Tester") lines = [ "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids open Cloak of Flames'", "[Wed Jun 12 23:07:49 2019] Foobar tells you, 'Cloak of Flames 10'", "[Wed Jun 12 23:07:49 2019] Playerone tells you, 'Cloak of Flames 10'", "[Wed Jun 12 23:07:49 2019] Playerone tells you, 'Cloak of Flames 11'", "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids closed Cloak of Flames '", ] body = { 'message': 'Cloak of Flames awarded to - Playerone for 11', 'warnings': [] } responses.add(responses.POST, 'http://padkp.net/api/resolve_auction/', json=body) for line in lines: # we assume that every action was parsed properly. parse failures will cause a type error here actions = parse.handle_line(line, set(['Cloak of Flames'])) if not isinstance(actions, list): actions = [actions] for action in actions: auc.update(action) data = json.loads(responses.calls[0].request.body) finished_auction = auc.concluded_auctions['Cloak of Flames'] assert finished_auction['item'] == 'Cloak of Flames' assert len(finished_auction['bids']) == 4 assert data['bids'] == [{ 'name': 'Foobar', 'bid': 10, 'tag': '' }, { 'name': 'Playerone', 'bid': 11, 'tag': '' }] assert data['item_name'] == 'Cloak of Flames' assert data['item_count'] == 1
def test_whole_auction_cancel_after_close_case(): auc = auction.AuctionState("Tester") lines = [ "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids open Cloak of Flames'", "[Wed Jun 12 23:07:49 2019] Foobar tells you, 'Cloak of Flames 10'", "[Wed Jun 12 23:07:49 2019] Playerone tells you, 'Cloak of Flames 10'", "[Wed Jun 12 23:07:49 2019] Playerone tells you, 'Cloak of Flames 11, 15 alt'", "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids closed Cloak of Flames '", "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Cancel Cloak of Flames '", ] body = { 'message': 'Cloak of Flames awarded to - Tester for 1', 'warnings': [] } responses.add(responses.POST, 'http://padkp.net/api/resolve_auction/', json=body) responses.add(responses.POST, 'http://padkp.net/api/cancel_auction/', json=body) for line in lines: # we assume that every action was parsed properly. parse failures will cause a type error here actions = parse.handle_line(line, set(['Cloak of Flames'])) if not isinstance(actions, list): actions = [actions] for action in actions: update = auc.update(action) close_finger = json.loads(responses.calls[0].request.body)['fingerprint'] cancel_finger = json.loads(responses.calls[1].request.body)['fingerprint'] assert len(auc.concluded_auctions) == 0 assert auc.active_auctions == {} assert close_finger == cancel_finger
def test_bad_open_bid(): result = parse.handle_line(AUCTION_OPEN_BAD_CHARACTERS, DEFAULT_ITEMS) assert result is None
def test_failed_bid_outside_auctions(): result = parse.handle_line(FAILED_BID, set()) assert result is None
def test_failed_close_bid(): result = parse.handle_line(FAILED_BID_TYPO, DEFAULT_ITEMS) assert result is not None assert result['action'] == 'FAILED_BID'
def test_whole_auction_case_3(): auc = auction.AuctionState("Tester") lines = [ "[Wed Jun 12 23:01:33 2019] You tell your raid, '!Bids open Amulet of Necropotence'", "[Wed Jun 12 23:01:34 2019] You tell your raid, '!Bids open Amulet of Awesome'", "[Wed Jun 12 23:07:49 2019] Foo tells you, 'Amulet of Necropotence 90'", "[Wed Jun 12 23:07:49 2019] Bar tells you, 'Amulet of Necropotence 112 ALT'", "[Wed Jun 12 23:07:49 2019] Baz tells you, 'Amulet of Necropotence 75'", "[Wed Jun 12 23:07:49 2019] Qux tells you, 'Amulet of Necropotence 40'", "[Wed Jun 12 23:07:50 2019] Qux tells you, 'Amulet of Awesome 40'", "[Wed Jun 12 23:07:49 2019] Quux tells you, 'Amulet of Necropotence 2'", "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids closed Amulet of Awesome'", "[Wed Jun 12 23:07:49 2019] Thud tells you, 'Amulet of Necropotence 89'", "[Wed Jun 12 23:07:49 2019] Waldo tells you, 'Amulet of Necropotence 13'", "[Wed Jun 12 23:24:33 2019] You tell your raid, '!Bids closed Amulet of Necropotence'", ] body = { 'message': 'Cloak of Flames awarded to - Foo for 1', 'warnings': ['bad bid 1', 'bad bid 2'] } responses.add(responses.POST, 'http://padkp.net/api/resolve_auction/', json=body) for line in lines: actions = parse.handle_line( line, set(['Amulet of Necropotence', 'Amulet of Awesome'])) # we assume that every action was parsed properly. parse failures will cause a type error here if not isinstance(actions, list): actions = [actions] for action in actions: update = auc.update(action) data = json.loads(responses.calls[1].request.body) assert len(auc.concluded_auctions) == 2 assert len(update.update_rows) == 1 assert update.update_rows[ 0].winner == 'Cloak of Flames awarded to - Foo for 1' assert data['bids'] == [{ 'name': 'Foo', 'bid': 90, 'tag': '' }, { 'name': "Bar", 'bid': 112, 'tag': 'ALT' }, { 'name': 'Baz', 'bid': 75, 'tag': '' }, { 'name': 'Qux', 'bid': 40, 'tag': '' }, { 'name': 'Quux', 'bid': 2, 'tag': '' }, { 'name': 'Thud', 'bid': 89, 'tag': '' }, { 'name': 'Waldo', 'bid': 13, 'tag': '' }] assert update.update_rows[0].warnings == 'bad bid 1, bad bid 2'