Пример #1
0
def create_app():
    get_api_settings.cache_clear()
    settings = get_api_settings()
    settings.docs_url = "/api/docs"
    settings.redoc_url = "/api/redoc"
    settings.title = "Exponea Task Api"
    app = FastAPI(openapi_tags=tags_metadata, **settings.fastapi_kwargs)
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["GET"],
        allow_headers=["*"],
    )

    api = Api(app, prefix="/api")
    api.add_resource(AllResponsesResource(), "/all", tags=["Exponea Test Server"])
    api.add_resource(FirstResponseResource(), "/first", tags=["Exponea Test Server"])
    api.add_resource(
        ThresholdResponsesResource(),
        "/within-timeout",
        tags=["Exponea Test Server"],
    )
    api.add_resource(SmartResponseResource(), "/smart", tags=["Exponea Test Server"])
    simplify_operation_ids(app)
    add_timing_middleware(app, record=log.info, prefix="/api")
    Instrumentator().instrument(app).expose(app)
    return app
Пример #2
0
def test_rounding():
    app = create_app()
    Instrumentator(should_round_latency_decimals=True).add(
        metrics.latency(buckets=(
            1,
            2,
            3,
        ))).instrument(app).expose(app)
    client = TestClient(app)

    get_response(client, "/")
    get_response(client, "/")
    get_response(client, "/")

    _ = get_response(client, "/metrics")

    result = REGISTRY.get_sample_value(
        "http_request_duration_seconds_sum",
        {
            "handler": "/",
            "method": "GET",
            "status": "2xx"
        },
    )

    entropy = calc_entropy(str(result).split(".")[1][4:])

    assert entropy < 10
def test_default():
    app = create_app()
    Instrumentator().add(metrics.default()).instrument(app).expose(app)
    client = TestClient(app)

    client.get("/", data="fefeef")
    client.get("/")

    _ = get_response(client, "/metrics")

    assert (REGISTRY.get_sample_value(
        "http_requests_total",
        {
            "handler": "/",
            "method": "GET",
            "status": "2xx"
        },
    ) > 0)
    assert (REGISTRY.get_sample_value(
        "http_request_size_bytes_sum",
        {"handler": "/"},
    ) > 0)
    assert (REGISTRY.get_sample_value(
        "http_response_size_bytes_sum",
        {"handler": "/"},
    ) > 0)
    assert (REGISTRY.get_sample_value(
        "http_request_duration_highr_seconds_sum",
        {},
    ) > 0)
    assert (REGISTRY.get_sample_value(
        "http_request_duration_seconds_sum",
        {"handler": "/"},
    ) > 0)
Пример #4
0
def create_app():
    create_logger("erudite")  # Logger creation

    from fastapi import FastAPI

    if settings.dev:
        app = FastAPI()
    else:
        app = FastAPI(root_path="/api/erudite")
        from core.middleware import authorization

        app.add_middleware(BaseHTTPMiddleware, dispatch=authorization)

    Instrumentator().instrument(app).expose(app)

    from core.routes.rooms import router as room_router
    from core.routes.equipment import router as equipment_router
    from core.routes.disciplines import router as discipline_router
    from core.routes.lessons import router as lesson_router
    from core.routes.records import router as record_router

    app.include_router(room_router, tags=["rooms"])
    app.include_router(equipment_router, tags=["equipment"])
    app.include_router(discipline_router, tags=["disciplines"])
    app.include_router(lesson_router, tags=["lessons"])
    app.include_router(record_router, tags=["records"])

    return app
Пример #5
0
def test_excluded_handlers_none():
    app = create_app()
    exporter = (Instrumentator(excluded_handlers=None).add(
        metrics.latency()).instrument(app))
    expose_metrics(app)

    assert len(exporter.excluded_handlers) == 0
    assert isinstance(exporter.excluded_handlers, list)
    assert exporter.excluded_handlers is not None
Пример #6
0
def test_multiprocess_env_folder(monkeypatch, tmp_path):
    monkeypatch.setenv("prometheus_multiproc_dir", "DOES/NOT/EXIST")

    app = create_app()
    with pytest.raises(Exception):
        Instrumentator(buckets=(
            1,
            2,
            3,
        )).add(metrics.latency()).instrument(app).expose(app)
def test_expose_defaults():
    app = create_app()
    Instrumentator().instrument(app).expose(app)
    client = TestClient(app)

    get_response(client, "/")

    response = get_response(client, "/metrics")
    assert response.status_code == 200
    assert b"http_request" in response.content
Пример #8
0
def test_should_respect_env_var_existence_exists():
    app = create_app()
    Instrumentator(should_respect_env_var=True,
                   env_var_name="eoioerwjioGFIUONEIO").add(
                       metrics.latency()).instrument(app).expose(app)
    client = TestClient(app)

    get_response(client, "/")

    response = get_response(client, "/metrics")
    assert response.status_code == 404
