1414package main
1515
1616import (
17+ "errors"
1718 "fmt"
1819 "net/http"
1920 "net/http/httptest"
2021 "net/url"
2122 "os"
23+ "os/exec"
2224 "runtime"
2325 "strings"
26+ "syscall"
2427 "testing"
2528 "time"
2629
@@ -30,6 +33,21 @@ import (
3033 "github.com/prometheus/prometheus/model/rulefmt"
3134)
3235
36+ var promtoolPath = os .Args [0 ]
37+
38+ func TestMain (m * testing.M ) {
39+ for i , arg := range os .Args {
40+ if arg == "-test.main" {
41+ os .Args = append (os .Args [:i ], os .Args [i + 1 :]... )
42+ main ()
43+ return
44+ }
45+ }
46+
47+ exitCode := m .Run ()
48+ os .Exit (exitCode )
49+ }
50+
3351func TestQueryRange (t * testing.T ) {
3452 s , getRequest := mockServer (200 , `{"status": "success", "data": {"resultType": "matrix", "result": []}}` )
3553 defer s .Close ()
@@ -359,3 +377,59 @@ func TestCheckMetricsExtended(t *testing.T) {
359377 },
360378 }, stats )
361379}
380+
381+ func TestExitCodes (t * testing.T ) {
382+ if testing .Short () {
383+ t .Skip ("skipping test in short mode." )
384+ }
385+
386+ for _ , c := range []struct {
387+ file string
388+ exitCode int
389+ lintIssue bool
390+ }{
391+ {
392+ file : "prometheus-config.good.yml" ,
393+ },
394+ {
395+ file : "prometheus-config.bad.yml" ,
396+ exitCode : 1 ,
397+ },
398+ {
399+ file : "prometheus-config.nonexistent.yml" ,
400+ exitCode : 1 ,
401+ },
402+ {
403+ file : "prometheus-config.lint.yml" ,
404+ lintIssue : true ,
405+ exitCode : 3 ,
406+ },
407+ } {
408+ t .Run (c .file , func (t * testing.T ) {
409+ for _ , lintFatal := range []bool {true , false } {
410+ t .Run (fmt .Sprintf ("%t" , lintFatal ), func (t * testing.T ) {
411+ args := []string {"-test.main" , "check" , "config" , "testdata/" + c .file }
412+ if lintFatal {
413+ args = append (args , "--lint-fatal" )
414+ }
415+ tool := exec .Command (promtoolPath , args ... )
416+ err := tool .Run ()
417+ if c .exitCode == 0 || (c .lintIssue && ! lintFatal ) {
418+ require .NoError (t , err )
419+ return
420+ }
421+
422+ require .Error (t , err )
423+
424+ var exitError * exec.ExitError
425+ if errors .As (err , & exitError ) {
426+ status := exitError .Sys ().(syscall.WaitStatus )
427+ require .Equal (t , c .exitCode , status .ExitStatus ())
428+ } else {
429+ t .Errorf ("unable to retrieve the exit status for promtool: %v" , err )
430+ }
431+ })
432+ }
433+ })
434+ }
435+ }
0 commit comments