11#!/usr/bin/python
22
3- # Copyright 2022 , NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+ # Copyright 2026 , NVIDIA CORPORATION & AFFILIATES. All rights reserved.
44#
55# Redistribution and use in source and binary forms, with or without
66# modification, are permitted provided that the following conditions
3333import json
3434import unittest
3535
36+ import mlflow .onnx
3637import numpy as np
38+ import onnx
3739import test_util as tu
3840from mlflow .deployments import get_deploy_client
3941
@@ -45,7 +47,7 @@ def setUp(self):
4547 def _validate_deployment (self , model_name ):
4648 # create
4749 self .client_ .create_deployment (
48- model_name , "models:/{}/1" . format ( model_name ) , flavor = "onnx"
50+ model_name , f "models:/{ model_name } /1" , flavor = "onnx"
4951 )
5052
5153 # list
@@ -79,8 +81,6 @@ def _validate_deployment(self, model_name):
7981
8082 def test_onnx_flavor (self ):
8183 # Log the ONNX model to MLFlow
82- import mlflow .onnx
83- import onnx
8484
8585 model = onnx .load (
8686 "./mlflow-triton-plugin/examples/onnx_float32_int32_int32/1/model.onnx"
@@ -92,8 +92,6 @@ def test_onnx_flavor(self):
9292
9393 def test_onnx_flavor_with_files (self ):
9494 # Log the ONNX model and additional Triton config file to MLFlow
95- import mlflow .onnx
96- import onnx
9795
9896 model = onnx .load (
9997 "./mlflow-triton-plugin/examples/onnx_float32_int32_int32/1/model.onnx"
@@ -116,6 +114,65 @@ def test_onnx_flavor_with_files(self):
116114 filecmp .cmp (config_path , "./models/onnx_model_with_files/config.pbtxt" )
117115 )
118116
117+ def test_model_name (self ):
118+ EMPTY_MODEL_NAMES = [
119+ "" ,
120+ " " ,
121+ " " ,
122+ "\n " ,
123+ "\t " ,
124+ "\r " ,
125+ "\v " ,
126+ "\f " ,
127+ ]
128+ INVALID_PATH_TRAVERSAL_NAMES = [
129+ "/opt/sys/" ,
130+ "../../etc/passwd" ,
131+ "../outside/repo" ,
132+ "test_models/../identity_py" ,
133+ ".." ,
134+ ]
135+ VALID_MODEL_NAMES = [
136+ "model123" ,
137+ # "model OAI", TRI-769: Fix this test case
138+ "model.version1" ,
139+ "..." ,
140+ "..my_model" ,
141+ "model..1" ,
142+ "model....1" ,
143+ ]
144+
145+ for model_name in EMPTY_MODEL_NAMES :
146+ model_uri = f"models:/{ model_name } /1"
147+ with self .assertRaises (Exception ) as e :
148+ self .client_ .create_deployment (model_name , model_uri , flavor = "onnx" )
149+ self .assertIn (
150+ "Model name cannot be empty. Please enter a valid name to deploy." ,
151+ str (e .exception ),
152+ )
153+
154+ for model_name in INVALID_PATH_TRAVERSAL_NAMES :
155+ model_uri = f"models:/{ model_name } /1"
156+ with self .assertRaises (Exception ) as e :
157+ self .client_ .create_deployment (model_name , model_uri , flavor = "onnx" )
158+ self .assertIn (
159+ f"Path traversal is not allowed in model's name: { model_name } " ,
160+ str (e .exception ),
161+ )
162+
163+ for model_name in VALID_MODEL_NAMES :
164+ model = onnx .load (
165+ "./mlflow-triton-plugin/examples/onnx_float32_int32_int32/1/model.onnx"
166+ )
167+
168+ # Use a different name to ensure the plugin operates on correct model
169+ mlflow .onnx .log_model (
170+ model , "triton" , registered_model_name = f"{ model_name } "
171+ )
172+
173+ # Validate deployment functionalities - create, list, get, predict, delete
174+ self ._validate_deployment (model_name )
175+
119176
120177if __name__ == "__main__" :
121178 unittest .main ()
0 commit comments