@@ -829,6 +829,158 @@ func waitForHTTP(t *testing.T, addr string) {
829829 t .Fatal ("server not ready after 5s" )
830830}
831831
832+ // ── Flag Parsing Tests ───────────────────────────────────────────────────
833+
834+ // serveSandboxFlags returns the sandbox CLI flags parsed by serveCmd.
835+ // Used by tests to verify flag parsing without starting the server.
836+ func serveSandboxFlags (args []string ) (addr string , open bool , sb * bool , sbr * bool , sbi , sbn , sbm , sbc , sbu string , err error ) {
837+ addr = "127.0.0.1:8080"
838+ open = false
839+
840+ for i := 0 ; i < len (args ); i ++ {
841+ switch args [i ] {
842+ case "--addr" :
843+ i ++
844+ if i < len (args ) {
845+ addr = args [i ]
846+ }
847+ case "--open" :
848+ open = true
849+ case "--help" , "-h" :
850+ return
851+ case "--sandbox" :
852+ sb = boolPtr (true )
853+ case "--sandbox-image" :
854+ i ++
855+ if i < len (args ) {
856+ sbi = args [i ]
857+ }
858+ case "--sandbox-network" :
859+ i ++
860+ if i < len (args ) {
861+ sbn = args [i ]
862+ }
863+ case "--sandbox-readonly" :
864+ sbr = boolPtr (true )
865+ case "--sandbox-memory" :
866+ i ++
867+ if i < len (args ) {
868+ sbm = args [i ]
869+ }
870+ case "--sandbox-cpus" :
871+ i ++
872+ if i < len (args ) {
873+ sbc = args [i ]
874+ }
875+ case "--sandbox-user" :
876+ i ++
877+ if i < len (args ) {
878+ sbu = args [i ]
879+ }
880+ default :
881+ err = fmt .Errorf ("unknown flag %q for serve" , args [i ])
882+ return
883+ }
884+ }
885+ return
886+ }
887+
888+ func TestServeCmd_Help (t * testing.T ) {
889+ err := serveCmd ([]string {"--help" })
890+ if err != nil {
891+ t .Fatalf ("serveCmd --help: %v" , err )
892+ }
893+ }
894+
895+ func TestServeCmd_SandboxFlags (t * testing.T ) {
896+ tests := []struct {
897+ name string
898+ args []string
899+ check func (t * testing.T , addr string , open bool , sb , sbr * bool , sbi , sbn , sbm , sbc , sbu string )
900+ }{
901+ {
902+ name : "sandbox only" ,
903+ args : []string {"--sandbox" },
904+ check : func (t * testing.T , addr string , open bool , sb , sbr * bool , sbi , sbn , sbm , sbc , sbu string ) {
905+ if sb == nil || ! * sb {
906+ t .Error ("--sandbox should be true" )
907+ }
908+ },
909+ },
910+ {
911+ name : "sandbox-readonly" ,
912+ args : []string {"--sandbox" , "--sandbox-readonly" },
913+ check : func (t * testing.T , addr string , open bool , sb , sbr * bool , sbi , sbn , sbm , sbc , sbu string ) {
914+ if sbr == nil || ! * sbr {
915+ t .Error ("--sandbox-readonly should be true" )
916+ }
917+ },
918+ },
919+ {
920+ name : "sandbox-image" ,
921+ args : []string {"--sandbox" , "--sandbox-image" , "ubuntu:22.04" },
922+ check : func (t * testing.T , addr string , open bool , sb , sbr * bool , sbi , sbn , sbm , sbc , sbu string ) {
923+ if sbi != "ubuntu:22.04" {
924+ t .Errorf ("sandbox-image = %q, want 'ubuntu:22.04'" , sbi )
925+ }
926+ },
927+ },
928+ {
929+ name : "sandbox-network" ,
930+ args : []string {"--sandbox" , "--sandbox-network" , "none" },
931+ check : func (t * testing.T , addr string , open bool , sb , sbr * bool , sbi , sbn , sbm , sbc , sbu string ) {
932+ if sbn != "none" {
933+ t .Errorf ("sandbox-network = %q, want 'none'" , sbn )
934+ }
935+ },
936+ },
937+ {
938+ name : "sandbox-memory" ,
939+ args : []string {"--sandbox" , "--sandbox-memory" , "512m" },
940+ check : func (t * testing.T , addr string , open bool , sb , sbr * bool , sbi , sbn , sbm , sbc , sbu string ) {
941+ if sbm != "512m" {
942+ t .Errorf ("sandbox-memory = %q, want '512m'" , sbm )
943+ }
944+ },
945+ },
946+ {
947+ name : "sandbox-cpus" ,
948+ args : []string {"--sandbox" , "--sandbox-cpus" , "2" },
949+ check : func (t * testing.T , addr string , open bool , sb , sbr * bool , sbi , sbn , sbm , sbc , sbu string ) {
950+ if sbc != "2" {
951+ t .Errorf ("sandbox-cpus = %q, want '2'" , sbc )
952+ }
953+ },
954+ },
955+ {
956+ name : "sandbox-user" ,
957+ args : []string {"--sandbox" , "--sandbox-user" , "1000:1000" },
958+ check : func (t * testing.T , addr string , open bool , sb , sbr * bool , sbi , sbn , sbm , sbc , sbu string ) {
959+ if sbu != "1000:1000" {
960+ t .Errorf ("sandbox-user = %q, want '1000:1000'" , sbu )
961+ }
962+ },
963+ },
964+ }
965+
966+ for _ , tt := range tests {
967+ t .Run (tt .name , func (t * testing.T ) {
968+ addr , open , sb , sbr , sbi , sbn , sbm , sbc , sbu , err := serveSandboxFlags (tt .args )
969+ if err != nil {
970+ t .Fatalf ("unexpected error: %v" , err )
971+ }
972+ tt .check (t , addr , open , sb , sbr , sbi , sbn , sbm , sbc , sbu )
973+ })
974+ }
975+ }
976+
977+ func TestServeCmd_UnknownFlag (t * testing.T ) {
978+ _ , _ , _ , _ , _ , _ , _ , _ , _ , err := serveSandboxFlags ([]string {"--bogus" })
979+ if err == nil {
980+ t .Fatal ("expected error for unknown flag" )
981+ }
982+ }
983+
832984// TestServe_E2E_MultiToolCall verifies the WebUI event sequence when
833985// the agent makes multiple tool calls in a single turn. This exercises
834986// the same code path the WebUI uses for sub-agent delegation rendering.
0 commit comments