Пример #1
0
    def test_close(self):
        conn = self.make_open_connector()
        session = ClientSession(loop=self.loop, connector=conn)

        session.close()
        self.assertIsNone(session.connector)
        self.assertTrue(conn.closed)
Пример #2
0
 def test_init_cookies_with_list_of_tuples(self):
     session = ClientSession(
         cookies=[("c1", "cookie1"),
                  ("c2", "cookie2")],
         loop=self.loop)
     self.assertEqual(set(session.cookies), {'c1', 'c2'})
     self.assertEqual(session.cookies['c1'].value, 'cookie1')
     self.assertEqual(session.cookies['c2'].value, 'cookie2')
     session.close()
Пример #3
0
 def test_detach(self):
     session = ClientSession(loop=self.loop)
     conn = session.connector
     self.assertFalse(conn.closed)
     session.detach()
     self.assertIsNone(session.connector)
     self.assertTrue(session.closed)
     self.assertFalse(conn.closed)
     conn.close()
Пример #4
0
 def test_init_cookies_with_simple_dict(self):
     session = ClientSession(
         cookies={
             "c1": "cookie1",
             "c2": "cookie2"
         }, loop=self.loop)
     self.assertEqual(set(session.cookies), {'c1', 'c2'})
     self.assertEqual(session.cookies['c1'].value, 'cookie1')
     self.assertEqual(session.cookies['c2'].value, 'cookie2')
     session.close()
Пример #5
0
 def test_init_headers_simple_dict(self):
     session = ClientSession(
         headers={
             "h1": "header1",
             "h2": "header2"
         }, loop=self.loop)
     self.assertEqual(
         sorted(session._default_headers.items()),
         ([("H1", "header1"),
           ("H2", "header2")]))
     session.close()
Пример #6
0
 def test_merge_headers_with_multi_dict(self):
     session = ClientSession(
         headers={
             "h1": "header1",
             "h2": "header2"
         }, loop=self.loop)
     headers = session._prepare_headers(MultiDict([("h1", "h1")]))
     self.assertIsInstance(headers, CIMultiDict)
     self.assertEqual(headers, CIMultiDict([
         ("h1", "h1"),
         ("h2", "header2")
     ]))
Пример #7
0
 def test_init_headers_list_of_tuples(self):
     session = ClientSession(
         headers=[("h1", "header1"),
                  ("h2", "header2"),
                  ("h3", "header3")],
         loop=self.loop)
     self.assertEqual(
         session._default_headers,
         CIMultiDict([("h1", "header1"),
                      ("h2", "header2"),
                      ("h3", "header3")]))
     session.close()
Пример #8
0
 def test_init_headers_MultiDict(self):
     session = ClientSession(
         headers=MultiDict(
             [("h1", "header1"),
              ("h2", "header2"),
              ("h3", "header3")]),
         loop=self.loop)
     self.assertEqual(
         session._default_headers,
         CIMultiDict([("H1", "header1"),
                      ("H2", "header2"),
                      ("H3", "header3")]))
     session.close()
Пример #9
0
 def test_merge_headers(self):
     # Check incoming simple dict
     session = ClientSession(
         headers={
             "h1": "header1",
             "h2": "header2"
         }, loop=self.loop)
     headers = session._prepare_headers({
         "h1": "h1"
     })
     self.assertIsInstance(headers, CIMultiDict)
     self.assertEqual(headers, CIMultiDict([
         ("h1", "h1"),
         ("h2", "header2")
     ]))
Пример #10
0
 def test_merge_headers_with_list_of_tuples_duplicated_names(self):
     session = ClientSession(
         headers={
             "h1": "header1",
             "h2": "header2"
         }, loop=self.loop)
     headers = session._prepare_headers([("h1", "v1"),
                                         ("h1", "v2")])
     self.assertIsInstance(headers, CIMultiDict)
     self.assertEqual(headers, CIMultiDict([
         ("H2", "header2"),
         ("H1", "v1"),
         ("H1", "v2"),
     ]))
     session.close()
Пример #11
0
        def go():
            err = OSError(1, "permission error")
            req = mock.Mock()
            req_factory = mock.Mock(return_value=req)
            req.send = mock.Mock(side_effect=err)
            session = ClientSession(loop=self.loop, request_class=req_factory)

            @asyncio.coroutine
            def create_connection(req):
                # return self.transport, self.protocol
                return mock.Mock(), mock.Mock()
            session._connector._create_connection = create_connection

            with self.assertRaises(aiohttp.ClientOSError) as ctx:
                yield from session.request('get', 'http://example.com')
            e = ctx.exception
            self.assertEqual(e.errno, err.errno)
            self.assertEqual(e.strerror, err.strerror)
Пример #12
0
    def __init__(self, rest_service_name='GenericService', spec=None, plugins=None, config=None,
                 parser=None, serializer=None, base_path='', loop=None, logger=None):
        self._plugins = []

        self.logger = logger or logging.getLogger('serviceClient.{}'.format(rest_service_name))
        self.rest_service_name = rest_service_name
        self.spec = spec or {}
        self.add_plugins(plugins or [])
        self.config = config or {}
        self.parser = parser or (lambda x, *args, **kwargs: x)
        self.serializer = serializer or (lambda x, *args, **kwargs: x)
        self.base_path = base_path
        self.loop = loop or get_event_loop()

        self.connector = TCPConnector(loop=self.loop, **self.config.get('connector', {}))
        self.session = ClientSession(connector=self.connector, loop=self.loop)
Пример #13
0
 async def fetch(self, request: Request, session: ClientSession):
     if self.use_proxy:
         # method, url, *,
         # params = None,
         # data = None,
         # json = None,
         # headers = None,
         # skip_auto_headers = None,
         # auth = None,
         # allow_redirects = True,
         # max_redirects = 10,
         # compress = None,
         # chunked = None,
         pass
     try:
         biu = session.request(request.method, request.url,
                               headers=request.header,
                               data=request.body)
         async with biu as req:
             text = await req.text()
             return Response(request, text, req.status)
     except Exception:
         pass
Пример #14
0
 async def async_method_wrapper(self, *args, **kwargs):
     async with ClientSession() as http_session:
         kwargs['http_session'] = http_session
         return await async_method(self, *args, **kwargs)
Пример #15
0
async def aiohttp_client_session(
        loop,  # pylint: disable=unused-argument
) -> ClientSession:
    """Initialize an aiohttp HTTP client session."""
    async with ClientSession() as http_session:
        yield http_session
