Skip to content

Commit c17cbfe

Browse files
committed
Add unit tests for business operation, process, and service components; update .gitignore to exclude coverage files
1 parent de1a16b commit c17cbfe

File tree

5 files changed

+310
-0
lines changed

5 files changed

+310
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ waitISC.log
1818

1919
prof
2020
src/tests/bench/result.txt
21+
.coverage
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import pytest
2+
from unittest.mock import MagicMock, patch
3+
from iop._business_operation import _BusinessOperation
4+
from registerFiles.message import SimpleMessage
5+
6+
@pytest.fixture
7+
def operation():
8+
op = _BusinessOperation()
9+
op.iris_handle = MagicMock()
10+
return op
11+
12+
def test_message_handling(operation):
13+
# Test on_message
14+
request = SimpleMessage(integer=1, string='test')
15+
assert operation.on_message(request) is None
16+
17+
# Test deprecated OnMessage
18+
assert operation.OnMessage(request) is None
19+
20+
def test_keepalive(operation):
21+
assert operation.on_keepalive() is None
22+
23+
def test_adapter_handling():
24+
# Test adapter setup with mock IRIS adapter
25+
op = _BusinessOperation()
26+
mock_current = MagicMock()
27+
mock_partner = MagicMock()
28+
29+
# Setup mock IRIS adapter
30+
mock_partner._IsA.return_value = True
31+
mock_partner.GetModule.return_value = "some.module"
32+
mock_partner.GetClassname.return_value = "SomeAdapter"
33+
34+
with patch('importlib.import_module') as mock_import:
35+
mock_module = MagicMock()
36+
mock_import.return_value = mock_module
37+
op._set_iris_handles(mock_current, mock_partner)
38+
39+
assert op.iris_handle == mock_current
40+
41+
def test_dispatch_methods(operation):
42+
# Test dispatch initialization
43+
operation.DISPATCH = [("MessageType1", "handle_type1")]
44+
mock_host = MagicMock()
45+
46+
operation._dispatch_on_init(mock_host)
47+
48+
# Test message dispatch
49+
request = SimpleMessage(integer=1, string='test')
50+
operation._dispatch_on_message(request)
51+
52+
# Verify internal method calls
53+
operation.iris_handle.dispatchOnMessage.assert_not_called()
54+
55+
def test_dispatch_with_custom_handlers():
56+
class CustomOperation(_BusinessOperation):
57+
def handle_simple(self, request: SimpleMessage):
58+
return SimpleMessage(integer=request.integer + 1, string="handled")
59+
60+
operation = CustomOperation()
61+
operation._dispatch_on_init(MagicMock())
62+
operation.iris_handle = MagicMock()
63+
64+
request = SimpleMessage(integer=1, string='test')
65+
response = operation._dispach_message(request)
66+
67+
assert isinstance(response, SimpleMessage)
68+
assert response.integer == 2
69+
assert response.string == "handled"

