def test_double_item_pass(self): """Tests if the agent can handle more than a single item correctly""" class LocalDataStore(self.FakeDataStore): def __init__(self): self.item1_history = [Decimal(500)] self.item2_history = [Decimal(1000)] def get_item_ids(self): return ["item1.html", "item2.html"] def get_item_history(self, id): if id == "item1.html": return self.item1_history elif id == "item2.html": return self.item2_history else: return super().get_item_history(id) def set_item_history(self, key, history): print("setting price key = '" + key + "', value = '" + str(history) + "'") self.modified = True if key == "item1.html": self.item1_history = history elif key == "item2.html": self.item2_history = history else: raise KeyError("Item '" + key + "' not mocked") class LocalEngine(self.TestEngine): def __init__(self): pass def fetch(self, server_url, item_id): if item_id == "item1.html": return Decimal(385) elif item_id == "item2.html": return Decimal(999) assert False notifier = self.TestNotifier() engine = LocalEngine() data_store = LocalDataStore() agent = Agent(data_store) agent.execute(notifier, engine) history1 = data_store.get_item_history("item1.html") history2 = data_store.get_item_history("item2.html") self.assertTrue(len(history1) == 2) self.assertTrue(history1[-1] == Decimal(385)) self.assertTrue(len(history2) == 2) self.assertTrue(history2[-1] == Decimal(999)) self.assertTrue(data_store.modified) self.assertTrue(notifier.notified) self.assertTrue(len(notifier.messages) == 2)
def exec(): data_stores = load_config("config.json", deserializer) for ds in data_stores: notifier = find_notifier(ds.task_id) engine = find_engine(ds.task_id) agent = Agent(ds) agent.execute(notifier, engine) save_config(data_stores, "config.json", serializer)
def test_invalid_history_length(self): """Tests what happens if the agent is given an invalid history length""" class LocalDataStore(self.FakeDataStore): def get_config_value(self, key): if key == "max_history_length": return 0 else: return super().get_config_value(key) notifier = self.TestNotifier() engine = self.TestEngine() data_store = LocalDataStore() agent = Agent(data_store) with self.assertRaises(RuntimeError): agent.execute(notifier, engine)
def test_single_item_pass(self): """Tests if the agent can handle a single item normally that passes on""" notifier = self.TestNotifier() engine = self.TestEngine() data_store = self.FakeDataStore() agent = Agent(data_store) agent.execute(notifier, engine) history = data_store.get_item_history("item1.html") self.assertTrue(len(history) == 2) self.assertTrue(history[-1] == Decimal(385) and history[-2] == Decimal(500)) self.assertTrue(data_store.modified) self.assertTrue(notifier.notified) self.assertTrue(len(notifier.messages) == 1)
def test_execution(self): """This end to end test starts a mock server, requests an item from it and checks if a mock data store is updated properly.""" # create mock data store data_store = self.FakeDataStore("TEST_E2E1") notifier = self.TestNotifier() # create and execute the agent agent = Agent(data_store) agent.execute(notifier, self.TestEngine()) # verify that the new cost is correct history = data_store.get_item_history("item1.html") self.assertTrue(len(history) == 2) self.assertAlmostEqual(history[1], 370.00) # assert that notifier works properly self.assertEqual(len(notifier.messages), 1) self.assertTrue(notifier.alerted)
def test_history_grows_too_large(self): """Tests the agent's behavior when the history grows larger than the limit""" class LocalDataStore(self.FakeDataStore): def __init__(self): self.item_history = [Decimal(500), Decimal(650)] notifier = self.TestNotifier() engine = self.TestEngine() data_store = LocalDataStore() agent = Agent(data_store) agent.execute(notifier, engine) history = data_store.get_item_history("item1.html") self.assertTrue(len(history) == 2) self.assertTrue(history[-2] == Decimal(650) and history[-1] == Decimal(385)) self.assertTrue(data_store.modified) self.assertTrue(notifier.notified) self.assertTrue(len(notifier.messages) == 1)
def test_single_item_fail(self): """Tests the agent's behavior when a single item fails on comparison""" class LocalEngine(self.TestEngine): def __init__(self): pass def fetch(self, server_url, item_id): return Decimal(685) notifier = self.TestNotifier() engine = LocalEngine() data_store = self.FakeDataStore() agent = Agent(data_store) agent.execute(notifier, engine) history = data_store.get_item_history("item1.html") self.assertTrue(len(history) == 2) self.assertTrue(history[-1] == Decimal(685)) self.assertTrue(data_store.modified) self.assertTrue(notifier.notified) self.assertTrue(len(notifier.messages) == 0)
def test_execution(self): """Tests the execution of the system by reading a configuration file, fetching requests from a dummy server, checking if the notification component is used properly, and if the persistence component works as expected.""" # load data stores from configuration file def deserialize(task, data_str): if task == "TEST1": return Decimal(data_str) elif task == "TEST2": return Decimal(data_str) else: raise RuntimeError("Task not implemented") input_data_stores = load_config("./test/input_config.json", deserialize) # load the engines and notifiers notifiers = [find_notifier(input_data_stores[0].task_id), find_notifier(input_data_stores[1].task_id)] engines = [find_engine(input_data_stores[0].task_id), find_engine(input_data_stores[1].task_id)] for i in range(len(input_data_stores)): # check that we only have one price in history (in our config) before_items = input_data_stores[i].get_item_ids() for it in before_items: assert(len(input_data_stores[i].get_item_history(it)) == 1) # create and execute the agent agent = Agent(input_data_stores[i]) agent.execute(notifiers[i], engines[i]) # check if we fetched an additional price after_items = input_data_stores[i].get_item_ids() assert before_items == after_items for it in after_items: assert (len(input_data_stores[i].get_item_history(it)) == 2) # assert that notifier works properly if input_data_stores[i].task_id == "TASK1": self.assertEqual(len(notifiers[i].messages), 2) elif input_data_stores[i].task_id == "TASK2": self.assertEqual(len(notifiers[i].messages), 2) self.assertTrue(notifiers[i].alerted) # check that persistence works fine def serialize(task, data_point): if task == "TEST1": return str(data_point) elif task == "TEST2": return str(data_point) else: raise RuntimeError("Task not implemented") save_config(input_data_stores, "./test/output_config.json", serialize) output_data_stores = load_config("./test/output_config.json", deserialize) assert input_data_stores == output_data_stores os.remove("./test/output_config.json")