11import json
2+ from pathlib import Path
23
4+ import pytest
35from inline_snapshot import snapshot
46from pytest_mock import MockerFixture
57from respx import MockRouter
68
79
8- async def test_docker_plugin_test (mocked_api : MockRouter , mocker : MockerFixture ):
10+ async def test_docker_plugin_test_from_file (
11+ mocked_api : MockRouter ,
12+ mocker : MockerFixture ,
13+ monkeypatch : pytest .MonkeyPatch ,
14+ tmp_path : Path ,
15+ ):
16+ TEST_DIR = tmp_path .absolute ().as_posix ()
17+ monkeypatch .setattr (
18+ "src.providers.docker_test.PLUGIN_TEST_DIR" , TEST_DIR , raising = False
19+ )
20+ from src .providers .constants import DOCKER_BIND_RESULT_PATH
21+
22+ test_result_path = Path (TEST_DIR ) / "module-name.json"
23+
24+ from src .providers .docker_test import DockerPluginTest , DockerTestResult
25+
26+ data = json .dumps (
27+ {
28+ "metadata" : None ,
29+ "output" : "test" ,
30+ "load" : True ,
31+ "run" : True ,
32+ "version" : "0.0.1" ,
33+ "config" : "" ,
34+ "test_env" : "python==3.12" ,
35+ }
36+ )
37+
38+ with open (test_result_path , "w" , encoding = "utf-8" ) as f :
39+ f .write (data )
40+
41+ mocked_run = mocker .Mock ()
42+ mocked_run .return_value = b""
43+ mocked_client = mocker .Mock ()
44+ mocked_client .containers .run = mocked_run
45+ mocked_docker = mocker .patch ("docker.DockerClient" )
46+ mocked_docker .return_value = mocked_client
47+
48+ test = DockerPluginTest ("project_link" , "module_name" )
49+ result = await test .run ("3.12" )
50+
51+ assert result == snapshot (
52+ DockerTestResult (
53+ run = True , load = True , output = "test" , version = "0.0.1" , test_env = "python==3.12"
54+ )
55+ )
56+
57+ assert not mocked_api ["store_plugins" ].called
58+ mocked_run .assert_called_once_with (
59+ "ghcr.io/nonebot/nonetest:latest" ,
60+ environment = snapshot (
61+ {
62+ "PROJECT_LINK" : "project_link" ,
63+ "MODULE_NAME" : "module_name" ,
64+ "PLUGIN_CONFIG" : "" ,
65+ "PYTHON_VERSION" : "3.12" ,
66+ "TEST_RESULT_PATH" : "/app/plugin_test/test_result.json" ,
67+ }
68+ ),
69+ detach = False ,
70+ remove = True ,
71+ volumes = {
72+ test_result_path .resolve (strict = False ).as_posix (): {
73+ "bind" : DOCKER_BIND_RESULT_PATH ,
74+ "mode" : "rw" ,
75+ }
76+ },
77+ )
78+
79+
80+ async def test_docker_plugin_test_from_output (
81+ mocked_api : MockRouter ,
82+ mocker : MockerFixture ,
83+ monkeypatch : pytest .MonkeyPatch ,
84+ tmp_path : Path ,
85+ ):
86+ TEST_DIR = tmp_path .absolute ().as_posix ()
87+ monkeypatch .setattr (
88+ "src.providers.docker_test.PLUGIN_TEST_DIR" , TEST_DIR , raising = False
89+ )
90+ from src .providers .constants import DOCKER_BIND_RESULT_PATH
91+
92+ test_result_path = Path (TEST_DIR ) / "module-name.json"
93+
994 from src .providers .docker_test import DockerPluginTest , DockerTestResult
1095
1196 mocked_run = mocker .Mock ()
@@ -19,7 +104,7 @@ async def test_docker_plugin_test(mocked_api: MockRouter, mocker: MockerFixture)
19104 "config" : "" ,
20105 "test_env" : "python==3.12" ,
21106 }
22- ).encode ()
107+ ).encode (encoding = "utf-8" )
23108 mocked_client = mocker .Mock ()
24109 mocked_client .containers .run = mocked_run
25110 mocked_docker = mocker .patch ("docker.DockerClient" )
@@ -30,11 +115,7 @@ async def test_docker_plugin_test(mocked_api: MockRouter, mocker: MockerFixture)
30115
31116 assert result == snapshot (
32117 DockerTestResult (
33- load = True ,
34- output = "test" ,
35- run = True ,
36- test_env = "python==3.12" ,
37- version = "0.0.1" ,
118+ load = True , output = "test" , run = True , version = "0.0.1" , test_env = "python==3.12"
38119 )
39120 )
40121
@@ -47,17 +128,35 @@ async def test_docker_plugin_test(mocked_api: MockRouter, mocker: MockerFixture)
47128 "MODULE_NAME" : "module_name" ,
48129 "PLUGIN_CONFIG" : "" ,
49130 "PYTHON_VERSION" : "3.12" ,
131+ "TEST_RESULT_PATH" : "/app/plugin_test/test_result.json" ,
50132 }
51133 ),
52134 detach = False ,
53135 remove = True ,
136+ volumes = {
137+ test_result_path .resolve (strict = False ).as_posix (): {
138+ "bind" : DOCKER_BIND_RESULT_PATH ,
139+ "mode" : "rw" ,
140+ }
141+ },
54142 )
55143
56144
57145async def test_docker_plugin_test_exception (
58- mocked_api : MockRouter , mocker : MockerFixture
146+ mocked_api : MockRouter ,
147+ mocker : MockerFixture ,
148+ monkeypatch : pytest .MonkeyPatch ,
149+ tmp_path : Path ,
59150):
60151 """插件测试时报错"""
152+ TEST_DIR = tmp_path .absolute ().as_posix ()
153+ monkeypatch .setattr (
154+ "src.providers.docker_test.PLUGIN_TEST_DIR" , TEST_DIR , raising = False
155+ )
156+ from src .providers .constants import DOCKER_BIND_RESULT_PATH
157+
158+ test_result_path = Path (TEST_DIR ) / "module-name.json"
159+
61160 from src .providers .docker_test import DockerPluginTest , DockerTestResult
62161
63162 mocked_run = mocker .Mock ()
@@ -74,7 +173,28 @@ async def test_docker_plugin_test_exception(
74173 DockerTestResult (
75174 run = False ,
76175 load = False ,
77- output = "Docker failed" ,
176+ output = """\
177+ Traceback (most recent call last):
178+ File "/home/bigorangeqwq/projects/noneflow/src/providers/docker_test/__init__.py", line 83, in run
179+ output = client.containers.run(
180+ ~~~~~~~~~~~~~~~~~~~~~^
181+ DOCKER_IMAGES,
182+ ^^^^^^^^^^^^^^
183+ ...<16 lines>...
184+ },
185+ ^^
186+ ).decode(errors="ignore", encoding="utf-8")
187+ ^
188+ File "/home/bigorangeqwq/.local/share/uv/python/cpython-3.13.4-linux-x86_64-gnu/lib/python3.13/unittest/mock.py", line 1169, in __call__
189+ return self._mock_call(*args, **kwargs)
190+ ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
191+ File "/home/bigorangeqwq/.local/share/uv/python/cpython-3.13.4-linux-x86_64-gnu/lib/python3.13/unittest/mock.py", line 1173, in _mock_call
192+ return self._execute_mock_call(*args, **kwargs)
193+ ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
194+ File "/home/bigorangeqwq/.local/share/uv/python/cpython-3.13.4-linux-x86_64-gnu/lib/python3.13/unittest/mock.py", line 1228, in _execute_mock_call
195+ raise effect
196+ Exception: Docker failed
197+ """ ,
78198 )
79199 )
80200
@@ -87,17 +207,35 @@ async def test_docker_plugin_test_exception(
87207 "MODULE_NAME" : "module_name" ,
88208 "PLUGIN_CONFIG" : "" ,
89209 "PYTHON_VERSION" : "3.12" ,
210+ "TEST_RESULT_PATH" : "/app/plugin_test/test_result.json" ,
90211 }
91212 ),
92213 detach = False ,
93214 remove = True ,
215+ volumes = {
216+ test_result_path .resolve (strict = False ).as_posix (): {
217+ "bind" : DOCKER_BIND_RESULT_PATH ,
218+ "mode" : "rw" ,
219+ }
220+ },
94221 )
95222
96223
97224async def test_docker_plugin_test_metadata_some_fields_empty (
98- mocked_api : MockRouter , mocker : MockerFixture
225+ mocked_api : MockRouter ,
226+ mocker : MockerFixture ,
227+ monkeypatch : pytest .MonkeyPatch ,
228+ tmp_path : Path ,
99229):
100230 """测试 metadata 的部分字段为空"""
231+ TEST_DIR = tmp_path .absolute ().as_posix ()
232+ monkeypatch .setattr (
233+ "src.providers.docker_test.PLUGIN_TEST_DIR" , TEST_DIR , raising = False
234+ )
235+ from src .providers .constants import DOCKER_BIND_RESULT_PATH
236+
237+ test_result_path = Path (TEST_DIR ) / "module-name.json"
238+
101239 from src .providers .docker_test import DockerPluginTest , DockerTestResult
102240
103241 mocked_run = mocker .Mock ()
@@ -129,17 +267,17 @@ async def test_docker_plugin_test_metadata_some_fields_empty(
129267 assert result == snapshot (
130268 DockerTestResult (
131269 load = True ,
270+ output = "test" ,
271+ run = True ,
272+ version = "0.0.1" ,
273+ test_env = "python==3.12" ,
132274 metadata = {
133275 "name" : "name" ,
134276 "desc" : "desc" ,
135277 "homepage" : None ,
136278 "type" : None ,
137279 "supported_adapters" : None ,
138280 },
139- output = "test" ,
140- run = True ,
141- test_env = "python==3.12" ,
142- version = "0.0.1" ,
143281 )
144282 )
145283
@@ -152,73 +290,101 @@ async def test_docker_plugin_test_metadata_some_fields_empty(
152290 "MODULE_NAME" : "module_name" ,
153291 "PLUGIN_CONFIG" : "" ,
154292 "PYTHON_VERSION" : "3.12" ,
293+ "TEST_RESULT_PATH" : "/app/plugin_test/test_result.json" ,
155294 }
156295 ),
157296 detach = False ,
158297 remove = True ,
298+ volumes = {
299+ test_result_path .resolve (strict = False ).as_posix (): {
300+ "bind" : DOCKER_BIND_RESULT_PATH ,
301+ "mode" : "rw" ,
302+ }
303+ },
159304 )
160305
161306
162307async def test_docker_plugin_test_metadata_some_fields_invalid (
163- mocked_api : MockRouter , mocker : MockerFixture
308+ mocked_api : MockRouter ,
309+ mocker : MockerFixture ,
310+ monkeypatch : pytest .MonkeyPatch ,
311+ tmp_path : Path ,
164312):
165313 """测试 metadata 的部分字段不符合规范"""
314+
315+ TEST_DIR = tmp_path .absolute ().as_posix ()
316+ monkeypatch .setattr (
317+ "src.providers.docker_test.PLUGIN_TEST_DIR" , TEST_DIR , raising = False
318+ )
319+ from src .providers .constants import DOCKER_BIND_RESULT_PATH
320+
321+ test_result_path = Path (TEST_DIR ) / "module-name.json"
322+
166323 from src .providers .docker_test import DockerPluginTest , DockerTestResult
167324
168325 mocked_run = mocker .Mock ()
169- mocked_run .return_value = json .dumps (
170- {
171- "metadata" : {
172- "name" : "name" ,
173- "desc" : "desc" ,
174- "homepage" : 12 ,
175- "type" : True ,
176- "supported_adapters" : {},
177- },
178- "output" : "test" ,
179- "load" : True ,
180- "run" : True ,
181- "version" : "0.0.1" ,
182- "config" : "" ,
183- "test_env" : "python==3.12" ,
184- }
185- ).encode ()
326+ mocked_run .return_value = b""
186327 mocked_client = mocker .Mock ()
187328 mocked_client .containers .run = mocked_run
188329 mocked_docker = mocker .patch ("docker.DockerClient" )
189330 mocked_docker .return_value = mocked_client
190331
332+ with open (test_result_path , "w" , encoding = "utf-8" ) as f :
333+ json .dump (
334+ {
335+ "metadata" : {
336+ "name" : "name" ,
337+ "desc" : "desc" ,
338+ "homepage" : 12 ,
339+ "type" : True ,
340+ "supported_adapters" : {},
341+ },
342+ "output" : "test" ,
343+ "load" : True ,
344+ "run" : True ,
345+ "version" : "0.0.1" ,
346+ "config" : "" ,
347+ "test_env" : "python==3.12" ,
348+ },
349+ f ,
350+ )
351+
191352 test = DockerPluginTest ("project_link" , "module_name" )
192353 result = await test .run ("3.12" )
193354
194355 assert result == snapshot (
195356 DockerTestResult (
357+ run = True ,
196358 load = True ,
197- metadata = {
359+ output = "test" ,
360+ version = "0.0.1" ,
361+ test_env = "python==3.12" ,
362+ metadata = { # type: ignore
198363 "name" : "name" ,
199364 "desc" : "desc" ,
200365 "homepage" : 12 ,
201366 "type" : True ,
202367 "supported_adapters" : {},
203- }, # type: ignore
204- output = "test" ,
205- run = True ,
206- test_env = "python==3.12" ,
207- version = "0.0.1" ,
368+ },
208369 )
209370 )
210371
211372 assert not mocked_api ["store_plugins" ].called
212373 mocked_run .assert_called_once_with (
213374 "ghcr.io/nonebot/nonetest:latest" ,
214- environment = snapshot (
215- {
216- "PROJECT_LINK" : "project_link" ,
217- "MODULE_NAME" : "module_name" ,
218- "PLUGIN_CONFIG" : "" ,
219- "PYTHON_VERSION" : "3.12" ,
220- }
221- ),
375+ environment = {
376+ "PROJECT_LINK" : "project_link" ,
377+ "MODULE_NAME" : "module_name" ,
378+ "PLUGIN_CONFIG" : "" ,
379+ "PYTHON_VERSION" : "3.12" ,
380+ "TEST_RESULT_PATH" : "/app/plugin_test/test_result.json" ,
381+ },
222382 detach = False ,
223383 remove = True ,
384+ volumes = {
385+ test_result_path .resolve (strict = False ).as_posix (): {
386+ "bind" : DOCKER_BIND_RESULT_PATH ,
387+ "mode" : "rw" ,
388+ }
389+ },
224390 )
0 commit comments