Skip to content

Commit 3c52f8a

Browse files
committed
update model control tests
1 parent ca9dc65 commit 3c52f8a

File tree

2 files changed

+106
-38
lines changed

2 files changed

+106
-38
lines changed

qa/L0_backend_python/model_control/model_control_test.py

Lines changed: 100 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2727
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828

29+
import base64
2930
import json
3031
import os
3132
import subprocess
@@ -85,9 +86,9 @@ def test_model_reload(self):
8586
self.assertFalse(client.is_model_ready(ensemble_model_name))
8687

8788

88-
class InputValidationTest(unittest.TestCase):
89+
class ModelIDValidationTest(unittest.TestCase):
8990
"""
90-
Test input validation for user-provided inputs
91+
Test model ID validation for user-provided model names
9192
"""
9293

9394
def setUp(self):
@@ -104,10 +105,39 @@ def setUp(self):
104105

105106
def _send_load_model_request(self, model_name):
106107
"""Send HTTP request to load model for testing input validation using curl"""
108+
109+
# Create simple Triton Python model code
110+
python_model_code = f"""import triton_python_backend_utils as pb_utils
111+
112+
class TritonPythonModel:
113+
def execute(self, requests):
114+
print('Hello world from model {model_name}')
115+
responses = []
116+
for request in requests:
117+
# Simple identity function
118+
input_tensor = pb_utils.get_input_tensor_by_name(request, "INPUT0")
119+
out_tensor = pb_utils.Tensor("OUTPUT0", input_tensor.as_numpy())
120+
responses.append(pb_utils.InferenceResponse([out_tensor]))
121+
return responses"""
122+
123+
# Base64 encode the Python code (as required by Triton server)
124+
python_code_b64 = base64.b64encode(python_model_code.encode("utf-8")).decode(
125+
"ascii"
126+
)
127+
128+
# Create simple config
129+
config = {
130+
"name": model_name,
131+
"backend": "python",
132+
"max_batch_size": 4,
133+
"input": [{"name": "INPUT0", "data_type": "TYPE_FP32", "dims": [-1]}],
134+
"output": [{"name": "OUTPUT0", "data_type": "TYPE_FP32", "dims": [-1]}],
135+
}
136+
107137
payload = {
108138
"parameters": {
109-
"config": f'{{"name": "{model_name}", "backend": "python", "max_batch_size": 4}}',
110-
"file:/1/model.py": "print('Hello from Python Model')",
139+
"config": json.dumps(config),
140+
"file:/1/model.py": python_code_b64,
111141
}
112142
}
113143

@@ -122,25 +152,18 @@ def _send_load_model_request(self, model_name):
122152
"curl",
123153
"-s",
124154
"-w",
125-
"\n%{http_code}",
155+
"\n%{http_code}", # Write HTTP status code on separate line
126156
"-X",
127157
"POST",
128158
"-H",
129159
"Content-Type: application/json",
130160
"-d",
131161
payload_json,
132-
"--connect-timeout",
133-
"10",
162+
url,
134163
]
135164

136-
# Add the URL as a separate argument to avoid shell interpretation issues
137-
curl_cmd.append(url)
138-
139-
# Debug: print the exact URL being requested
140-
print(f"DEBUG: Curl URL: {url}")
141-
142165
result = subprocess.run(
143-
curl_cmd, capture_output=True, text=True, timeout=15
166+
curl_cmd, capture_output=True, text=True, timeout=10
144167
)
145168

146169
# Parse curl output - last line is status code, rest is response body
@@ -188,16 +211,24 @@ def test_invalid_character_model_names(self):
188211
"""Test that model names with invalid characters are properly rejected"""
189212

190213
# Model names with various invalid characters that should be rejected
214+
# Based on INVALID_CHARS = ";|&$<>(){}\\\"'`*?~#!"
191215
invalid_model_names = [
192-
"model$(test)",
193-
"model\{test\}",
194-
"model`test`",
195-
"model;test",
196-
"model|test",
197-
"model&test",
198-
"model'test'",
199-
"model*test",
200-
"model!test",
216+
r"model;test",
217+
r"model|test",
218+
r"model&test",
219+
r"model$test",
220+
r"model<test>",
221+
r"model(test)",
222+
r"model{test}",
223+
r"model\test",
224+
r'model"test"',
225+
r"model'test'",
226+
r"model`test`",
227+
r"model*test",
228+
# r"model?test", # curl fails to send this request
229+
r"model~test",
230+
# r"model#test", # curl fails to send this request
231+
r"model!test",
201232
]
202233

