wg-portal/internal/common/healthcheck/healthcheck_test.go

244 lines
5.6 KiB
Go
Raw Normal View History

2023-10-26 10:31:29 +02:00
// source taken from https://git.prolicht.digital/golib/healthcheck/-/blob/master/healthcheck_test.go
package healthcheck
import (
"context"
"net/http"
"os"
"reflect"
"testing"
"time"
)
func TestNew(t *testing.T) {
type args struct {
opts []Option
}
tests := []struct {
name string
args args
want *service
}{
{
name: "Test Plain",
args: args{},
want: &service{
listenAddress: ":11223",
checkFunc: nil, // we cannot compare the check function
},
},
{
name: "Test With Empty Options",
args: args{
opts: []Option{},
},
want: &service{
listenAddress: ":11223",
checkFunc: nil, // we cannot compare the check function
},
},
{
name: "Test With Options",
args: args{
opts: []Option{ListenOn(":123456")},
},
want: &service{
listenAddress: ":123456",
checkFunc: nil, // we cannot compare the check function
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := New(tt.args.opts...)
got.checkFunc = nil
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("New() = %v, want %v", got, tt.want)
}
})
}
}
func TestListenOn(t *testing.T) {
type args struct {
addr string
}
tests := []struct {
name string
args args
want *service
}{
{
name: "Test Port Only",
args: args{
addr: ":8080",
},
want: &service{
listenAddress: ":8080",
checkFunc: nil, // cannot deeply compare check func,
},
},
{
name: "Test Addr:Port Only",
args: args{
addr: "localhost:8080",
},
want: &service{
listenAddress: "localhost:8080",
checkFunc: nil, // cannot deeply compare check func,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := New(ListenOn(tt.args.addr))
got.checkFunc = nil
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("ListenOn() = %v, want %v", got, tt.want)
}
})
}
}
func TestListenOnEnv(t *testing.T) {
_ = os.Setenv("HC_LISTEN_ADDR", "")
hc := New(ListenOnFromEnv())
if hc.listenAddress != New().listenAddress {
t.Errorf("ListenOnFromEnv() = %v, want %v", hc.listenAddress, New().listenAddress)
}
want := ":1337"
_ = os.Setenv("HC_LISTEN_ADDR", want)
hc = New(ListenOnFromEnv())
if hc.listenAddress != want {
t.Errorf("ListenOnFromEnv() = %v, want %v", hc.listenAddress, want)
}
hc = New() // check that the env var has no effect
if hc.listenAddress != New().listenAddress {
t.Errorf("ListenOnFromEnv() = %v, want %v", hc.listenAddress, New().listenAddress)
}
want = ":1338"
_ = os.Setenv("SOME_RANDOM_ENV_VAR", want)
hc = New(ListenOnFromEnv("SOME_RANDOM_ENV_VAR"))
if hc.listenAddress != want {
t.Errorf("ListenOnFromEnv() = %v, want %v", hc.listenAddress, want)
}
hc = New(ListenOnFromEnv("SOME_RANDOM_ENV_VAR", "ignored", "ignored 2"))
if hc.listenAddress != want {
t.Errorf("ListenOnFromEnv() = %v, want %v", hc.listenAddress, want)
}
}
func TestWithCustomCheck(t *testing.T) {
customFnc := func() int { return 123 }
type args struct {
fnc func() int
}
tests := []struct {
name string
args args
want *service
wantFnc func() int
}{
{
name: "Test Custom Function",
args: args{
fnc: customFnc,
},
want: &service{
listenAddress: New().listenAddress,
checkFunc: nil, // cannot deeply compare check func,
},
wantFnc: customFnc,
},
{
name: "Test Nil Function",
args: args{
fnc: nil,
},
want: &service{
listenAddress: New().listenAddress,
checkFunc: nil, // cannot deeply compare check func,
},
wantFnc: New().checkFunc,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := New(WithCustomCheck(tt.args.fnc))
gotFnc := got.checkFunc
got.checkFunc = nil
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("WithContext() = %v, want %v", got, tt.want)
}
if reflect.ValueOf(gotFnc).Pointer() != reflect.ValueOf(tt.wantFnc).Pointer() {
t.Error("WithContext() function mismatch")
}
})
}
}
func Test_service_StartForeground(t *testing.T) {
runTime := 550 * time.Millisecond
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()
hc := New()
start := time.Now()
hc.StartForeground(ctx)
elapsed := time.Since(start)
// check if execution time is within +-10% of the runTime
if elapsed > (runTime+(runTime/10)) || elapsed < (runTime-(runTime/10)) {
t.Errorf("StartForeground() invalid execution time = %v, want %v", elapsed, runTime)
}
}
func Test_service_HTTPResponse(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()
hc := New()
hc.StartWithContext(ctx)
time.Sleep(200 * time.Millisecond) // ensure that web server is up and running
cl := http.Client{Timeout: time.Millisecond * 200}
req, _ := http.NewRequest("GET", "http://localhost:11223/health", nil)
resp, err := cl.Do(req)
if err != nil {
t.Errorf("http request failed: %v", err)
return
}
if resp.StatusCode != http.StatusOK {
t.Errorf("http request with wrong response code: %v, want %v", err, http.StatusOK)
}
<-ctx.Done() // wait for clean shutdown
}
func Test_service_CustomCheckResponse(t *testing.T) {
want := http.StatusExpectationFailed
hc := New(WithCustomCheck(func() int {
return want
}))
hc.Start()
time.Sleep(200 * time.Millisecond) // ensure that web server is up and running
cl := http.Client{Timeout: time.Millisecond * 200}
req, _ := http.NewRequest("GET", "http://localhost:11223/health", nil)
resp, err := cl.Do(req)
if err != nil {
t.Errorf("http request failed: %v", err)
return
}
if resp.StatusCode != want {
t.Errorf("http request with wrong response code: %v, want %v", err, want)
}
}