openmodule-test 15.2.0__tar.gz → 16.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/PKG-INFO +1 -1
  2. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/database.py +4 -0
  3. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/gate.py +4 -4
  4. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/interrupt.py +0 -3
  5. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/io_simulator.py +6 -6
  6. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/openmodule_test.egg-info/PKG-INFO +1 -1
  7. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/presence.py +10 -10
  8. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/rpc.py +11 -2
  9. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/settings.py +4 -3
  10. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/signal_simulator.py +1 -1
  11. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/zeromq.py +2 -4
  12. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/__init__.py +0 -0
  13. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/alert.py +0 -0
  14. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/connection_status.py +0 -0
  15. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/core.py +0 -0
  16. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/eventlistener.py +0 -0
  17. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/files.py +0 -0
  18. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/health.py +0 -0
  19. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/openmodule_test.egg-info/SOURCES.txt +0 -0
  20. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/openmodule_test.egg-info/dependency_links.txt +0 -0
  21. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/openmodule_test.egg-info/not-zip-safe +0 -0
  22. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/openmodule_test.egg-info/requires.txt +0 -0
  23. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/openmodule_test.egg-info/top_level.txt +0 -0
  24. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/package_reader.py +0 -0
  25. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/sentry.py +0 -0
  26. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/setup.cfg +0 -0
  27. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/setup.py +0 -0
  28. {openmodule_test-15.2.0 → openmodule_test-16.0.0}/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openmodule_test
3
- Version: 15.2.0
3
+ Version: 16.0.0
4
4
  Summary: Libraries for testing openmodule services
5
5
  Home-page: https://gitlab.com/arivo-public/device-python/openmodule.git
6
6
  Author: ARIVO
@@ -41,6 +41,7 @@ class SQLiteTestMixin(TestCase):
41
41
  alembic_path = "../src/database"
42
42
  database_name = "database"
43
43
  main_process_migration = True # change if migration should be performed in a separate process
44
+ delete_backups = True # if True, all database backups are deleted on teardown
44
45
 
45
46
  @classmethod
46
47
  def get_database_folder(cls):
@@ -81,6 +82,9 @@ class SQLiteTestMixin(TestCase):
81
82
  super().tearDown()
82
83
  if self.create_database:
83
84
  truncate_all_tables(self.database)
85
+ if self.delete_backups:
86
+ for file in glob(os.path.join(self.get_database_folder(), f"{self.database_name}_*.sqlite3.backup")):
87
+ os.unlink(file)
84
88
 
85
89
  @classmethod
86
90
  def tearDownClass(cls):
@@ -25,10 +25,8 @@ class TestGate:
25
25
  def __init__(self, gate: str, direction: Direction, dispatcher: MessageDispatcher):
26
26
  self.gate = gate
27
27
  self.direction = direction
28
- dispatcher.register_handler("access_accept", TestGateAccessMessage, self._access_accept,
29
- register_schema=False, match_type=False)
30
- dispatcher.register_handler("access_reject", TestGateAccessMessage, self._access_reject,
31
- register_schema=False, match_type=False)
28
+ dispatcher.register_handler("access_accept", TestGateAccessMessage, self._access_accept, match_type=False)
29
+ dispatcher.register_handler("access_reject", TestGateAccessMessage, self._access_reject, match_type=False)
32
30
  _all_gates.add(self)
33
31
 
34
32
  @classmethod
@@ -42,10 +40,12 @@ class TestGate:
42
40
  self._wait_called_since_reset = False
43
41
 
44
42
  def _access_accept(self, message: TestGateAccessMessage):
43
+ """ increment open_count if correct gate """
45
44
  if message.gateway.gate == self.gate:
46
45
  self.open_count += 1
47
46
 
48
47
  def _access_reject(self, message: TestGateAccessMessage):
48
+ """ increment reject_count if correct gate """
49
49
  if message.gateway.gate == self.gate:
50
50
  self.reject_count += 1
51
51
 
@@ -13,7 +13,6 @@ from unittest import TestCase
13
13
  import multiprocessing_logging
14
14
 
15
15
  from openmodule.core import shutdown_openmodule