src/tests/test_business_process.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import pytest
2+
from unittest.mock import MagicMock, patch
3+
from iop._business_process import _BusinessProcess
4+
from registerFiles.message import SimpleMessage, PickledMessage, FullMessage
5+
6+
@pytest.fixture
7+
def process():
8+
proc = _BusinessProcess()
9+
proc.iris_handle = MagicMock()
10+
return proc
11+
12+
def test_message_handling(process):
13+
# Test on_message
14+
request = SimpleMessage(integer=1, string='test')
15+
assert process.on_message(request) is None
16+
17+
# Test on_request
18+
assert process.on_request(request) is None
19+
20+
# Test on_response
21+
response = SimpleMessage(integer=2, string='response')
22+
call_request = SimpleMessage(integer=3, string='call_request')
23+
call_response = SimpleMessage(integer=4, string='call_response')
24+
completion_key = "test_key"
25+
26+
assert process.on_response(
27+
request, response, call_request, call_response, completion_key
28+
) == response
29+
30+
# Test on_complete
31+
assert process.on_complete(request, response) == response
32+
33+
def test_async_operations(process):
34+
# Test send_request_async
35+
target = "target_service"
36+
request = SimpleMessage(integer=1, string='test')
37+
process.send_request_async(target, request)
38+
process.iris_handle.dispatchSendRequestAsync.assert_called_once()
39+
40+
# Test set_timer
41+
timeout = 1000
42+
completion_key = "timer_key"
43+
process.set_timer(timeout, completion_key)
44+
process.iris_handle.dispatchSetTimer.assert_called_once_with(
45+
timeout, completion_key
46+
)
47+
48+
def test_persistent_properties():
49+
# Test persistent property handling
50+
class ProcessWithProperties(_BusinessProcess):
51+
PERSISTENT_PROPERTY_LIST = ["test_prop"]
52+
def __init__(self):
53+
super().__init__()
54+
self.test_prop = "test_value"
55+
56+
process = ProcessWithProperties()
57+
mock_host = MagicMock()
58+
59+
# Test save properties
60+
process._save_persistent_properties(mock_host)
61+
mock_host.setPersistentProperty.assert_called_once_with("test_prop", "test_value")
62+
63+
# Test restore properties
64+
mock_host.getPersistentProperty.return_value = "restored_value"
65+
process._restore_persistent_properties(mock_host)
66+
assert process.test_prop == "restored_value"
67+
68+
def test_dispatch_methods(process):
69+
mock_host = MagicMock()
70+
request = SimpleMessage(integer=1, string='test')
71+
response = SimpleMessage(integer=2, string='response')
72+
73+
# Test dispatch methods
74+
process._dispatch_on_init(mock_host)
75+
process._dispatch_on_connected(mock_host)
76+
process._dispatch_on_request(mock_host, request)
77+
process._dispatch_on_response(
78+
mock_host, request, response, request, response, "completion_key"
79+
)
80+
process._dispatch_on_tear_down(mock_host)
81+
82+
def test_reply(process):
83+
response = SimpleMessage(integer=1, string='test')
84+
process.reply(response)
85+
process.iris_handle.dispatchReply.assert_called_once()

src/tests/test_business_service.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import pytest
2+
from unittest.mock import MagicMock, patch
3+
from iop._business_service import _BusinessService
4+
from registerFiles.message import SimpleMessage
5+
6+
@pytest.fixture
7+
def service():
8+
svc = _BusinessService()
9+
svc.iris_handle = MagicMock()
10+
return svc
11+
12+
def test_process_input(service):
13+
# Test on_process_input
14+
message = SimpleMessage(integer=1, string='test')
15+
assert service.on_process_input(message) is None
16+
17+
# Test deprecated OnProcessInput
18+
assert service.OnProcessInput(message) is None
19+
20+
def test_adapter_handling():
21+
# Test adapter setup with mock IRIS adapter
22+
svc = _BusinessService()
23+
mock_current = MagicMock()
24+
mock_partner = MagicMock()
25+
26+
# Setup mock IRIS adapter
27+
mock_partner._IsA.return_value = True
28+
mock_partner.GetModule.return_value = "some.module"
29+
mock_partner.GetClassname.return_value = "SomeAdapter"
30+
31+
with patch('importlib.import_module') as mock_import:
32+
mock_module = MagicMock()
33+
mock_import.return_value = mock_module
34+
svc._set_iris_handles(mock_current, mock_partner)
35+
36+
assert svc.iris_handle == mock_current
37+
assert svc.Adapter is not None
38+
assert svc.adapter is not None
39+
40+
def test_dispatch_on_process_input(service):
41+
message = SimpleMessage(integer=1, string='test')
42+
service._dispatch_on_process_input(message)
43+
44+
# Verify the message was processed
45+
service.iris_handle.dispatchOnProcessInput.assert_not_called()
46+
47+
def test_custom_service():
48+
class CustomService(_BusinessService):
49+
def on_process_input(self, message):
50+
return SimpleMessage(integer=message.integer * 2, string=f"processed_{message.string}")
51+
52+
service = CustomService()
53+
service.iris_handle = MagicMock()
54+
55+
input_msg = SimpleMessage(integer=5, string='test')
56+
result = service.on_process_input(input_msg)
57+
58+
assert isinstance(result, SimpleMessage)
59+
assert result.integer == 10
60+
assert result.string == "processed_test"
61+
62+
def test_wait_for_next_call_interval(service):
63+
assert service._wait_for_next_call_interval is False

