Skip to content

Commit 9379663

Browse files
add unit tests
1 parent 4ca7f80 commit 9379663

5 files changed

Lines changed: 602 additions & 0 deletions

File tree

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import re
2+
3+
import pytest
4+
5+
from askui.tools.askui.agent_os_server import (
6+
AgentOsServer,
7+
LocalAgentOsServer,
8+
RemoteAgentOsServer,
9+
_generate_session_guid,
10+
_replace_port,
11+
)
12+
13+
14+
class TestSessionGuid:
15+
def test_generated_guid_is_brace_wrapped_uuid(self) -> None:
16+
guid = _generate_session_guid()
17+
assert re.fullmatch(
18+
r"\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}",
19+
guid,
20+
)
21+
22+
def test_each_generated_guid_is_unique(self) -> None:
23+
assert _generate_session_guid() != _generate_session_guid()
24+
25+
26+
class TestReplacePort:
27+
def test_replaces_port_on_bare_authority(self) -> None:
28+
assert _replace_port("example.com:1234", 23000) == "example.com:23000"
29+
30+
def test_replaces_port_on_url_with_scheme(self) -> None:
31+
assert _replace_port("http://example.com:1234", 23000) == "example.com:23000"
32+
33+
def test_falls_back_to_localhost_when_host_missing(self) -> None:
34+
# A bare ":1234" has no hostname, so the helper falls back to "localhost".
35+
assert _replace_port(":1234", 23000) == "localhost:23000"
36+
37+
38+
class TestAgentOsServer:
39+
def test_session_guid_unique_per_instance(self) -> None:
40+
a = RemoteAgentOsServer(address="1.2.3.4:23000", description="a")
41+
b = RemoteAgentOsServer(address="5.6.7.8:23000", description="b")
42+
assert a.session_guid != b.session_guid
43+
44+
def test_computer_id_defaults_to_session_guid(self) -> None:
45+
s = RemoteAgentOsServer(address="1.2.3.4:23000", description="a")
46+
assert s.computer_id == s.session_guid
47+
48+
def test_explicit_computer_id_is_preserved(self) -> None:
49+
s = RemoteAgentOsServer(
50+
address="1.2.3.4:23000", description="a", computer_id="laptop"
51+
)
52+
assert s.computer_id == "laptop"
53+
assert s.session_guid != "laptop"
54+
55+
def test_display_defaults_to_one_and_is_settable(self) -> None:
56+
s = RemoteAgentOsServer(address="1.2.3.4:23000", description="a")
57+
assert s.display == 1
58+
s.display = 3
59+
assert s.display == 3
60+
61+
def test_explicit_display_is_preserved(self) -> None:
62+
s = RemoteAgentOsServer(address="1.2.3.4:23000", description="a", display=2)
63+
assert s.display == 2
64+
65+
def test_repr_contains_identity_fields(self) -> None:
66+
s = RemoteAgentOsServer(
67+
address="1.2.3.4:23000",
68+
description="my rig",
69+
display=2,
70+
computer_id="rig",
71+
)
72+
r = repr(s)
73+
assert "RemoteAgentOsServer" in r
74+
assert "computer_id='rig'" in r
75+
assert "description='my rig'" in r
76+
assert "display=2" in r
77+
78+
def test_base_class_is_not_local(self) -> None:
79+
s = RemoteAgentOsServer(address="1.2.3.4:23000", description="a")
80+
assert s.is_local is False
81+
82+
def test_start_and_stop_are_no_ops_on_remote(self) -> None:
83+
s = RemoteAgentOsServer(address="1.2.3.4:23000", description="a")
84+
s.start()
85+
s.stop()
86+
87+
88+
class TestLocalAgentOsServer:
89+
def test_is_local(self) -> None:
90+
s = LocalAgentOsServer(discover_service=False)
91+
assert s.is_local is True
92+
93+
def test_default_description(self) -> None:
94+
s = LocalAgentOsServer(discover_service=False)
95+
assert s.description == "Local Agent OS server"
96+
97+
def test_default_address(self) -> None:
98+
s = LocalAgentOsServer(discover_service=False)
99+
assert s.address == "localhost:23000"
100+
101+
def test_is_service_default_false(self) -> None:
102+
s = LocalAgentOsServer(discover_service=False)
103+
assert s.is_service is False
104+
105+
def test_explicit_computer_id(self) -> None:
106+
s = LocalAgentOsServer(discover_service=False, computer_id="my-laptop")
107+
assert s.computer_id == "my-laptop"
108+
109+
def test_parse_port_rejects_bad_address(self) -> None:
110+
s = LocalAgentOsServer(discover_service=False, address="no-port-here")
111+
with pytest.raises(ValueError, match="Could not parse port"):
112+
s._parse_port() # noqa: SLF001 - intentional unit test against helper
113+
114+
def test_parse_port_extracts_port(self) -> None:
115+
s = LocalAgentOsServer(discover_service=False, address="localhost:24567")
116+
assert s._parse_port() == 24567 # noqa: SLF001
117+
118+
119+
class TestSubclassesPassThroughDisplayAndId:
120+
@pytest.mark.parametrize(
121+
"factory",
122+
[
123+
lambda: LocalAgentOsServer(
124+
discover_service=False, display=4, computer_id="local"
125+
),
126+
lambda: RemoteAgentOsServer(
127+
address="1.2.3.4:23000",
128+
description="r",
129+
display=4,
130+
computer_id="remote",
131+
),
132+
],
133+
)
134+
def test_display_and_computer_id_round_trip(self, factory) -> None: # noqa: ANN001
135+
s: AgentOsServer = factory()
136+
assert s.display == 4
137+
assert s.computer_id in {"local", "remote"}
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
import pytest
2+
3+
from askui.tools.askui.agent_os_server import (
4+
LocalAgentOsServer,
5+
RemoteAgentOsServer,
6+
)
7+
from askui.tools.askui.agent_os_server_manager import AgentOsServerManager
8+
9+
10+
def _make_remote(
11+
address: str = "1.2.3.4:23000",
12+
description: str = "remote",
13+
computer_id: str | None = None,
14+
) -> RemoteAgentOsServer:
15+
return RemoteAgentOsServer(
16+
address=address, description=description, computer_id=computer_id
17+
)
18+
19+
20+
def _make_local(computer_id: str | None = None) -> LocalAgentOsServer:
21+
return LocalAgentOsServer(discover_service=False, computer_id=computer_id)
22+
23+
24+
class TestConstruction:
25+
def test_empty_constructor_yields_empty_manager(self) -> None:
26+
m = AgentOsServerManager()
27+
assert m.list() == []
28+
assert m.active is None
29+
assert len(m) == 0
30+
31+
def test_constructor_registers_initial_servers_in_order(self) -> None:
32+
a = _make_remote(address="1.1.1.1:23000", computer_id="a")
33+
b = _make_remote(address="2.2.2.2:23000", computer_id="b")
34+
m = AgentOsServerManager(agent_os_servers=[a, b])
35+
assert m.list() == [a, b]
36+
# First registered becomes active.
37+
assert m.active is a
38+
39+
def test_first_added_becomes_active(self) -> None:
40+
m = AgentOsServerManager()
41+
a = _make_remote(computer_id="a")
42+
m.add(a)
43+
assert m.active is a
44+
45+
46+
class TestAddConstraints:
47+
def test_rejects_second_local_server(self) -> None:
48+
m = AgentOsServerManager()
49+
m.add(_make_local(computer_id="first"))
50+
with pytest.raises(ValueError, match="second local Agent OS server"):
51+
m.add(_make_local(computer_id="second"))
52+
53+
def test_rejects_duplicate_computer_id(self) -> None:
54+
m = AgentOsServerManager()
55+
m.add(_make_remote(address="1.1.1.1:23000", computer_id="rig"))
56+
with pytest.raises(ValueError, match="computer_id='rig'"):
57+
m.add(_make_remote(address="2.2.2.2:23000", computer_id="rig"))
58+
59+
def test_rejects_duplicate_remote_address(self) -> None:
60+
m = AgentOsServerManager()
61+
m.add(_make_remote(address="1.1.1.1:23000", computer_id="a"))
62+
with pytest.raises(
63+
ValueError, match="remote Agent OS server with address '1.1.1.1:23000'"
64+
):
65+
m.add(_make_remote(address="1.1.1.1:23000", computer_id="b"))
66+
67+
def test_allows_local_plus_remote_with_same_address(self) -> None:
68+
m = AgentOsServerManager()
69+
m.add(_make_local(computer_id="local"))
70+
# Local target's default address is 'localhost:23000' but the local/remote
71+
# address-uniqueness rule only applies between remote servers.
72+
m.add(
73+
_make_remote(
74+
address="localhost:23000", description="remote", computer_id="remote"
75+
)
76+
)
77+
assert len(m) == 2
78+
79+
80+
class TestAddRemote:
81+
def test_constructs_and_registers(self) -> None:
82+
m = AgentOsServerManager()
83+
server = m.add_remote(address="1.2.3.4:23000", description="r")
84+
assert isinstance(server, RemoteAgentOsServer)
85+
assert server.address == "1.2.3.4:23000"
86+
assert server.description == "r"
87+
assert m.list() == [server]
88+
89+
90+
class TestGetAndSwitch:
91+
def test_get_returns_server_by_computer_id(self) -> None:
92+
m = AgentOsServerManager()
93+
a = _make_remote(address="1.1.1.1:23000", computer_id="a")
94+
m.add(a)
95+
assert m.get("a") is a
96+
97+
def test_get_raises_keyerror_with_registered_ids(self) -> None:
98+
m = AgentOsServerManager()
99+
m.add(_make_remote(address="1.1.1.1:23000", computer_id="a"))
100+
with pytest.raises(KeyError) as exc_info:
101+
m.get("missing")
102+
message = str(exc_info.value)
103+
assert "missing" in message
104+
assert "'a'" in message # registered id surfaced
105+
106+
def test_switch_changes_active(self) -> None:
107+
m = AgentOsServerManager()
108+
a = _make_remote(address="1.1.1.1:23000", computer_id="a")
109+
b = _make_remote(address="2.2.2.2:23000", computer_id="b")
110+
m.add(a)
111+
m.add(b)
112+
assert m.active is a
113+
m.switch("b")
114+
assert m.active is b
115+
116+
def test_switch_unknown_id_raises_keyerror(self) -> None:
117+
m = AgentOsServerManager()
118+
m.add(_make_remote(computer_id="a"))
119+
with pytest.raises(KeyError, match="missing"):
120+
m.switch("missing")
121+
122+
123+
class TestGetBySessionGuid:
124+
def test_returns_server_by_session_guid(self) -> None:
125+
m = AgentOsServerManager()
126+
a = _make_remote(address="1.1.1.1:23000", computer_id="a")
127+
m.add(a)
128+
assert m.get_by_session_guid(a.session_guid) is a
129+
130+
def test_returns_none_for_unknown_session_guid(self) -> None:
131+
m = AgentOsServerManager()
132+
m.add(_make_remote(computer_id="a"))
133+
assert m.get_by_session_guid("no-such-guid") is None
134+
135+
136+
class TestRemove:
137+
def test_remove_drops_server(self) -> None:
138+
m = AgentOsServerManager()
139+
a = _make_remote(address="1.1.1.1:23000", computer_id="a")
140+
b = _make_remote(address="2.2.2.2:23000", computer_id="b")
141+
m.add(a)
142+
m.add(b)
143+
m.remove("a")
144+
assert m.list() == [b]
145+
146+
def test_remove_active_falls_back_to_first_remaining(self) -> None:
147+
m = AgentOsServerManager()
148+
a = _make_remote(address="1.1.1.1:23000", computer_id="a")
149+
b = _make_remote(address="2.2.2.2:23000", computer_id="b")
150+
m.add(a)
151+
m.add(b)
152+
assert m.active is a
153+
m.remove("a")
154+
assert m.active is b
155+
156+
def test_remove_last_clears_active(self) -> None:
157+
m = AgentOsServerManager()
158+
m.add(_make_remote(computer_id="a"))
159+
m.remove("a")
160+
assert m.active is None
161+
assert len(m) == 0
162+
163+
def test_remove_inactive_keeps_active_unchanged(self) -> None:
164+
m = AgentOsServerManager()
165+
a = _make_remote(address="1.1.1.1:23000", computer_id="a")
166+
b = _make_remote(address="2.2.2.2:23000", computer_id="b")
167+
m.add(a)
168+
m.add(b)
169+
m.remove("b")
170+
assert m.active is a
171+
172+
def test_remove_unknown_raises_keyerror(self) -> None:
173+
m = AgentOsServerManager()
174+
m.add(_make_remote(computer_id="a"))
175+
with pytest.raises(KeyError):
176+
m.remove("missing")
177+
178+
179+
class TestReset:
180+
def test_reset_clears_all(self) -> None:
181+
m = AgentOsServerManager()
182+
m.add(_make_remote(computer_id="a"))
183+
m.add(_make_remote(address="2.2.2.2:23000", computer_id="b"))
184+
m.reset()
185+
assert m.list() == []
186+
assert m.active is None
187+
assert len(m) == 0

0 commit comments

Comments
 (0)