Refactoring of test scripts

This commit is contained in:
Manuel de Brito Fontes 2017-06-02 14:56:29 -04:00
parent 8db5788c34
commit 1bde95aba5
10 changed files with 304 additions and 18 deletions

View file

@ -38,8 +38,8 @@ test:
@go test -v -race -tags "$(BUILDTAGS) cgo" ${GO_LIST_FILES}
.PHONY: test-e2e
test-e2e: ginkgo
@go run hack/e2e.go -v --up --test --down
test-e2e:
@go run hack/e2e.go --verbose --up --test --down --files="hack/nginx-ingress-controller.yaml,hack/default-backend.yaml"
.PHONY: cover
cover:
@ -66,7 +66,3 @@ docker-build:
.PHONY: docker-push
docker-push:
make -C controllers/nginx push
.PHONY: ginkgo
ginkgo:
go get github.com/onsi/ginkgo/ginkgo

51
hack/default-backend.yaml Normal file
View file

@ -0,0 +1,51 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: default-http-backend
labels:
k8s-app: default-http-backend
namespace: kube-system
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: default-http-backend
spec:
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
# Any image is permissable as long as:
# 1. It serves a 404 page at /
# 2. It serves 200 on a /healthz endpoint
image: gcr.io/google_containers/defaultbackend:1.0
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
ports:
- containerPort: 8080
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi
---
apiVersion: v1
kind: Service
metadata:
name: default-http-backend
namespace: kube-system
labels:
k8s-app: default-http-backend
spec:
ports:
- port: 80
targetPort: 8080
selector:
k8s-app: default-http-backend

View file

@ -18,7 +18,7 @@ if [ ! -e ${KUBECTL} ]; then
fi
if [ ! -e ${MINIKUBE} ]; then
echo "kubectl binary is missing. downloading..."
echo "minikube binary is missing. downloading..."
curl -sSLo ${MINIKUBE} https://storage.googleapis.com/minikube/releases/v${MINIKUBE_VERSION}/minikube-linux-amd64
chmod +x ${MINIKUBE}
fi

View file

@ -1,3 +0,0 @@
#!/usr/bin/env bash
echo "running ginkgo"

3
hack/e2e-internal/run-e2e.sh Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
go test -v k8s.io/ingress/hack/... -tags -run ^TestIngressSuite$ --args --alsologtostderr --v=10

View file

