def test_transition_events(storage): """It should call the appropriate functions on every state transition.""" class Listener(CircuitBreakerListener): def __init__(self): self.out = [] def state_change(self, breaker, old, new): assert breaker self.out.append((old.state, new.state)) listener = Listener() breaker = CircuitBreaker(listeners=(listener, ), state_storage=storage) assert CircuitBreakerState.CLOSED == breaker.current_state breaker.open() assert CircuitBreakerState.OPEN == breaker.current_state breaker.half_open() assert CircuitBreakerState.HALF_OPEN == breaker.current_state breaker.close() assert CircuitBreakerState.CLOSED == breaker.current_state assert [(CircuitBreakerState.CLOSED, CircuitBreakerState.OPEN), (CircuitBreakerState.OPEN, CircuitBreakerState.HALF_OPEN), (CircuitBreakerState.HALF_OPEN, CircuitBreakerState.CLOSED) ] == listener.out
def test_close(storage): """It should allow the circuit to be closed manually.""" breaker = CircuitBreaker(fail_max=3, state_storage=storage) breaker.open() assert 0 == breaker.fail_counter assert CircuitBreakerState.OPEN == breaker.current_state breaker.close() assert 0 == breaker.fail_counter assert CircuitBreakerState.CLOSED == breaker.current_state
class TestMAPEIntegration(TestCase): async def setUp(self): self.monitor = Monitor("monitor@localhost", "passw0rd", "data0") self.engine = create_engine("sqlite:///database.sql") self.breaker = CircuitBreaker() self.cache_to_save = 10 self.connection = Connection(self.engine, self.cache_to_save, 100000, self.breaker) self.analyser_predictor = HelperAnalyserPredictor(self.connection) self.sink = HelperSink(self.breaker) self.sink.external.reset_mock() self.analyser = Analyser("analyser@localhost", "passw0rd", self.analyser_predictor, self.connection, ["monitor@localhost"]) self.executor = Executor("executor@localhost", "passw0rd", self.sink) self.planner_predictor = HelperPlannerPredictor(self.connection) self.planner = Planner("planner@localhost", "passw0rd", self.planner_predictor, ["executor@localhost"]) self.monitor.start() self.executor.start() await asyncio.sleep(2) self.analyser.start() self.planner.start() await asyncio.sleep(2) def tearDown(self): self.monitor.stop() self.analyser.stop() self.planner.stop() self.executor.stop() self.breaker.close() os.unlink("database.sql") @patch("driftage.planner.behaviour.predict.datetime") async def test_should_execute_monitored_data(self, mock_dt): now = datetime.utcnow() mock_dt.utcnow.return_value = now for i in range(self.cache_to_save): self.monitor({"my data": i}) await asyncio.sleep(1) self.sink.external.assert_called_once_with({ 'timestamp': now.timestamp(), 'identifier': 'data0', 'predicted': True })
class TestMonitorAnalyseIntegration(TestCase): async def setUp(self): self.monitor = Monitor("monitor@localhost", "passw0rd", "data0") self.engine = create_engine("sqlite:///database.sql") self.breaker = CircuitBreaker() self.connection = Connection(self.engine, 10, 10000, self.breaker) self.predictor = HelperAnalyserPredictor(self.connection) self.analyser = Analyser("analyser@localhost", "passw0rd", self.predictor, self.connection, ["monitor@localhost"]) self.monitor.start() await asyncio.sleep(2) self.analyser.start() await asyncio.sleep(1) def tearDown(self): self.monitor.stop() self.analyser.stop() self.breaker.close() os.unlink("database.sql") async def test_should_analyse_monitored_data(self): dt_from = datetime.utcnow() for i in range(10): self.monitor({"my data": i}) dt_to = datetime.utcnow() time.sleep(1) df = await self.connection.get_between( table.c.driftage_datetime_monitored, dt_from, dt_to) self.assertEqual(len(df.index), 10) async def test_should_not_save_monitored_data_less_than_bulk(self): dt_from = datetime.utcnow() for i in range(9): self.monitor({"my data": i}) dt_to = datetime.utcnow() time.sleep(1) df = await self.connection.get_between( table.c.driftage_datetime_monitored, dt_from, dt_to) self.assertEqual(len(df.index), 0)
class TestPlannerExecutorIntegration(TestCase): async def setUp(self): if not path.exists("test/resources/database.dump"): raise IOError("database not exists") self.engine = create_engine("sqlite:///test/resources/database.dump") self.breaker = CircuitBreaker() self.connection = Connection(self.engine, 10, 10000, self.breaker) self.sink = HelperSink(self.breaker) self.sink.external.reset_mock() self.executor = Executor("executor@localhost", "passw0rd", self.sink) self.planner_predictor = HelperPlannerPredictor(self.connection) self.cache_number = 3 self.planner = Planner("planner@localhost", "passw0rd", self.planner_predictor, ["executor@localhost"], self.cache_number) def tearDown(self): self.planner_predictor.send = True self.planner.stop() self.executor.stop() self.breaker.close() @patch("driftage.planner.behaviour.predict.datetime") async def test_should_export_to_sink(self, mock_dt): now = datetime.utcnow() mock_dt.utcnow.return_value = now self.executor.start() await asyncio.sleep(2) self.planner.start() await asyncio.sleep(3) self.sink.external.assert_called_with({ "timestamp": now.timestamp(), "identifier": "data0", "predicted": True }) async def test_should_not_export_to_sink_if_unavailable(self): self.executor.start() self.executor.sink.available = False await asyncio.sleep(2) self.planner.start() await asyncio.sleep(3) self.sink.external.assert_not_called() async def test_should_continualy_export_to_sink(self): self.executor.start() await asyncio.sleep(2) self.planner.start() await asyncio.sleep(2) for i in range(1, 5): self.assertGreaterEqual(self.sink.external.call_count, i) self.assertLessEqual(self.sink.external.call_count, i + 1) await asyncio.sleep(self.planner_predictor.predict_period) async def test_should_wait_executor_up(self): self.executor.start() await asyncio.sleep(2) self.planner.start() self.executor.stop() await asyncio.sleep(self.cache_number + 2) self.assertEqual(len(self.planner.cache), self.cache_number) self.assertEqual(len(self.planner.sent_data.values()), 0) self.executor.start() await asyncio.sleep(2) self.assertEqual(len(self.planner.cache), self.cache_number) self.assertEqual(len(self.planner.sent_data.values()), 1) self.assertEqual(len(list(self.planner.sent_data.values())[0]), self.cache_number) async def test_should_never_send_if_predictor_say(self): self.executor.start() await asyncio.sleep(2) self.planner_predictor.send = False self.planner.start() await asyncio.sleep(2) self.planner_predictor.send = True await asyncio.sleep(1) self.assertEqual(len(self.planner.cache), 1) self.assertEqual(len(self.planner.sent_data.values()), 1) self.planner_predictor.send = False await asyncio.sleep(1) await asyncio.sleep(self.cache_number) self.assertEqual(len(self.planner.cache), 1) self.assertEqual(len(self.planner.sent_data.values()), 1)