async def test_parsing_in_streams( resp_mocker, aresponses, hostname, method, settings, logger): mock = resp_mocker(return_value=aresponses.Response(text=textwrap.dedent(""" {"fake": "result1"} {"fake": "result2"} """))) aresponses.add(hostname, '/url', method, mock) items = [] async for item in stream( url='/url', payload={'fake': 'payload'}, headers={'fake': 'headers'}, settings=settings, logger=logger, ): items.append(item) assert items == [{'fake': 'result1'}, {'fake': 'result2'}] assert mock.call_count == 1 assert isinstance(mock.call_args[0][0], aiohttp.web.BaseRequest) assert mock.call_args[0][0].method.lower() == method assert mock.call_args[0][0].path == '/url' assert mock.call_args[0][0].data == {'fake': 'payload'} assert mock.call_args[0][0].headers['fake'] == 'headers' # and other system headers
async def watch_objs( *, settings: configuration.OperatorSettings, resource: references.Resource, namespace: references.Namespace, since: Optional[str] = None, operator_pause_waiter: aiotasks.Future, ) -> AsyncIterator[bodies.RawInput]: """ Watch objects of a specific resource type. The cluster-scoped call is used in two cases: * The resource itself is cluster-scoped, and namespacing makes not sense. * The operator serves all namespaces for the namespaced custom resource. Otherwise, the namespace-scoped call is used: * The resource is namespace-scoped AND operator is namespaced-restricted. """ params: Dict[str, str] = {} params['watch'] = 'true' if since is not None: params['resourceVersion'] = since if settings.watching.server_timeout is not None: params['timeoutSeconds'] = str(settings.watching.server_timeout) connect_timeout = (settings.watching.connect_timeout if settings.watching.connect_timeout is not None else settings.networking.connect_timeout if settings.networking.connect_timeout is not None else settings.networking.request_timeout) # Stream the parsed events from the response until it is closed server-side, # or until it is closed client-side by the pause-waiting future's callbacks. try: async for raw_input in api.stream( url=resource.get_url(namespace=namespace, params=params), logger=logger, settings=settings, stopper=operator_pause_waiter, timeout=aiohttp.ClientTimeout( total=settings.watching.client_timeout, sock_connect=connect_timeout, ), ): yield raw_input except (aiohttp.ClientConnectionError, aiohttp.ClientPayloadError, asyncio.TimeoutError): pass
async def test_settings_timeout_in_streams( resp_mocker, aresponses, hostname, method, settings, logger, timer): async def serve_slowly(): await asyncio.sleep(1.0) return "{}" mock = resp_mocker(side_effect=serve_slowly) aresponses.add(hostname, '/url', method, mock) with timer, pytest.raises(asyncio.TimeoutError): settings.networking.request_timeout = 0.1 # aiohttp raises an asyncio.TimeoutError which is automatically retried. # To reduce the test duration we disable retries for this test. settings.networking.error_backoffs = None async for _ in stream('/url', settings=settings, logger=logger): pass assert 0.1 < timer.seconds < 0.2
async def test_stopper_in_streams( resp_mocker, aresponses, hostname, method, delay, expected, settings, logger): async def stream_slowly(request: aiohttp.ClientRequest): response = aiohttp.web.StreamResponse() await response.prepare(request) await asyncio.sleep(0.05) await response.write(b'{"fake": "result1"}\n') await asyncio.sleep(0.15) await response.write(b'{"fake": "result2"}\n') await response.write_eof() return response aresponses.add(hostname, '/url', method, stream_slowly) stopper = asyncio.Future() asyncio.get_running_loop().call_later(delay, stopper.set_result, None) items = [] async for item in stream('/url', stopper=stopper, settings=settings, logger=logger): items.append(item) assert items == expected