Skip to content

Commit

Permalink
chore: use terratest to build scaffold
Browse files Browse the repository at this point in the history
  • Loading branch information
tokers committed Dec 17, 2020
1 parent e75cb2e commit 0b07ca5
Show file tree
Hide file tree
Showing 13 changed files with 796 additions and 908 deletions.
11 changes: 6 additions & 5 deletions test/e2e/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ module github.com/api7/ingress-controller/test/e2e
go 1.14

require (
github.com/api7/ingress-controller v0.0.0-20201216014256-7be016730204
github.com/gavv/httpexpect/v2 v2.1.0
github.com/gxthrj/apisix-ingress-types v0.1.2
github.com/gorilla/websocket v1.4.2 // indirect
github.com/gruntwork-io/terratest v0.31.2
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/onsi/ginkgo v1.14.2
github.com/sergi/go-diff v1.1.0 // indirect
github.com/stretchr/testify v1.6.1
k8s.io/api v0.0.0-20190819141258-3544db3b9e44
k8s.io/apimachinery v0.0.0-20190817020851-f2f3a405f61d
k8s.io/client-go v0.0.0-20190819141724-e14f31a72a77
k8s.io/api v0.19.3
k8s.io/client-go v0.19.3
)
499 changes: 366 additions & 133 deletions test/e2e/go.sum

Large diffs are not rendered by default.

28 changes: 1 addition & 27 deletions test/e2e/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,4 @@ import (
_ "github.com/api7/ingress-controller/test/e2e/proxy"
)

func main() {
//defer ginkgo.GinkgoRecover()
// FIXME Remove these lines after we creating the first e2e test case.
//opts := &scaffold.Options{
// Name: "sample",
// Kubeconfig: "/Users/alex/.kube/config",
// ETCDImage: "bitnami/etcd:3.4.14-debian-10-r0",
// IngressAPISIXImage: "viewking/apisix-ingress-controller:dev",
// APISIXImage: "apache/apisix:latest",
// HTTPBINImage: "kennethreitz/httpbin",
// IngressAPISIXConfig: &config.Config{
// LogLevel: "info",
// LogOutput: "stdout",
// HTTPListen: ":8080",
// APISIX: config.APISIXConfig{
// // We don't use FQDN since we don't know the namespace in advance.
// BaseURL: "https://apisix-service-e2e-test:9180/apisix",
// },
// },
// APISIXConfigPath: "/Users/alex/Workstation/tokers/apisix-ingress-controller/test/e2e/testdata/apisix-gw-config.yaml",
// APISIXDefaultConfigPath: "/Users/alex/Workstation/tokers/apisix-ingress-controller/test/e2e/testdata/apisix-gw-config-default.yaml",
//}
//s := scaffold.NewScaffold(opts)
//assert.NotNil(ginkgo.GinkgoT(), s, "creating scaffold")
//s.BeforeEach()
//s.AfterEach()
}
func main() {}
3 changes: 2 additions & 1 deletion test/e2e/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
package main

import (
"github.com/onsi/ginkgo"
"testing"

"github.com/onsi/ginkgo"
)

