Skip to content

Commit 2eba025

Browse files
Refactor, extend functionality and add examples
1 parent c2d5124 commit 2eba025

5 files changed

Lines changed: 105 additions & 21 deletions

File tree

hello/api.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ class HelloConfig:
1919

2020
class Hello(object):
2121

22-
@classmethod
23-
def default_config(cls) -> HelloConfig:
24-
return HelloConfig()
25-
2622
@classmethod
2723
def default_advertizer(cls, config: HelloConfig) -> DefaultAdvertizer:
2824
sender = RadioSender(config.context)
@@ -49,8 +45,8 @@ def scheduled_discoverer(cls, config: HelloConfig) -> ScheduledDiscoverer:
4945
return ScheduledDiscoverer(discoverer, ReusableTimer())
5046

5147
@classmethod
52-
def builder(cls) -> 'HelloBuilder':
53-
return HelloBuilder()
48+
def builder(cls, config: HelloConfig | None = None) -> 'HelloBuilder':
49+
return HelloBuilder(config if config else HelloConfig())
5450

5551

5652
class AdvertizerBuilder(object):
@@ -79,12 +75,8 @@ def scheduled(self) -> ScheduledDiscoverer:
7975

8076
class HelloBuilder(object):
8177

82-
def __init__(self) -> None:
83-
self._config = Hello.default_config()
84-
85-
def config(self, config: HelloConfig) -> 'HelloBuilder':
78+
def __init__(self, config: HelloConfig) -> None:
8679
self._config = config
87-
return self
8880

8981
def advertizer(self) -> AdvertizerBuilder:
9082
return AdvertizerBuilder(self._config)

hello/discoverer.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,5 +157,17 @@ def stop(self) -> None:
157157
def discover(self, query: ServiceQuery | None = None) -> None:
158158
self._discoverer.discover(query)
159159

160+
def get_services(self) -> dict[str, ServiceInfo]:
161+
return self._discoverer.get_services()
162+
163+
def register(self, handler: OnDiscoveryEvent) -> None:
164+
self._discoverer.register(handler)
165+
166+
def deregister(self, handler: OnDiscoveryEvent) -> None:
167+
self._discoverer.deregister(handler)
168+
169+
def get_handlers(self) -> list[OnDiscoveryEvent]:
170+
return self._discoverer.get_handlers()
171+
160172
def _execute(self, query: ServiceQuery | None = None) -> None:
161173
self.discover(query)

hello/scheduler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ def stop(self) -> None:
3434
def schedule(self, data: T | None = None, interval: float = 60, one_shot: bool = False) -> None:
3535
if one_shot:
3636
self._timer.start(interval, self._execute, [data])
37-
log.info('One-shot execution scheduled', service=data, interval=interval)
37+
log.info('One-shot execution scheduled', data=data, interval=interval)
3838
else:
3939
self._timer.start(interval, self._execute_and_restart, [data])
40-
log.info('Periodic execution scheduled', service=data, interval=interval)
40+
log.info('Periodic execution scheduled', data=data, interval=interval)
4141

4242
def _execute(self, data: T | None = None) -> None:
4343
raise NotImplementedError()

tests/apiIntegrationTest.py

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ def test_discoverer_caches_advertised_service(self):
2424
# Given
2525
config = HelloConfig(advertizer_responder=False)
2626

27-
with Hello.default_advertizer(config) as advertizer, Hello.default_discoverer(config) as discoverer:
27+
with (Hello.builder(config).advertizer().default() as advertizer,
28+
Hello.builder(config).discoverer().default() as discoverer):
2829
advertizer.start(GROUP, SERVICE_INFO)
2930
discoverer.start(GROUP, SERVICE_QUERY)
3031

@@ -36,11 +37,12 @@ def test_discoverer_caches_advertised_service(self):
3637
# Then
3738
self.assertEqual({SERVICE_INFO.name: SERVICE_INFO}, discoverer.get_services())
3839

39-
def test_discoverer_caches_advertised_service_when_scheduled_once(self):
40+
def test_discoverer_caches_advertised_service_when_advertisement_scheduled_once(self):
4041
# Given
4142
config = HelloConfig(advertizer_responder=False)
4243

43-
with Hello.scheduled_advertizer(config) as advertizer, Hello.default_discoverer(config) as discoverer:
44+
with (Hello.builder(config).advertizer().scheduled() as advertizer,
45+
Hello.builder(config).discoverer().default() as discoverer):
4446
advertizer.start(GROUP, SERVICE_INFO)
4547
discoverer.start(GROUP, SERVICE_QUERY)
4648

@@ -52,11 +54,12 @@ def test_discoverer_caches_advertised_service_when_scheduled_once(self):
5254
# Then
5355
self.assertEqual({SERVICE_INFO.name: SERVICE_INFO}, discoverer.get_services())
5456

55-
def test_discoverer_caches_advertised_service_when_scheduled_periodically(self):
57+
def test_discoverer_caches_advertised_service_when_advertisement_scheduled_periodically(self):
5658
# Given
5759
config = HelloConfig()
5860

