Skip to main content
Glama
logging_test.go7.85 kB
//go:build integration // +build integration package test import ( "regexp" "strings" "testing" "time" "github.com/standardbeagle/brummer/test/testutil" ) // TestSystemLoggingNoTUI tests system logging in headless mode func TestSystemLoggingNoTUI(t *testing.T) { bt := testutil.NewBrummerTest(t) defer bt.Cleanup() // Start brummer in headless mode err := bt.Start("--no-tui", "--debug") if err != nil { t.Fatalf("failed to start brummer: %v", err) } // Check for startup message err = bt.WaitForOutput("🚀 Brummer started", 5*time.Second) if err != nil { t.Errorf("Startup message not found: %v", err) t.Logf("Output: %s", bt.Output()) } // Check for MCP logging err = bt.WaitForOutput("MCP server started", 5*time.Second) if err != nil { t.Errorf("MCP log message not found: %v", err) } // Verify system messages are being logged output := bt.Output() systemLogPatterns := []string{ "🚀 Brummer started", "MCP server", "Starting", } foundCount := 0 for _, pattern := range systemLogPatterns { if strings.Contains(output, pattern) { foundCount++ t.Logf("Found system log pattern: %s", pattern) } } if foundCount < 2 { t.Errorf("Insufficient system log messages found (%d/%d)", foundCount, len(systemLogPatterns)) } } // TestSystemLoggingTUI tests system logging in TUI mode func TestSystemLoggingTUI(t *testing.T) { if testing.Short() { t.Skip("Skipping TUI test in short mode") } bt := testutil.NewBrummerTest(t) defer bt.Cleanup() // Start brummer in TUI mode err := bt.Start("--debug") if err != nil { t.Fatalf("failed to start brummer: %v", err) } // TUI should start successfully time.Sleep(2 * time.Second) // Check that process is still running if bt.Cmd.ProcessState != nil { t.Errorf("TUI process exited unexpectedly") t.Logf("Output: %s", bt.Output()) } else { t.Log("TUI mode started successfully, system logging assumed working") } } // TestProcessOutputCapture tests that process output is captured correctly func TestProcessOutputCapture(t *testing.T) { bt := testutil.NewBrummerTest(t) defer bt.Cleanup() // Start brummer with test script err := bt.Start("--no-tui", "test") if err != nil { t.Fatalf("failed to start brummer: %v", err) } // Check for process output processOutputs := []string{ "[test] Running tests...", "[test] Tests completed!", "Started script 'test'", } for _, expected := range processOutputs { err = bt.WaitForOutput(expected, 5*time.Second) if err != nil { t.Errorf("Process output not captured: %s - %v", expected, err) } else { t.Logf("Captured process output: %s", expected) } } // Verify output has process prefixes output := bt.Output() if !strings.Contains(output, "[test]") { t.Errorf("Process output prefix not found") } } // TestLogTimestamps tests that logs include proper timestamps func TestLogTimestamps(t *testing.T) { bt := testutil.NewBrummerTest(t) defer bt.Cleanup() // Start brummer err := bt.Start("--no-tui", "test") if err != nil { t.Fatalf("failed to start brummer: %v", err) } // Wait for some output err = bt.WaitForOutput("Running tests", 5*time.Second) if err != nil { t.Fatalf("No output to check timestamps: %v", err) } // Check for timestamp patterns [HH:MM:SS] output := bt.Output() timestampPattern := regexp.MustCompile(`\[\d{2}:\d{2}:\d{2}\]`) matches := timestampPattern.FindAllString(output, -1) if len(matches) < 2 { t.Errorf("Insufficient timestamp entries found: %d", len(matches)) t.Logf("Output: %s", output) } else { t.Logf("Found %d timestamp entries", len(matches)) // Show first few timestamps for i := 0; i < len(matches) && i < 3; i++ { t.Logf("Timestamp %d: %s", i+1, matches[i]) } } } // TestErrorDetection tests error detection and logging func TestErrorDetection(t *testing.T) { bt := testutil.NewBrummerTest(t) defer bt.Cleanup() // Start brummer with error script err := bt.Start("--no-tui", "error") if err != nil { t.Fatalf("failed to start brummer: %v", err) } // Check that error is captured err = bt.WaitForOutput("Error: Something went wrong!", 5*time.Second) if err != nil { t.Errorf("Error message not captured: %v", err) t.Logf("Output: %s", bt.Output()) } else { t.Log("Error detection working - error message captured") } // Verify error appears in output output := bt.Output() if strings.Contains(output, "Error:") || strings.Contains(output, "error") { t.Log("Error keyword detected in logs") } } // TestLogFiltering tests log filtering in TUI mode func TestLogFiltering(t *testing.T) { if testing.Short() { t.Skip("Skipping TUI filtering test in short mode") } // This is primarily a TUI feature, so we just verify TUI starts bt := testutil.NewBrummerTest(t) defer bt.Cleanup() err := bt.Start("test") if err != nil { t.Fatalf("failed to start brummer: %v", err) } time.Sleep(2 * time.Second) if bt.Cmd.ProcessState != nil { t.Errorf("TUI process exited unexpectedly") } else { t.Log("TUI mode working - log filtering available via slash commands") } } // TestMultilineLogging tests handling of multiline output func TestMultilineLogging(t *testing.T) { bt := testutil.NewBrummerTest(t) defer bt.Cleanup() // Create a test that outputs multiple lines // The test script outputs on multiple lines err := bt.Start("--no-tui", "test", "build") if err != nil { t.Fatalf("failed to start brummer: %v", err) } // Wait for both scripts to produce output time.Sleep(3 * time.Second) output := bt.Output() lines := strings.Split(output, "\n") if len(lines) < 5 { t.Errorf("Expected multiple lines of output, got %d lines", len(lines)) } else { t.Logf("Multiline output captured: %d lines", len(lines)) } // Check that output from different processes is interleaved hasTest := false hasBuild := false for _, line := range lines { if strings.Contains(line, "[test]") { hasTest = true } if strings.Contains(line, "[build]") { hasBuild = true } } if hasTest && hasBuild { t.Log("Multiple process outputs properly interleaved") } else { t.Errorf("Expected output from both test and build processes") } } // TestLogColors tests ANSI color handling func TestLogColors(t *testing.T) { bt := testutil.NewBrummerTest(t) defer bt.Cleanup() // Start brummer - emojis indicate color support err := bt.Start("--no-tui", "--debug") if err != nil { t.Fatalf("failed to start brummer: %v", err) } // Wait for colorful output (emojis) err = bt.WaitForOutput("🚀", 5*time.Second) if err != nil { t.Logf("No emoji found (color support might be disabled)") } else { t.Log("Color/emoji output detected") } // Check for other visual indicators output := bt.Output() visualIndicators := []string{"🚀", "✅", "🌐", "📦"} foundCount := 0 for _, indicator := range visualIndicators { if strings.Contains(output, indicator) { foundCount++ } } if foundCount > 0 { t.Logf("Found %d visual indicators (emojis) in output", foundCount) } } // TestLogBuffering tests that logs are properly buffered func TestLogBuffering(t *testing.T) { bt := testutil.NewBrummerTest(t) defer bt.Cleanup() // Start a long-running process err := bt.Start("--no-tui", "long-running") if err != nil { t.Fatalf("failed to start brummer: %v", err) } // Let it run for a bit err = bt.WaitForOutput("Long running process", 5*time.Second) if err != nil { t.Fatalf("Process did not start: %v", err) } // Get output at different times output1 := bt.Output() time.Sleep(1 * time.Second) output2 := bt.Output() // Output should accumulate if len(output2) <= len(output1) { t.Errorf("Log buffer not accumulating: len1=%d, len2=%d", len(output1), len(output2)) } else { t.Logf("Log buffering working: %d -> %d bytes", len(output1), len(output2)) } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/standardbeagle/brummer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server