@@ -305,3 +305,90 @@ func TestThinkFlagBehavior(t *testing.T) {
305305 })
306306 }
307307}
308+
309+ func TestRuntimeFlagsValidation (t * testing.T ) {
310+ tests := []struct {
311+ name string
312+ runtimeFlags []string
313+ expectError bool
314+ errorContains string
315+ }{
316+ {
317+ name : "valid runtime flags without paths" ,
318+ runtimeFlags : []string {"--verbose" , "--threads" , "4" },
319+ expectError : false ,
320+ },
321+ {
322+ name : "empty runtime flags" ,
323+ runtimeFlags : []string {},
324+ expectError : false ,
325+ },
326+ {
327+ name : "reject absolute path in value" ,
328+ runtimeFlags : []string {"--log-file" , "/var/log/model.log" },
329+ expectError : true ,
330+ errorContains : "paths are not allowed" ,
331+ },
332+ {
333+ name : "reject absolute path in flag=value format" ,
334+ runtimeFlags : []string {"--output-file=/tmp/output.txt" },
335+ expectError : true ,
336+ errorContains : "paths are not allowed" ,
337+ },
338+ {
339+ name : "reject relative path" ,
340+ runtimeFlags : []string {"--config" , "../config.yaml" },
341+ expectError : true ,
342+ errorContains : "paths are not allowed" ,
343+ },
344+ {
345+ name : "reject URL" ,
346+ runtimeFlags : []string {"--endpoint" , "http://example.com/api" },
347+ expectError : true ,
348+ errorContains : "paths are not allowed" ,
349+ },
350+ }
351+
352+ for _ , tt := range tests {
353+ t .Run (tt .name , func (t * testing.T ) {
354+ flags := ConfigureFlags {}
355+ req , err := flags .BuildConfigureRequest ("test-model" )
356+ if err != nil {
357+ t .Fatalf ("BuildConfigureRequest failed: %v" , err )
358+ }
359+
360+ // Set runtime flags after building request
361+ req .RuntimeFlags = tt .runtimeFlags
362+
363+ // Note: The actual validation happens in scheduler.ConfigureRunner,
364+ // but we're testing that the BuildConfigureRequest correctly
365+ // preserves the RuntimeFlags for validation downstream.
366+ // For a true integration test, we would need to mock the scheduler.
367+
368+ if tt .expectError {
369+ // In this unit test context, we verify the flags are preserved
370+ // The actual validation will happen in the scheduler
371+ if len (req .RuntimeFlags ) == 0 && len (tt .runtimeFlags ) > 0 {
372+ t .Error ("RuntimeFlags should be preserved in the request" )
373+ }
374+ } else {
375+ if ! equalStringSlices (req .RuntimeFlags , tt .runtimeFlags ) {
376+ t .Errorf ("Expected RuntimeFlags %v, got %v" , tt .runtimeFlags , req .RuntimeFlags )
377+ }
378+ }
379+ })
380+ }
381+ }
382+
383+ // equalStringSlices checks if two string slices are equal
384+ func equalStringSlices (a , b []string ) bool {
385+ if len (a ) != len (b ) {
386+ return false
387+ }
388+ for i := range a {
389+ if a [i ] != b [i ] {
390+ return false
391+ }
392+ }
393+ return true
394+ }
0 commit comments