Skip to content

Commit 1b4208a

Browse files
phlogistonjohnmergify[bot]
authored andcommitted
tests: add test_grpc_server.py to test grpc server behavior
Signed-off-by: John Mulligan <[email protected]>
1 parent 74c35a4 commit 1b4208a

File tree

1 file changed

+225
-0
lines changed

1 file changed

+225
-0
lines changed

tests/test_grpc_server.py

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
#
2+
# sambacc: a samba container configuration tool
3+
# Copyright (C) 2025 John Mulligan
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU General Public License
16+
# along with this program. If not, see <http://www.gnu.org/licenses/>
17+
#
18+
19+
import collections
20+
21+
import pytest
22+
23+
from sambacc.grpc import backend
24+
25+
json1 = """
26+
{
27+
"timestamp": "2025-05-08T20:41:57.273489+0000",
28+
"version": "4.23.0pre1-UNKNOWN",
29+
"smb_conf": "/etc/samba/smb.conf",
30+
"sessions": {
31+
"2891148582": {
32+
"session_id": "2891148582",
33+
"server_id": {
34+
"pid": "1243",
35+
"task_id": "0",
36+
"vnn": "2",
37+
"unique_id": "1518712196307698939"
38+
},
39+
"uid": 103107,
40+
"gid": 102513,
41+
"username": "DOMAIN1\\\\bwayne",
42+
"groupname": "DOMAIN1\\\\domain users",
43+
"creation_time": "2025-05-08T20:39:36.456835+00:00",
44+
"expiration_time": "30828-09-14T02:48:05.477581+00:00",
45+
"auth_time": "2025-05-08T20:39:36.457633+00:00",
46+
"remote_machine": "127.0.0.1",
47+
"hostname": "ipv4:127.0.0.1:59396",
48+
"session_dialect": "SMB3_11",
49+
"client_guid": "adc145fe-0677-4ab6-9d61-c25b30211174",
50+
"encryption": {
51+
"cipher": "-",
52+
"degree": "none"
53+
},
54+
"signing": {
55+
"cipher": "AES-128-GMAC",
56+
"degree": "partial"
57+
},
58+
"channels": {
59+
"1": {
60+
"channel_id": "1",
61+
"creation_time": "2025-05-08T20:39:36.456835+00:00",
62+
"local_address": "ipv4:127.0.0.1:445",
63+
"remote_address": "ipv4:127.0.0.1:59396",
64+
"transport": "tcp"
65+
}
66+
}
67+
}
68+
},
69+
"tcons": {
70+
"3757739897": {
71+
"service": "cephomatic",
72+
"server_id": {
73+
"pid": "1243",
74+
"task_id": "0",
75+
"vnn": "2",
76+
"unique_id": "1518712196307698939"
77+
},
78+
"tcon_id": "3757739897",
79+
"session_id": "2891148582",
80+
"machine": "127.0.0.1",
81+
"connected_at": "2025-05-08T20:39:36.464088+00:00",
82+
"encryption": {
83+
"cipher": "-",
84+
"degree": "none"
85+
},
86+
"signing": {
87+
"cipher": "-",
88+
"degree": "none"
89+
}
90+
}
91+
},
92+
"open_files": {}
93+
}
94+
"""
95+
96+
97+
class MockBackend:
98+
def __init__(self):
99+
self._counter = collections.Counter()
100+
self._versions = backend.Versions(
101+
samba_version="4.99.5",
102+
sambacc_version="a.b.c",
103+
container_version="test.v",
104+
)
105+
self._is_clustered = False
106+
self._status = backend.Status.parse(json1)
107+
self._kaboom = None
108+
109+
def get_versions(self) -> backend.Versions:
110+
self._counter["get_versions"] += 1
111+
if self._kaboom:
112+
raise self._kaboom
113+
return self._versions
114+
115+
def is_clustered(self) -> bool:
116+
self._counter["is_clustered"] += 1
117+
return self._is_clustered
118+
119+
def get_status(self) -> backend.Status:
120+
self._counter["get_status"] += 1
121+
return self._status
122+
123+
def close_share(self, share_name: str, denied_users: bool) -> None:
124+
self._counter["close_share"] += 1
125+
126+
def kill_client(self, ip_address: str) -> None:
127+
self._counter["kill_client"] += 1
128+
129+
130+
@pytest.fixture()
131+
def mock_grpc_server():
132+
try:
133+
import sambacc.grpc.server
134+
except ImportError:
135+
pytest.skip("can not import grpc server")
136+
137+
class TestConfig(sambacc.grpc.server.ServerConfig):
138+
max_workers = 3
139+
address = "localhost:54445"
140+
insecure = True
141+
_server = None
142+
backend = None
143+
144+
def wait(self, server):
145+
self._server = server
146+
147+
tc = TestConfig()
148+
tc.backend = MockBackend()
149+
sambacc.grpc.server.serve(tc, tc.backend)
150+
assert tc._server
151+
assert tc.backend
152+
yield tc
153+
tc._server.stop(0.1).wait()
154+
155+
156+
def test_info(mock_grpc_server):
157+
import grpc
158+
import sambacc.grpc.generated.control_pb2_grpc as _rpc
159+
import sambacc.grpc.generated.control_pb2 as _pb
160+
161+
with grpc.insecure_channel(mock_grpc_server.address) as channel:
162+
client = _rpc.SambaControlStub(channel)
163+
rsp = client.Info(_pb.InfoRequest())
164+
165+
assert mock_grpc_server.backend._counter["get_versions"] == 1
166+
assert rsp.samba_info.version == "4.99.5"
167+
assert not rsp.samba_info.clustered
168+
assert rsp.container_info.sambacc_version == "a.b.c"
169+
assert rsp.container_info.container_version == "test.v"
170+
171+
172+
def test_info_error(mock_grpc_server):
173+
import grpc
174+
import sambacc.grpc.generated.control_pb2_grpc as _rpc
175+
import sambacc.grpc.generated.control_pb2 as _pb
176+
177+
mock_grpc_server.backend._kaboom = ValueError("kaboom")
178+
with grpc.insecure_channel(mock_grpc_server.address) as channel:
179+
client = _rpc.SambaControlStub(channel)
180+
with pytest.raises(grpc.RpcError):
181+
client.Info(_pb.InfoRequest())
182+
183+
assert mock_grpc_server.backend._counter["get_versions"] == 1
184+
185+
186+
def test_status(mock_grpc_server):
187+
import grpc
188+
import sambacc.grpc.generated.control_pb2_grpc as _rpc
189+
import sambacc.grpc.generated.control_pb2 as _pb
190+
191+
with grpc.insecure_channel(mock_grpc_server.address) as channel:
192+
client = _rpc.SambaControlStub(channel)
193+
rsp = client.Status(_pb.StatusRequest())
194+
195+
assert mock_grpc_server.backend._counter["get_status"] == 1
196+
assert rsp.server_timestamp == "2025-05-08T20:41:57.273489+0000"
197+
# TODO data assertions
198+
199+
200+
def test_close_share(mock_grpc_server):
201+
import grpc
202+
import sambacc.grpc.generated.control_pb2_grpc as _rpc
203+
import sambacc.grpc.generated.control_pb2 as _pb
204+
205+
with grpc.insecure_channel(mock_grpc_server.address) as channel:
206+
client = _rpc.SambaControlStub(channel)
207+
rsp = client.CloseShare(_pb.CloseShareRequest(share_name="bob"))
208+
209+
assert mock_grpc_server.backend._counter["close_share"] == 1
210+
assert rsp
211+
212+
213+
def test_kill_client(mock_grpc_server):
214+
import grpc
215+
import sambacc.grpc.generated.control_pb2_grpc as _rpc
216+
import sambacc.grpc.generated.control_pb2 as _pb
217+
218+
with grpc.insecure_channel(mock_grpc_server.address) as channel:
219+
client = _rpc.SambaControlStub(channel)
220+
rsp = client.KillClientConnection(
221+
_pb.KillClientRequest(ip_address="192.168.76.18")
222+
)
223+
224+
assert mock_grpc_server.backend._counter["kill_client"] == 1
225+
assert rsp

0 commit comments

Comments
 (0)