Skip to content

Add test coverage for agents router endpoints#370

Open
reo0603 wants to merge 3 commits intoLight-Heart-Labs:mainfrom
reo0603:test/agents-router-coverage
Open

Add test coverage for agents router endpoints#370
reo0603 wants to merge 3 commits intoLight-Heart-Labs:mainfrom
reo0603:test/agents-router-coverage

Conversation

@reo0603
Copy link
Contributor

@reo0603 reo0603 commented Mar 18, 2026

Summary

Adds comprehensive test coverage for the agents router which was previously untested in test_routers.py.

Changes

Auth enforcement tests (401 without token):

  • GET /api/agents/metrics
  • GET /api/agents/cluster
  • GET /api/agents/throughput

Authenticated endpoint tests (200 with token):

  • GET /api/agents/metrics → validates response structure (agent, cluster, throughput)
  • GET /api/agents/cluster → validates cluster status fields (nodes, total_gpus, active_gpus, failover_ready)
  • GET /api/agents/throughput → validates throughput stats fields (current, average, peak, history)

Consistency

This brings agents router coverage in line with other routers (workflows, privacy, setup, features) which all have similar auth + authenticated test pairs.

The agents router had 4 endpoints but zero tests in test_routers.py. All other routers have test coverage.

Copy link
Collaborator

@Lightheartdevs Lightheartdevs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Add test coverage for agents router endpoints

The auth-enforcement tests (401 without token) are solid and follow the established pattern — no issues there.

However, the authenticated endpoint tests have a significant gap: they only exercise the default/zeroed state of the global singletons (agent_metrics, cluster_status, throughput in agent_monitor.py), not any real behavior.

Specific issues

1. test_agents_cluster_authenticated tests nothing beyond defaults (test_routers.py, new lines ~340-347)

The /api/agents/cluster endpoint calls await cluster_status.refresh(), which shells out to curl to hit a cluster proxy. In the test environment, curl either fails or the proxy isn't running, so every exception is silently caught, and to_dict() returns the initial {"nodes": [], "total_gpus": 0, "active_gpus": 0, "failover_ready": False}. The test asserts those keys exist — which they always will, even if the endpoint were completely broken.

Suggestion: mock asyncio.create_subprocess_exec to simulate a healthy cluster response (e.g., two nodes, one healthy) and assert the parsed values (active_gpus == 1, failover_ready == False). Then a second case with two healthy nodes where failover_ready == True. This tests the actual parsing/logic in ClusterStatus.refresh().

2. test_agents_throughput_authenticated only sees empty history (test_routers.py, new lines ~350-358)

throughput.get_stats() returns {"current": 0, "average": 0, "peak": 0, "history": []} when data_points is empty. The test asserts those keys exist but never verifies the endpoint works with actual data. Since ThroughputMetrics is a global singleton, you could call throughput.add_sample(42.0) before the request and assert current == 42.0, peak == 42.0, etc. This would test real behavior with minimal setup.

3. test_agents_metrics_authenticated — same default-state issue (test_routers.py, new lines ~334-339)

get_full_agent_metrics() composes the other two plus agent_metrics.to_dict(). Since all are at defaults, this test only confirms the response shape, not any meaningful aggregation. At minimum, seeding throughput and agent_metrics with non-default values and checking the composed output would add value.

4. Missing coverage for /api/agents/metrics.html

The router has 4 endpoints but only 3 are tested. The metrics.html endpoint renders an HTML fragment with interpolated values and html.escape() for XSS safety — that escaping logic is worth testing (e.g., inject a <script> tag into a metric value and assert it's escaped in the response).

Summary

The auth tests are good. The authenticated tests need to move beyond asserting default response shapes and actually exercise the endpoint logic with non-trivial inputs. As written, these tests would still pass even if the parsing, aggregation, or refresh logic were completely removed.

@Lightheartdevs
Copy link
Collaborator

What's needed to get this merged:

  1. Seed real data in tests — the authenticated endpoint tests only verify default/zeroed state. Inject some actual metrics data before asserting, otherwise tests pass even if endpoint logic is gutted.
  2. Add coverage for /api/agents/metrics.html — it has html.escape() XSS-prevention logic worth verifying. Test that HTML-special chars in agent names are escaped.

@reo0603
Copy link
Contributor Author

reo0603 commented Mar 18, 2026

Updated to address the review feedback:

1. Seeded real data in authenticated tests

  • test_agents_metrics_authenticated now sets session_count=5, tokens_per_second=123.45, and adds throughput samples
  • test_agents_throughput_authenticated adds 3 samples and verifies calculated stats (current=38.0, peak=55.0, average=45.0)
  • Tests now verify actual behavior instead of just default/zeroed state

2. Mocked cluster responses to test parsing logic

  • test_agents_cluster_authenticated mocks a 2-node cluster with 1 healthy node, verifies active_gpus=1 and failover_ready=False
  • Added test_agents_cluster_failover_ready with 2 healthy nodes to verify failover_ready=True logic

3. Added XSS escaping coverage

  • test_agents_metrics_html_xss_escaping injects <script>alert(1)</script> into cluster node data
  • Verifies HTML special chars are escaped in the response (no raw <script> tags)
  • Tests the html.escape() logic in the metrics.html endpoint

All tests now exercise real endpoint logic with non-trivial inputs.

@reo0603 reo0603 requested a review from Lightheartdevs March 18, 2026 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants