diff --git a/cmd/prometheus/main_test.go b/cmd/prometheus/main_test.go index 0efbe5f06..71d638bf0 100644 --- a/cmd/prometheus/main_test.go +++ b/cmd/prometheus/main_test.go @@ -14,11 +14,101 @@ package main import ( + "flag" + "fmt" + "net/http" + "os" + "os/exec" + "path/filepath" "testing" + "time" "github.com/prometheus/prometheus/util/testutil" ) +var promPath string +var promConfig = filepath.Join("..", "..", "documentation", "examples", "prometheus.yml") +var promData = filepath.Join(os.TempDir(), "data") + +func TestMain(m *testing.M) { + flag.Parse() + if testing.Short() { + os.Exit(m.Run()) + } + var err error + promPath, err = os.Getwd() + if err != nil { + fmt.Printf("can't get current dir :%s \n", err) + os.Exit(1) + } + promPath = filepath.Join(promPath, "prometheus") + + build := exec.Command("go", "build", "-o", promPath) + output, err := build.CombinedOutput() + if err != nil { + fmt.Printf("compilation error :%s \n", output) + os.Exit(1) + } + + exitCode := m.Run() + os.Remove(promPath) + os.RemoveAll(promData) + os.Exit(exitCode) +} + +// As soon as prometheus starts responding to http request should be able to accept Interrupt signals for a gracefull shutdown. +func TestStartupInterrupt(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode.") + } + + prom := exec.Command(promPath, "--config.file="+promConfig, "--storage.tsdb.path="+promData) + err := prom.Start() + if err != nil { + t.Errorf("execution error: %v", err) + return + } + + done := make(chan error) + go func() { + done <- prom.Wait() + }() + + var startedOk bool + var stoppedOk bool + var stoppedErr error + +Loop: + for x := 0; x < 10; x++ { + + // error=nil means prometheus has started so can send the interrupt signal and wait for the grace shutdown. + if _, err := http.Get("http://localhost:9090/graph"); err == nil { + startedOk = true + prom.Process.Signal(os.Interrupt) + select { + case stoppedErr = <-done: + stoppedOk = true + break Loop + case <-time.After(10 * time.Second): + + } + break Loop + + } + time.Sleep(500 * time.Millisecond) + } + + if !startedOk { + t.Errorf("prometheus didn't start in the specified timeout") + return + } + if err := prom.Process.Kill(); err == nil && !stoppedOk { + t.Errorf("prometheus didn't shutdown gracefully after sending the Interrupt signal") + } else if stoppedErr != nil { + t.Errorf("prometheus exited with an error:%v", stoppedErr) + } +} + func TestComputeExternalURL(t *testing.T) { tests := []struct { input string