Skip to content

Commit 76d5ec1

Browse files
committed
update model control tests
1 parent 223ca21 commit 76d5ec1

File tree

2 files changed

+115
-33
lines changed

2 files changed

+115
-33
lines changed

qa/L0_backend_python/model_control/model_control_test.py

Lines changed: 101 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
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
30+
import json
2931
import os
3032
import subprocess
3133
import sys
@@ -84,9 +86,9 @@ def test_model_reload(self):
8486
self.assertFalse(client.is_model_ready(ensemble_model_name))
8587

8688

87-
class InputValidationTest(unittest.TestCase):
89+
class ModelIDValidationTest(unittest.TestCase):
8890
"""
89-
Test input validation for user-provided inputs
91+
Test model ID validation for user-provided model names
9092
"""
9193

9294
def setUp(self):
@@ -103,10 +105,39 @@ def setUp(self):
103105

104106
def _send_load_model_request(self, model_name):
105107
"""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+
106137
payload = {
107138
"parameters": {
108-
"config": f'{{"name": "{model_name}", "backend": "python", "max_batch_size": 4}}',
109-
"file:/1/model.py": "print('Hello from Python Model')",
139+
"config": json.dumps(config),
140+
"file:/1/model.py": python_code_b64,
110141
}
111142
}
112143

@@ -121,25 +152,18 @@ def _send_load_model_request(self, model_name):
121152
"curl",
122153
"-s",
123154
"-w",
124-
"\n%{http_code}",
155+
"\n%{http_code}", # Write HTTP status code on separate line
125156
"-X",
126157
"POST",
127158
"-H",
128159
"Content-Type: application/json",
129160
"-d",
130161
payload_json,
131-
"--connect-timeout",
132-
"10",
162+
url,
133163
]
134164

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

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

189213
# Model names with various invalid characters that should be rejected
214+
# Based on INVALID_CHARS = ";|&$<>(){}\\\"'`*?~#!"
190215
invalid_model_names = [
191-
"model$(test)",
192-
"model\{test\}",
193-
"model`test`",
194-
"model;test",
195-
"model|test",
196-
"model&test",
197-
"model'test'",
198-
"model*test",
199-
"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",
200232
]
201233

202234
for invalid_name in invalid_model_names:
@@ -215,11 +247,32 @@ def test_invalid_character_model_names(self):
215247
f"Invalid model name '{invalid_name}' should not get 200 OK response",
216248
)
217249

218-
self.assertIn(
219-
"Invalid stub name: contains invalid characters",
220-
response.text,
221-
f"invalid response for '{invalid_name}' should contain 'Invalid stub name: contains invalid characters'",
222-
)
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+
)
223276

224277
def test_valid_model_names(self):
225278
"""Test that valid model names work"""
@@ -239,15 +292,31 @@ def test_valid_model_names(self):
239292
f"Response for valid '{valid_name}': Status {response.status_code}, Text: {response.text[:100]}..."
240293
)
241294

242-
# Valid names might still fail for other reasons (model doesn't exist, etc.)
243-
# but they should not be rejected due to character validation
244-
# 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
245303
self.assertNotIn(
246304
"Invalid stub name: contains invalid characters",
247305
response.text,
248-
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",
249307
)
250308

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+
251320

252321
if __name__ == "__main__":
253322
unittest.main()

qa/L0_backend_python/model_control/test.sh

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,25 @@ if [ $? -ne 0 ]; then
5555
echo -e "\n***\n*** model_control_test.py FAILED. \n***"
5656
RET=1
5757
fi
58+
59+
echo -e "\n***\n*** Running model ID validation test\n***"
60+
SUBTEST="model_id_validation"
61+
python3 -m pytest --junitxml=model_control.${SUBTEST}.report.xml model_control_test.py::ModelIDValidationTest >> ${CLIENT_LOG} 2>&1
62+
63+
if [ $? -ne 0 ]; then
64+
echo -e "\n***\n*** model_id_validation_test.py FAILED. \n***"
65+
echo -e "\n***\n*** Server logs:\n***"
66+
cat $SERVER_LOG
67+
echo -e "\n***\n*** Client logs:\n***"
68+
cat $CLIENT_LOG
69+
RET=1
70+
fi
71+
5872
set -e
5973

6074
kill_server
6175

6276
if [ $RET -eq 1 ]; then
63-
cat $CLIENT_LOG
6477
echo -e "\n***\n*** model_control_test FAILED. \n***"
6578
else
6679
echo -e "\n***\n*** model_control_test PASSED. \n***"

0 commit comments

Comments
 (0)