@@ -678,3 +678,163 @@ func parseSSEResponse(t *testing.T, body string) map[string]interface{} {
678678
679679 return result
680680}
681+
682+ // TestBinaryInvocation_LogFileCreation tests that the mcp-gateway.log file is created when the binary runs
683+ func TestBinaryInvocation_LogFileCreation (t * testing.T ) {
684+ if testing .Short () {
685+ t .Skip ("Skipping binary integration test in short mode" )
686+ }
687+
688+ binaryPath := findBinary (t )
689+ t .Logf ("Using binary: %s" , binaryPath )
690+
691+ // Create a temporary directory for logs
692+ tmpLogDir , err := os .MkdirTemp ("" , "awmg-log-test-*" )
693+ if err != nil {
694+ t .Fatalf ("Failed to create temp log directory: %v" , err )
695+ }
696+ defer os .RemoveAll (tmpLogDir )
697+
698+ // Create a temporary config file
699+ configFile := createTempConfig (t , map [string ]interface {}{
700+ "testserver" : map [string ]interface {}{
701+ "command" : "echo" ,
702+ "args" : []string {},
703+ },
704+ })
705+ defer os .Remove (configFile )
706+
707+ // Start the server process with custom log directory
708+ ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
709+ defer cancel ()
710+
711+ port := "13006"
712+ cmd := exec .CommandContext (ctx , binaryPath ,
713+ "--config" , configFile ,
714+ "--listen" , "127.0.0.1:" + port ,
715+ "--log-dir" , tmpLogDir ,
716+ "--routed" ,
717+ )
718+
719+ var stdout , stderr bytes.Buffer
720+ cmd .Stdout = & stdout
721+ cmd .Stderr = & stderr
722+
723+ if err := cmd .Start (); err != nil {
724+ t .Fatalf ("Failed to start server: %v" , err )
725+ }
726+
727+ defer func () {
728+ if cmd .Process != nil {
729+ cmd .Process .Kill ()
730+ }
731+ }()
732+
733+ // Wait for server to start
734+ serverURL := "http://127.0.0.1:" + port
735+ if ! waitForServer (t , serverURL + "/health" , 5 * time .Second ) {
736+ t .Logf ("STDOUT: %s" , stdout .String ())
737+ t .Logf ("STDERR: %s" , stderr .String ())
738+ t .Fatal ("Server did not start in time" )
739+ }
740+
741+ t .Log ("✓ Server started successfully" )
742+
743+ // Check that the log file was created
744+ logFilePath := filepath .Join (tmpLogDir , "mcp-gateway.log" )
745+ if _ , err := os .Stat (logFilePath ); os .IsNotExist (err ) {
746+ t .Fatalf ("Log file was not created at %s" , logFilePath )
747+ }
748+
749+ t .Logf ("✓ Log file created at: %s" , logFilePath )
750+
751+ // Read the log file to verify it contains log entries
752+ logContent , err := os .ReadFile (logFilePath )
753+ if err != nil {
754+ t .Fatalf ("Failed to read log file: %v" , err )
755+ }
756+
757+ if len (logContent ) == 0 {
758+ t .Error ("Log file is empty" )
759+ } else {
760+ t .Logf ("✓ Log file contains %d bytes" , len (logContent ))
761+ }
762+
763+ // Verify log file contains expected startup messages
764+ logStr := string (logContent )
765+ expectedMessages := []string {
766+ "startup" ,
767+ "Starting MCPG" ,
768+ }
769+
770+ for _ , msg := range expectedMessages {
771+ if ! bytes .Contains (logContent , []byte (msg )) {
772+ t .Errorf ("Log file does not contain expected message: %q" , msg )
773+ t .Logf ("Log content:\n %s" , logStr )
774+ }
775+ }
776+
777+ t .Log ("✓ Log file contains expected startup messages" )
778+
779+ // Verify log file permissions (should be 0644)
780+ fileInfo , err := os .Stat (logFilePath )
781+ if err != nil {
782+ t .Fatalf ("Failed to stat log file: %v" , err )
783+ }
784+
785+ perms := fileInfo .Mode ().Perm ()
786+ expectedPerms := os .FileMode (0644 )
787+ if perms != expectedPerms {
788+ t .Errorf ("Log file has incorrect permissions: got %o, expected %o" , perms , expectedPerms )
789+ } else {
790+ t .Logf ("✓ Log file has correct permissions: %o" , perms )
791+ }
792+
793+ // Test that the log file is readable by other processes
794+ // Try to open and read the file while the server is still running
795+ readFile , err := os .Open (logFilePath )
796+ if err != nil {
797+ t .Fatalf ("Failed to open log file for reading (concurrent access): %v" , err )
798+ }
799+ defer readFile .Close ()
800+
801+ // Read content
802+ concurrentRead , err := io .ReadAll (readFile )
803+ if err != nil {
804+ t .Fatalf ("Failed to read log file concurrently: %v" , err )
805+ }
806+
807+ if len (concurrentRead ) == 0 {
808+ t .Error ("Concurrent read returned empty content" )
809+ } else {
810+ t .Logf ("✓ Log file is readable by other processes (%d bytes read concurrently)" , len (concurrentRead ))
811+ }
812+
813+ // Make an API call to generate more log entries
814+ resp , err := http .Get (serverURL + "/health" )
815+ if err == nil {
816+ resp .Body .Close ()
817+ }
818+
819+ // Wait a moment for logs to be written
820+ time .Sleep (200 * time .Millisecond )
821+
822+ // Read the log file again to verify new entries were added (or at least it's still readable)
823+ newLogContent , err := os .ReadFile (logFilePath )
824+ if err != nil {
825+ t .Fatalf ("Failed to read log file after API call: %v" , err )
826+ }
827+
828+ // Log file should either grow or stay the same (health endpoint may not always log)
829+ if len (newLogContent ) >= len (logContent ) {
830+ if len (newLogContent ) > len (logContent ) {
831+ t .Logf ("✓ Log file grew from %d to %d bytes after API call (immediate flush working)" , len (logContent ), len (newLogContent ))
832+ } else {
833+ t .Logf ("✓ Log file size unchanged (%d bytes) but still readable after API call" , len (logContent ))
834+ }
835+ } else {
836+ t .Errorf ("Log file shrank from %d to %d bytes - unexpected behavior" , len (logContent ), len (newLogContent ))
837+ }
838+
839+ t .Log ("✓ All log file checks passed" )
840+ }
0 commit comments