Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Revert "Simple 7407 diagnostics in client" #137

Merged
merged 2 commits into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 0 additions & 39 deletions tests/test_client_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
from virl2_client.virl2_client import (
ClientConfig,
ClientLibrary,
DiagnosticCategory,
InitializationError,
Version,
)
Expand Down Expand Up @@ -740,41 +739,3 @@ def test_convergence_parametrization(client_library_server_current, mocked_sessi
with pytest.raises(RuntimeError) as err:
lab.wait_until_lab_converged(max_iterations=1)
assert ("has not converged, maximum tries %s exceeded" % 1) in err.value.args[0]


@pytest.mark.parametrize(
"categories, expected_paths",
[
(None, [diag.value for diag in DiagnosticCategory]),
([DiagnosticCategory.COMPUTES], [DiagnosticCategory.COMPUTES.value]),
(
[DiagnosticCategory.LABS, DiagnosticCategory.SERVICES],
[DiagnosticCategory.LABS.value, DiagnosticCategory.SERVICES.value],
),
],
)
def test_get_diagnostics_paths(client_library, categories, expected_paths):
with respx.mock(base_url="https://0.0.0.0/api/v0/") as respx_mock:
for path in expected_paths:
respx_mock.get(f"diagnostics/{path}").mock(
return_value=httpx.Response(200, json={"data": "sample"})
)
diagnostics_data = client_library.get_diagnostics(categories=categories)
for path in expected_paths:
assert path in diagnostics_data
assert diagnostics_data[path] == {"data": "sample"}


def test_get_diagnostics_error_handling(client_library):
with respx.mock(base_url="https://0.0.0.0/api/v0/") as respx_mock:
for diag_type in DiagnosticCategory:
respx_mock.get(f"diagnostics/{diag_type.value}").mock(
return_value=httpx.Response(404)
)

diagnostics_data = client_library.get_diagnostics()

for diag_type in DiagnosticCategory:
assert diagnostics_data[diag_type.value] == {
"error": f"Failed to fetch {diag_type.value} diagnostics"
}
47 changes: 11 additions & 36 deletions virl2_client/virl2_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import os
import re
import time
from enum import Enum
from functools import lru_cache
from pathlib import Path
from threading import RLock
Expand Down Expand Up @@ -163,18 +162,6 @@ def make_client(self) -> ClientLibrary:
return client


class DiagnosticCategory(Enum):
COMPUTES = "computes"
LABS = "labs"
LAB_EVENTS = "lab_events"
NODE_LAUNCH_QUEUE = "node_launch_queue"
SERVICES = "services"
NODE_DEFINITIONS = "node_definitions"
USER_LIST = "user_list"
LICENSING = "licensing"
STARTUP_SCHEDULER = "startup_scheduler"


class ClientLibrary:
"""Python bindings for the REST API of a CML controller."""

Expand Down Expand Up @@ -207,7 +194,7 @@ class ClientLibrary:
"labs": "labs",
"lab": "labs/{lab_id}",
"lab_topology": "labs/{lab_id}/topology",
"diagnostics": "diagnostics/{category}",
"diagnostics": "diagnostics",
"system_health": "system_health",
"system_stats": "system_stats",
"populate_lab_tiles": "populate_lab_tiles",
Expand Down Expand Up @@ -639,11 +626,16 @@ def all_labs(self, show_all: bool = False) -> list[Lab]:
:param show_all: Whether to get only labs owned by the admin or all user labs.
:returns: A list of Lab objects.
"""
lab_ids = self.get_lab_list(show_all=show_all)
url = {"url": self._url_for("labs")}
if show_all:
url["params"] = {"show_all": True}
lab_ids = self._session.get(**url).json()

result = []
for lab_id in lab_ids:
lab = self.join_existing_lab(lab_id)
result.append(lab)

return result

@locked
Expand Down Expand Up @@ -818,31 +810,14 @@ def join_existing_lab(self, lab_id: str, sync_lab: bool = True) -> Lab:
self._labs[lab_id] = lab
return lab

def get_diagnostics(
self, categories: list[DiagnosticCategory] | None = None
) -> dict:
def get_diagnostics(self) -> dict:
"""
Return selected diagnostic data as a JSON object.
Return the controller diagnostic data as a JSON object.

:param categories: List of diagnostic categories to fetch. If None, fetch all.
:returns: The diagnostic data.
"""
if categories is None:
categories = list(DiagnosticCategory)

diagnostics_data = {}
for category in categories:
value = category.value
url = self._url_for("diagnostics", category=value)
try:
response = self._session.get(url)
response.raise_for_status()
diagnostics_data[value] = response.json()
except httpx.HTTPStatusError:
diagnostics_data[value] = {
"error": f"Failed to fetch {value} diagnostics"
}
return diagnostics_data
url = self._url_for("diagnostics")
return self._session.get(url).json()

def get_system_health(self) -> dict:
"""
Expand Down