src/tests/test_iop_director.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,95 @@ def test_component_with_iris_classname_and_body(self):
5252
def test_component_with_nonexistent_iris_classname(self):
5353
with pytest.raises(RuntimeError):
5454
_Director.test_component('test', classname='iris.test', body='test')
55+
56+
class TestBusinessService:
57+
def test_get_business_service(self):
58+
director = _Director()
59+
iris.cls("IOP.Director").dispatchCreateBusinessService = MagicMock(return_value=MagicMock())
60+
service = director.get_business_service("test")
61+
assert service is not None
62+
63+
def test_get_business_service_force_session(self):
64+
director = _Director()
65+
mock_service = MagicMock()
66+
mock_service.iris_handle = MagicMock()
67+
iris.cls("IOP.Director").dispatchCreateBusinessService = MagicMock(return_value=mock_service)
68+
service = director.get_business_service("test", force_session_id=True)
69+
assert service.iris_handle.ForceSessionId.called
70+
71+
def test_create_business_service(self):
72+
iris.cls("IOP.Director").dispatchCreateBusinessService = MagicMock(return_value="test")
73+
result = _Director.create_business_service("test")
74+
assert result == "test"
75+
76+
def test_create_python_business_service(self):
77+
mock_obj = MagicMock()
78+
mock_obj.GetClass = MagicMock(return_value="test_class")
79+
iris.cls("IOP.Director").dispatchCreateBusinessService = MagicMock(return_value=mock_obj)
80+
result = _Director.create_python_business_service("test")
81+
assert result == "test_class"
82+
83+
class TestProductionManagement:
84+
@pytest.fixture(autouse=True)
85+
def setup_mocks(self):
86+
self.start_mock = MagicMock()
87+
self.stop_mock = MagicMock()
88+
self.restart_mock = MagicMock()
89+
self.update_mock = MagicMock()
90+
iris.cls('Ens.Director').StartProduction = self.start_mock
91+
iris.cls('Ens.Director').StopProduction = self.stop_mock
92+
iris.cls('Ens.Director').RestartProduction = self.restart_mock
93+
iris.cls('Ens.Director').UpdateProduction = self.update_mock
94+
95+
def test_start_production(self):
96+
_Director.start_production("test_prod")
97+
self.start_mock.assert_called_once_with("test_prod")
98+
99+
def test_stop_production(self):
100+
_Director.stop_production()
101+
self.stop_mock.assert_called_once()
102+
103+
def test_restart_production(self):
104+
_Director.restart_production()
105+
self.restart_mock.assert_called_once()
106+
107+
def test_shutdown_production(self):
108+
_Director.shutdown_production()
109+
self.stop_mock.assert_called_once_with(10, 1)
110+
111+
def test_update_production(self):
112+
_Director.update_production()
113+
self.update_mock.assert_called_once()
114+
115+
def test_list_productions(self):
116+
iris.cls('IOP.Director').dispatchListProductions = MagicMock(return_value=["prod1", "prod2"])
117+
result = _Director.list_productions()
118+
assert result == ["prod1", "prod2"]
119+
120+
def test_status_production(self):
121+
mock_status = {'Production': 'test_prod', 'Status': 'running'}
122+
iris.cls('IOP.Director').StatusProduction = MagicMock(return_value=mock_status)
123+
result = _Director.status_production()
124+
assert result == mock_status
125+
126+
class TestLogging:
127+
def test_format_log(self):
128+
test_row = [1, 'Config1', 'Job1', 'Msg1', 'Session1', 'Source1', 'Method1',
129+
'Stack1', 'Text1', '2023-01-01', 'TraceCat1', 1]
130+
result = _Director.format_log(test_row)
131+
assert 'Assert' in result
132+
assert 'Config1' in result
133+
134+
def test_format_log_different_types(self):
135+
types = {1: 'Assert', 2: 'Error', 3: 'Warning', 4: 'Info', 5: 'Trace', 6: 'Alert'}
136+
for type_num, type_str in types.items():
137+
test_row = [1, 'Config1', 'Job1', 'Msg1', 'Session1', 'Source1', 'Method1',
138+
'Stack1', 'Text1', '2023-01-01', 'TraceCat1', type_num]
139+
result = _Director.format_log(test_row)
140+
assert type_str in result
141+
142+
@pytest.mark.asyncio
143+
async def test_log_production_async(self):
144+
handler = MagicMock()
145+
handler.sigint_log = True
146+
await _Director._log_production_async(handler)

0 commit comments

Comments
 (0)