micro/test/webserver_test.go

157 lines
3.5 KiB
Go

package test
import (
"crypto/tls"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"os"
"testing"
"github.com/go-chi/chi/v5"
"github.com/go-chi/render"
"github.com/stretchr/testify/assert"
"scm.yoorie.de/go-lib/micro/web"
"scm.yoorie.de/go-lib/util"
)
var (
internalCount int
httpPort int
sslPort int
)
type MyData struct {
Message string `json:"message"`
Count int `json:"count"`
}
func MyTestEndpoint(w http.ResponseWriter, r *http.Request) {
internalCount++
render.JSON(w, r, &MyData{
Message: "A message",
Count: internalCount,
})
}
func CreateTestRouter() *chi.Mux {
router := chi.NewRouter()
router.Get("/myendpoint", MyTestEndpoint)
return router
}
// GetFreePort asks the kernel for a free open port that is ready to use.
func GetFreePort() (int, error) {
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
if err != nil {
return 0, err
}
l, err := net.ListenTCP("tcp", addr)
if err != nil {
return 0, err
}
defer l.Close()
return l.Addr().(*net.TCPAddr).Port, nil
}
func getServerURL(ssl bool, path string) string {
var scheme string
var port int
if ssl {
scheme = "https"
port = sslPort
} else {
scheme = "http"
port = httpPort
}
return util.JoiningSlash(fmt.Sprintf("%s://localhost:%d", scheme, port), path)
}
func TestMain(m *testing.M) {
internalCount = 0
var err error
httpPort, err = GetFreePort()
if err != nil {
panic(err)
}
sslPort, err = GetFreePort()
if err != nil {
panic(err)
}
config := &web.WebServerConfiguration{
Port: httpPort,
SslPort: sslPort,
}
server, err := web.NewWebServer(config)
if err != nil {
panic(err)
}
server.Mount("/api", CreateTestRouter())
server.Start()
// Allow insecure calls to https
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
exitVal := m.Run()
server.Stop()
os.Exit(exitVal)
}
func TestReady(t *testing.T) {
uri := getServerURL(false, "/readyz")
resp, err := http.Get(uri)
assert.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
body, _ := io.ReadAll(resp.Body)
healthData := web.HealthData{}
err = json.Unmarshal(body, &healthData)
assert.Nil(t, err)
assert.Equal(t, "service is ready", healthData.Message)
assert.NotEmpty(t, healthData.LastChecked)
}
func TestReadySSL(t *testing.T) {
uri := getServerURL(true, "/health/readyz")
resp, err := http.Get(uri)
assert.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
body, _ := io.ReadAll(resp.Body)
healthData := web.HealthData{}
err = json.Unmarshal(body, &healthData)
assert.Nil(t, err)
assert.Equal(t, "service is ready", healthData.Message)
assert.NotEmpty(t, healthData.LastChecked)
}
func TestHealthy(t *testing.T) {
resp, err := http.Get(getServerURL(false, "/healthz"))
assert.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
body, _ := io.ReadAll(resp.Body)
healthData := web.HealthData{}
err = json.Unmarshal(body, &healthData)
assert.Nil(t, err)
assert.Equal(t, "service up and running", healthData.Message)
assert.NotEmpty(t, healthData.LastChecked)
}
func TestSslEndpoint(t *testing.T) {
uri := getServerURL(true, "/api/myendpoint")
resp, err := http.Get(uri)
assert.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
body, err := ioutil.ReadAll(resp.Body)
assert.Nil(t, err)
t.Logf("Body: %s", string(body))
myData := MyData{}
err = json.Unmarshal(body, &myData)
assert.Nil(t, err)
assert.NotNil(t, myData)
assert.Equal(t, "A message", myData.Message)
assert.Greater(t, myData.Count, 0)
}