Skip to content

Commit

Permalink
Add tests for api handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
databus23 committed Nov 10, 2017
1 parent 6ffe0f4 commit 8b32417
Show file tree
Hide file tree
Showing 56 changed files with 9,809 additions and 49 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ _output
_scratch
.git
_output
Docker*
1 change: 1 addition & 0 deletions Dockerfile.kubernikus-binaries
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ RUN apk add --no-cache make
COPY . .
ARG VERSION
RUN make all
RUN go test -v ./... | grep -v 'no test files'

FROM scratch as kubernikus-binaries
COPY --from=builder /go/src/github.com/sapcc/kubernikus/bin/linux/* /
13 changes: 11 additions & 2 deletions cmd/apiserver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ import (

"github.com/spf13/pflag"

apipkg "github.com/sapcc/kubernikus/pkg/api"
"github.com/sapcc/kubernikus/pkg/api/rest"
"github.com/sapcc/kubernikus/pkg/api/rest/operations"
"github.com/sapcc/kubernikus/pkg/api/spec"
)

// This file was generated by the swagger tool.
// Make sure not to overwrite this file after you generated it because all your edits would be lost!
var namespace string

func init() {
pflag.StringVar(&namespace, "namespace", "kubernikus", "Namespace the apiserver should work in")
}

func main() {

Expand Down Expand Up @@ -46,6 +50,11 @@ func main() {
//goflag.CommandLine.Parse([]string{}) //https://github.com/kubernetes/kubernetes/issues/17162

api := operations.NewKubernikusAPI(swaggerSpec)

rt := &apipkg.Runtime{Namespace: namespace}
rt.Kubernikus, rt.Kubernetes = rest.NewKubeClients()
rest.Configure(api, rt)

// get server with flag values filled out
server = rest.NewServer(api)

Expand Down
14 changes: 11 additions & 3 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
package: github.com/sapcc/kubernikus
testImport:
- package: github.com/stretchr/testify
version: ^1.1.0
subpackages:
- assert
import:
- package: github.com/spf13/cobra
subpackages:
Expand Down
113 changes: 113 additions & 0 deletions pkg/api/rest/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package rest

import (
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
"testing"

errors "github.com/go-openapi/errors"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

apipkg "github.com/sapcc/kubernikus/pkg/api"
"github.com/sapcc/kubernikus/pkg/api/models"
"github.com/sapcc/kubernikus/pkg/api/rest/operations"
"github.com/sapcc/kubernikus/pkg/api/spec"
"github.com/sapcc/kubernikus/pkg/generated/clientset/fake"
)

const (
NAMESPACE = "test"
TOKEN = "abc123"
ACCOUNT = "testaccount"
)

func mockAuth(token string) (*models.Principal, error) {
if token != TOKEN {
return nil, errors.New(401, "auth failed")
}
return &models.Principal{
AuthURL: "http://identity.test/v3",
ID: "test",
Name: "Test Mc Dougle",
Domain: "TestDomain",
Account: ACCOUNT,
Roles: []string{"member", "os:kubernikus_admin"},
}, nil

}

func createTestHandler(t *testing.T) (http.Handler, *apipkg.Runtime) {
swaggerSpec, err := spec.Spec()
if err != nil {
t.Fatal(err)
}
api := operations.NewKubernikusAPI(swaggerSpec)
rt := &apipkg.Runtime{
Namespace: NAMESPACE,
Kubernikus: fake.NewSimpleClientset(),
}
Configure(api, rt)
api.KeystoneAuth = mockAuth
return configureAPI(api), rt

}

func createRequest(method, path, body string) *http.Request {
var buf io.Reader
if body != "" {
buf = strings.NewReader(body)
}
req := httptest.NewRequest(method, path, buf)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Auth-Token", TOKEN)
return req
}
func result(handler http.Handler, req *http.Request) (int, http.Header, []byte) {
rec := httptest.NewRecorder()
handler.ServeHTTP(rec, req)
response := rec.Result()
body, _ := ioutil.ReadAll(response.Body)
return response.StatusCode, response.Header, body

}

func TestCreateCluster(t *testing.T) {
handler, rt := createTestHandler(t)
req := createRequest("POST", "/api/v1/clusters", `{"name": "nase"}`)
_, _, body := result(handler, req)

_, err := rt.Kubernikus.KubernikusV1().Klusters(rt.Namespace).Get(fmt.Sprintf("%s-%s", "nase", ACCOUNT), metav1.GetOptions{})
assert.NoError(t, err, "resource not persisted")

var kluster models.Kluster
assert.NoError(t, kluster.UnmarshalBinary(body), "Failed to parse response")
assert.Equal(t, "nase", kluster.Name)
assert.Equal(t, "nase", kluster.Spec.Name)
assert.Equal(t, models.KlusterPhasePending, kluster.Status.Phase)

//ensure authentication
req = createRequest("POST", "/api/v1/clusters", `{"name": "nase2"}`)
req.Header.Del("X-Auth-Token")
code, _, body := result(handler, req)
if code != 401 {
t.Errorf("Expected auth failure. Got status %d, body: %s", code, body)
}

}

func TestClusterShow(t *testing.T) {
//kluster := kubernikusv1.Kluster{
// ObjectMeta: metav1.ObjectMeta{
// Name: "nase-testaccount",
// Namespace: rt.Namespace,
// Labels: map[string]string{"account": "testaccount"},
// },
// Spec: models.KlusterSpec{Name: "nase"},
//}

}
48 changes: 48 additions & 0 deletions pkg/api/rest/configure.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package rest

import (
"fmt"

"github.com/go-openapi/errors"
runtime "github.com/go-openapi/runtime"
"github.com/golang/glog"

apipkg "github.com/sapcc/kubernikus/pkg/api"
"github.com/sapcc/kubernikus/pkg/api/handlers"
"github.com/sapcc/kubernikus/pkg/api/rest/operations"
)

func Configure(api *operations.KubernikusAPI, rt *apipkg.Runtime) {
// configure the api here
api.ServeError = errors.ServeError

// Set your custom logger if needed. Default one is log.Printf
// Expected interface func(string, ...interface{})
//
// Example:
api.Logger = func(msg string, args ...interface{}) {
glog.InfoDepth(2, fmt.Sprintf(msg, args...))
}

api.JSONConsumer = runtime.JSONConsumer()
api.JSONProducer = runtime.JSONProducer()

// Applies when the "x-auth-token" header is set
api.KeystoneAuth = keystoneAuth()

// Set your custom authorizer if needed. Default one is security.Authorized()
// api.APIAuthorizer = security.Authorized()

api.InfoHandler = handlers.NewInfo(rt)
api.ListAPIVersionsHandler = handlers.NewListAPIVersions(rt)
api.ListClustersHandler = handlers.NewListClusters(rt)
api.CreateClusterHandler = handlers.NewCreateCluster(rt)
api.ShowClusterHandler = handlers.NewShowCluster(rt)
api.TerminateClusterHandler = handlers.NewTerminateCluster(rt)
api.UpdateClusterHandler = handlers.NewUpdateCluster(rt)
api.GetClusterCredentialsHandler = handlers.NewGetClusterCredentials(rt)
api.GetClusterInfoHandler = handlers.NewGetClusterInfo(rt)

api.ServerShutdown = func() {}

}
39 changes: 0 additions & 39 deletions pkg/api/rest/configure_kubernikus.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,16 @@ package rest

import (
"crypto/tls"
"fmt"
"net/http"
"os"
"strings"

errors "github.com/go-openapi/errors"
runtime "github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/golang/glog"
gmiddleware "github.com/gorilla/handlers"
"github.com/justinas/alice"
"github.com/rs/cors"
graceful "github.com/tylerb/graceful"

apipkg "github.com/sapcc/kubernikus/pkg/api"
"github.com/sapcc/kubernikus/pkg/api/handlers"
"github.com/sapcc/kubernikus/pkg/api/rest/operations"
)
Expand All @@ -30,40 +25,6 @@ func configureFlags(api *operations.KubernikusAPI) {
}

func configureAPI(api *operations.KubernikusAPI) http.Handler {
// configure the api here
api.ServeError = errors.ServeError

// Set your custom logger if needed. Default one is log.Printf
// Expected interface func(string, ...interface{})
//
// Example:
api.Logger = func(msg string, args ...interface{}) {
glog.InfoDepth(2, fmt.Sprintf(msg, args...))
}

api.JSONConsumer = runtime.JSONConsumer()
api.JSONProducer = runtime.JSONProducer()

// Applies when the "x-auth-token" header is set
api.KeystoneAuth = keystoneAuth()

// Set your custom authorizer if needed. Default one is security.Authorized()
// api.APIAuthorizer = security.Authorized()

rt := &apipkg.Runtime{Namespace: namespace}
rt.Kubernikus, rt.Kubernetes = NewKubeClients()

api.InfoHandler = handlers.NewInfo(rt)
api.ListAPIVersionsHandler = handlers.NewListAPIVersions(rt)
api.ListClustersHandler = handlers.NewListClusters(rt)
api.CreateClusterHandler = handlers.NewCreateCluster(rt)
api.ShowClusterHandler = handlers.NewShowCluster(rt)
api.TerminateClusterHandler = handlers.NewTerminateCluster(rt)
api.UpdateClusterHandler = handlers.NewUpdateCluster(rt)
api.GetClusterCredentialsHandler = handlers.NewGetClusterCredentials(rt)
api.GetClusterInfoHandler = handlers.NewGetClusterInfo(rt)

api.ServerShutdown = func() {}

return setupGlobalMiddleware(api.Serve(setupMiddlewares))
}
Expand Down
2 changes: 0 additions & 2 deletions pkg/api/rest/kubeclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ import (
)

var kubeconfig string
var namespace string
var context string

func init() {
pflag.StringVar(&kubeconfig, "kubeconfig", "", "Path to kubeconfig file with authorization information")
pflag.StringVar(&context, "context", "", "Override context")
pflag.StringVar(&namespace, "namespace", "kubernikus", "Namespace the apiserver should work in")
}

func NewKubeClients() (kubernikus_clientset.Interface, kubernetes_clientset.Interface) {
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/kubernikus/v1/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// +k8s:deepcopy-gen=package,register
//+groupName=kubernikus.sap.cc
package v1
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ type FakeKlusters struct {
ns string
}

var klustersResource = schema.GroupVersionResource{Group: "kubernikus", Version: "v1", Resource: "klusters"}
var klustersResource = schema.GroupVersionResource{Group: "kubernikus.sap.cc", Version: "v1", Resource: "klusters"}

var klustersKind = schema.GroupVersionKind{Group: "kubernikus", Version: "v1", Kind: "Kluster"}
var klustersKind = schema.GroupVersionKind{Group: "kubernikus.sap.cc", Version: "v1", Kind: "Kluster"}

// Get takes name of the kluster, and returns the corresponding kluster object, and an error if there is any.
func (c *FakeKlusters) Get(name string, options v1.GetOptions) (result *kubernikus_v1.Kluster, err error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type KubernikusV1Interface interface {
KlustersGetter
}

// KubernikusV1Client is used to interact with features provided by the kubernikus group.
// KubernikusV1Client is used to interact with features provided by the kubernikus.sap.cc group.
type KubernikusV1Client struct {
restClient rest.Interface
}
Expand Down
5 changes: 5 additions & 0 deletions vendor/github.com/pmezard/go-difflib/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions vendor/github.com/pmezard/go-difflib/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8b32417

Please sign in to comment.