Пример #9
0
def test_gzip_not_accepted():
    app = create_app()
    Instrumentator().instrument(app).expose(app, should_gzip=False)
    client = TestClient(app)

    get_response(client, "/")
    get_response(client, "/")

    response = get_response(client, "/metrics")

    assert response.headers.get("Content-Encoding") is None
    assert int(response.headers["Content-Length"]) >= 2000
Пример #10
0
def test_gzip_accepted():
    app = create_app()
    Instrumentator().instrument(app).expose(app, should_gzip=True)
    client = TestClient(app)

    get_response(client, "/")
    get_response(client, "/")

    response = get_response(client, "/metrics")

    assert response.headers["Content-Encoding"] == "gzip"
    assert int(response.headers["Content-Length"]) <= 2000
Пример #11
0
def test_expose_default_content_type():
    reset_prometheus()
    app = create_app()
    Instrumentator().instrument(app).expose(app)
    client = TestClient(app)

    response = client.get("/metrics")
    print(response.headers.items())
    assert (
        "text/plain; version=0.0.4; charset=utf-8; charset=utf-8"
        not in response.headers.values()
    )
def test_request_size_no_cl():
    app = create_app()
    Instrumentator(excluded_handlers=["/metrics"]).add(
        metrics.request_size()).instrument(app).expose(app)
    client = TestClient(app)

    client.get("/")

    response = get_response(client, "/metrics")

    assert b"http_request_size_bytes" in response.content
    assert b"http_request_size_bytes_count{" in response.content
def test_default_should_only_respect_2xx_for_highr():
    app = create_app()
    Instrumentator(excluded_handlers=["/metrics"]).add(
        metrics.default(should_only_respect_2xx_for_highr=True)).instrument(
            app).expose(app)
    client = TestClient(app)

    client.get("/efefewffe", data="fefeef")
    client.get("/ffe04904nfiuo-ni")

    response = get_response(client, "/metrics")

    assert b"http_request_duration_highr_seconds_count 0.0" in response.content
def test_combined_size_no_labels():
    app = create_app()
    Instrumentator().add(
        metrics.combined_size(
            should_include_handler=False,
            should_include_method=False,
            should_include_status=False,
        )).instrument(app)
    client = TestClient(app)

    client.get("/")

    assert REGISTRY.get_sample_value("http_combined_size_bytes_sum", {}) == 14
Пример #15
0
def test_metrics_endpoint_availability():
    app = create_app()
    Instrumentator(excluded_handlers=["/metrics"]).add(
        metrics.latency()).instrument(app)
    expose_metrics(app)
    client = TestClient(app)

    get_response(client, "/")
    get_response(client, "/")

    response = get_response(client, "/metrics")
    assert_is_not_multiprocess(response)
    assert_request_count(2)
Пример #16
0
def test_default_without_add():
    app = create_app()
    Instrumentator(excluded_handlers=["/metrics"]).add(
        metrics.latency()).instrument(app)
    expose_metrics(app)
    client = TestClient(app)

    get_response(client, "/")

    response = get_response(client, "/metrics")
    assert_is_not_multiprocess(response)
    assert_request_count(1)
    assert b"http_request_duration_seconds" in response.content
def test_default_with_runtime_error():
    app = create_app()
    Instrumentator().instrument(app).expose(app)
    client = TestClient(app)

    try:
        get_response(client, "/runtime_error")
    except RuntimeError:
        pass

    response = get_response(client, "/metrics")

    assert (b'http_request_size_bytes_count{handler="/runtime_error"} 1.0'
            in response.content)
Пример #18
0
def test_custom_metric_name():
    app = create_app()
    Instrumentator(excluded_handlers=["/metrics"]).add(
        metrics.latency(metric_name="fastapi_latency")).instrument(app)
    expose_metrics(app)
    client = TestClient(app)

    get_response(client, "/")

    response = get_response(client, "/metrics")
    assert_is_not_multiprocess(response)
    assert_request_count(1, name="fastapi_latency_count")
    assert b"fastapi_latency" in response.content
    assert b"http_request_duration_seconds" not in response.content
def test_expose_custom_path():
    app = create_app()
    Instrumentator().instrument(app).expose(app, endpoint="/custom_metrics")
    client = TestClient(app)

    get_response(client, "/")

    response = get_response(client, "/metrics")
    assert response.status_code == 404
    assert b"http_request" not in response.content

    response = get_response(client, "/custom_metrics")
    assert response.status_code == 200
    assert b"http_request" in response.content