16
- from openmodule.utils.schema import Schema
17
16
  from openmodule_test.health import HealthTestMixin
18
17
 
19
18
 
@@ -26,7 +25,6 @@ class ExceptionProcess(Process):
26
25
  def run(self):
27
26
  try:
28
27
  super().run()
29
- Schema.to_file()
30
28
  self.is_finished.set()
31
29
  except Exception as e:
32
30
  logging.exception(e)
@@ -96,7 +94,6 @@ class InterruptTestMixin(TestCase):
96
94
 
97
95
  def tearDown(self):
98
96
  super().tearDown()
99
- Schema.to_file()
100
97
  self._kill_process()
101
98
 
102
99
  def wait_for_setup(self):
@@ -1,12 +1,12 @@
1
1
  from collections import defaultdict
2
2
  from typing import Callable
3
3
 
4
- from openmodule.models.base import Gateway
4
+ from openmodule.models.base import Gateway, Direction
5
5
  from openmodule.models.io import IoMessage, IoState
6
6
  from openmodule.utils.misc_functions import utcnow
7
7
 
8
8
 
9
- def generate_example_states(count: int | None = 8) -> dict[str, IoState]:
9
+ def generate_example_states(count: int=8) -> dict[str, IoState]:
10
10
  """
11
11
  Creates a dict with pin as key and IoState as value.
12
12
  param count: how many pins should be created.
@@ -17,7 +17,7 @@ def generate_example_states(count: int | None = 8) -> dict[str, IoState]:
17
17
  states: dict[str, IoState] = defaultdict(IoState)
18
18
  for i in range(count):
19
19
  gate = int(i/4)
20
- direction = "in" if gate % 2 == 0 else "out"
20
+ direction = Direction.IN if gate % 2 == 0 else Direction.OUT
21
21
  gateway = Gateway(gate="gate_{}".format(gate), direction=direction)
22
22
  state = IoState(pin="", gateway=gateway, value=0, physical=0, inverted=False, type="input",
23
23
  last_timestamp=utcnow())
@@ -75,11 +75,11 @@ class IoSimulator:
75
75
  def set_pin_high(self, pin: str):
76
76
  self._emit(pin, 1)
77
77
 
78
- def emit_custom_io_message(self, pin: str, value: int = None, physical: int = None, inverted: bool = None,
79
- edge: int = None):
78
+ def emit_custom_io_message(self, pin: str, value: int | None = None, physical: int | None = None,
79
+ inverted: bool | None = None, edge: int | None = None):
80
80
  state = self.pin_states[pin]
81
81
  if edge is None:
82
- if state.value != value or state.is_inverted != inverted:
82
+ if state.value != value or state.inverted != inverted:
83
83
  edge = 1
84
84
  else:
85
85
  edge = 0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openmodule_test
3
- Version: 15.2.0
3
+ Version: 16.0.0
4
4
  Summary: Libraries for testing openmodule services
5
5
  Home-page: https://gitlab.com/arivo-public/device-python/openmodule.git
6
6
  Author: ARIVO
@@ -1,7 +1,7 @@
1
1
  import random
2
2
  import time
3
3
  from datetime import datetime
4
- from typing import Callable
4
+ from typing import Callable, Self
5
5
 
6
6
  from openmodule.models.base import Direction, Gateway, datetime_to_timestamp
7
7
  from openmodule.models.presence import PresenceBaseMessage, PresenceEnterMessage, PresenceLeaveMessage, \
@@ -36,11 +36,11 @@ class VehicleBuilder:
36
36
  leave_time=self.leave_time
37
37
  )
38
38
 
39
- def id(self, id: int) -> 'VehicleBuilder':
39
+ def id(self, id: int) -> Self:
40
40
  self.vehicle_id = id
41
41
  return self
42
42
 
43
- def lpr(self, country: str | None, plate: str | None = None, state="") -> 'VehicleBuilder':
43
+ def lpr(self, country: str | None, plate: str | None = None, state="") -> Self:
44
44
  if country is None:
45
45
  self.medium.lpr = None
46
46
  else:
@@ -50,40 +50,40 @@ class VehicleBuilder:
50
50
  )
51
51
  return self
52
52
 
53
- def nfc(self, id: str | None) -> 'VehicleBuilder':
53
+ def nfc(self, id: str | None) -> Self:
54
54
  if id is None:
55
55
  self.medium.nfc = id
56
56
  else:
57
57
  self.medium.nfc = Medium(id=id, type=MediumType.nfc)
58
58
  return self
59
59
 
60
- def qr(self, id: str | None, binary: str | None = None) -> 'VehicleBuilder':
60
+ def qr(self, id: str | None, binary: str | None = None) -> Self:
61
61
  if id is None:
62
62
  self.medium.qr = id
63
63
  else:
64
64
  self.medium.qr = QRMedium(id=id, binary=binary)
65
65
  return self
66
66
 
67
- def pin(self, id: str | None) -> 'VehicleBuilder':
67
+ def pin(self, id: str | None) -> Self:
68
68
  if id is None:
69
69
  self.medium.pin = id
70
70
  else:
71
71
  self.medium.pin = Medium(id=id, type=MediumType.pin)
72
72
  return self
73
73
 
74
- def set_make_model(self, make_model) -> 'VehicleBuilder':
74
+ def set_make_model(self, make_model) -> Self:
75
75
  self.make_model = make_model
76
76
  return self
77
77
 
78
- def set_enter_direction(self, enter_direction: EnterDirection) -> 'VehicleBuilder':
78
+ def set_enter_direction(self, enter_direction: EnterDirection) -> Self:
79
79
  self.enter_direction = enter_direction
80
80
  return self
81
81
 
82
- def set_enter_time(self, enter_time: datetime) -> 'VehicleBuilder':
82
+ def set_enter_time(self, enter_time: datetime) -> Self:
83
83
  self.enter_time = enter_time
84
84
  return self
85
85
 
86
- def set_leave_time(self, leave_time: datetime) -> 'VehicleBuilder':
86
+ def set_leave_time(self, leave_time: datetime) -> Self:
87
87
  self.leave_time = leave_time
88
88
  return self
89
89
 
@@ -7,7 +7,7 @@ from typing import Any, Callable
7
7
 
8
8
  from pydantic.main import BaseModel
9
9
 
10
- from openmodule.models.base import OpenModuleModel
10
+ from openmodule.models.base import OpenModuleModel, ZMQMessage
11
11
  from openmodule.models.rpc import RPCErrorResult, RPCServerError
12
12
  from openmodule.rpc import RPCClient
13
13
  from openmodule_test.zeromq import ZMQTestMixin
@@ -18,6 +18,14 @@ class _EmptyModel(BaseModel):
18
18
 
19
19
 
20
20
  class RPCServerTestMixin(ZMQTestMixin):
21
+ def setUp(self):
22
+ ZMQMessage._ALLOW_CUSTOM_TIMESTAMP = True
23
+ return super().setUp()
24
+
25
+ def tearDown(self):
26
+ ZMQMessage._ALLOW_CUSTOM_TIMESTAMP = False
27
+ return super().tearDown()
28
+
21
29
  def wait_for_rpc_response(self, channel: str, type: str, request: BaseModel, response_type: type[OpenModuleModel]):
22
30
  """