Пример #16
0
async def receive(  # pylint: disable=too-many-arguments,too-many-locals
    ctx: click.Context,
    event: str,
    event_payload: TextIOWrapper,
    token: str,
    app: int,
    private_key: TextIOWrapper,
    entrypoint_module: str,
    event_routers: Iterable[str],
) -> None:
    """Webhook event receive command."""
    app_missing_private_key = app is not None and not private_key
    if app_missing_private_key:
        ctx.fail(click.style('App requires a private key', fg='red'))

    creds_present = token or (app and private_key)
    if not creds_present:
        ctx.fail(click.style('GitHub auth credentials are missing', fg='red'))

    too_many_creds_present = token and (app or private_key)
    if too_many_creds_present:
        ctx.fail(
            click.style(
                'Please choose between a token or '
                'an app id with a private key',
                fg='red',
            ), )

    make_event = GitHubEvent if app is None else GitHubWebhookEvent
    try:
        gh_event = make_event.from_fixture_fd(event_payload, event=event)
    except ValueError as val_err:
        ctx.fail(click.style(str(val_err), fg='red'))

    os.environ.update(get_extra_env_vars(gh_event, token, app, private_key))

    try:
        target_routers = set(
            load_event_routers(
                entrypoint_module,
                # pylint: disable=fixme
                event_routers,  # type: ignore[arg-type]  # FIXME: typing
            ), )
    except AttributeError as attr_err:
        ctx.fail(
            click.style(
                f'Could not find an event router: {attr_err!s}',
                fg='red',
            ), )
    except ImportError as imp_err:
        ctx.fail(
            click.style(f'Could not load a module: {imp_err!s}', fg='red'), )

    config = BotAppConfig.from_dotenv()
    gh_app_kwargs = {'config': config.github}
    make_gh_app = GitHubApp
    if app is None:
        make_gh_app = GitHubAction
        gh_app_kwargs['metadata'] = config.action
    async with ClientSession() as http_client_session:
        github_app = make_gh_app(
            http_session=http_client_session,
            # FIXME: typing  # pylint: disable=fixme
            event_routers=target_routers or None,  # type: ignore[arg-type]
            **gh_app_kwargs,
        )
        await route_github_event(
            github_event=gh_event,
            github_app=github_app,
        )

    click.echo(
        click.style(
            f'Finished processing {gh_event.name!s} event!',
            fg='green',
        ), )
Пример #17
0
 def test_http_methods(self, patched):
     session = ClientSession(loop=self.loop)
     add_params = dict(
         headers={"Authorization": "Basic ..."},
         max_redirects=2,
         encoding="latin1",
         version=aiohttp.HttpVersion10,
         compress="deflate",
         chunked=True,
         expect100=True,
         read_until_eof=False)
     run = self.loop.run_until_complete
     # Check GET
     run(session.get(
         "http://test.example.com",
         params={"x": 1},
         **add_params))
     self.assertEqual(
         patched.call_count, 1, "`ClientSession.request` not called")
     self.assertEqual(
         list(patched.call_args),
         [("GET", "http://test.example.com",),
          dict(
             params={"x": 1},
             allow_redirects=True,
             **add_params)])
     # Check OPTIONS
     run(session.options(
         "http://opt.example.com",
         params={"x": 2},
         **add_params))
     self.assertEqual(
         patched.call_count, 2, "`ClientSession.request` not called")
     self.assertEqual(
         list(patched.call_args),
         [("OPTIONS", "http://opt.example.com",),
          dict(
             params={"x": 2},
             allow_redirects=True,
             **add_params)])
     # Check HEAD
     run(session.head(
         "http://head.example.com",
         params={"x": 2},
         **add_params))
     self.assertEqual(
         patched.call_count, 3, "`ClientSession.request` not called")
     self.assertEqual(
         list(patched.call_args),
         [("HEAD", "http://head.example.com",),
          dict(
             params={"x": 2},
             allow_redirects=False,
             **add_params)])
     # Check POST
     run(session.post(
         "http://post.example.com",
         params={"x": 2},
         data="Some_data",
         files={"x": '1'},
         **add_params))
     self.assertEqual(
         patched.call_count, 4, "`ClientSession.request` not called")
     self.assertEqual(
         list(patched.call_args),
         [("POST", "http://post.example.com",),
          dict(
             params={"x": 2},
             data="Some_data",
             files={"x": '1'},
             **add_params)])
     # Check PUT
     run(session.put(
         "http://put.example.com",
         params={"x": 2},
         data="Some_data",
         files={"x": '1'},
         **add_params))
     self.assertEqual(
         patched.call_count, 5, "`ClientSession.request` not called")
     self.assertEqual(
         list(patched.call_args),
         [("PUT", "http://put.example.com",),
          dict(
             params={"x": 2},
             data="Some_data",
             files={"x": '1'},
             **add_params)])
     # Check PATCH
     run(session.patch(
         "http://patch.example.com",
         params={"x": 2},
         data="Some_data",
         files={"x": '1'},
         **add_params))
     self.assertEqual(
         patched.call_count, 6, "`ClientSession.request` not called")
     self.assertEqual(
         list(patched.call_args),
         [("PATCH", "http://patch.example.com",),
          dict(
             params={"x": 2},
             data="Some_data",
             files={"x": '1'},
             **add_params)])
     # Check DELETE
     run(session.delete(
         "http://delete.example.com",
         params={"x": 2},
         **add_params))
     self.assertEqual(
         patched.call_count, 7, "`ClientSession.request` not called")
     self.assertEqual(
         list(patched.call_args),
         [("DELETE", "http://delete.example.com",),
          dict(
             params={"x": 2},
             **add_params)])
Пример #18
0
    def test_context_manager(self):
        conn = self.make_open_connector()
        with ClientSession(loop=self.loop, connector=conn) as session:
            pass

        self.assertTrue(session.closed)
