예제 #1
0
def test_store_endpoint_update_existing(db: Session, client: TestClient):
    access_key = _get_access_key()
    endpoint = _mock_random_endpoint()
    write_endpoint_to_kv(access_key=access_key, endpoint=endpoint)

    kv_record_before_update = ModelEndpoints.get_endpoint(
        access_key=access_key,
        project=endpoint.metadata.project,
        endpoint_id=endpoint.metadata.uid,
    )

    assert kv_record_before_update.status.state is None

    endpoint_dict = endpoint.dict()
    endpoint_dict["status"]["state"] = "testing...testing...1 2 1 2"

    response = client.put(
        url=f"/api/projects/{endpoint.metadata.project}/model-endpoints/{endpoint.metadata.uid}",
        headers={"X-V3io-Session-Key": access_key},
        json=endpoint_dict,
    )

    assert response.status_code == 204

    kv_record_after_update = ModelEndpoints.get_endpoint(
        access_key=access_key,
        project=endpoint.metadata.project,
        endpoint_id=endpoint.metadata.uid,
    )

    assert kv_record_after_update.status.state == "testing...testing...1 2 1 2"
예제 #2
0
def test_deserialize_endpoint_from_kv():
    endpoint = _mock_random_endpoint()
    write_endpoint_to_kv(_get_access_key(), endpoint)
    endpoint_from_kv = ModelEndpoints.get_endpoint(
        access_key=_get_access_key(),
        project=endpoint.metadata.project,
        endpoint_id=endpoint.metadata.uid,
    )
    assert endpoint.metadata.uid == endpoint_from_kv.metadata.uid
예제 #3
0
def test_get_endpoint_metrics(db: Session, client: TestClient):
    path = config.model_endpoint_monitoring.store_prefixes.default.format(
        project=TEST_PROJECT, kind=EVENTS
    )
    _, container, path = parse_model_endpoint_store_prefix(path)

    frames = get_frames_client(
        token=_get_access_key(), container=container, address=config.v3io_framesd,
    )

    start = datetime.utcnow()

    for i in range(5):
        endpoint = _mock_random_endpoint()
        write_endpoint_to_kv(_get_access_key(), endpoint)
        frames.create(backend="tsdb", table=path, rate="10/m", if_exists=1)

        total = 0

        dfs = []

        for i in range(10):
            count = randint(1, 10)
            total += count
            data = {
                "predictions_per_second_count_1s": count,
                "endpoint_id": endpoint.metadata.uid,
                "timestamp": start - timedelta(minutes=10 - i),
            }
            df = pd.DataFrame(data=[data])
            dfs.append(df)

        frames.write(
            backend="tsdb",
            table=path,
            dfs=dfs,
            index_cols=["timestamp", "endpoint_id"],
        )

        response = client.get(
            url=f"/api/projects/{TEST_PROJECT}/model-endpoints/{endpoint.metadata.uid}?metric=predictions_per_second_count_1s",  # noqa
            headers={"X-V3io-Session-Key": _get_access_key()},
        )

        endpoint = ModelEndpoint(**response.json())

        assert len(endpoint.status.metrics) > 0

        predictions_per_second = endpoint.status.metrics[
            "predictions_per_second_count_1s"
        ]

        assert predictions_per_second.name == "predictions_per_second_count_1s"

        response_total = sum((m[1] for m in predictions_per_second.values))

        assert total == response_total
예제 #4
0
def test_get_endpoint_metric_function():
    path = config.model_endpoint_monitoring.store_prefixes.default.format(
        project=TEST_PROJECT, kind=EVENTS
    )
    _, container, path = parse_model_endpoint_store_prefix(path)

    frames = get_frames_client(
        token=_get_access_key(), container=container, address=config.v3io_framesd,
    )

    start = datetime.utcnow()

    endpoint = _mock_random_endpoint()
    write_endpoint_to_kv(_get_access_key(), endpoint)

    frames.create(backend="tsdb", table=path, rate="10/m", if_exists=1)

    total = 0
    dfs = []

    for i in range(10):
        count = randint(1, 10)
        total += count
        data = {
            "predictions_per_second_count_1s": count,
            "endpoint_id": endpoint.metadata.uid,
            "timestamp": start - timedelta(minutes=10 - i),
        }
        df = pd.DataFrame(data=[data])
        dfs.append(df)

    frames.write(
        backend="tsdb", table=path, dfs=dfs, index_cols=["timestamp", "endpoint_id"],
    )

    endpoint_metrics = get_endpoint_metrics(
        access_key=_get_access_key(),
        project=TEST_PROJECT,
        endpoint_id=endpoint.metadata.uid,
        metrics=["predictions_per_second_count_1s"],
    )

    assert "predictions_per_second_count_1s" in endpoint_metrics

    actual_values = endpoint_metrics["predictions_per_second_count_1s"].values
    assert len(actual_values) == 10
    assert sum(map(lambda t: t[1], actual_values)) == total
