Files
mesh/pkg/api/api_test.go
2022-01-10 09:58:21 +01:00

246 lines
5.7 KiB
Go

package api
import (
"net"
"net/http"
"net/http/httptest"
"os"
"testing"
"github.com/gorilla/mux"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/traefik/mesh/pkg/k8s"
"k8s.io/client-go/kubernetes/fake"
)
var localhost = "127.0.0.1"
func TestEnableReadiness(t *testing.T) {
log := logrus.New()
log.SetOutput(os.Stdout)
log.SetLevel(logrus.DebugLevel)
client := fake.NewSimpleClientset()
api, err := NewAPI(log, 9000, localhost, client, "foo")
require.NoError(t, err)
assert.Equal(t, false, api.readiness.Get().(bool))
api.SetReadiness(true)
assert.Equal(t, true, api.readiness.Get().(bool))
}
func TestGetReadiness(t *testing.T) {
testCases := []struct {
desc string
readiness bool
expectedStatusCode int
}{
{
desc: "ready",
readiness: true,
expectedStatusCode: http.StatusOK,
},
{
desc: "not ready",
readiness: false,
expectedStatusCode: http.StatusInternalServerError,
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
log := logrus.New()
log.SetOutput(os.Stdout)
log.SetLevel(logrus.DebugLevel)
client := fake.NewSimpleClientset()
api, err := NewAPI(log, 9000, localhost, client, "foo")
require.NoError(t, err)
api.readiness.Set(test.readiness)
res := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, "/api/status/readiness", nil)
if err != nil {
require.NoError(t, err)
return
}
api.getReadiness(res, req)
assert.Equal(t, test.expectedStatusCode, res.Code)
})
}
}
func TestGetCurrentConfiguration(t *testing.T) {
log := logrus.New()
log.SetOutput(os.Stdout)
log.SetLevel(logrus.DebugLevel)
client := fake.NewSimpleClientset()
api, err := NewAPI(log, 9000, localhost, client, "foo")
require.NoError(t, err)
api.configuration.Set("foo")
res := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, "/api/configuration/current", nil)
if err != nil {
require.NoError(t, err)
return
}
api.getCurrentConfiguration(res, req)
assert.Equal(t, "\"foo\"\n", res.Body.String())
}
func TestGetMeshNodes(t *testing.T) {
testCases := []struct {
desc string
mockFile string
expectedBody string
expectedStatusCode int
podError bool
}{
{
desc: "empty mesh node list",
mockFile: "getmeshnodes_empty.yaml",
expectedBody: "[]\n",
expectedStatusCode: http.StatusOK,
},
{
desc: "one item in mesh node list",
mockFile: "getmeshnodes_one_mesh_pod.yaml",
expectedBody: "[{\"Name\":\"mesh-pod-1\",\"IP\":\"10.4.3.2\",\"Ready\":true}]\n",
expectedStatusCode: http.StatusOK,
},
{
desc: "one item in mesh node list with non ready pod",
mockFile: "getmeshnodes_one_nonready_mesh_pod.yaml",
expectedBody: "[{\"Name\":\"mesh-pod-1\",\"IP\":\"10.4.19.1\",\"Ready\":false}]\n",
expectedStatusCode: http.StatusOK,
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
log := logrus.New()
log.SetOutput(os.Stdout)
log.SetLevel(logrus.DebugLevel)
clientMock := k8s.NewClientMock(test.mockFile)
api, err := NewAPI(log, 9000, localhost, clientMock.KubernetesClient(), "foo")
require.NoError(t, err)
res := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, "/api/status/nodes", nil)
if err != nil {
require.NoError(t, err)
return
}
api.getMeshNodes(res, req)
assert.Equal(t, test.expectedBody, res.Body.String())
assert.Equal(t, test.expectedStatusCode, res.Code)
})
}
}
func TestGetMeshNodeConfiguration(t *testing.T) {
testCases := []struct {
desc string
mockFile string
expectedBody string
expectedStatusCode int
podError bool
}{
{
desc: "simple mesh node configuration",
mockFile: "getmeshnodeconfiguration_simple.yaml",
expectedBody: "{test_configuration_json}",
expectedStatusCode: http.StatusOK,
},
{
desc: "pod not found",
mockFile: "getmeshnodeconfiguration_empty.yaml",
expectedBody: "\n",
expectedStatusCode: http.StatusNotFound,
},
}
apiServer := startTestAPIServer("8080", http.StatusOK, []byte("{test_configuration_json}"))
defer apiServer.Close()
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
log := logrus.New()
log.SetOutput(os.Stdout)
log.SetLevel(logrus.DebugLevel)
clientMock := k8s.NewClientMock(test.mockFile)
api, err := NewAPI(log, 9000, localhost, clientMock.KubernetesClient(), "foo")
require.NoError(t, err)
res := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, "/api/status/node/mesh-pod-1/configuration", nil)
if err != nil {
require.NoError(t, err)
return
}
// fake gorilla/mux vars
vars := map[string]string{
"node": "mesh-pod-1",
}
req = mux.SetURLVars(req, vars)
api.getMeshNodeConfiguration(res, req)
assert.Equal(t, test.expectedBody, res.Body.String())
assert.Equal(t, test.expectedStatusCode, res.Code)
})
}
}
func startTestAPIServer(port string, statusCode int, bodyData []byte) (ts *httptest.Server) {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(statusCode)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write(bodyData)
})
listener, err := net.Listen("tcp", "127.0.0.1:"+port)
if err != nil {
panic(err)
}
ts = &httptest.Server{
Listener: listener,
Config: &http.Server{Handler: handler},
}
ts.Start()
return ts
}