Skip to content

Commit a568291

Browse files
committed
Avoid running processes in integration test
1 parent ffa6847 commit a568291

File tree

4 files changed

+87
-39
lines changed

4 files changed

+87
-39
lines changed

model-archiver/model_archiver/model_packaging_utils.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import tempfile
1212
import zipfile
1313
from io import BytesIO
14+
from pathlib import Path
1415

1516
from .manifest_components.manifest import Manifest
1617
from .manifest_components.model import Model
@@ -164,6 +165,10 @@ def copy_artifacts(model_name, **kwargs):
164165

165166
if file_type == "extra_files":
166167
for path_or_wildcard in path.split(","):
168+
if not Path(path_or_wildcard).exists():
169+
raise FileNotFoundError(
170+
f"File does not exist: {path_or_wildcard}"
171+
)
167172
for file in glob.glob(path_or_wildcard.strip()):
168173
if os.path.isfile(file):
169174
shutil.copy2(file, model_path)

model-archiver/model_archiver/tests/integ_tests/configuration.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,32 @@
9999
"iterations": 2,
100100
"version": "1.0",
101101
"force": true
102+
},
103+
{
104+
"name": "extra_files_path",
105+
"model-name": "model",
106+
"model-file": "model_archiver/tests/integ_tests/resources/regular_model/test_model.py",
107+
"serialized-file": "model_archiver/tests/integ_tests/resources/regular_model/test_serialized_file.pt",
108+
"handler": "model_archiver/tests/integ_tests/resources/regular_model/test_handler",
109+
"extra-files": "model_archiver/tests/integ_tests/resources/regular_model/",
110+
"export-path": "model",
111+
"archive-format": "default",
112+
"iterations": 1,
113+
"version": "1.0",
114+
"config-file": "",
115+
"expect-error": false
116+
},
117+
{
118+
"name": "missing_extra_files",
119+
"model-name": "model",
120+
"model-file": "model_archiver/tests/integ_tests/resources/regular_model/test_model.py",
121+
"serialized-file": "model_archiver/tests/integ_tests/resources/regular_model/test_serialized_file.pt",
122+
"handler": "model_archiver/tests/integ_tests/resources/regular_model/test_handler",
123+
"extra-files": "model_archiver/tests/integ_tests/resources/regular_model/missing.json",
124+
"export-path": "model",
125+
"archive-format": "default",
126+
"iterations": 1,
127+
"version": "1.0",
128+
"config-file": "",
129+
"expect-error": true
102130
}]

model-archiver/model_archiver/tests/integ_tests/test_integration_model_archiver.py

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import os
44
import platform
55
import shutil
6-
import subprocess
76
import tempfile
87
import time
8+
from argparse import Namespace
99
from datetime import datetime
1010
from pathlib import Path
1111

@@ -40,16 +40,28 @@ def delete_file_path(path):
4040
pass
4141

4242

43-
def run_test(test, cmd):
44-
it = test.get("iterations") if test.get("iterations") is not None else 1
43+
def run_test(test, args, mocker):
44+
m = mocker.Mock()
45+
m.parse_args = lambda: args
46+
mocker.patch(
47+
"model_archiver.model_packaging.ArgParser.export_model_args_parser",
48+
return_value=m,
49+
)
50+
mocker.patch("sys.exit", side_effect=Exception())
51+
from model_archiver.model_packaging import generate_model_archive
52+
53+
it = test.get("iterations", 1)
4554
for i in range(it):
4655
try:
47-
subprocess.check_call(cmd, shell=True)
48-
except subprocess.CalledProcessError as exc:
56+
generate_model_archive()
57+
except Exception as exc:
4958
if test.get("expect-error") is not True:
5059
assert 0, "{}".format(exc.output)
5160
else:
5261
return 0
62+
# In case we expect an error we should not be here
63+
if test.get("expect-error") is True:
64+
assert 0, f"Error expected in test: {test['name']}"
5365
return 1
5466

5567

@@ -146,8 +158,8 @@ def validate(test):
146158
validate_archive_content(test)
147159

148160

149-
def build_cmd(test):
150-
args = [
161+
def build_namespace(test):
162+
keys = [
151163
"model-name",
152164
"model-file",
153165
"serialized-file",
@@ -157,15 +169,19 @@ def build_cmd(test):
157169
"version",
158170
"export-path",
159171
"runtime",
172+
"requirements-file",
173+
"config-file",
174+
"force",
160175
]
176+
test["requirements-file"] = None
177+
test["config-file"] = None
178+
test["force"] = test.get("force", False)
179+
test["runtime"] = test.get("runtime", DEFAULT_RUNTIME)
180+
test["archive-format"] = test.get("archive-format", "default")
161181

162-
cmd = ["torch-model-archiver"]
182+
args = Namespace(**{k.replace("-", "_"): test[k] for k in keys})
163183

164-
for arg in args:
165-
if arg in test:
166-
cmd.append("--{0} {1}".format(arg, test[arg]))
167-
168-
return " ".join(cmd)
184+
return args
169185

170186

171187
def make_paths_absolute(test, keys):
@@ -180,7 +196,7 @@ def make_absolute(paths):
180196
return test
181197

182198

183-
def test_model_archiver(integ_tests):
199+
def test_model_archiver(integ_tests, mocker):
184200
for test in integ_tests:
185201
# tar.gz format problem on windows hence ignore
186202
if platform.system() == "Windows" and test["archive-format"] == "tgz":
@@ -195,33 +211,28 @@ def test_model_archiver(integ_tests):
195211
test["model-name"] = (
196212
test["model-name"] + "_" + str(int(time.time() * 1000.0))
197213
)
198-
cmd = build_cmd(test)
199-
if test.get("force"):
200-
cmd += " -f"
214+
args = build_namespace(test)
201215

202-
if run_test(test, cmd):
216+
if run_test(test, args, mocker):
203217
validate(test)
204218
finally:
205219
delete_file_path(test.get("export-path"))
206220

207221

208-
def test_default_handlers(default_handler_tests):
222+
def test_default_handlers(default_handler_tests, mocker):
209223
for test in default_handler_tests:
210-
cmd = build_cmd(test)
224+
cmd = build_namespace(test)
211225
try:
212226
delete_file_path(test.get("export-path"))
213227
create_file_path(test.get("export-path"))
214228

215-
if test.get("force"):
216-
cmd += " -f"
217-
218-
if run_test(test, cmd):
229+
if run_test(test, cmd, mocker):
219230
validate(test)
220231
finally:
221232
delete_file_path(test.get("export-path"))
222233

223234

224-
def test_zip_store(tmp_path, integ_tests):
235+
def test_zip_store(tmp_path, integ_tests, mocker):
225236
integ_tests = list(
226237
filter(lambda t: t["name"] == "packaging_zip_store_mar", integ_tests)
227238
)
@@ -232,11 +243,11 @@ def test_zip_store(tmp_path, integ_tests):
232243
test["iterations"] = 1
233244

234245
test["model-name"] = "zip-store"
235-
run_test(test, build_cmd(test))
246+
run_test(test, build_namespace(test), mocker)
236247

237248
test["model-name"] = "zip"
238249
test["archive-format"] = "default"
239-
run_test(test, build_cmd(test))
250+
run_test(test, build_namespace(test), mocker)
240251

241252
stored_size = Path(tmp_path).joinpath("zip-store.mar").stat().st_size
242253
zipped_size = Path(tmp_path).joinpath("zip.mar").stat().st_size

model-archiver/model_archiver/tests/unit_tests/test_model_packaging_utils.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import json
22
import platform
3-
import shutil
43
from collections import namedtuple
54
from pathlib import Path
65

@@ -267,42 +266,47 @@ def create_manifest_from_test_json(test_json):
267266
return manifest
268267

269268

270-
def test_archive_creation_with_zip_store(tmp_path, integ_tests):
271-
integ_tests = list(
272-
filter(lambda t: t["name"] == "packaging_zip_store_mar", integ_tests)
273-
)
269+
def prepare_model_dir(test_name, integ_tests):
270+
integ_tests = list(filter(lambda t: t["name"] == test_name, integ_tests))
274271
assert len(integ_tests) == 1
275272
test = integ_tests[0]
276273

277-
model_dir = Path(tmp_path).joinpath("model_dir")
278-
model_dir.mkdir()
279-
280274
keys = (
281275
"model-file",
282276
"serialized-file",
283277
"handler",
284278
"extra-files",
285279
"config-file",
286280
)
281+
artifact_files = {k.replace("-", "_"): test[k] for k in keys}
287282

288-
for k in keys:
289-
shutil.copy(test[k], model_dir)
283+
model_path = ModelExportUtils.copy_artifacts(test["model-name"], **artifact_files)
290284

291285
manifest = create_manifest_from_test_json(test)
286+
return manifest, model_path
287+
288+
289+
def test_archive_creation_with_zip_store(tmp_path, integ_tests, mocker):
290+
manifest, model_path = prepare_model_dir("packaging_zip_store_mar", integ_tests)
292291

293292
ModelExportUtils.archive(
294293
tmp_path,
295294
"zip-store",
296-
model_dir.as_posix(),
295+
model_path,
297296
manifest,
298297
archive_format="zip-store",
299298
)
300299

301300
ModelExportUtils.archive(
302-
tmp_path, "zip", model_dir.as_posix(), manifest, archive_format="default"
301+
tmp_path, "zip", model_path, manifest, archive_format="default"
303302
)
304303

305304
stored_size = Path(tmp_path).joinpath("zip-store.mar").stat().st_size
306305
zipped_size = Path(tmp_path).joinpath("zip.mar").stat().st_size
307306

308307
assert zipped_size < stored_size
308+
309+
310+
def test_missing_extra_files(integ_tests):
311+
with pytest.raises(FileNotFoundError):
312+
prepare_model_dir("missing_extra_files", integ_tests)

0 commit comments

Comments
 (0)