Пример #19
0
class AIOResponsesTestCase(TestCase):
    def setUp(self):
        self.url = 'http://example.com/api'
        self.loop = asyncio.get_event_loop()
        self.session = ClientSession()

    def tearDown(self):
        self.session.close()

    @data(
        hdrs.METH_GET,
        hdrs.METH_POST,
        hdrs.METH_PUT,
        hdrs.METH_PATCH,
        hdrs.METH_DELETE,
        hdrs.METH_OPTIONS,
    )
    @patch('aioresponses.aioresponses.add')
    def test_shortcut_method(self, http_method, mocked):
        with aioresponses() as m:
            getattr(m, http_method.lower())(self.url)
            mocked.assert_called_once_with(self.url, method=http_method)

    @aioresponses()
    def test_returned_instance(self, m):
        m.get(self.url)
        response = self.loop.run_until_complete(self.session.get(self.url))
        self.assertIsInstance(response, ClientResponse)

    @aioresponses()
    def test_returned_response_headers(self, m):
        m.get(self.url,
              content_type='text/html',
              headers={'Connection': 'keep-alive'})
        response = self.loop.run_until_complete(self.session.get(self.url))

        self.assertEqual(response.headers['Connection'], 'keep-alive')
        self.assertEqual(response.headers[hdrs.CONTENT_TYPE], 'text/html')

    @aioresponses()
    def test_method_dont_match(self, m):
        m.get(self.url)
        with self.assertRaises(ClientConnectionError):
            self.loop.run_until_complete(self.session.post(self.url))

    @aioresponses()
    def test_streaming(self, m):
        m.get(self.url, body='Test')
        resp = self.loop.run_until_complete(self.session.get(self.url))
        content = self.loop.run_until_complete(resp.content.read())
        self.assertEqual(content, b'Test')

    @aioresponses()
    def test_streaming_up_to(self, m):
        m.get(self.url, body='Test')
        resp = self.loop.run_until_complete(self.session.get(self.url))
        content = self.loop.run_until_complete(resp.content.read(2))
        self.assertEqual(content, b'Te')
        content = self.loop.run_until_complete(resp.content.read(2))
        self.assertEqual(content, b'st')

    def test_mocking_as_context_manager(self):
        with aioresponses() as aiomock:
            aiomock.add(self.url, payload={'foo': 'bar'})
            resp = self.loop.run_until_complete(self.session.get(self.url))
            self.assertEqual(resp.status, 200)
            payload = self.loop.run_until_complete(resp.json())
            self.assertDictEqual(payload, {'foo': 'bar'})

    def test_mocking_as_decorator(self):
        @aioresponses()
        def foo(m):
            m.add(self.url, payload={'foo': 'bar'})

            resp = self.loop.run_until_complete(self.session.get(self.url))
            self.assertEqual(resp.status, 200)
            payload = self.loop.run_until_complete(resp.json())
            self.assertDictEqual(payload, {'foo': 'bar'})

        foo()

    def test_passing_argument(self):
        @aioresponses(param='mocked')
        def foo(mocked):
            mocked.add(self.url, payload={'foo': 'bar'})
            resp = self.loop.run_until_complete(self.session.get(self.url))
            self.assertEqual(resp.status, 200)

        foo()

    def test_mocking_as_decorator_wrong_mocked_arg_name(self):
        @aioresponses(param='foo')
        def foo(bar):
            # no matter what is here it should raise an error
            pass

        with self.assertRaises(TypeError) as cm:
            foo()
        exc = cm.exception
        self.assertIn("foo() got an unexpected keyword argument 'foo'",
                      str(exc))

    def test_unknown_request(self):
        with aioresponses() as aiomock:
            aiomock.add(self.url, payload={'foo': 'bar'})
            with self.assertRaises(ClientConnectionError):
                self.loop.run_until_complete(
                    self.session.get('http://example.com/foo')
                )

    def test_raising_custom_error(self):
        with aioresponses() as aiomock:
            aiomock.get(self.url, exception=HttpProcessingError(message='foo'))
            with self.assertRaises(HttpProcessingError):
                self.loop.run_until_complete(
                    self.session.get(self.url)
                )

    def test_multiple_requests(self):
        with aioresponses() as m:
            m.get(self.url, status=200)
            m.get(self.url, status=201)
            m.get(self.url, status=202)
            resp = self.loop.run_until_complete(self.session.get(self.url))
            self.assertEqual(resp.status, 200)
            resp = self.loop.run_until_complete(self.session.get(self.url))
            self.assertEqual(resp.status, 201)
            resp = self.loop.run_until_complete(self.session.get(self.url))
            self.assertEqual(resp.status, 202)

            key = ('GET', self.url)
            self.assertIn(key, m.requests)
            self.assertEqual(len(m.requests[key]), 3)
            self.assertEqual(m.requests[key][0].args, tuple())
            self.assertEqual(m.requests[key][0].kwargs,
                             {'allow_redirects': True})

    def test_address_as_instance_of_url_combined_with_pass_through(self):
        external_api = 'http://google.com'

        @asyncio.coroutine
        def doit():
            api_resp = yield from self.session.get(self.url)
            # we have to hit actual url,
            # otherwise we do not test pass through option properly
            ext_rep = yield from self.session.get(URL(external_api))
            return api_resp, ext_rep

        with aioresponses(passthrough=[external_api]) as m:
            m.get(self.url, status=200)
            api, ext = self.loop.run_until_complete(doit())

            self.assertEqual(api.status, 200)
            self.assertEqual(ext.status, 200)
Пример #20
0
async def test_context_manager(connector, loop) -> None:
    with pytest.raises(TypeError):
        with ClientSession(loop=loop, connector=connector) as session:
            pass

        assert session.closed
Пример #21
0
 def test_borrow_connector_loop(self):
     conn = self.make_open_connector()
     session = ClientSession(connector=conn)
     self.assertIs(session._loop, self.loop)
     session.close()
Пример #22
0
def test_client_session_custom_attr(loop) -> None:
    session = ClientSession(loop=loop)
    with pytest.warns(DeprecationWarning):
        session.custom = None
Пример #23
0
 async def make_sess():
     return ClientSession(connector=connector, loop=loop)
Пример #24
0
 def __init__(self, config: AppleConfig):
     super().__init__(config)
     self._session = ClientSession()
Пример #25
0
 async def prepare(self):
     """
     Acquires HTTP connection pool.
     """
     self._session = ClientSession()
Пример #26
0
class Crawler:
    """
    Simple asynchronous HTTP client, which encapsulates the logic of web requests
    inside itself. All descendants are specialized on concrete web sites, but the
    current class supplies simple interface of the web interaction with any site.
    It's reusable and portable, that's why any crawler can easily fetch data via
    the Internet.

    Class properties:
        _limit: the max number of concurrent connections to the same site
        _timeout: default HTTP request timeout

    Instance properties:
        _session: HTTP connection pool
        _scribbler: statistics entity which writes success & failure shapes
        _semaphore: HTTP connection "restriction frame"
    """
    _limit = 10
    _timeout = 1

    def __init__(self):
        self._session = None
        self._semaphore = Semaphore(self._limit)

    async def prepare(self):
        """
        Acquires HTTP connection pool.
        """
        self._session = ClientSession()

    async def get_json(self, url: str, **kwargs: Any) -> Union[List, Dict]:
        """
        Makes an HTTP request and returns response in JSON format.

        :param url: request's URL
        :param kwargs: additional config like timeout, content-type, etc.
        :return: JSON content via native python objects
        """
        return await self.__get_content(url, 'json', **kwargs)

    @networking
    async def __get_content(self, url: str, content_type: str,
                            **kwargs: Any) -> Any:
        """
        Makes an HTTP request and returns response in a specified format.

        :param url: request's URL
        :param content_type: response's data type, like JSON, text, etc.
        :param kwargs: additional config like timeout, content-type, etc.
        :return: response's content
        """
        kwargs['timeout'] = kwargs.get('timeout', self._timeout)
        async with kwargs.pop('semaphore', self._semaphore):
            async with self._session.get(url, **kwargs) as response:
                return await getattr(response, content_type)()

    async def get_text(self, url: str, **kwargs: Any) -> str:
        """
        Makes an HTTP request and returns response in HTML (text) format.

        :param url: request's URL
        :param kwargs: additional config like timeout, content-type, etc.
        :return: HTML file's markup
        """
        return await self.__get_content(url, 'text', **kwargs)

    async def spare(self):
        """
        Releases HTTP connection pool.
        """
        await self._session.close()
Пример #27
0
 def test_connector(self):
     connector = TCPConnector(loop=self.loop)
     session = ClientSession(connector=connector, loop=self.loop)
     self.assertIs(session.connector, connector)
     session.close()
Пример #28
0
async def test_borrow_connector_loop(connector, create_session, loop) -> None:
    session = ClientSession(connector=connector, loop=None)
    try:
        assert session._loop, loop
    finally:
        await session.close()
Пример #29
0
 def __init__(self, base, http_session=None):
     self.base = base
     if http_session:
         self.http = http_session or ClientSession()
Пример #30
0
async def test_client_session_custom_attr(loop) -> None:
    session = ClientSession(loop=loop)
    with pytest.raises(AttributeError):
        session.custom = None
Пример #31
0
async def _async_get_swagger(url) -> Dict:
    async with ClientSession() as session:
        async with session.request(url=url, method=METH_GET) as resp:
            return json.loads(await resp.text())
Пример #32
0
async def test_requote_redirect_url_default() -> None:
    session = ClientSession()
    assert session.requote_redirect_url
Пример #33
0
 def __init__(self):
     super().__init__()
     self.session = ClientSession()
Пример #34
0
async def test_requote_redirect_url_default_disable() -> None:
    session = ClientSession(requote_redirect_url=False)
    assert not session.requote_redirect_url
Пример #35
0
 def test_close(self):
     session = ClientSession(loop=self.loop)
     session._connector = mock.Mock(BaseConnector)
     session.close()
     session._connector.close.assert_called_once_with()
Пример #36
0
async def test_requote_redirect_setter() -> None:
    session = ClientSession()
    assert session.requote_redirect_url
    with pytest.warns(DeprecationWarning):
        session.requote_redirect_url = False
    assert not session.requote_redirect_url
Пример #37
0
    async def run(download_list: list[template_media_table]):
        session_m = subscription.session_manager
        proxies = session_m.proxies
        proxy = (session_m.proxies[random.randint(0,
                                                  len(proxies) -
                                                  1)] if proxies else "")
        connector = ProxyConnector.from_url(proxy) if proxy else None
        final_cookies: dict[Any,
                            Any] = session_m.auth.auth_details.cookie.format(
                            ) if session_m.use_cookies else {}
        async with ClientSession(
                connector=connector,
                cookies=final_cookies,
                read_timeout=None,
        ) as session:
            tasks = []
            # Get content_lengths
            for download_item in download_list:
                link = download_item.link
                if link:
                    task = asyncio.ensure_future(
                        session_m.json_request(
                            download_item.link,
                            session,
                            method="HEAD",
                            json_format=False,
                        ))
                    tasks.append(task)
            responses = await asyncio.gather(*tasks)
            tasks.clear()

            async def check(download_item: template_media_table,
                            response: ClientResponse):
                filepath = os.path.join(download_item.directory,
                                        download_item.filename)
                response_status = False
                if response.status == 200:
                    response_status = True
                    if response.content_length:
                        download_item.size = response.content_length

                if os.path.exists(filepath):
                    if os.path.getsize(filepath) == response.content_length:
                        download_item.downloaded = True
                    else:
                        return download_item
                else:
                    if response_status:
                        return download_item

            for download_item in download_list:
                temp_response = [
                    response for response in responses
                    if response and str(response.url) == download_item.link
                ]
                if temp_response:
                    temp_response = temp_response[0]
                    task = check(download_item, temp_response)
                    tasks.append(task)
            result = await asyncio.gather(*tasks)
            download_list = [x for x in result if x]
            tasks.clear()
            progress_bar = None
            if download_list:
                progress_bar = download_session()
                progress_bar.start(unit="B", unit_scale=True, miniters=1)
                [progress_bar.update_total_size(x.size) for x in download_list]

            async def process_download(download_item: template_media_table):
                while True:
                    result = await session_m.download_content(
                        download_item, session, progress_bar, subscription)
                    if result:
                        response, download_item = result.values()
                        if response:
                            download_path = os.path.join(
                                download_item.directory,
                                download_item.filename)
                            status_code = await write_data(
                                response, download_path, progress_bar)
                            if not status_code:
                                pass
                            elif status_code == 1:
                                continue
                            elif status_code == 2:
                                break
                            timestamp = download_item.created_at.timestamp()
                            await format_image(download_path, timestamp)
                            download_item.size = response.content_length
                            download_item.downloaded = True
                    break

            max_threads = api_helper.calculate_max_threads(
                session_m.max_threads)
            download_groups = grouper(max_threads, download_list)
            for download_group in download_groups:
                tasks = []
                for download_item in download_group:
                    task = process_download(download_item)
                    if task:
                        tasks.append(task)
                await asyncio.gather(*tasks)
            if isinstance(progress_bar, download_session):
                progress_bar.close()
            return True
Пример #38
0
 async def _fetch_website(url: str, session: client.ClientSession):
     try:
         async with session.get(url) as response:
             await response.text()
     except ClientError:
         pass  # information is saved in on_request_exception
Пример #39
0
class ServiceClient:

    def __init__(self, rest_service_name='GenericService', spec=None, plugins=None, config=None,
                 parser=None, serializer=None, base_path='', loop=None, logger=None):
        self._plugins = []

        self.logger = logger or logging.getLogger('serviceClient.{}'.format(rest_service_name))
        self.rest_service_name = rest_service_name
        self.spec = spec or {}
        self.add_plugins(plugins or [])
        self.config = config or {}
        self.parser = parser or (lambda x, *args, **kwargs: x)
        self.serializer = serializer or (lambda x, *args, **kwargs: x)
        self.base_path = base_path
        self.loop = loop or get_event_loop()

        self.connector = TCPConnector(loop=self.loop, **self.config.get('connector', {}))
        self.session = ClientSession(connector=self.connector, loop=self.loop)

    @coroutine
    def call(self, service_name, payload=None, **kwargs):
        self.logger.debug("Calling service_client {0}...".format(service_name))
        service_desc = self.spec[service_name].copy()
        service_desc['service_name'] = service_name

        request_params = kwargs
        session = yield from self.prepare_session(service_desc, request_params)

        request_params['url'] = yield from self.generate_path(service_desc, session, request_params)
        request_params['method'] = service_desc.get('method', 'GET').upper()

        yield from self.prepare_request_params(service_desc, session, request_params)

        self.logger.info("Calling service_client {0} using {1} {2}".format(service_name,
                                                                           request_params['method'],
                                                                           request_params['url']))

        payload = yield from self.prepare_payload(service_desc, session, request_params, payload)
        try:
            if request_params['method'] not in ['GET', 'DELETE']:
                try:
                    stream_request = service_desc['stream_request']
                except KeyError:
                    stream_request = False
                if payload and not stream_request:
                    request_params['data'] = self.serializer(payload, session=session,
                                                             service_desc=service_desc,
                                                             request_params=request_params)

            yield from self.before_request(service_desc, session, request_params)

            response = yield from session.request(**request_params)
        except Exception as e:
            self.logger.warn("Exception calling service_client {0}: {1}".format(service_name, e))
            yield from self.on_exception(service_desc, session, request_params, e)
            raise e

        yield from self.on_response(service_desc, session, request_params, response)

        try:
            if service_desc['stream_response']:
                return response
        except KeyError:
            pass

        try:
            self.logger.info("Parsing response from {0}...".format(service_name))
            response.data = self.parser((yield from response.read()),
                                        session=session,
                                        service_desc=service_desc,
                                        response=response)
            yield from self.on_parsed_response(service_desc, session, request_params, response)
        except Exception as e:
            self.logger.warn("[Response code: {0}] Exception parsing response from service_client "
                             "{1}: {2}".format(response.status, service_name, e))
            yield from self.on_parse_exception(service_desc, session, request_params, response, e)
            e.response = response
            raise e

        return response

    @coroutine
    def prepare_session(self, service_desc, request_params):
        session = SessionWrapper(self.session)
        yield from self._execute_plugin_hooks('prepare_session', service_desc=service_desc, session=session,
                                              request_params=request_params)
        return session

    @coroutine
    def generate_path(self, service_desc, session, request_params):
        path = service_desc.get('path', '')
        url = list(urlparse(self.base_path))
        url[2] = '/'.join([url[2].rstrip('/'), path.lstrip('/')])
        url.pop()
        path = urlunsplit(url)
        hooks = [getattr(plugin, 'prepare_path') for plugin in self._plugins
                 if hasattr(plugin, 'prepare_path')]
        self.logger.debug("Calling {0} plugin hooks...".format('prepare_path'))
        for func in hooks:
            path = yield from func(service_desc=service_desc, session=session,
                                   request_params=request_params, path=path)

        return path

    @coroutine
    def prepare_request_params(self, service_desc, session, request_params):
        yield from self._execute_plugin_hooks('prepare_request_params', service_desc=service_desc,
                                              session=session, request_params=request_params)

    @coroutine
    def prepare_payload(self, service_desc, session, request_params, payload):
        hooks = [getattr(plugin, 'prepare_payload') for plugin in self._plugins
                 if hasattr(plugin, 'prepare_payload')]
        self.logger.debug("Calling {0} plugin hooks...".format('prepare_payload'))
        for func in hooks:
            payload = yield from func(service_desc=service_desc, session=session,
                                      request_params=request_params, payload=payload)
        return payload

    @coroutine
    def before_request(self, service_desc, session, request_params):
        yield from self._execute_plugin_hooks('before_request', service_desc=service_desc,
                                              session=session, request_params=request_params)

    @coroutine
    def on_exception(self, service_desc, session, request_params, ex):
        yield from self._execute_plugin_hooks('on_exception', service_desc=service_desc,
                                              session=session, request_params=request_params, ex=ex)

    @coroutine
    def on_response(self, service_desc, session, request_params, response):
        yield from self._execute_plugin_hooks('on_response', service_desc=service_desc,
                                              session=session, request_params=request_params, response=response)

    @coroutine
    def on_parse_exception(self, service_desc, session, request_params, response, ex):
        yield from self._execute_plugin_hooks('on_parse_exception', service_desc=service_desc,
                                              session=session, request_params=request_params, response=response, ex=ex)

    @coroutine
    def on_parsed_response(self, service_desc, session, request_params, response):
        yield from self._execute_plugin_hooks('on_parsed_response', service_desc=service_desc, session=session,
                                              request_params=request_params, response=response)

    @coroutine
    def _execute_plugin_hooks(self, hook, *args, **kwargs):
        hooks = [getattr(plugin, hook) for plugin in self._plugins if hasattr(plugin, hook)]
        self.logger.debug("Calling {0} plugin hooks...".format(hook))
        for func in hooks:
            yield from func(*args, **kwargs)

    def add_plugins(self, plugins):
        self._plugins.extend(plugins)

        hook = 'assign_service_client'
        hooks = [getattr(plugin, hook) for plugin in self._plugins if hasattr(plugin, hook)]
        self.logger.debug("Calling {0} plugin hooks...".format(hook))
        for func in hooks:
            func(service_client=self)

    def __getattr__(self, item):

        @coroutine
        def wrap(*args, **kwargs):

            return self.call(item, *args, **kwargs)

        return wrap

    def __del__(self):  # pragma: no cover
        self.session.close()
Пример #40
0
def test_borrow_connector_loop(connector, create_session, loop):
    session = ClientSession(connector=connector, loop=None)
    try:
        assert session._loop, loop
    finally:
        session.close()
Пример #41
0
def test_client_session_custom_attr(loop):
    session = ClientSession(loop=loop)
    with pytest.warns(DeprecationWarning):
        session.custom = None
Пример #42
0
 def setUp(self):
     self.url = 'http://example.com/api'
     self.session = ClientSession()
     super().setUp()
Пример #43
0
 def test_closed(self):
     session = ClientSession(loop=self.loop)
     self.assertFalse(session.closed)
     session.close()
     self.assertTrue(session.closed)
Пример #44
0
 def test_close_flag_for_closed_connector(self):
     session = ClientSession(loop=self.loop)
     conn = session.connector
     self.assertFalse(session.closed)
     conn.close()
     self.assertTrue(session.closed)
Пример #45
0
 def test_cookies_are_readonly(self):
     session = ClientSession(loop=self.loop)
     with self.assertRaises(AttributeError):
         session.cookies = 123
     session.close()
Пример #46
0
async def download_multiple(url_start: str, url_endings: list):
    async with ClientSession() as client:
        await asyncio.gather(*(download_to_file(client, url_start + x, x)
                               for x in url_endings))
Пример #47
0
 def go():
     session = ClientSession(loop=self.loop)
     session.close()
     with self.assertRaises(RuntimeError):
         yield from session.request('get', '/')
Пример #48
0
 def maker(*args, **kwargs):
     nonlocal session
     session = ClientSession(*args, loop=loop, **kwargs)
     return session
Пример #49
0
def test_context_manager(connector, loop):
    with pytest.warns(DeprecationWarning):
        with ClientSession(loop=loop, connector=connector) as session:
            pass

    assert session.closed
Пример #50
0
def test_create_session_outside_of_coroutine(loop):
    with pytest.warns(ResourceWarning):
        sess = ClientSession(loop=loop)
    sess.close()
Пример #51
0
 def test_borrow_connector_loop(self):
     conn = self.make_open_connector()
     session = ClientSession(connector=conn)
     self.assertIs(session._loop, self.loop)
     session.close()
Пример #52
0
 def setUp(self):
     self.url = 'http://example.com/api'
     self.loop = asyncio.get_event_loop()
     self.session = ClientSession()