23
31
  waits until a rpc server is responding to the channel/type
@@ -37,6 +45,7 @@ class RPCServerTestMixin(ZMQTestMixin):
37
45
  message_received = False
38
46
 
39
47
  def handler(_, __):
48
+ """ handler to set message_received true """
40
49
  nonlocal message_received
41
50
  message_received = True
42
51
 
@@ -48,7 +57,7 @@ class RPCServerTestMixin(ZMQTestMixin):
48
57
  assert server.handlers, "you need to register the handlers beforehand"
49
58
  random_channel = "_test" + "".join(random.choices(string.ascii_letters, k=10))
50
59
 
51
- server.register_handler(random_channel, "ping", _EmptyModel, _EmptyModel, handler, register_schema=False)
60
+ server.register_handler(random_channel, "ping", _EmptyModel, _EmptyModel, handler)
52
61
 
53
62
  for x in range(self.zmq_client.startup_check_iterations):
54
63
  self.rpc_no_response(random_channel, "ping", {})
@@ -85,10 +85,9 @@ class SettingsRPCMocker:
85
85
  for setting, value in settings.items():
86
86
  if setting[0] in serialization._model_mapping:
87
87
  serialization.parse_setting_from_obj(setting[0], value)
88
- rpc_server.register_handler("settings", "get", SettingsGetRequest, SettingsGetResponse, self._get_handler,
89
- register_schema=False)
88
+ rpc_server.register_handler("settings", "get", SettingsGetRequest, SettingsGetResponse, self._get_handler)
90
89
  rpc_server.register_handler("settings", "get_many", SettingsGetManyRequest, SettingsGetManyResponse,
91
- self._get_many_handler, register_schema=False)
90
+ self._get_many_handler)
92
91
  self.settings = settings