203234
for invalid_name in invalid_model_names:
@@ -216,11 +247,32 @@ def test_invalid_character_model_names(self):
216247
f"Invalid model name '{invalid_name}' should not get 200 OK response",
217248
)
218249

219-
self.assertIn(
220-
"Invalid stub name: contains invalid characters",
221-
response.text,
222-
f"invalid response for '{invalid_name}' should contain 'Invalid stub name: contains invalid characters'",
223-
)
250+
# Special case for curly braces - they get stripped and cause load failures prior to the validation check
251+
if "{" in invalid_name or "}" in invalid_name:
252+
self.assertIn(
253+
"failed to load",
254+
response.text,
255+
f"Model with curly braces '{invalid_name}' should fail to load",
256+
)
257+
else:
258+
# Normal case - should get character validation error
259+
self.assertIn(
260+
"Invalid stub name: contains invalid characters",
261+
response.text,
262+
f"invalid response for '{invalid_name}' should contain 'Invalid stub name: contains invalid characters'",
263+
)
264+
265+
# Verify the model is not loaded/ready since it was rejected
266+
try:
267+
self.assertFalse(
268+
self._client.is_model_ready(invalid_name),
269+
f"Model '{invalid_name}' should not be ready after failed load attempt",
270+
)
271+
except Exception as e:
272+
# If checking model readiness fails, that's also acceptable since the model name is invalid
273+
print(
274+
f"Note: Could not check model readiness for '{invalid_name}': {e}"
275+
)
224276

225277
def test_valid_model_names(self):
226278
"""Test that valid model names work"""
@@ -240,15 +292,31 @@ def test_valid_model_names(self):
240292
f"Response for valid '{valid_name}': Status {response.status_code}, Text: {response.text[:100]}..."
241293
)
242294

243-
# Valid names might still fail for other reasons (model doesn't exist, etc.)
244-
# but they should not be rejected due to character validation
245-
# We just check it's not a validation error
295+
# Valid model names should be accepted and load successfully
296+
self.assertEqual(
297+
200,
298+
response.status_code,
299+
f"Valid model name '{valid_name}' should get 200 OK response, got {response.status_code}. Response: {response.text}",
300+
)
301+
302+
# Should not contain validation error message
246303
self.assertNotIn(
247304
"Invalid stub name: contains invalid characters",
248305
response.text,
249-
f"valid response for '{valid_name}' should not contain 'Invalid stub name: contains invalid characters'",
306+
f"Valid model name '{valid_name}' should not contain validation error message",
250307
)
251308

309+
# Verify the model is actually loaded by checking if it's ready
310+
try:
311+
self.assertTrue(
312+
self._client.is_model_ready(valid_name),
313+
f"Model '{valid_name}' should be ready after successful load",
314+
)
315+
# Clean up - unload the model after testing
316+
self._client.unload_model(valid_name)
317+
except Exception as e:
318+
self.fail(f"Failed to check if model '{valid_name}' is ready: {e}")
319+
252320

253321
if __name__ == "__main__":
254322
unittest.main()

qa/L0_backend_python/model_control/test.sh

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ if [ $? -ne 0 ]; then
6262
RET=1
6363
fi
6464

65-
echo -e "\n***\n*** Running simple input validation test\n***"
66-
SUBTEST="simple_validation"
67-
python3 -m pytest --junitxml=model_control.${SUBTEST}.report.xml model_control_test.py::InputValidationTest >> ${CLIENT_LOG} 2>&1
65+
echo -e "\n***\n*** Running model ID validation test\n***"
66+
SUBTEST="model_id_validation"
67+
python3 -m pytest --junitxml=model_control.${SUBTEST}.report.xml model_control_test.py::ModelIDValidationTest >> ${CLIENT_LOG} 2>&1
6868

6969
if [ $? -ne 0 ]; then
70-
echo -e "\n***\n*** simple_validation_test.py FAILED. \n***"
70+
echo -e "\n***\n*** model_id_validation_test.py FAILED. \n***"
7171
echo -e "\n***\n*** Server logs:\n***"
7272
cat $SERVER_LOG
7373
echo -e "\n***\n*** Client logs:\n***"
@@ -80,9 +80,9 @@ set -e
8080
kill_server
8181

8282
if [ $RET -eq 1 ]; then
83-
echo -e "\n***\n*** Model control and input validation tests FAILED. \n***"
83+
echo -e "\n***\n*** model_control_test FAILED. \n***"
8484
else
85-
echo -e "\n***\n*** Model control and input validation tests PASSED. \n***"
85+
echo -e "\n***\n*** model_control_test PASSED. \n***"
8686
fi
8787

8888
exit $RET

0 commit comments

Comments
 (0)