func TestRunE2E(t *testing.T) {
Expand Down
42 changes: 2 additions & 40 deletions test/e2e/proxy/sanity.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,52 +15,14 @@
package proxy

import (
"encoding/json"
"time"

"github.com/onsi/ginkgo"
"github.com/stretchr/testify/assert"

"github.com/api7/ingress-controller/test/e2e/scaffold"
)

var _ = ginkgo.Describe("proxy-sanity", func() {
s := scaffold.NewDefaultScaffold()

ginkgo.It("/ip should return your ip", func() {
// Wait all containers ready.
// FIXME Remove this limitation.
time.Sleep(15)

svcName, svcPorts := s.DefaultHTTPBackend()
s.CreateApisixRoute(&scaffold.ApisixRouteDesc{
Name: "ingress-apisix-e2e-test-proxy-sanity",
Host: "foo.com",
Paths: []scaffold.ApisixRoutePath{
{
Path: "/ip",
Backend: scaffold.ApisixRouteBackend{
ServiceName: svcName,
ServicePort: int64(svcPorts[0]),
},
},
},
})
time.Sleep(time.Second)

body := s.NewHTTPClient().
GET("/ip").
WithHeader("Host", "foo.com").
Expect().
Status(200).
Body().
Raw()
_ = scaffold.NewDefaultScaffold()

var resp struct {
IP string `json:"ip"`
}
err := json.Unmarshal([]byte(body), &resp)
assert.Nil(ginkgo.GinkgoT(), err)
assert.Equal(ginkgo.GinkgoT(), resp.IP, "127.0.0.1")
ginkgo.It("make sure the environment is OK", func() {
})
})
229 changes: 126 additions & 103 deletions test/e2e/scaffold/apisix.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,130 +15,153 @@
package scaffold

import (
"io/ioutil"
"net/url"
"errors"
"fmt"
"strings"
"text/template"

appsv1 "k8s.io/api/apps/v1"
"github.com/gruntwork-io/terratest/modules/k8s"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)

const (
_apisixConfigConfigMap = "apisix-gw-config.yaml"
var (
_apisixConfigMap = `
kind: ConfigMap
apiVersion: v1
metadata:
name: apisix-gw-config.yaml
data:
config-default.yaml: |
%s
config.yaml: |
%s
`
_apisixDeployment = `
apiVersion: apps/v1
kind: Deployment
metadata:
name: apisix-deployment-e2e-test
spec:
replicas: 1
selector:
matchLabels:
app: apisix-deployment-e2e-test
strategy:
rollingUpdate:
maxSurge: 50%
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app: apisix-deployment-e2e-test
spec:
terminationGracePeriodSeconds: 0
containers:
- livenessProbe:
failureThreshold: 3
initialDelaySeconds: 2
periodSeconds: 5
successThreshold: 1
tcpSocket:
port: 9080
timeoutSeconds: 2
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 2
periodSeconds: 5
successThreshold: 1
tcpSocket:
port: 9080
timeoutSeconds: 2
image: "apache/apisix:latest"
imagePullPolicy: IfNotPresent
name: apisix-deployment-e2e-test
ports:
- containerPort: 9080
name: "http"
protocol: "TCP"
- containerPort: 9180
name: "http-admin"
protocol: "TCP"
volumeMounts:
- mountPath: /usr/local/apisix/conf/config.yaml
name: apisix-config-yaml-configmap
subPath: config.yaml
- mountPath: /usr/local/apisix/conf/config-default.yaml
name: apisix-config-yaml-configmap
subPath: config-default.yaml
volumes:
- configMap:
name: apisix-gw-config.yaml
name: apisix-config-yaml-configmap
`
_apisixService = `
apiVersion: v1
kind: Service
metadata:
name: apisix-service-e2e-test
spec:
selector:
app: apisix-deployment-e2e-test
ports:
- name: http
port: 9080
protocol: TCP
targetPort: 9080
- name: http-admin
port: 9180
protocol: TCP
targetPort: 9180
type: NodePort
`
)

func (s *Scaffold) apisixServiceURL() string {
// TODO remove these hacks after we create NodePort serivce.
// For now, we forward service port to local.
u := url.URL{
Scheme: "http",
Host: "127.0.0.1",
func (s *Scaffold) apisixServiceURL() (string, error) {
if len(s.nodes) == 0 {
return "", errors.New("no available node")
}
return u.String()
}

func (s *Scaffold) readAPISIXConfigFromFile(path string) (string, error) {
data, err := ioutil.ReadFile(path)
if err != nil {
return "", err
}

var buf strings.Builder
t := template.Must(template.New(path).Parse(string(data)))
if err := t.Execute(&buf, s); err != nil {
return "", err
for _, port := range s.apisixService.Spec.Ports {
if port.Name == "http" {
// Basically we use minikube, so just use the first node.
return fmt.Sprintf("http://%s:%d", s.nodes[0], port.NodePort), nil
}
}
return buf.String(), nil
return "", errors.New("no http port in apisix service")
}

func (s *Scaffold) newAPISIX() (*appsv1.Deployment, *corev1.Service, error) {
data, err := s.readAPISIXConfigFromFile(s.opts.APISIXConfigPath)
func (s *Scaffold) newAPISIX() (*corev1.Service, error) {
defaultData, err := s.renderConfig(s.opts.APISIXDefaultConfigPath)
if err != nil {
return nil, nil, err
return nil, err
}
defaultData, err := s.readAPISIXConfigFromFile(s.opts.APISIXDefaultConfigPath)
data, err := s.renderConfig(s.opts.APISIXConfigPath)
if err != nil {
return nil, nil, err
return nil, err
}
cmData := map[string]string{
"config.yaml": data,
"config-default.yaml": defaultData,
defaultData = indent(defaultData)
data = indent(data)
configData := fmt.Sprintf(_apisixConfigMap, defaultData, data)
if err := k8s.KubectlApplyFromStringE(s.t, s.kubectlOptions, configData); err != nil {
return nil, err
}
if err := createConfigMap(s.clientset, _apisixConfigConfigMap, s.namespace, cmData); err != nil {
return nil, nil, err
if err := k8s.KubectlApplyFromStringE(s.t, s.kubectlOptions, _apisixDeployment); err != nil {
return nil, err
}
desc := &deploymentDesc{
name: "apisix-deployment-e2e-test",
namespace: s.namespace,
image: s.opts.APISIXImage,
ports: []int32{9080, 9180},
replica: 1,
probe: &corev1.Probe{
Handler: corev1.Handler{
TCPSocket: &corev1.TCPSocketAction{
Port: intstr.FromInt(9080),
},
},
InitialDelaySeconds: 2,
TimeoutSeconds: 2,
PeriodSeconds: 5,
},
volumeMounts: []corev1.VolumeMount{
{
Name: "apisix-config-yaml-configmap",
MountPath: "/usr/local/apisix/conf/config.yaml",
SubPath: "config.yaml",
},
{
Name: "apisix-config-yaml-configmap",
MountPath: "/usr/local/apisix/conf/config-default.yaml",
SubPath: "config-default.yaml",
},
},
volumes: []corev1.Volume{
{
Name: "apisix-config-yaml-configmap",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: _apisixConfigConfigMap,
},
},
},
},
},
if err := k8s.KubectlApplyFromStringE(s.t, s.kubectlOptions, _apisixService); err != nil {
return nil, err
}

d, err := ensureDeployment(s.clientset, newDeployment(desc))
svc, err := k8s.GetServiceE(s.t, s.kubectlOptions, "apisix-service-e2e-test")
if err != nil {
return nil, nil, err
}

svcDesc := &serviceDesc{
name: "apisix-service-e2e-test",
namespace: s.namespace,
selector: d.Spec.Selector.MatchLabels,
ports: []corev1.ServicePort{
{
Protocol: corev1.ProtocolTCP,
Name: "apisix-dp",
Port: 9080,
TargetPort: intstr.FromInt(9080),
},
{
Protocol: corev1.ProtocolTCP,
Name: "apisix-cp",
Port: 9180,
TargetPort: intstr.FromInt(9180),
},
},
return nil, err
}
return svc, nil
}

svc, err := ensureService(s.clientset, newService(svcDesc))
if err != nil {
return nil, nil, err
func indent(data string) string {
list := strings.Split(data, "\n")
for i := 0; i < len(list); i++ {
list[i] = " " + list[i]
}
return d, svc, nil
return strings.Join(list, "\n")
}
Loading

0 comments on commit 0b07ca5

Please sign in to comment.