mirror of
https://github.com/prometheus/prometheus.git
synced 2025-01-11 13:57:36 -08:00
Add windows tests for query logger (#6653)
* Add windows tests * Do not rely on time.Time in timer Signed-off-by: Julien Pivotto <roidelapluie@inuits.eu>
This commit is contained in:
parent
46d18112a3
commit
2b2eb79e8b
|
@ -56,8 +56,14 @@ jobs:
|
||||||
working_directory: /go/src/github.com/prometheus/prometheus
|
working_directory: /go/src/github.com/prometheus/prometheus
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
# TSDB is where the most risk is Windows wise, so only test there for now.
|
- run:
|
||||||
- run: go test ./tsdb/...
|
shell: bash
|
||||||
|
command: |
|
||||||
|
(cd web/ui && GOOS= GOARCH= go generate -mod=vendor)
|
||||||
|
go test -mod=vendor -test.v `go list ./...|grep -Exv "(github.com/prometheus/prometheus/discovery.*|github.com/prometheus/prometheus/config|github.com/prometheus/prometheus/web)"`
|
||||||
|
environment:
|
||||||
|
GOGC: "20"
|
||||||
|
GOOPTS: "-p 2 -mod=vendor"
|
||||||
fuzzit_regression:
|
fuzzit_regression:
|
||||||
executor: fuzzit
|
executor: fuzzit
|
||||||
working_directory: /go/src/github.com/prometheus/prometheus
|
working_directory: /go/src/github.com/prometheus/prometheus
|
||||||
|
|
|
@ -16,7 +16,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -51,54 +51,6 @@ func TestMain(m *testing.M) {
|
||||||
os.Exit(exitCode)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// As soon as prometheus starts responding to http request should be able to accept Interrupt signals for a graceful shutdown.
|
|
||||||
func TestStartupInterrupt(t *testing.T) {
|
|
||||||
if testing.Short() {
|
|
||||||
t.Skip("skipping test in short mode.")
|
|
||||||
}
|
|
||||||
|
|
||||||
prom := exec.Command(promPath, "-test.main", "--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 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:
|
|
||||||
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 {
|
|
||||||
t.Errorf("prometheus didn't shutdown gracefully after sending the Interrupt signal")
|
|
||||||
} else if stoppedErr != nil && stoppedErr.Error() != "signal: interrupt" { // TODO - find a better way to detect when the process didn't exit as expected!
|
|
||||||
t.Errorf("prometheus exited with an unexpected error:%v", stoppedErr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestComputeExternalURL(t *testing.T) {
|
func TestComputeExternalURL(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
input string
|
input string
|
||||||
|
@ -246,7 +198,16 @@ func TestWALSegmentSizeBounds(t *testing.T) {
|
||||||
|
|
||||||
for size, expectedExitStatus := range map[string]int{"9MB": 1, "257MB": 1, "10": 2, "1GB": 1, "12MB": 0} {
|
for size, expectedExitStatus := range map[string]int{"9MB": 1, "257MB": 1, "10": 2, "1GB": 1, "12MB": 0} {
|
||||||
prom := exec.Command(promPath, "-test.main", "--storage.tsdb.wal-segment-size="+size, "--config.file="+promConfig)
|
prom := exec.Command(promPath, "-test.main", "--storage.tsdb.wal-segment-size="+size, "--config.file="+promConfig)
|
||||||
err := prom.Start()
|
|
||||||
|
// Log stderr in case of failure.
|
||||||
|
stderr, err := prom.StderrPipe()
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
go func() {
|
||||||
|
slurp, _ := ioutil.ReadAll(stderr)
|
||||||
|
t.Log(string(slurp))
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = prom.Start()
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
if expectedExitStatus == 0 {
|
if expectedExitStatus == 0 {
|
||||||
|
@ -256,7 +217,7 @@ func TestWALSegmentSizeBounds(t *testing.T) {
|
||||||
case err := <-done:
|
case err := <-done:
|
||||||
t.Errorf("prometheus should be still running: %v", err)
|
t.Errorf("prometheus should be still running: %v", err)
|
||||||
case <-time.After(5 * time.Second):
|
case <-time.After(5 * time.Second):
|
||||||
prom.Process.Signal(os.Interrupt)
|
prom.Process.Kill()
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
74
cmd/prometheus/main_unix_test.go
Normal file
74
cmd/prometheus/main_unix_test.go
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// As soon as prometheus starts responding to http request it should be able to
|
||||||
|
// accept Interrupt signals for a graceful shutdown.
|
||||||
|
func TestStartupInterrupt(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("skipping test in short mode.")
|
||||||
|
}
|
||||||
|
|
||||||
|
prom := exec.Command(promPath, "-test.main", "--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 stoppedErr error
|
||||||
|
|
||||||
|
Loop:
|
||||||
|
for x := 0; x < 10; x++ {
|
||||||
|
// error=nil means prometheus has started so we can send the interrupt
|
||||||
|
// signal and wait for the graceful shutdown.
|
||||||
|
if _, err := http.Get("http://localhost:9090/graph"); err == nil {
|
||||||
|
startedOk = true
|
||||||
|
prom.Process.Signal(os.Interrupt)
|
||||||
|
select {
|
||||||
|
case stoppedErr = <-done:
|
||||||
|
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 {
|
||||||
|
t.Errorf("prometheus didn't shutdown gracefully after sending the Interrupt signal")
|
||||||
|
} else if stoppedErr != nil && stoppedErr.Error() != "signal: interrupt" { // TODO - find a better way to detect when the process didn't exit as expected!
|
||||||
|
t.Errorf("prometheus exited with an unexpected error:%v", stoppedErr)
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -248,7 +249,7 @@ func (p *queryLogTest) run(t *testing.T) {
|
||||||
testutil.Ok(t, prom.Start())
|
testutil.Ok(t, prom.Start())
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
prom.Process.Signal(os.Interrupt)
|
prom.Process.Kill()
|
||||||
prom.Wait()
|
prom.Wait()
|
||||||
}()
|
}()
|
||||||
testutil.Ok(t, p.waitForPrometheus())
|
testutil.Ok(t, p.waitForPrometheus())
|
||||||
|
@ -298,9 +299,15 @@ func (p *queryLogTest) run(t *testing.T) {
|
||||||
p.validateLastQuery(t, ql)
|
p.validateLastQuery(t, ql)
|
||||||
qc = len(ql)
|
qc = len(ql)
|
||||||
|
|
||||||
|
// The last part of the test can not succeed on Windows because you can't
|
||||||
|
// rename files used by other processes.
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
return
|
||||||
|
}
|
||||||
// Move the file, Prometheus should still write to the old file.
|
// Move the file, Prometheus should still write to the old file.
|
||||||
newFile, err := ioutil.TempFile("", "newLoc")
|
newFile, err := ioutil.TempFile("", "newLoc")
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
testutil.Ok(t, newFile.Close())
|
||||||
defer os.Remove(newFile.Name())
|
defer os.Remove(newFile.Name())
|
||||||
testutil.Ok(t, os.Rename(queryLogFile.Name(), newFile.Name()))
|
testutil.Ok(t, os.Rename(queryLogFile.Name(), newFile.Name()))
|
||||||
ql = readQueryLog(t, newFile.Name())
|
ql = readQueryLog(t, newFile.Name())
|
||||||
|
|
|
@ -80,6 +80,7 @@ func (t *testRunner) copyFileTo(src string, name string) string {
|
||||||
_, err = io.Copy(newf, f)
|
_, err = io.Copy(newf, f)
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
testutil.Ok(t, f.Close())
|
testutil.Ok(t, f.Close())
|
||||||
|
testutil.Ok(t, newf.Close())
|
||||||
|
|
||||||
dst := filepath.Join(t.dir, name)
|
dst := filepath.Join(t.dir, name)
|
||||||
err = os.Rename(newf.Name(), dst)
|
err = os.Rename(newf.Name(), dst)
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
package logging
|
package logging
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
"github.com/prometheus/prometheus/util/testutil"
|
||||||
|
@ -32,7 +32,8 @@ func TestJSONFileLogger_basic(t *testing.T) {
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
testutil.Assert(t, l != nil, "logger can't be nil")
|
testutil.Assert(t, l != nil, "logger can't be nil")
|
||||||
|
|
||||||
l.Log("test", "yes")
|
err = l.Log("test", "yes")
|
||||||
|
testutil.Ok(t, err)
|
||||||
r := make([]byte, 1024)
|
r := make([]byte, 1024)
|
||||||
_, err = f.Read(r)
|
_, err = f.Read(r)
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
@ -44,5 +45,40 @@ func TestJSONFileLogger_basic(t *testing.T) {
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
err = l.file.Close()
|
err = l.file.Close()
|
||||||
testutil.Assert(t, errors.Is(err, os.ErrClosed), "file was not closed")
|
testutil.NotOk(t, err)
|
||||||
|
testutil.Assert(t, strings.HasSuffix(err.Error(), os.ErrClosed.Error()), "file not closed")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJSONFileLogger_parallel(t *testing.T) {
|
||||||
|
f, err := ioutil.TempFile("", "")
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
l, err := NewJSONFileLogger(f.Name())
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
testutil.Assert(t, l != nil, "logger can't be nil")
|
||||||
|
|
||||||
|
err = l.Log("test", "yes")
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
|
l2, err := NewJSONFileLogger(f.Name())
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
testutil.Assert(t, l != nil, "logger can't be nil")
|
||||||
|
|
||||||
|
err = l2.Log("test", "yes")
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
|
err = l.Close()
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
|
err = l.file.Close()
|
||||||
|
testutil.NotOk(t, err)
|
||||||
|
testutil.Assert(t, strings.HasSuffix(err.Error(), os.ErrClosed.Error()), "file not closed")
|
||||||
|
|
||||||
|
err = l2.Close()
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
|
err = l2.file.Close()
|
||||||
|
testutil.NotOk(t, err)
|
||||||
|
testutil.Assert(t, strings.HasSuffix(err.Error(), os.ErrClosed.Error()), "file not closed")
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ package promql
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -106,7 +107,9 @@ func TestQueryTimeout(t *testing.T) {
|
||||||
testutil.NotOk(t, res.Err, "expected timeout error but got none")
|
testutil.NotOk(t, res.Err, "expected timeout error but got none")
|
||||||
|
|
||||||
var e ErrQueryTimeout
|
var e ErrQueryTimeout
|
||||||
testutil.Assert(t, errors.As(res.Err, &e), "expected timeout error but got: %s", res.Err)
|
// TODO: when circleci-windows moves to go 1.13:
|
||||||
|
// testutil.Assert(t, errors.As(res.Err, &e), "expected timeout error but got: %s", res.Err)
|
||||||
|
testutil.Assert(t, strings.HasPrefix(res.Err.Error(), e.Error()), "expected timeout error but got: %s", res.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const errQueryCanceled = ErrQueryCanceled("test statement execution")
|
const errQueryCanceled = ErrQueryCanceled("test statement execution")
|
||||||
|
@ -496,7 +499,9 @@ func TestEngineShutdown(t *testing.T) {
|
||||||
testutil.NotOk(t, res2.Err, "expected error on querying with canceled context but got none")
|
testutil.NotOk(t, res2.Err, "expected error on querying with canceled context but got none")
|
||||||
|
|
||||||
var e ErrQueryCanceled
|
var e ErrQueryCanceled
|
||||||
testutil.Assert(t, errors.As(res2.Err, &e), "expected cancellation error but got: %s", res2.Err)
|
// TODO: when circleci-windows moves to go 1.13:
|
||||||
|
// testutil.Assert(t, errors.As(res2.Err, &e), "expected cancellation error but got: %s", res2.Err)
|
||||||
|
testutil.Assert(t, strings.HasPrefix(res2.Err.Error(), e.Error()), "expected cancellation error but got: %s", res2.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEngineEvalStmtTimestamps(t *testing.T) {
|
func TestEngineEvalStmtTimestamps(t *testing.T) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ import (
|
||||||
// was running (the time between Start() and Stop()).
|
// was running (the time between Start() and Stop()).
|
||||||
type Timer struct {
|
type Timer struct {
|
||||||
name fmt.Stringer
|
name fmt.Stringer
|
||||||
created time.Time
|
created int
|
||||||
start time.Time
|
start time.Time
|
||||||
duration time.Duration
|
duration time.Duration
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ func (t *TimerGroup) GetTimer(name fmt.Stringer) *Timer {
|
||||||
}
|
}
|
||||||
timer := &Timer{
|
timer := &Timer{
|
||||||
name: name,
|
name: name,
|
||||||
created: time.Now(),
|
created: len(t.timers),
|
||||||
}
|
}
|
||||||
t.timers[name] = timer
|
t.timers[name] = timer
|
||||||
return timer
|
return timer
|
||||||
|
@ -95,7 +95,7 @@ func (t Timers) Swap(i, j int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s byCreationTimeSorter) Less(i, j int) bool {
|
func (s byCreationTimeSorter) Less(i, j int) bool {
|
||||||
return s.Timers[i].created.Before(s.Timers[j].created)
|
return s.Timers[i].created < s.Timers[j].created
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a string representation of a TimerGroup.
|
// Return a string representation of a TimerGroup.
|
||||||
|
|
|
@ -57,7 +57,7 @@ func NotOk(tb TB, err error, a ...interface{}) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if len(a) != 0 {
|
if len(a) != 0 {
|
||||||
format := a[0].(string)
|
format := a[0].(string)
|
||||||
tb.Fatalf("\033[31m"+format+": expected error, got none\033[39m", a...)
|
tb.Fatalf("\033[31m"+format+": expected error, got none\033[39m", a[1:]...)
|
||||||
}
|
}
|
||||||
tb.Fatalf("\033[31mexpected error, got none\033[39m")
|
tb.Fatalf("\033[31mexpected error, got none\033[39m")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue