Пример #1
0
    async def test_parallel_connection(
        self,
        client: TestClient,
        client_name: str,
        namespace_prefix: str,
        current_registry: prometheus_client.CollectorRegistry,
    ):
        results = await asyncio.gather(client.get("/200"), client.get("/200"))
        await asyncio.gather(*(r.json() for r in results))

        current_frozen_registry: List[prometheus_client.Metric] = list(
            current_registry.collect())

        assert_metric_exists(
            current_frozen_registry,
            f"{namespace_prefix}aiohttp_client_connection_create_seconds",
            f"{namespace_prefix}aiohttp_client_connection_create_seconds_bucket",
            labels={
                "client_name": client_name,
            },
        )

        assert_metric_value(
            current_frozen_registry,
            f"{namespace_prefix}aiohttp_client_connection_reuseconn",
            f"{namespace_prefix}aiohttp_client_connection_reuseconn_total",
            1.0,
            labels={
                "client_name": client_name,
            },
        )
async def test_route_asgi(loop, client: test_utils.TestClient):
    async with client.get("/asgi") as response:
        response.raise_for_status()
        body = await response.json()

    assert body == {'message': 'Hello World', 'root_path': ''}

    async with client.get("/not-found") as response:
        with pytest.raises(aiohttp.ClientError) as err:
            response.raise_for_status()

        assert err.value.status == 404
Пример #3
0
async def test_simple(compressor, client: test_utils.TestClient):
    headers = {hdrs.ACCEPT_ENCODING: compressor}

    async with client.get("/data", headers=headers) as response:
        response.raise_for_status()
        body = await response.json()
        assert compressor in response.headers[hdrs.CONTENT_ENCODING]
        assert isinstance(body, dict)
