Skip to content

Commit

Permalink
TEST: Add a sequential e2e test for map updates
Browse files Browse the repository at this point in the history
The test ensures that the controller update haproxy maps without
reloading haproxy.
  • Loading branch information
Mo3m3n committed May 23, 2022
1 parent 2f200cf commit ac2b49f
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 12 deletions.
48 changes: 38 additions & 10 deletions deploy/tests/e2e/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
"net"
"net/http"
"os"
"regexp"
"strconv"
"strings"

proxyproto "github.com/pires/go-proxyproto"
Expand Down Expand Up @@ -178,25 +180,52 @@ func ProxyProtoConn() (result []byte, err error) {
return ioutil.ReadAll(conn)
}

func GetGlobalHAProxyInfo() (info GlobalHAProxyInfo, err error) {
func runtimeCommand(command string) (result []byte, err error) {
kindURL := os.Getenv("KIND_URL")
if kindURL == "" {
kindURL = "127.0.0.1"
}
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", kindURL, STATS_PORT))
if err != nil {
return info, err
return
}
_, err = conn.Write([]byte("show info\n"))
_, err = conn.Write([]byte(command + "\n"))
if err != nil {
return info, err
return
}
reply := make([]byte, 1024)
_, err = conn.Read(reply)
result = make([]byte, 1024)
_, err = conn.Read(result)
conn.Close()
return
}

func GetHAProxyMapCount(mapName string) (count int, err error) {
var result []byte
result, err = runtimeCommand("show map")
if err != nil {
return info, err
return
}
scanner := bufio.NewScanner(bytes.NewReader(reply))
scanner := bufio.NewScanner(bytes.NewReader(result))
for scanner.Scan() {
line := scanner.Text()
if strings.Contains(line, mapName) {
r := regexp.MustCompile("entry_cnt=[0-9]*")
match := r.FindString(line)
nbr := strings.Split(match, "=")[1]
count, err = strconv.Atoi(nbr)
break
}
}
return
}

func GetGlobalHAProxyInfo() (info GlobalHAProxyInfo, err error) {
var result []byte
result, err = runtimeCommand("show info")
if err != nil {
return
}
scanner := bufio.NewScanner(bytes.NewReader(result))
for scanner.Scan() {
line := scanner.Text()
switch {
Expand All @@ -208,6 +237,5 @@ func GetGlobalHAProxyInfo() (info GlobalHAProxyInfo, err error) {
info.Pid = strings.Split(line, ": ")[1]
}
}
conn.Close()
return info, nil
return
}
5 changes: 4 additions & 1 deletion deploy/tests/e2e/endpoints/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ func (suite *EndpointsSuite) Test_HTTP_Reach() {
for i := 0; i < replicas*2; i++ {
func() {
res, cls, err := suite.client.Do()
suite.NoError(err)
if err != nil {
suite.NoError(err)
return
}
defer cls()
if res.StatusCode == 200 {
body, err := ioutil.ReadAll(res.Body)
Expand Down
5 changes: 4 additions & 1 deletion deploy/tests/e2e/endpoints/tcp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ func (suite *EndpointsSuite) Test_TCP_Reach() {
for i := 0; i < 4; i++ {
func() {
res, cls, err := suite.client.Do()
suite.NoError(err)
if err != nil {
suite.NoError(err)
return
}
defer cls()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
Expand Down
42 changes: 42 additions & 0 deletions deploy/tests/e2e/map-updates/config/deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
kind: Deployment
apiVersion: apps/v1
metadata:
name: http-echo
spec:
replicas: 1
selector:
matchLabels:
app: http-echo
template:
metadata:
labels:
app: http-echo
spec:
containers:
- name: http-echo
image: mo3m3n/http-echo:v1.0.0
args:
ports:
- name: http
containerPort: 8888
protocol: TCP
- name: https
containerPort: 8443
protocol: TCP
---
kind: Service
apiVersion: v1
metadata:
name: http-echo
spec:
ports:
- name: http
protocol: TCP
port: 80
targetPort: http
- name: https
protocol: TCP
port: 443
targetPort: https
selector:
app: http-echo
18 changes: 18 additions & 0 deletions deploy/tests/e2e/map-updates/config/ingress.yaml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: http-echo
annotations:
ingress.class: haproxy
spec:
rules:
- host: {{ .Host }}
http:
paths:
{{- range $path := .Paths}}
- path: /{{$path}}
backend:
serviceName: http-echo
servicePort: http
{{- end}}
65 changes: 65 additions & 0 deletions deploy/tests/e2e/map-updates/suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright 2019 HAProxy Technologies LLC
//
// 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 under the License.

//go:build e2e_sequential

package mapupdate

import (
"testing"

"github.com/stretchr/testify/suite"

"github.com/haproxytech/kubernetes-ingress/deploy/tests/e2e"
)

type MapUpdateSuite struct {
suite.Suite
test e2e.Test
client *e2e.Client
tmplData tmplData
}

type tmplData struct {
Host string
Paths []string
}

func (suite *MapUpdateSuite) SetupSuite() {
var err error
suite.test, err = e2e.NewTest()
suite.NoError(err)
suite.tmplData = tmplData{Host: suite.test.GetNS() + ".test", Paths: []string{""}}
suite.client, err = e2e.NewHTTPClient(suite.tmplData.Host)
suite.NoError(err)
suite.NoError(suite.test.Apply("config/deploy.yaml", suite.test.GetNS(), nil))
suite.NoError(suite.test.Apply("config/ingress.yaml.tmpl", suite.test.GetNS(), suite.tmplData))
suite.Require().Eventually(func() bool {
r, cls, err := suite.client.Do()
if err != nil {
suite.T().Log(err)
return false
}
defer cls()
return r.StatusCode == 200
}, e2e.WaitDuration, e2e.TickDuration)
}

func (suite *MapUpdateSuite) TearDownSuite() {
suite.test.TearDown()
}

func TestMapUpdateSuite(t *testing.T) {
suite.Run(t, new(MapUpdateSuite))
}
43 changes: 43 additions & 0 deletions deploy/tests/e2e/map-updates/update_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2019 HAProxy Technologies LLC
//
// 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 under the License.

//go:build e2e_sequential

package mapupdate

import (
"strconv"

"github.com/haproxytech/kubernetes-ingress/deploy/tests/e2e"
)

func (suite *MapUpdateSuite) Test_Update() {
suite.Run("Update", func() {
suite.tmplData.Paths = make([]string, 0, 700)
for i := 0; i < 700; i++ {
suite.tmplData.Paths = append(suite.tmplData.Paths, strconv.Itoa(i))
}
oldInfo, err := e2e.GetGlobalHAProxyInfo()
suite.NoError(err)
suite.NoError(suite.test.Apply("config/ingress.yaml.tmpl", suite.test.GetNS(), suite.tmplData))
suite.Require().Eventually(func() bool {
newInfo, err := e2e.GetGlobalHAProxyInfo()
suite.NoError(err)
count, err := e2e.GetHAProxyMapCount("path-prefix")
suite.NoError(err)
suite.T().Log(count)
return oldInfo.Pid == newInfo.Pid && count == 700
}, e2e.WaitDuration, e2e.TickDuration)
})
}

0 comments on commit ac2b49f

Please sign in to comment.