59-
with Hello.scheduled_advertizer(config) as advertizer, Hello.default_discoverer(config) as discoverer:
61+
with (Hello.builder(config).advertizer().scheduled() as advertizer,
62+
Hello.builder(config).discoverer().default() as discoverer):
6063
advertizer.start(GROUP, SERVICE_INFO)
6164
discoverer.start(GROUP, SERVICE_QUERY)
6265

@@ -72,14 +75,49 @@ def test_discoverer_caches_discovery_response_service(self):
7275
# Given
7376
config = HelloConfig()
7477

75-
with Hello.default_advertizer(config) as advertizer, Hello.default_discoverer(config) as discoverer:
78+
with (Hello.builder(config).advertizer().default() as advertizer,
79+
Hello.builder(config).discoverer().default() as discoverer):
7680
advertizer.start(GROUP, SERVICE_INFO)
7781
discoverer.start(GROUP, SERVICE_QUERY)
7882

7983
# When
8084
discoverer.discover()
8185

82-
wait_for_assertion(0.2, lambda: self.assertEqual(1, len(discoverer.get_services())))
86+
wait_for_assertion(0.1, lambda: self.assertEqual(1, len(discoverer.get_services())))
87+
88+
# Then
89+
self.assertEqual({SERVICE_INFO.name: SERVICE_INFO}, discoverer.get_services())
90+
91+
def test_discoverer_caches_discovery_response_service_when_discovery_scheduled_once(self):
92+
# Given
93+
config = HelloConfig()
94+
95+
with (Hello.builder(config).advertizer().default() as advertizer,
96+
Hello.builder(config).discoverer().scheduled() as discoverer):
97+
advertizer.start(GROUP, SERVICE_INFO)
98+
discoverer.start(GROUP, SERVICE_QUERY)
99+
100+
# When
101+
discoverer.schedule(interval=0.01, one_shot=True)
102+
103+
wait_for_assertion(0.1, lambda: self.assertEqual(1, len(discoverer.get_services())))
104+
105+
# Then
106+
self.assertEqual({SERVICE_INFO.name: SERVICE_INFO}, discoverer.get_services())
107+
108+
def test_discoverer_caches_discovery_response_service_when_discovery_scheduled_periodically(self):
109+
# Given
110+
config = HelloConfig()
111+
112+
with (Hello.builder(config).advertizer().default() as advertizer,
113+
Hello.builder(config).discoverer().scheduled() as discoverer):
114+
advertizer.start(GROUP, SERVICE_INFO)
115+
discoverer.start(GROUP, SERVICE_QUERY)
116+
117+
# When
118+
discoverer.schedule(interval=0.01)
119+
120+
wait_for_assertion(0.1, lambda: self.assertEqual(1, len(discoverer.get_services())))
83121

84122
# Then
85123
self.assertEqual({SERVICE_INFO.name: SERVICE_INFO}, discoverer.get_services())

tests/scheduledDiscovererTest.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from common_utility import IReusableTimer
66
from context_logger import setup_logging
77

8-
from hello import ServiceQuery, Group, ScheduledDiscoverer, Discoverer
8+
from hello import ServiceQuery, Group, ScheduledDiscoverer, Discoverer, OnDiscoveryEvent
99

1010
GROUP = Group('test-group', 'udp://239.0.0.1:5555')
1111
SERVICE_QUERY = ServiceQuery('test-service', 'test-role')
@@ -60,6 +60,48 @@ def test_starts_discoverer_when_started(self):
6060
# Then
6161
_discoverer.start.assert_called_once_with(GROUP, SERVICE_QUERY)
6262

63+
def test_registers_event_handler(self):
64+
# Given
65+
_discoverer = MagicMock(spec=Discoverer)
66+
timer = MagicMock(spec=IReusableTimer)
67+
discoverer = ScheduledDiscoverer(_discoverer, timer)
68+
handler = MagicMock(spec=OnDiscoveryEvent)
69+
70+
# When
71+
discoverer.register(handler)
72+
73+
# Then
74+
_discoverer.register.assert_called_once_with(handler)
75+
76+
def test_deregisters_event_handler(self):
77+
# Given
78+
_discoverer = MagicMock(spec=Discoverer)
79+
timer = MagicMock(spec=IReusableTimer)
80+
discoverer = ScheduledDiscoverer(_discoverer, timer)
81+
handler = MagicMock(spec=OnDiscoveryEvent)
82+
discoverer.register(handler)
83+
84+
# When
85+
discoverer.deregister(handler)
86+
87+
# Then
88+
_discoverer.deregister.assert_called_once_with(handler)
89+
90+
def test_returns_event_handlers(self):
91+
# Given
92+
_discoverer = MagicMock(spec=Discoverer)
93+
timer = MagicMock(spec=IReusableTimer)
94+
discoverer = ScheduledDiscoverer(_discoverer, timer)
95+
discoverer.start(GROUP, SERVICE_QUERY)
96+
handler = MagicMock(spec=OnDiscoveryEvent)
97+
discoverer.register(handler)
98+
99+
# When
100+
result = discoverer.get_handlers()
101+
102+
# Then
103+
self.assertEqual(_discoverer.get_handlers(), result)
104+
63105
def test_sends_service_query(self):
64106
# Given
65107
_discoverer = MagicMock(spec=Discoverer)

0 commit comments

Comments
 (0)