Пример #20
0
def test_ungrouped_status_codes():
    app = create_app()
    Instrumentator(should_group_status_codes=False).add(
        metrics.latency()).instrument(app)
    expose_metrics(app)
    client = TestClient(app)

    get_response(client, "/")

    response = get_response(client, "/metrics")
    assert_is_not_multiprocess(response)
    assert_request_count(1, status="200")
    assert b'status="2xx"' not in response.content
    assert b'status="200"' in response.content
Пример #21
0
def test_multiprocess_reg_is_not(monkeypatch, tmp_path):
    monkeypatch.setenv("prometheus_multiproc_dir", str(tmp_path))

    app = create_app()
    Instrumentator(excluded_handlers=["/metrics"]).add(
        metrics.latency()).instrument(app).expose(app)

    client = TestClient(app)

    get_response(client, "/")

    response = get_response(client, "/metrics")
    assert response.status_code == 200
    assert b"" == response.content
def test_combined_size_with_runtime_error():
    app = create_app()
    Instrumentator().add(metrics.combined_size()).instrument(app).expose(app)
    client = TestClient(app)

    try:
        get_response(client, "/runtime_error")
    except RuntimeError:
        pass

    response = get_response(client, "/metrics")

    assert (
        b'http_combined_size_bytes_count{handler="/runtime_error",method="GET",status="5xx"} 1.0'
        in response.content)
Пример #23
0
def test_bucket_without_inf():
    app = create_app()
    Instrumentator(excluded_handlers=["/metrics"]).add(
        metrics.latency(buckets=(
            1,
            2,
            3,
        ))).instrument(app).expose(app)
    client = TestClient(app)

    get_response(client, "/")

    response = get_response(client, "/metrics")
    assert_is_not_multiprocess(response)
    assert b"http_request_duration_seconds" in response.content
def test_request_size_all_labels():
    app = create_app()
    Instrumentator().add(metrics.request_size()).instrument(app)
    client = TestClient(app)

    client.get("/", data="some data")

    assert (REGISTRY.get_sample_value(
        "http_request_size_bytes_sum",
        {
            "handler": "/",
            "method": "GET",
            "status": "2xx"
        },
    ) == 9)
def test_response_size_no_labels():
    app = create_app()
    Instrumentator(excluded_handlers=["/metrics"]).add(
        metrics.response_size(
            should_include_handler=False,
            should_include_method=False,
            should_include_status=False,
        )).instrument(app).expose(app)
    client = TestClient(app)

    client.get("/")

    _ = get_response(client, "/metrics")

    assert REGISTRY.get_sample_value("http_response_size_bytes_sum", {}) == 14
Пример #26
0
def test_excluding_handlers_regex():
    app = create_app()
    Instrumentator(excluded_handlers=["^/$"]).add(
        metrics.latency()).instrument(app)
    expose_metrics(app)
    client = TestClient(app)

    get_response(client, "/ignore")
    get_response(client, "/ignore")
    get_response(client, "/")

    response = get_response(client, "/metrics")

    assert b'handler="/"' not in response.content
    assert b'handler="none"' not in response.content
    assert b'handler="/ignore"' in response.content
Пример #27
0
def test_grouping_untemplated():
    app = create_app()
    Instrumentator(excluded_handlers=["/metrics"]).add(
        metrics.latency()).instrument(app)
    expose_metrics(app)
    client = TestClient(app)

    get_response(client, "/")
    get_response(client, "/items/678?q=43243")
    get_response(client, "/does_not_exist")

    response = get_response(client, "/metrics")
    assert_is_not_multiprocess(response)
    assert_request_count(1)
    assert b'handler="/does_not_exist"' not in response.content
    assert b'handler="none"' in response.content
def test_namespace_subsystem():
    app = create_app()
    Instrumentator().add(
        metrics.request_size(
            should_include_handler=False,
            should_include_method=False,
            should_include_status=False,
            metric_namespace="namespace",
            metric_subsystem="subsystem",
        )).instrument(app).expose(app)
    client = TestClient(app)

    response = get_response(client, "/metrics")

    assert b" http_request_size_bytes" not in response.content
    assert b" namespace_subsystem_http_request_size_bytes" in response.content
def test_requests_all_labels():
    app = create_app()
    Instrumentator().add(metrics.requests()).instrument(app).expose(app)
    client = TestClient(app)

    client.get("/")

    _ = get_response(client, "/metrics")

    assert (REGISTRY.get_sample_value(
        "http_requests_total",
        {
            "handler": "/",
            "method": "GET",
            "status": "2xx"
        },
    ) == 1)
def test_latency_all_labels():
    app = create_app()
    Instrumentator().add(metrics.latency()).instrument(app).expose(app)
    client = TestClient(app)

    client.get("/")

    _ = get_response(client, "/metrics")

    assert (REGISTRY.get_sample_value(
        "http_request_duration_seconds_sum",
        {
            "handler": "/",
            "method": "GET",
            "status": "2xx"
        },
    ) > 0)