Пример #53
0
class AIOResponsesTestCase(TestCase):
    use_default_loop = False

    @asyncio.coroutine
    def setUp(self):
        self.url = 'http://example.com/api?foo=bar#fragment'
        self.session = ClientSession()
        super().setUp()

    @asyncio.coroutine
    def tearDown(self):
        close_result = self.session.close()
        if close_result is not None:
            yield from close_result
        super().tearDown()

    def run_async(self, coroutine: Union[Coroutine, Generator]):
        return self.loop.run_until_complete(coroutine)

    @asyncio.coroutine
    def request(self, url: str):
        return (yield from self.session.get(url))

    @data(
        hdrs.METH_HEAD,
        hdrs.METH_GET,
        hdrs.METH_POST,
        hdrs.METH_PUT,
        hdrs.METH_PATCH,
        hdrs.METH_DELETE,
        hdrs.METH_OPTIONS,
    )
    @patch('aioresponses.aioresponses.add')
    @fail_on(unused_loop=False)
    def test_shortcut_method(self, http_method, mocked):
        with aioresponses() as m:
            getattr(m, http_method.lower())(self.url)
            mocked.assert_called_once_with(self.url, method=http_method)

    @aioresponses()
    def test_returned_instance(self, m):
        m.get(self.url)
        response = self.run_async(self.session.get(self.url))
        self.assertIsInstance(response, ClientResponse)

    @aioresponses()
    @asyncio.coroutine
    def test_returned_instance_and_status_code(self, m):
        m.get(self.url, status=204)
        response = yield from self.session.get(self.url)
        self.assertIsInstance(response, ClientResponse)
        self.assertEqual(response.status, 204)

    @aioresponses()
    @asyncio.coroutine
    def test_returned_response_headers(self, m):
        m.get(self.url,
              content_type='text/html',
              headers={'Connection': 'keep-alive'})
        response = yield from self.session.get(self.url)

        self.assertEqual(response.headers['Connection'], 'keep-alive')
        self.assertEqual(response.headers[hdrs.CONTENT_TYPE], 'text/html')

    @aioresponses()
    @asyncio.coroutine
    def test_returned_response_raw_headers(self, m):
        m.get(self.url,
              content_type='text/html',
              headers={'Connection': 'keep-alive'})
        response = yield from self.session.get(self.url)
        expected_raw_headers = ((b'Content-Type', b'text/html'),
                                (b'Connection', b'keep-alive'))

        self.assertEqual(response.raw_headers, expected_raw_headers)

    @aioresponses()
    @asyncio.coroutine
    def test_raise_for_status(self, m):
        m.get(self.url, status=400)
        with self.assertRaises(ClientResponseError) as cm:
            response = yield from self.session.get(self.url)
            response.raise_for_status()
        self.assertEqual(cm.exception.message, http.RESPONSES[400][0])

    @aioresponses()
    @asyncio.coroutine
    @skipIf(condition=AIOHTTP_VERSION < '3.4.0',
            reason='aiohttp<3.4.0 does not support raise_for_status '
            'arguments for requests')
    def test_request_raise_for_status(self, m):
        m.get(self.url, status=400)
        with self.assertRaises(ClientResponseError) as cm:
            yield from self.session.get(self.url, raise_for_status=True)
        self.assertEqual(cm.exception.message, http.RESPONSES[400][0])

    @aioresponses()
    @asyncio.coroutine
    def test_returned_instance_and_params_handling(self, m):
        expected_url = 'http://example.com/api?foo=bar&x=42#fragment'
        m.get(expected_url)
        response = yield from self.session.get(self.url, params={'x': 42})
        self.assertIsInstance(response, ClientResponse)
        self.assertEqual(response.status, 200)

        expected_url = 'http://example.com/api?x=42#fragment'
        m.get(expected_url)
        response = yield from self.session.get(
            'http://example.com/api#fragment', params={'x': 42})
        self.assertIsInstance(response, ClientResponse)
        self.assertEqual(response.status, 200)

    @aioresponses()
    def test_method_dont_match(self, m):
        m.get(self.url)
        with self.assertRaises(ClientConnectionError):
            self.run_async(self.session.post(self.url))

    @aioresponses()
    @asyncio.coroutine
    def test_streaming(self, m):
        m.get(self.url, body='Test')
        resp = yield from self.session.get(self.url)
        content = yield from resp.content.read()
        self.assertEqual(content, b'Test')

    @aioresponses()
    @asyncio.coroutine
    def test_streaming_up_to(self, m):
        m.get(self.url, body='Test')
        resp = yield from self.session.get(self.url)
        content = yield from resp.content.read(2)
        self.assertEqual(content, b'Te')
        content = yield from resp.content.read(2)
        self.assertEqual(content, b'st')

    @asyncio.coroutine
    def test_mocking_as_context_manager(self):
        with aioresponses() as aiomock:
            aiomock.add(self.url, payload={'foo': 'bar'})
            resp = yield from self.session.get(self.url)
            self.assertEqual(resp.status, 200)
            payload = yield from resp.json()
            self.assertDictEqual(payload, {'foo': 'bar'})

    def test_mocking_as_decorator(self):
        @aioresponses()
        def foo(loop, m):
            m.add(self.url, payload={'foo': 'bar'})

            resp = loop.run_until_complete(self.session.get(self.url))
            self.assertEqual(resp.status, 200)
            payload = loop.run_until_complete(resp.json())
            self.assertDictEqual(payload, {'foo': 'bar'})

        foo(self.loop)

    @asyncio.coroutine
    def test_passing_argument(self):
        @aioresponses(param='mocked')
        @asyncio.coroutine
        def foo(mocked):
            mocked.add(self.url, payload={'foo': 'bar'})
            resp = yield from self.session.get(self.url)
            self.assertEqual(resp.status, 200)

        yield from foo()

    @fail_on(unused_loop=False)
    def test_mocking_as_decorator_wrong_mocked_arg_name(self):
        @aioresponses(param='foo')
        def foo(bar):
            # no matter what is here it should raise an error
            pass

        with self.assertRaises(TypeError) as cm:
            foo()
        exc = cm.exception
        self.assertIn("foo() got an unexpected keyword argument 'foo'",
                      str(exc))

    @asyncio.coroutine
    def test_unknown_request(self):
        with aioresponses() as aiomock:
            aiomock.add(self.url, payload={'foo': 'bar'})
            with self.assertRaises(ClientConnectionError):
                yield from self.session.get('http://example.com/foo')

    @asyncio.coroutine
    def test_raising_custom_error(self):
        with aioresponses() as aiomock:
            aiomock.get(self.url, exception=HttpProcessingError(message='foo'))
            with self.assertRaises(HttpProcessingError):
                yield from self.session.get(self.url)

    @asyncio.coroutine
    def test_multiple_requests(self):
        with aioresponses() as m:
            m.get(self.url, status=200)
            m.get(self.url, status=201)
            m.get(self.url, status=202)
            resp = yield from self.session.get(self.url)
            self.assertEqual(resp.status, 200)
            resp = yield from self.session.get(self.url)
            self.assertEqual(resp.status, 201)
            resp = yield from self.session.get(self.url)
            self.assertEqual(resp.status, 202)

            key = ('GET', URL(self.url))
            self.assertIn(key, m.requests)
            self.assertEqual(len(m.requests[key]), 3)
            self.assertEqual(m.requests[key][0].args, tuple())
            self.assertEqual(m.requests[key][0].kwargs,
                             {'allow_redirects': True})

    @asyncio.coroutine
    def test_address_as_instance_of_url_combined_with_pass_through(self):
        external_api = 'http://httpbin.org/status/201'

        @asyncio.coroutine
        def doit():
            api_resp = yield from self.session.get(self.url)
            # we have to hit actual url,
            # otherwise we do not test pass through option properly
            ext_rep = yield from self.session.get(URL(external_api))
            return api_resp, ext_rep

        with aioresponses(passthrough=[external_api]) as m:
            m.get(self.url, status=200)
            api, ext = yield from doit()

            self.assertEqual(api.status, 200)
            self.assertEqual(ext.status, 201)

    @aioresponses()
    @asyncio.coroutine
    def test_custom_response_class(self, m):
        class CustomClientResponse(ClientResponse):
            pass

        m.get(self.url, body='Test', response_class=CustomClientResponse)
        resp = yield from self.session.get(self.url)
        self.assertTrue(isinstance(resp, CustomClientResponse))

    @aioresponses()
    def test_exceptions_in_the_middle_of_responses(self, mocked):
        mocked.get(self.url, payload={}, status=204)
        mocked.get(
            self.url,
            exception=ValueError('oops'),
        )
        mocked.get(self.url, payload={}, status=204)
        mocked.get(
            self.url,
            exception=ValueError('oops'),
        )
        mocked.get(self.url, payload={}, status=200)

        @asyncio.coroutine
        def doit():
            return (yield from self.session.get(self.url))

        self.assertEqual(self.run_async(doit()).status, 204)
        with self.assertRaises(ValueError):
            self.run_async(doit())
        self.assertEqual(self.run_async(doit()).status, 204)
        with self.assertRaises(ValueError):
            self.run_async(doit())
        self.assertEqual(self.run_async(doit()).status, 200)

    @aioresponses()
    @asyncio.coroutine
    def test_request_should_match_regexp(self, mocked):
        mocked.get(re.compile(r'^http://example\.com/api\?foo=.*$'),
                   payload={},
                   status=200)

        response = yield from self.request(self.url)
        self.assertEqual(response.status, 200)

    @aioresponses()
    @asyncio.coroutine
    def test_request_does_not_match_regexp(self, mocked):
        mocked.get(re.compile(r'^http://exampleexample\.com/api\?foo=.*$'),
                   payload={},
                   status=200)
        with self.assertRaises(ClientConnectionError):
            yield from self.request(self.url)

    @aioresponses()
    def test_timeout(self, mocked):
        mocked.get(self.url, timeout=True)

        with self.assertRaises(asyncio.TimeoutError):
            self.run_async(self.request(self.url))

    @aioresponses()
    def test_callback(self, m):
        body = b'New body'

        def callback(url, **kwargs):
            self.assertEqual(str(url), self.url)
            self.assertEqual(kwargs, {'allow_redirects': True})
            return CallbackResult(body=body)

        m.get(self.url, callback=callback)
        response = self.run_async(self.request(self.url))
        data = self.run_async(response.read())
        assert data == body

    @aioresponses()
    def test_callback_coroutine(self, m):
        body = b'New body'
        event = asyncio.Event()

        @asyncio.coroutine
        def callback(url, **kwargs):
            yield from event.wait()
            self.assertEqual(str(url), self.url)
            self.assertEqual(kwargs, {'allow_redirects': True})
            return CallbackResult(body=body)

        m.get(self.url, callback=callback)
        future = asyncio.ensure_future(self.request(self.url))
        self.run_async(asyncio.wait([future], timeout=0))
        assert not future.done()
        event.set()
        self.run_async(asyncio.wait([future], timeout=0))
        assert future.done()
        response = future.result()
        data = self.run_async(response.read())
        assert data == body
