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) }