@ -34,11 +34,12 @@ var (
build = flag.Bool("build", true, "Build the backends images indicated by the env var BACKENDS required to run e2e tests.")
up = flag.Bool("up", true, "Creates a kubernetes cluster using hyperkube (containerized kubelet).")
down = flag.Bool("down", true, "destroys the created cluster.")
test = flag.Bool("test", true, "Run Ginkgo tests.")
test = flag.Bool("test", true, "Run tests.")
dump = flag.String("dump", "", "If set, dump cluster logs to this location on test or cluster-up failure")
testArgs = flag.String("test-args", "", "Space-separated list of arguments to pass to Ginkgo test runner.")
testArgs = flag.String("test-args", "", "Space-separated list of arguments to pass to the test runner.")
deployment = flag.String("deployment", "bash", "up/down mechanism")
verbose = flag.Bool("v", false, "If true, print all command output.")
verbose = flag.Bool("verbose", false, "If true, print all command output.")
files = flag.String("files", "", "Path to a file/S descriptor that will create an Ingress controller")
)
func appendError(errs []error, err error) []error {
@ -139,6 +140,10 @@ func main() {
}
func run(deploy deployer) error {
if *files == "" {
return fmt.Errorf("missing required flag --files")
}
if *dump != "" {
defer writeXML(time.Now())
}
@ -172,7 +177,7 @@ func run(deploy deployer) error {
return fmt.Errorf("starting e2e cluster: %s", err)
}
if *dump != "" {
cmd := exec.Command("./cluster/kubectl.sh", "--match-server-version=false", "get", "nodes", "-oyaml")
cmd := exec.Command("./hack/e2e-internal/kubectl", "get", "nodes", "-oyaml")
b, err := cmd.CombinedOutput()
if *verbose {
log.Printf("kubectl get nodes:\n%s", string(b))
@ -187,6 +192,10 @@ func run(deploy deployer) error {
}
}
if err := deploy.SetupController(*files); err != nil {
errs = appendError(errs, err)
}
if *test {
if err := xmlWrap("IsUp", deploy.IsUp); err != nil {
errs = appendError(errs, err)
@ -226,6 +235,7 @@ type deployer interface {
Up() error
IsUp() error
SetupKubecfg() error
SetupController(p string) error
Down() error
}
@ -252,6 +262,18 @@ func (b bash) SetupKubecfg() error {
return nil
}
func (b bash) SetupController(p string) error {
files := strings.Split(p, ",")
for _, f := range files {
err := finishRunning("setup controller", exec.Command("./hack/e2e-internal/kubectl", "create", "-f", f))
if err != nil {
return err
}
}
return nil
}
func (b bash) Down() error {
return finishRunning("teardown", exec.Command("./hack/e2e-internal/e2e-down.sh"))
}
@ -262,10 +284,7 @@ func DumpClusterLogs(location string) error {
}
func Test() error {
if *testArgs == "" {
*testArgs = "--ginkgo.focus=\\[Feature:Ingress\\]"
}
return finishRunning("Ginkgo tests", exec.Command("./hack/e2e-internal/ginkgo-e2e.sh", strings.Fields(*testArgs)...))
return finishRunning("Ingress tests", exec.Command("./hack/e2e-internal/run-e2e.sh", strings.Fields(*testArgs)...))
}
func finishRunning(stepName string, cmd *exec.Cmd) error {

61
hack/e2e_types.go Normal file
View file

@ -0,0 +1,61 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations
*/
package main
import (
"time"
"k8s.io/client-go/pkg/api"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
)
// IngressTestCase defines a test case for Ingress
type IngressTestCase struct {
Name string `yaml:"name"`
Description string `yaml:"description"`
Pod *api.Pod `yaml:"pod"`
ReplicationController *api.ReplicationController `yaml:"replicationController"`
Deployment *extensions.Deployment `yaml:"deployment"`
Assert []*Assert `yaml:"tests"`
}
// Assert defines a verification over the
type Assert struct {
Name string `yaml:"name"`
Request Request `yaml:"request"`
Expect []*Expect `yaml:"expect"`
Timeout time.Duration `yaml:"timeout"`
}
// Request defines a HTTP/s request to be executed against an Ingress
type Request struct {
Method string `yaml:"method"`
URL string `yaml:"url"`
Query map[string]interface{} `yaml:"query"`
Form map[string]interface{} `yaml:"form"`
Body interface{} `yaml:"body"`
Headers map[string]string `yaml:"headers"`
}
// Expect defines the required conditions that must be true from a request response
type Expect struct {
Body []byte `yaml:"body"`
ContentType string `yaml:"contentType"`
Header []string `yaml:"header"`
HeaderAndValue map[string]string `yaml:"headerAndValue"`
Statuscode int `yaml:"statucDode"`
}

111
hack/ingress_test.go Normal file
View file

@ -0,0 +1,111 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations
*/
package main
import (
"fmt"
"os"
"path"
"path/filepath"
"strings"
"testing"
)
func TestIngressSuite(t *testing.T) {
pwd, _ := os.Getwd()
filepath.Walk(path.Join(pwd, "/suite"),
func(path string, info os.FileInfo, err error) error {
if strings.HasSuffix(path, ".yaml") {
t.Log(path)
runTestCase(path, t)
}
return nil
})
}
func runTestCase(rawtc string, t *testing.T) {
tc, err := parseTestCase(rawtc)
if err != nil {
t.Fatalf("unexpected error reading Ingress test case file %v: %v", rawtc, err)
}
t.Run(tc.Name, func(t *testing.T) {
t.Logf("starting deploy of requirements for test case '%v'", tc.Name)
err := tc.deploy()
if err != nil {
t.Fatalf("unexpected error in test case deploy process: %v", err)
}
if tc.Assert == nil {
t.Fatalf("test case %v does not contains tests", tc.Name)
}
for _, assert := range tc.Assert {
t.Logf("running assert %v", assert.Name)
}
err = tc.undeploy()
if err != nil {
t.Fatalf("unexpected error in test case deploy process: %v", err)
}
})
}
// parseTestCase parses a test case from a yaml file
func parseTestCase(p string) (IngressTestCase, error) {
return IngressTestCase{
Name: "basic test",
}, nil
}
// deploy creates the kubernetes object specified in the test case
func (tc IngressTestCase) deploy() error {
if tc.Pod != nil {
return nil
}
if tc.ReplicationController != nil {
return nil
}
if tc.Deployment != nil {
return nil
}
return fmt.Errorf("invalid deployment option. Please check the test case")
}
// undeploy removes the kubernetes object created by the test case
func (tc IngressTestCase) undeploy() error {
if tc.Pod != nil {
return nil
}
if tc.ReplicationController != nil {
return nil
}
if tc.Deployment != nil {
return nil
}
return nil
}
func deployIngressController() error {
return nil
}

View file

@ -0,0 +1,47 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress-controller
labels:
k8s-app: nginx-ingress-controller
namespace: kube-system
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: nginx-ingress-controller
spec:
terminationGracePeriodSeconds: 60
containers:
- image: gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.7
name: nginx-ingress-controller
readinessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
livenessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 1
ports:
- containerPort: 80
hostPort: 80
- containerPort: 443
hostPort: 443
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend

1
hack/suite/0001.yaml Normal file
View file

@ -0,0 +1 @@
-