Пример #54
0
class GraphitePlugin(BasePlugin):
    _type = 'graphite'
    condition_map = {
        '>': operator.gt,
        '>=': operator.ge,
        '<': operator.lt,
        '<=': operator.le,
        '==': operator.eq
    }

    def __init__(self):
        super().__init__()
        self.session = ClientSession()

    def supported_types(self):
        return settings.GRAPHITE_TYPES

    def init(self, *args):
        super().init(*args)

    def get_graphite_url(self, env):
        return 'http://{}/render'.format(
            settings.ENVIRONMENTS[env]['metrics_service']['host']
        )

    def get_graph_url(self, env: str):
        """Returns a formatted URL for a graph."""
        return settings.ENVIRONMENTS[env]['metrics_service'].get(
            'graph_url',
            self.get_graphite_url(env)
        )

    @asyncio.coroutine
    @stats.increment(metric_name='graphite.execute')
    @stats.timer(metric_name='graphite.execute')
    def execute(self, check):
        logger.info(
            'Processing check: id="{}", metric="{}"'.format(
                check['id'], check['fields']['metric']
            )
        )
        fields = check['fields']
        check['target'] = fields['metric']

        env = check.get('environment', 'test')
        url = self.get_graphite_url(env)

        try:
            metric = fields['metric']
            with Timeout(settings.GRAPHITE_TIMEOUT):
                response = yield from self.session.get(
                    url,
                    params={
                        'target': metric,
                        'from': settings.GRAPHITE_TIME_RANGE,
                        'format': 'json'
                    }
                )

                response.raise_for_status()
                data = yield from response.json()
            self.process(check, data, env)

        except (ValueError, HttpProcessingError,
                TimeoutError, ClientOSError) as e:
            message = self.exception_repr(e, pattern='{}: {}')
            logger.error('Could not execute plugin for check `%s`, %s',
                         check['id'], message)
            self.set_check_status(check, RESULT_UNKNOWN, message)

    def add_meta(self, check, trigger, env, threshold=None):
        threshold = threshold or 0.0
        now = datetime.now()
        # - 1 hour
        from_date = now - timedelta(0, 3600)
        params = [
            ('width', settings.GRAPHITE_CHART_WIDTH),
            ('height', settings.GRAPHITE_CHART_HEIGHT),
            ('tz', settings.GRAPHITE_TIME_ZONE),
            ('from', from_date.strftime('%H:%M_%Y%m%d')),
            ('until', now.strftime('%H:%M_%Y%m%d')),
            ('target', check['fields']['metric']),
            ('target', 'threshold({}, \"{}\", red)'.format(
                threshold, 'threshold = {}'.format(threshold),
            )),
        ]
        graphite_url = "{}?{}".format(
            self.get_graph_url(env), urlencode(params)
        )
        trigger['meta']['links']['graphite_url'] = dict(
            type='link', href=graphite_url
        )

    @stats.increment(metric_name='graphite.process')
    @stats.timer(metric_name='graphite.process')
    def process(self, check, data, env):
        frequency = int(check['fields']['frequency'])
        expected_num_hosts = check['fields'].get('expected_num_hosts', 0)

        ret = Result()

        for result in data:
            datapoints = result['datapoints']

            values = [float(t[0])
                      for t in datapoints[-int(frequency / 60) - 1:-1]
                      if t[0] is not None]

            ret.num_series_with_data += 1 if values else 0
            ret.num_series_no_data += 0 if values else 1
            ret.all_values.extend(values)

        for trigger in check['triggers']:
            status, failed_values, message = RESULT_OK, [], ''
            hyst_status, hystfail_values = RESULT_OK, []

            debounce = trigger.get('debounce') or check['fields'].get(
                'debounce', 1)

            trigger_expected_num_hosts = int(
                trigger.get('expected_num_hosts', 0) or expected_num_hosts
            )
            try:
                threshold = float(trigger.get('threshold'))
                condition = self.condition_map[trigger.get('condition')]
                hysteresis_value = float(trigger.get('hysteresis', "0.0"))
            except (ValueError, TypeError) as e:
                message = INVALID_THRESHOLD.format(
                    trigger.get('threshold', '<unknown>'), check['id'], e
                )
                logger.error(message)
                self.set_status(
                    trigger, RESULT_UNKNOWN, message, hysteresis=RESULT_UNKNOWN
                )
                continue
            except KeyError:
                message = INVALID_OPERATOR.format(
                    trigger.get('condition'),
                    list(self.condition_map.keys())
                )
                logger.error(message)
                self.set_status(
                    trigger, RESULT_UNKNOWN, message, hysteresis=RESULT_UNKNOWN
                )
                self.add_meta(check, trigger, env, threshold=threshold)
                continue

            if trigger.get('condition') in ['<', '<=']:
                hyst_threshold = threshold + hysteresis_value
            elif trigger.get('condition') in ['>', '>=']:
                hyst_threshold = threshold - hysteresis_value
            else:
                hyst_threshold = threshold

            failed_values = list(filter(
                lambda x: condition(x, threshold), ret.all_values
            ))

            hystfail_values = list(filter(
                lambda x: condition(x, hyst_threshold), ret.all_values
            ))

            if failed_values:
                status = hyst_status = RESULT_FAILED
                values = ', '.join(
                    [str(x) for x in failed_values[-int(debounce):]]
                )
                message = '[{}] {} {}'.format(
                    values, trigger['condition'], threshold
                )
            elif hystfail_values:
                # if hysteresis is off or hardfail threshold hits,
                # we won't even reach here
                hyst_status = RESULT_FAILED

                hysteresis_sign = '-' if hyst_threshold < threshold else '+'
                values = ', '.join(
                    [str(x) for x in hystfail_values[-int(debounce):]]
                )
                message = '[{}] {} ({} {} {} hysteresis)'.format(
                    values, trigger['condition'],
                    threshold, hysteresis_sign, hysteresis_value
                )

            if ret.num_series_with_data < trigger_expected_num_hosts:
                status = hyst_status = RESULT_FAILED
                msg = MESSAGE_TPL.format(
                    ret.num_series_with_data, trigger_expected_num_hosts
                )
                message = '\n '.join(msg for msg in [msg, message] if msg)

            self.set_status(trigger, status, message, hysteresis=hyst_status)
            self.add_meta(check, trigger, env, threshold=threshold)