Пример #4
0
class TestWeb(asynctest.ClockedTestCase):
    haproxy_bind: Optional[Tuple[str, int]] = None
    maxDiff = None

    async def setUp(self) -> None:
        self.mc_server = mock.MagicMock()
        self.mc_server.sensors = SensorSet()
        self.mc_server.orig_sensors = SensorSet()

        self.mc_server.sensors.add(
            Sensor(str,
                   'products',
                   '',
                   default='["product1", "product2"]',
                   initial_status=Sensor.Status.NOMINAL))
        self.mc_server.sensors.add(
            Sensor(str,
                   'gui-urls',
                   '',
                   default=json.dumps(ROOT_GUI_URLS),
                   initial_status=Sensor.Status.NOMINAL))

        self.mc_server.orig_sensors.add(
            Sensor(str,
                   'product1.gui-urls',
                   '',
                   default=json.dumps(PRODUCT1_GUI_URLS),
                   initial_status=Sensor.Status.NOMINAL))
        self.mc_server.orig_sensors.add(
            Sensor(str,
                   'product2.cal.1.gui-urls',
                   '',
                   default=json.dumps(PRODUCT2_CAL_GUI_URLS),
                   initial_status=Sensor.Status.NOMINAL))
        self.mc_server.orig_sensors.add(
            Sensor(str,
                   'product2.ingest.1.gui-urls',
                   '',
                   default=json.dumps(PRODUCT2_CAL_GUI_URLS),
                   initial_status=Sensor.Status.UNKNOWN))
        for sensor in self.mc_server.orig_sensors.values():
            if self.haproxy_bind is not None and sensor.name.endswith(
                    '.gui-urls'):
                new_value = web.rewrite_gui_urls(EXTERNAL_URL, sensor)
                new_sensor = Sensor(sensor.stype, sensor.name,
                                    sensor.description, sensor.units)
                new_sensor.set_value(new_value,
                                     timestamp=sensor.timestamp,
                                     status=sensor.status)
                self.mc_server.sensors.add(new_sensor)
            else:
                self.mc_server.sensors.add(sensor)

        self.app = web.make_app(self.mc_server, self.haproxy_bind)
        self.server = TestServer(self.app)
        self.client = TestClient(self.server)
        await self.client.start_server()
        self.addCleanup(self.client.close)
        self.mc_server.add_interface_changed_callback.assert_called_once()
        self.dirty_set = self.mc_server.add_interface_changed_callback.mock_calls[
            0][1][0]
        self.dirty_set()
        await self.advance(1)

    async def test_get_guis(self) -> None:
        guis = web._get_guis(self.mc_server)
        haproxy = self.haproxy_bind is not None
        expected = {
            "general": ROOT_GUI_URLS,
            "products": {
                "product1": expected_gui_urls(PRODUCT1_GUI_URLS_OUT, haproxy,
                                              True),
                "product2": expected_gui_urls(PRODUCT2_GUI_URLS_OUT, haproxy,
                                              True)
            }
        }
        self.assertEqual(guis, expected)

    async def test_get_guis_not_nominal(self) -> None:
        for name in [
                'gui-urls', 'product1.gui-urls', 'product2.cal.1.gui-urls'
        ]:
            sensor = self.mc_server.sensors[name]
            sensor.set_value(sensor.value, status=Sensor.Status.ERROR)
        guis = web._get_guis(self.mc_server)
        expected = {
            "general": [],
            "products": {
                "product1": [],
                "product2": []
            }
        }
        self.assertEqual(guis, expected)

    async def test_update_bad_gui_sensor(self) -> None:
        with self.assertLogs('katsdpcontroller.web', logging.ERROR):
            self.mc_server.sensors[
                'product1.gui-urls'].value = 'not valid json'
            await self.advance(1)

    async def test_index(self) -> None:
        async with self.client.get('/') as resp:
            self.assertEqual(resp.status, 200)
            self.assertEqual(resp.headers['Content-type'],
                             'text/html; charset=utf-8')
            self.assertEqual(resp.headers['Cache-control'], 'no-store')

    async def test_favicon(self) -> None:
        async with self.client.get('/favicon.ico') as resp:
            self.assertEqual(resp.status, 200)
            self.assertEqual(resp.headers['Content-type'],
                             'image/vnd.microsoft.icon')

    async def test_prometheus(self) -> None:
        async with self.client.get('/metrics') as resp:
            self.assertEqual(resp.status, 200)

    async def test_rotate(self) -> None:
        # A good test of this probably needs Selenium plus a whole lot of
        # extra infrastructure.
        async with self.client.get('/rotate?width=500&height=600') as resp:
            text = await resp.text()
            self.assertEqual(resp.status, 200)
            self.assertIn('width: 500', text)
            self.assertIn('height: 600', text)

    async def test_missing_gui(self) -> None:
        for path in [
                '/gui/product3/service/label',
                '/gui/product3/service/label/foo'
        ]:
            async with self.client.get(path) as resp:
                text = await resp.text()
                self.assertEqual(resp.status, 404)
                self.assertIn('product3', text)

    async def test_websocket(self) -> None:
        haproxy = self.haproxy_bind is not None
        expected = {
            "general": ROOT_GUI_URLS,
            "products": {
                "product1":
                expected_gui_urls(PRODUCT1_GUI_URLS_OUT, haproxy, False),
                "product2":
                expected_gui_urls(PRODUCT2_GUI_URLS_OUT, haproxy, False)
            }
        }
        async with self.client.ws_connect('/ws') as ws:
            await ws.send_str('guis')
            guis = await ws.receive_json()
            self.assertEqual(guis, expected)
            # Updating should trigger an unsolicited update
            sensor = self.mc_server.sensors['products']
            sensor.value = '["product1"]'
            del expected["products"]["product2"]  # type: ignore
            self.dirty_set()
            await self.advance(1)
            guis = await ws.receive_json()
            self.assertEqual(guis, expected)
            await ws.close()

    async def test_websocket_close_server(self) -> None:
        """Close the server while a websocket is still connected"""
        async with self.client.ws_connect('/ws'):
            await self.server.close()
async def test(client: TestClient):
    async with client.get("/api/service") as resp:
        assert resp.status == 200
        data = await resp.json()

    assert set(data) == {"service", "version", "build"}