def test_availability_tracker_integration(blockchain_ursulas, monkeypatch): # Start up self-services ursula = blockchain_ursulas.pop() start_pytest_ursula_services(ursula=ursula) ursula._availability_tracker = AvailabilityTracker(ursula=ursula) def maintain(): tracker = ursula._availability_tracker def mock_node_information_endpoint(middleware, port, *args, **kwargs): ursula_were_looking_for = ursula.rest_interface.port == port if ursula_were_looking_for: raise RestMiddleware.NotFound( "Fake Reason") # Make this node unreachable else: response = Response(response=bytes(ursula), mimetype='application/octet-stream') return response # apply the monkeypatch for requests.get to mock_get monkeypatch.setattr(NucypherMiddlewareClient, NucypherMiddlewareClient.node_information.__name__, mock_node_information_endpoint) ursula._availability_tracker.start() tracker.measure_sample() # This makes a REST Call start, timeout = maya.now(), 1 # seconds while True: try: assert len(tracker.excuses) except AssertionError: now = maya.now() if (now - start).total_seconds() > timeout: pytest.fail() time.sleep(0.1) continue else: break # Run the Callbacks try: d = threads.deferToThread(maintain) yield d finally: if ursula._availability_tracker: ursula._availability_tracker.stop() ursula._availability_tracker = None
def test_availability_tracker_success(blockchain_ursulas): # Start up self-services ursula = blockchain_ursulas.pop() start_pytest_ursula_services(ursula=ursula) ursula._availability_tracker = AvailabilityTracker(ursula=ursula) def measure(): ursula._availability_tracker.start() assert ursula._availability_tracker.score == 10 ursula._availability_tracker.record(False) assert ursula._availability_tracker.score == 9.0 for i in range(7): ursula._availability_tracker.record(True) assert ursula._availability_tracker.score > 9.5 def maintain(): tracker = ursula._availability_tracker tracker.maintain() # The node goes offline for some time... for _ in range(10): ursula._availability_tracker.record( False, reason={'error': 'fake failure reason'}) assert tracker.score < 4 assert tracker.status() == ( tracker.score > (tracker.SENSITIVITY * tracker.MAXIMUM_SCORE)) assert not tracker.status() original_issuer = AvailabilityTracker.issue_warnings warnings = dict() def issue_warnings(tracker, *args, **kwargs): result = original_issuer(tracker, *args, **kwargs) warnings[tracker.score] = result AvailabilityTracker.issue_warnings = issue_warnings tracker.maintain() assert warnings AvailabilityTracker.issue_warnings = original_issuer # to keep this test fast, were just checking for a single entry # (technically there will be 10, but resolution is one second.) assert len(tracker.excuses) > 0 def raise_to_maximum(): tracker = ursula._availability_tracker for i in range(150): tracker.record(True) assert tracker.score > 9.98 assert tracker.status() == bool( tracker.score > (tracker.SENSITIVITY * tracker.MAXIMUM_SCORE)) assert tracker.status() # Run the Callbacks try: d = threads.deferToThread(measure) yield d d = threads.deferToThread(maintain) yield d d = threads.deferToThread(raise_to_maximum) yield d finally: if ursula._availability_tracker: ursula._availability_tracker.stop() ursula._availability_tracker = None