Пример #55
0
class AIOResponsesTestCase(TestCase):
    use_default_loop = False

    @asyncio.coroutine
    def setUp(self):
        self.url = 'http://example.com/api'
        self.session = ClientSession()
        super().setUp()

    @asyncio.coroutine
    def tearDown(self):
        self.session.close()
        super().tearDown()

    @data(
        hdrs.METH_HEAD,
        hdrs.METH_GET,
        hdrs.METH_POST,
        hdrs.METH_PUT,
        hdrs.METH_PATCH,
        hdrs.METH_DELETE,
        hdrs.METH_OPTIONS,
    )
    @patch('aioresponses.aioresponses.add')
    @fail_on(unused_loop=False)
    def test_shortcut_method(self, http_method, mocked):
        with aioresponses() as m:
            getattr(m, http_method.lower())(self.url)
            mocked.assert_called_once_with(self.url, method=http_method)

    @aioresponses()
    def test_returned_instance(self, m):
        m.get(self.url)
        response = self.loop.run_until_complete(self.session.get(self.url))
        self.assertIsInstance(response, ClientResponse)

    @aioresponses()
    @asyncio.coroutine
    def test_returned_instance_and_status_code(self, m):
        m.get(self.url, status=204)
        response = yield from self.session.get(self.url)
        self.assertIsInstance(response, ClientResponse)
        self.assertEqual(response.status, 204)

    @aioresponses()
    @asyncio.coroutine
    def test_returned_response_headers(self, m):
        m.get(self.url,
              content_type='text/html',
              headers={'Connection': 'keep-alive'})
        response = yield from self.session.get(self.url)

        self.assertEqual(response.headers['Connection'], 'keep-alive')
        self.assertEqual(response.headers[hdrs.CONTENT_TYPE], 'text/html')

    @aioresponses()
    def test_method_dont_match(self, m):
        m.get(self.url)
        with self.assertRaises(ClientConnectionError):
            self.loop.run_until_complete(self.session.post(self.url))

    @aioresponses()
    @asyncio.coroutine
    def test_streaming(self, m):
        m.get(self.url, body='Test')
        resp = yield from self.session.get(self.url)
        content = yield from resp.content.read()
        self.assertEqual(content, b'Test')

    @aioresponses()
    @asyncio.coroutine
    def test_streaming_up_to(self, m):
        m.get(self.url, body='Test')
        resp = yield from self.session.get(self.url)
        content = yield from resp.content.read(2)
        self.assertEqual(content, b'Te')
        content = yield from resp.content.read(2)
        self.assertEqual(content, b'st')

    @asyncio.coroutine
    def test_mocking_as_context_manager(self):
        with aioresponses() as aiomock:
            aiomock.add(self.url, payload={'foo': 'bar'})
            resp = yield from self.session.get(self.url)
            self.assertEqual(resp.status, 200)
            payload = yield from resp.json()
            self.assertDictEqual(payload, {'foo': 'bar'})

    def test_mocking_as_decorator(self):
        @aioresponses()
        def foo(loop, m):
            m.add(self.url, payload={'foo': 'bar'})

            resp = loop.run_until_complete(self.session.get(self.url))
            self.assertEqual(resp.status, 200)
            payload = loop.run_until_complete(resp.json())
            self.assertDictEqual(payload, {'foo': 'bar'})

        foo(self.loop)

    @asyncio.coroutine
    def test_passing_argument(self):
        @aioresponses(param='mocked')
        @asyncio.coroutine
        def foo(mocked):
            mocked.add(self.url, payload={'foo': 'bar'})
            resp = yield from self.session.get(self.url)
            self.assertEqual(resp.status, 200)

        yield from foo()

    @fail_on(unused_loop=False)
    def test_mocking_as_decorator_wrong_mocked_arg_name(self):
        @aioresponses(param='foo')
        def foo(bar):
            # no matter what is here it should raise an error
            pass

        with self.assertRaises(TypeError) as cm:
            foo()
        exc = cm.exception
        self.assertIn("foo() got an unexpected keyword argument 'foo'",
                      str(exc))

    @asyncio.coroutine
    def test_unknown_request(self):
        with aioresponses() as aiomock:
            aiomock.add(self.url, payload={'foo': 'bar'})
            with self.assertRaises(ClientConnectionError):
                yield from self.session.get('http://example.com/foo')

    @asyncio.coroutine
    def test_raising_custom_error(self):
        with aioresponses() as aiomock:
            aiomock.get(self.url, exception=HttpProcessingError(message='foo'))
            with self.assertRaises(HttpProcessingError):
                yield from self.session.get(self.url)

    @asyncio.coroutine
    def test_multiple_requests(self):
        with aioresponses() as m:
            m.get(self.url, status=200)
            m.get(self.url, status=201)
            m.get(self.url, status=202)
            resp = yield from self.session.get(self.url)
            self.assertEqual(resp.status, 200)
            resp = yield from self.session.get(self.url)
            self.assertEqual(resp.status, 201)
            resp = yield from self.session.get(self.url)
            self.assertEqual(resp.status, 202)

            key = ('GET', self.url)
            self.assertIn(key, m.requests)
            self.assertEqual(len(m.requests[key]), 3)
            self.assertEqual(m.requests[key][0].args, tuple())
            self.assertEqual(m.requests[key][0].kwargs,
                             {'allow_redirects': True})

    @asyncio.coroutine
    def test_address_as_instance_of_url_combined_with_pass_through(self):
        external_api = 'http://httpbin.org/status/201'

        @asyncio.coroutine
        def doit():
            api_resp = yield from self.session.get(self.url)
            # we have to hit actual url,
            # otherwise we do not test pass through option properly
            ext_rep = yield from self.session.get(URL(external_api))
            return api_resp, ext_rep

        with aioresponses(passthrough=[external_api]) as m:
            m.get(self.url, status=200)
            api, ext = yield from doit()

            self.assertEqual(api.status, 200)
            self.assertEqual(ext.status, 201)
Пример #56
0
 def setUp(self):
     self.url = 'http://example.com/api?foo=bar#fragment'
     self.session = ClientSession()
     super().setUp()
Пример #57
0
 def setUp(self):
     self.url = 'http://example.com/api?foo=bar#fragment'
     self.session = ClientSession(raise_for_status=True)
     super().setUp()
Пример #58
0
 def go():
     session = ClientSession(loop=self.loop)
     session.close()
     with self.assertRaises(RuntimeError):
         yield from session.request('get', '/')