93
92
  self.result_mode = SettingsRPCMocker.ResultMode.ok
94
93
  self.error_code = "no such setting"
@@ -109,10 +108,12 @@ class SettingsRPCMocker:
109
108
  raise RuntimeError()
110
109
 
111
110
  def _get_handler(self, request: SettingsGetRequest, _) -> SettingsGetResponse:
111
+ """ either raise set error or return requested value """
112
112
  self._do_errors()
113
113
  return self._get_setting(request.key, request.scope)
114
114
 
115
115
  def _get_many_handler(self, request: SettingsGetManyRequest, _) -> SettingsGetManyResponse:
116
+ """ either raise set error or return requested values """
116
117
  self._do_errors()
117
118
  return SettingsGetManyResponse(settings={key: self._get_setting(key, request.scope, i)
118
119
  for i, key in enumerate(request.key)})
@@ -18,7 +18,7 @@ class SignalSimulator:
18
18
  signal_msg = SignalMessage(signal=signal_name, type=signal_type, gate=gate, parking_area_id=parking_area_id,
19
19
  value=value, additional_data=additional_data)
20
20
  elif signal_type == SignalType.parkinglot_full:
21
- signal_name = signal_type.value
21
+ signal_name: str = signal_type.value # type: ignore (just pycharm)
22
22
  signal_msg = SignalMessage(signal=signal_name, type=signal_type,
23
23
  value=value, additional_data=additional_data)
24
24
  elif signal_type == SignalType.area_full:
@@ -24,7 +24,6 @@ from openmodule.dispatcher import SubscribingMessageDispatcher
24
24
  from openmodule.models.base import OpenModuleModel
25
25
  from openmodule.models.rpc import RPCResponse
26
26
  from openmodule.rpc import RPCClient
27
- from openmodule.utils.schema import Schema
28
27
  from openmodule_test.utils import DeveloperError
29
28
 
30
29
 
@@ -433,7 +432,7 @@ class ZMQTestMixin(TestCase):
433
432
  and if it is connected, all previous subscriptions will also be connected
434
433
  """
435
434
  random_topic = "_test" + "".join(random.choices(string.ascii_letters, k=10))
436
- dispatcher.register_handler(random_topic, OpenModuleModel, handler, register_schema=False, match_type=False)
435
+ dispatcher.register_handler(random_topic, OpenModuleModel, handler, match_type=False)
437
436
 
438
437
  for _ in range(self.zmq_client.startup_check_iterations):
439
438
  self.zmq_client.send(random_topic, {"type": "connection-check"})
@@ -469,7 +468,6 @@ class ZMQTestMixin(TestCase):
469
468
  )
470
469
  self._cleanup()
471
470
  super(ZMQTestMixin, self).tearDown()
472
- Schema.to_file()
473
471
 
474
472
  def rpc(self, channel: str, type: str, request, response_type: type[OpenModuleModel], timeout=3, resource=None) \
475
473
  -> str | OpenModuleModel:
@@ -507,7 +505,7 @@ class ZMQTestMixin(TestCase):
507
505
  except TimeoutError:
508
506
  raise RPCClient.TimeoutError()
509
507
  entry = RPCClient.RPCEntry(0) # timeout 0 because timeout is handled above, so we never have to wait here
510
- entry.response = RPCResponse(**response).response
508
+ entry.response = RPCResponse.model_validate(response).response
511
509
  return entry.result(response_type)
512
510
 
513
511
  def assertSubscription(self, *topics: str):