예제 #5
0
def test_list_endpoints(db: Session, client: TestClient):
    endpoints_in = [_mock_random_endpoint("testing") for _ in range(5)]

    for endpoint in endpoints_in:
        write_endpoint_to_kv(_get_access_key(), endpoint)

    response = client.get(
        url=f"/api/projects/{TEST_PROJECT}/model-endpoints",
        headers={"X-V3io-Session-Key": _get_access_key()},
    )

    endpoints_out = [ModelEndpoint(**e) for e in response.json()["endpoints"]]

    in_endpoint_ids = set(map(lambda e: e.metadata.uid, endpoints_in))
    out_endpoint_ids = set(map(lambda e: e.metadata.uid, endpoints_out))

    endpoints_intersect = in_endpoint_ids.intersection(out_endpoint_ids)
    assert len(endpoints_intersect) == 5
예제 #6
0
def test_list_endpoints_filter(db: Session, client: TestClient):
    access_key = _get_access_key()
    for i in range(5):
        endpoint_details = _mock_random_endpoint()

        if i < 1:
            endpoint_details.spec.model = "filterme"

        if i < 2:
            endpoint_details.spec.function_uri = "test/filterme"

        if i < 4:
            endpoint_details.metadata.labels = {"filtermex": "1", "filtermey": "2"}

        write_endpoint_to_kv(_get_access_key(), endpoint_details)

    filter_model = client.get(
        f"/api/projects/{TEST_PROJECT}/model-endpoints/?model=filterme",
        headers={"X-V3io-Session-Key": access_key},
    )
    assert len(filter_model.json()["endpoints"]) == 1

    filter_labels = client.get(
        f"/api/projects/{TEST_PROJECT}/model-endpoints/?label=filtermex=1",
        headers={"X-V3io-Session-Key": access_key},
    )
    assert len(filter_labels.json()["endpoints"]) == 4

    filter_labels = client.get(
        f"/api/projects/{TEST_PROJECT}/model-endpoints/?label=filtermex=1&label=filtermey=2",
        headers={"X-V3io-Session-Key": access_key},
    )
    assert len(filter_labels.json()["endpoints"]) == 4

    filter_labels = client.get(
        f"/api/projects/{TEST_PROJECT}/model-endpoints/?label=filtermey=2",
        headers={"X-V3io-Session-Key": access_key},
    )
    assert len(filter_labels.json()["endpoints"]) == 4
예제 #7
0
def test_grafana_list_endpoints(db: Session, client: TestClient):
    endpoints_in = [_mock_random_endpoint("active") for _ in range(5)]

    for endpoint in endpoints_in:
        write_endpoint_to_kv(_get_access_key(), endpoint)

    response = client.post(
        url="/api/grafana-proxy/model-endpoints/query",
        headers={"X-V3io-Session-Key": _get_access_key()},
        json={
            "targets": [{
                "target":
                f"project={TEST_PROJECT};target_endpoint=list_endpoints"
            }]
        },
    )

    response_json = response.json()
    if not response_json:
        fail(f"Empty response, expected list of dictionaries. {response_json}")

    response_json = response_json[0]
    if not response_json:
        fail(
            f"Empty dictionary, expected dictionary with 'columns', 'rows' and 'type' fields. {response_json}"
        )

    if "columns" not in response_json:
        fail(f"Missing 'columns' key in response dictionary. {response_json}")

    if "rows" not in response_json:
        fail(f"Missing 'rows' key in response dictionary. {response_json}")

    if "type" not in response_json:
        fail(f"Missing 'type' key in response dictionary. {response_json}")

    assert len(response_json["rows"]) == 5
예제 #8
0
def test_clear_endpoint(db: Session, client: TestClient):
    access_key = _get_access_key()
    endpoint = _mock_random_endpoint()
    write_endpoint_to_kv(access_key, endpoint)
    kv_record = ModelEndpoints.get_endpoint(
        access_key=access_key,
        project=endpoint.metadata.project,
        endpoint_id=endpoint.metadata.uid,
    )

    assert kv_record
    response = client.delete(
        url=f"/api/projects/{kv_record.metadata.project}/model-endpoints/{endpoint.metadata.uid}",
        headers={"X-V3io-Session-Key": access_key},
    )

    assert response.status_code == 204

    with pytest.raises(MLRunNotFoundError):
        ModelEndpoints.get_endpoint(
            access_key=access_key,
            project=endpoint.metadata.project,
            endpoint_id=endpoint.metadata.uid,
        )