@@ -2,6 +2,7 @@ package config
22
33import (
44 "encoding/json"
5+ "fmt"
56 "os"
67 "strings"
78 "testing"
@@ -656,3 +657,253 @@ func contains(slice []string, item string) bool {
656657 }
657658 return false
658659}
660+
661+ func TestLoadFromStdin_WithEntrypoint (t * testing.T ) {
662+ jsonConfig := `{
663+ "mcpServers": {
664+ "custom": {
665+ "type": "stdio",
666+ "container": "test/container:latest",
667+ "entrypoint": "/custom/entrypoint.sh",
668+ "entrypointArgs": ["--verbose"]
669+ }
670+ }
671+ }`
672+
673+ r , w , _ := os .Pipe ()
674+ oldStdin := os .Stdin
675+ os .Stdin = r
676+ go func () {
677+ w .Write ([]byte (jsonConfig ))
678+ w .Close ()
679+ }()
680+
681+ cfg , err := LoadFromStdin ()
682+ os .Stdin = oldStdin
683+
684+ if err != nil {
685+ t .Fatalf ("LoadFromStdin() failed: %v" , err )
686+ }
687+
688+ server , ok := cfg .Servers ["custom" ]
689+ if ! ok {
690+ t .Fatal ("Server 'custom' not found" )
691+ }
692+
693+ // Check that --entrypoint flag is present
694+ hasEntrypoint := false
695+ for i := 0 ; i < len (server .Args ); i ++ {
696+ if server .Args [i ] == "--entrypoint" && i + 1 < len (server .Args ) {
697+ if server .Args [i + 1 ] == "/custom/entrypoint.sh" {
698+ hasEntrypoint = true
699+ }
700+ }
701+ }
702+
703+ if ! hasEntrypoint {
704+ t .Error ("Entrypoint flag not found in Docker args" )
705+ }
706+
707+ // Check that entrypoint args are present
708+ if ! contains (server .Args , "--verbose" ) {
709+ t .Error ("Entrypoint args not found" )
710+ }
711+ }
712+
713+ func TestLoadFromStdin_WithMounts (t * testing.T ) {
714+ jsonConfig := `{
715+ "mcpServers": {
716+ "mounted": {
717+ "type": "stdio",
718+ "container": "test/container:latest",
719+ "mounts": [
720+ "/host/path:/container/path:ro",
721+ "/host/data:/app/data:rw"
722+ ]
723+ }
724+ }
725+ }`
726+
727+ r , w , _ := os .Pipe ()
728+ oldStdin := os .Stdin
729+ os .Stdin = r
730+ go func () {
731+ w .Write ([]byte (jsonConfig ))
732+ w .Close ()
733+ }()
734+
735+ cfg , err := LoadFromStdin ()
736+ os .Stdin = oldStdin
737+
738+ if err != nil {
739+ t .Fatalf ("LoadFromStdin() failed: %v" , err )
740+ }
741+
742+ server , ok := cfg .Servers ["mounted" ]
743+ if ! ok {
744+ t .Fatal ("Server 'mounted' not found" )
745+ }
746+
747+ // Check that volume mount flags are present
748+ mountCount := 0
749+ for i := 0 ; i < len (server .Args ); i ++ {
750+ if server .Args [i ] == "-v" && i + 1 < len (server .Args ) {
751+ nextArg := server .Args [i + 1 ]
752+ if nextArg == "/host/path:/container/path:ro" || nextArg == "/host/data:/app/data:rw" {
753+ mountCount ++
754+ }
755+ }
756+ }
757+
758+ if mountCount != 2 {
759+ t .Errorf ("Expected 2 volume mounts, found %d" , mountCount )
760+ }
761+ }
762+
763+ func TestLoadFromStdin_WithAllNewFields (t * testing.T ) {
764+ jsonConfig := `{
765+ "mcpServers": {
766+ "comprehensive": {
767+ "type": "stdio",
768+ "container": "test/container:latest",
769+ "entrypoint": "/bin/bash",
770+ "entrypointArgs": ["-c", "echo test"],
771+ "mounts": ["/tmp:/data:rw"],
772+ "env": {
773+ "DEBUG": "true"
774+ }
775+ }
776+ }
777+ }`
778+
779+ r , w , _ := os .Pipe ()
780+ oldStdin := os .Stdin
781+ os .Stdin = r
782+ go func () {
783+ w .Write ([]byte (jsonConfig ))
784+ w .Close ()
785+ }()
786+
787+ cfg , err := LoadFromStdin ()
788+ os .Stdin = oldStdin
789+
790+ if err != nil {
791+ t .Fatalf ("LoadFromStdin() failed: %v" , err )
792+ }
793+
794+ server , ok := cfg .Servers ["comprehensive" ]
795+ if ! ok {
796+ t .Fatal ("Server 'comprehensive' not found" )
797+ }
798+
799+ // Verify command is docker
800+ if server .Command != "docker" {
801+ t .Errorf ("Expected command 'docker', got '%s'" , server .Command )
802+ }
803+
804+ // Check entrypoint
805+ hasEntrypoint := false
806+ for i := 0 ; i < len (server .Args )- 1 ; i ++ {
807+ if server .Args [i ] == "--entrypoint" && server .Args [i + 1 ] == "/bin/bash" {
808+ hasEntrypoint = true
809+ break
810+ }
811+ }
812+ if ! hasEntrypoint {
813+ t .Error ("Entrypoint not found in args" )
814+ }
815+
816+ // Check mounts
817+ hasMount := false
818+ for i := 0 ; i < len (server .Args )- 1 ; i ++ {
819+ if server .Args [i ] == "-v" && server .Args [i + 1 ] == "/tmp:/data:rw" {
820+ hasMount = true
821+ break
822+ }
823+ }
824+ if ! hasMount {
825+ t .Error ("Mount not found in args" )
826+ }
827+
828+ // Check env var
829+ hasDebug := false
830+ for i := 0 ; i < len (server .Args )- 1 ; i ++ {
831+ if server .Args [i ] == "-e" && server .Args [i + 1 ] == "DEBUG=true" {
832+ hasDebug = true
833+ break
834+ }
835+ }
836+ if ! hasDebug {
837+ t .Error ("Environment variable DEBUG=true not found" )
838+ }
839+
840+ // Check entrypoint args
841+ if ! contains (server .Args , "-c" ) || ! contains (server .Args , "echo test" ) {
842+ t .Error ("Entrypoint args not found" )
843+ }
844+
845+ // Verify container name is present
846+ if ! contains (server .Args , "test/container:latest" ) {
847+ t .Error ("Container name not found" )
848+ }
849+ }
850+
851+ func TestLoadFromStdin_InvalidMountFormat (t * testing.T ) {
852+ tests := []struct {
853+ name string
854+ mounts string
855+ errorMsg string
856+ }{
857+ {
858+ name : "missing mode" ,
859+ mounts : `["/host:/container"]` ,
860+ errorMsg : "invalid mount format" ,
861+ },
862+ {
863+ name : "invalid mode" ,
864+ mounts : `["/host:/container:invalid"]` ,
865+ errorMsg : "invalid mount mode" ,
866+ },
867+ {
868+ name : "empty source" ,
869+ mounts : `[":/container:ro"]` ,
870+ errorMsg : "mount source cannot be empty" ,
871+ },
872+ {
873+ name : "empty destination" ,
874+ mounts : `["/host::ro"]` ,
875+ errorMsg : "mount destination cannot be empty" ,
876+ },
877+ }
878+
879+ for _ , tt := range tests {
880+ t .Run (tt .name , func (t * testing.T ) {
881+ jsonConfig := fmt .Sprintf (`{
882+ "mcpServers": {
883+ "test": {
884+ "type": "stdio",
885+ "container": "test:latest",
886+ "mounts": %s
887+ }
888+ }
889+ }` , tt .mounts )
890+
891+ r , w , _ := os .Pipe ()
892+ oldStdin := os .Stdin
893+ os .Stdin = r
894+ go func () {
895+ w .Write ([]byte (jsonConfig ))
896+ w .Close ()
897+ }()
898+
899+ _ , err := LoadFromStdin ()
900+ os .Stdin = oldStdin
901+
902+ if err == nil {
903+ t .Error ("Expected error but got none" )
904+ } else if ! strings .Contains (err .Error (), tt .errorMsg ) {
905+ t .Errorf ("Expected error containing %q, got: %v" , tt .errorMsg , err )
906+ }
907+ })
908+ }
909+ }
0 commit comments