async def _wait_for_channel( host: str, port: int, timeout: float = CONNECTION_TIMEOUT, ssl_context: Optional[ssl.SSLContext] = None, ) -> Channel: logger.debug('Starting service health check') request = HealthCheckRequest() request.service = '' # empty service name for a server check deadline = time.time() + timeout while time.time() < deadline: channel = Channel(host, port, ssl=ssl_context, loop=asyncio.get_event_loop()) client = HealthStub(channel) try: response = await client.Check(request) if response.status == HealthCheckResponse.SERVING: logger.debug('Service health check completed with success') return channel except (StreamTerminatedError, ConnectionError): pass channel.close() sleep_time = 0.1 logger.debug( 'Service health check failed, will try again in %fs. deadline=%r', sleep_time, deadline, ) await asyncio.sleep(sleep_time) raise TimeoutError
async def test_watch_service_status(loop): svc = Service() s1 = ServiceStatus(loop=loop) s2 = ServiceStatus(loop=loop) health = Health({svc: [s1, s2]}) with channel_for([svc, health], loop=loop) as channel: stub = HealthStub(channel) async with stub.Watch.open() as stream: await stream.send_message( HealthCheckRequest(service=Service.__name__, )) assert await stream.recv_message() == HealthCheckResponse( status=HealthCheckResponse.UNKNOWN, ) s1.set(True) assert await stream.recv_message() == HealthCheckResponse( status=HealthCheckResponse.NOT_SERVING, ) s2.set(True) assert await stream.recv_message() == HealthCheckResponse( status=HealthCheckResponse.SERVING, ) s1.set(False) assert await stream.recv_message() == HealthCheckResponse( status=HealthCheckResponse.NOT_SERVING, ) s1.set(True) assert await stream.recv_message() == HealthCheckResponse( status=HealthCheckResponse.SERVING, ) # check that there are no unnecessary messages if status isn't # changed s1.set(True) try: with async_timeout.timeout(0.01): assert not await stream.recv_message() except asyncio.TimeoutError: pass await stream.cancel()
async def test_check_zero_checks(): svc = Service() health = Health({svc: []}) async with ChannelFor([svc, health]) as channel: stub = HealthStub(channel) response = await stub.Check(HealthCheckRequest(service=SERVICE_NAME)) assert response == HealthCheckResponse( status=HealthCheckResponse.SERVING, )
async def test_check_unknown_service(): svc = Service() health = Health({svc: []}) async with ChannelFor([svc, health]) as channel: stub = HealthStub(channel) with pytest.raises(GRPCError) as err: await stub.Check(HealthCheckRequest(service='Unknown')) assert err.value.status == Status.NOT_FOUND
async def test_check_zero_checks(loop): svc = Service() health = Health({svc: []}) with channel_for([svc, health], loop=loop) as channel: stub = HealthStub(channel) response = await stub.Check( HealthCheckRequest(service=Service.__name__, )) assert response == HealthCheckResponse( status=HealthCheckResponse.SERVING, )
async def main(*, host: str = 'localhost', port: int = 50051) -> None: ssl_context = create_secure_context( CLIENT_CERT, CLIENT_KEY, trusted=SERVER_CERT, ) async with Channel(host, port, ssl=ssl_context) as channel: stub = HealthStub(channel) response = await stub.Check(HealthCheckRequest()) print(response)
async def test_check_unknown_service(loop): svc = Service() health = Health({svc: []}) with channel_for([svc, health], loop=loop) as channel: stub = HealthStub(channel) with pytest.raises(GRPCError): await stub.Check(HealthCheckRequest()) with pytest.raises(GRPCError): await stub.Check(HealthCheckRequest(service='Unknown'))
async def test_check_service_status(v1, v2, status): svc = Service() s1 = ServiceStatus() s2 = ServiceStatus() health = Health({svc: [s1, s2]}) async with ChannelFor([svc, health]) as channel: stub = HealthStub(channel) s1.set(v1) s2.set(v2) response = await stub.Check(HealthCheckRequest(service=SERVICE_NAME)) assert response == HealthCheckResponse(status=status)
async def test_check_service_status(loop, v1, v2, status): svc = Service() s1 = ServiceStatus(loop=loop) s2 = ServiceStatus(loop=loop) health = Health({svc: [s1, s2]}) with channel_for([svc, health], loop=loop) as channel: stub = HealthStub(channel) s1.set(v1) s2.set(v2) response = await stub.Check( HealthCheckRequest(service=Service.__name__, )) assert response == HealthCheckResponse(status=status)
async def main(): svc = Service() loop = asyncio.get_event_loop() test_check = ServiceCheck(test, loop=loop, check_ttl=5) health = Health({svc: [test_check]}) print(svc) print(health) async with ChannelFor([svc, health]) as channel: print(channel) stub = HealthStub(channel) print(stub) async with stub.Watch.open() as stream: await stream.send_message( HealthCheckRequest(service=Service.__name__, )) await stream.recv_message()
async def test_watch_unknown_service(loop, request): svc = Service() health = Health({svc: []}) with channel_for([svc, health], loop=loop) as channel: stub = HealthStub(channel) async with stub.Watch.open() as stream: await stream.send_message(request, end=True) assert await stream.recv_message() == HealthCheckResponse( status=HealthCheckResponse.SERVICE_UNKNOWN, ) try: with async_timeout.timeout(0.01): assert not await stream.recv_message() except asyncio.TimeoutError: pass await stream.cancel()
async def test_check_service_check(loop, v1, v2, status): svc = Service() c1 = Check() c2 = Check() health = Health({ svc: [ ServiceCheck(c1, check_ttl=0), ServiceCheck(c2, check_ttl=0), ] }) async with ChannelFor([svc, health]) as channel: stub = HealthStub(channel) c1.__current_status__ = v1 c2.__current_status__ = v2 response = await stub.Check(HealthCheckRequest(service=SERVICE_NAME)) assert response == HealthCheckResponse(status=status)
async def test_check_service_check(loop, v1, v2, status): svc = Service() c1 = Check() c2 = Check() health = Health({ svc: [ ServiceCheck(c1, loop=loop, check_ttl=0), ServiceCheck(c2, loop=loop, check_ttl=0), ] }) with channel_for([svc, health], loop=loop) as channel: stub = HealthStub(channel) c1.__current_status__ = v1 c2.__current_status__ = v2 response = await stub.Check( HealthCheckRequest(service=Service.__name__, )) assert response == HealthCheckResponse(status=status)
async def test_watch_zero_checks(loop): svc = Service() health = Health({svc: []}) with channel_for([svc, health], loop=loop) as channel: stub = HealthStub(channel) async with stub.Watch.open() as stream: await stream.send_message( HealthCheckRequest(service=Service.__name__, )) response = await stream.recv_message() assert response == HealthCheckResponse( status=HealthCheckResponse.SERVING, ) try: with async_timeout.timeout(0.01): assert not await stream.recv_message() except asyncio.TimeoutError: pass await stream.cancel()
async def test_watch_service_check(loop): svc = Service() c1 = Check() c2 = Check() health = Health({ svc: [ ServiceCheck(c1, loop=loop, check_ttl=0.001), ServiceCheck(c2, loop=loop, check_ttl=0.001), ] }) with channel_for([svc, health], loop=loop) as channel: stub = HealthStub(channel) async with stub.Watch.open() as stream: await stream.send_message( HealthCheckRequest(service=Service.__name__, )) assert await stream.recv_message() == HealthCheckResponse( status=HealthCheckResponse.UNKNOWN, ) # check that there are no unnecessary messages try: with async_timeout.timeout(0.01): assert not await stream.recv_message() except asyncio.TimeoutError: pass c1.__current_status__ = True assert await stream.recv_message() == HealthCheckResponse( status=HealthCheckResponse.NOT_SERVING, ) c2.__current_status__ = True assert await stream.recv_message() == HealthCheckResponse( status=HealthCheckResponse.SERVING, ) c1.__current_status__ = False assert await stream.recv_message() == HealthCheckResponse( status=HealthCheckResponse.NOT_SERVING, ) c1.__current_status__ = True assert await stream.recv_message() == HealthCheckResponse( status=HealthCheckResponse.SERVING, ) await stream.cancel()
def client(self) -> HealthStub: return HealthStub(self.channel)