async def test_empty_stream_yields_nothing(settings, resource, stream, namespace): stream.feed([], namespace=namespace) stream.close(namespace=namespace) events = [] async for event in continuous_watch( settings=settings, resource=resource, namespace=namespace, operator_pause_waiter=asyncio.Future()): events.append(event) assert len(events) == 1 assert events[0] == Bookmark.LISTED
async def test_exception_escalates(settings, resource, stream, namespace, enforced_session, mocker): enforced_session.get = mocker.Mock(side_effect=SampleException()) stream.feed([], namespace=namespace) stream.close(namespace=namespace) events = [] with pytest.raises(SampleException): async for event in continuous_watch( settings=settings, resource=resource, namespace=namespace, operator_pause_waiter=asyncio.Future()): events.append(event) assert len(events) == 0
async def test_long_line_parsing(settings, resource, stream, namespace, aresponses): content = [ { 'type': 'ADDED', 'object': { 'spec': { 'field': 'x' } } }, { 'type': 'ADDED', 'object': { 'spec': { 'field': 'y' * (2 * 1024 * 1024) } } }, { 'type': 'ADDED', 'object': { 'spec': { 'field': 'z' * (4 * 1024 * 1024) } } }, ] stream.feed(content, namespace=namespace) stream.close(namespace=namespace) events = [] async for event in continuous_watch( settings=settings, resource=resource, namespace=namespace, operator_pause_waiter=asyncio.Future()): events.append(event) assert len(events) == 4 assert events[0] == Bookmark.LISTED assert len(events[1]['object']['spec']['field']) == 1 assert len(events[2]['object']['spec']['field']) == 2 * 1024 * 1024 assert len(events[3]['object']['spec']['field']) == 4 * 1024 * 1024
async def test_event_stream_yields_everything(settings, resource, stream, namespace): stream.feed(STREAM_WITH_NORMAL_EVENTS, namespace=namespace) stream.close(namespace=namespace) events = [] async for event in continuous_watch( settings=settings, resource=resource, namespace=namespace, operator_pause_waiter=asyncio.Future()): events.append(event) assert len(events) == 3 assert events[0] == Bookmark.LISTED assert events[1]['object']['spec'] == 'a' assert events[2]['object']['spec'] == 'b'
async def test_unknown_error_raises_exception(settings, resource, stream, namespace): stream.feed(STREAM_WITH_ERROR_CODE, namespace=namespace) stream.close(namespace=namespace) events = [] with pytest.raises(WatchingError) as e: async for event in continuous_watch( settings=settings, resource=resource, namespace=namespace, operator_pause_waiter=asyncio.Future()): events.append(event) assert len(events) == 2 assert events[0] == Bookmark.LISTED assert events[1]['object']['spec'] == 'a' assert '666' in str(e.value)
async def test_error_410gone_exits_normally(settings, resource, stream, namespace, caplog): caplog.set_level(logging.DEBUG) stream.feed(STREAM_WITH_ERROR_410GONE, namespace=namespace) stream.close(namespace=namespace) events = [] async for event in continuous_watch( settings=settings, resource=resource, namespace=namespace, operator_pause_waiter=asyncio.Future()): events.append(event) assert len(events) == 2 assert events[0] == Bookmark.LISTED assert events[1]['object']['spec'] == 'a' assert "Restarting the watch-stream" in caplog.text
async def test_unknown_event_type_ignored(settings, resource, stream, namespace, caplog): caplog.set_level(logging.DEBUG) stream.feed(STREAM_WITH_UNKNOWN_EVENT, namespace=namespace) stream.close(namespace=namespace) events = [] async for event in continuous_watch( settings=settings, resource=resource, namespace=namespace, operator_pause_waiter=asyncio.Future()): events.append(event) assert len(events) == 3 assert events[0] == Bookmark.LISTED assert events[1]['object']['spec'] == 'a' assert events[2]['object']['spec'] == 'b' assert "Ignoring an unsupported event type" in caplog.text assert "UNKNOWN" in caplog.text
async def test_listed_is_inbetween(settings, resource, namespace, hostname, aresponses): # Resource version is used as a continutation for the watch-queries. list_data = { 'metadata': { 'resourceVersion': '123' }, 'items': [ { 'spec': 'a' }, { 'spec': 'b' }, ] } list_resp = aiohttp.web.json_response(list_data) list_url = resource.get_url(namespace=namespace) # The same as in the `stream` fixture. But here, we also mock lists. stream_data = [ { 'type': 'ADDED', 'object': { 'spec': 'c' } }, # stream.feed() { 'type': 'ADDED', 'object': { 'spec': 'd' } }, # stream.feed() { 'type': 'ERROR', 'object': { 'code': 410 } }, # stream.close() ] stream_text = '\n'.join(json.dumps(event) for event in stream_data) stream_resp = aresponses.Response(text=stream_text) stream_query = {'watch': 'true', 'resourceVersion': '123'} stream_url = resource.get_url(namespace=namespace, params=stream_query) aresponses.add(hostname, list_url, 'get', list_resp, match_querystring=True) aresponses.add(hostname, stream_url, 'get', stream_resp, match_querystring=True) events = [] async for event in continuous_watch( settings=settings, resource=resource, namespace=namespace, operator_pause_waiter=asyncio.Future()): events.append(event) assert len(events) == 5 assert events[0]['object']['spec'] == 'a' assert events[1]['object']['spec'] == 'b' assert events[2] == Bookmark.LISTED assert events[3]['object']['spec'] == 'c' assert events[4]['object']['spec'] == 'd'