Skip to content

Commit cc4d7f7

Browse files
committed
TEST: test HTTP Requests Backend CRD
1 parent a8af0e4 commit cc4d7f7

File tree

2 files changed

+241
-0
lines changed

2 files changed

+241
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2019 HAProxy Technologies LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package httprequests
16+
17+
import (
18+
"os"
19+
"path/filepath"
20+
"strings"
21+
)
22+
23+
func (suite *HTTPRequestsSuite) TestHTTPRequests() {
24+
suite.UseHTTPRequestsFixture()
25+
contents, err := os.ReadFile(filepath.Join(suite.test.TempDir, "haproxy.cfg"))
26+
if err != nil {
27+
suite.T().Fatal(err.Error())
28+
}
29+
30+
suite.Run("http-request set-var(txn.admintenant)", func() {
31+
c := strings.Count(string(contents), "http-request set-var(txn.admintenant) str({{RUN.serviceId2}})")
32+
suite.Exactly(c, 1, "http-request set-var(txn.admintenant) is repeated %d times but expected 1", c)
33+
})
34+
35+
suite.Run("http-request track-sc1 txn.key", func() {
36+
c := strings.Count(string(contents), " table connected.local if cookie_found")
37+
suite.Exactly(c, 1, "http-request track-sc1 txn.key is repeated %d times but expected 1", c)
38+
})
39+
}
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
// Copyright 2019 HAProxy Technologies LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package httprequests
16+
17+
import (
18+
_ "embed"
19+
"os"
20+
"testing"
21+
22+
"github.com/haproxytech/client-native/v5/models"
23+
v1 "github.com/haproxytech/kubernetes-ingress/crs/api/ingress/v1"
24+
"github.com/haproxytech/kubernetes-ingress/pkg/annotations"
25+
c "github.com/haproxytech/kubernetes-ingress/pkg/controller"
26+
"github.com/haproxytech/kubernetes-ingress/pkg/haproxy"
27+
"github.com/haproxytech/kubernetes-ingress/pkg/haproxy/env"
28+
"github.com/haproxytech/kubernetes-ingress/pkg/ingress"
29+
k8ssync "github.com/haproxytech/kubernetes-ingress/pkg/k8s/sync"
30+
"github.com/haproxytech/kubernetes-ingress/pkg/store"
31+
"github.com/haproxytech/kubernetes-ingress/pkg/utils"
32+
"github.com/jessevdk/go-flags"
33+
"github.com/stretchr/testify/assert"
34+
"github.com/stretchr/testify/suite"
35+
networkingv1 "k8s.io/api/networking/v1"
36+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
37+
"k8s.io/apimachinery/pkg/watch"
38+
)
39+
40+
type FakeUpdateSatusManager struct{}
41+
42+
func (m *FakeUpdateSatusManager) AddIngress(ingress *ingress.Ingress) {}
43+
func (m *FakeUpdateSatusManager) Update(k store.K8s, h haproxy.HAProxy, a annotations.Annotations) (err error) {
44+
return
45+
}
46+
47+
type HTTPRequestsSuite struct {
48+
suite.Suite
49+
test Test
50+
}
51+
52+
func TestHTTPRequests(t *testing.T) {
53+
suite.Run(t, new(HTTPRequestsSuite))
54+
}
55+
56+
type Test struct {
57+
Controller *c.HAProxyController
58+
TempDir string
59+
}
60+
61+
func (suite *HTTPRequestsSuite) BeforeTest(suiteName, testName string) {
62+
tempDir, err := os.MkdirTemp("", "tnr-"+testName+"-*")
63+
if err != nil {
64+
suite.T().Fatalf("Suite '%s': Test '%s' : error : %s", suiteName, testName, err)
65+
}
66+
suite.test.TempDir = tempDir
67+
suite.T().Logf("temporary configuration dir %s", suite.test.TempDir)
68+
}
69+
70+
func (suite *HTTPRequestsSuite) UseHTTPRequestsFixture() (eventChan chan k8ssync.SyncDataEvent) {
71+
var osArgs utils.OSArgs
72+
os.Args = []string{os.Args[0], "-e", "-t", "--config-dir=" + suite.test.TempDir}
73+
parser := flags.NewParser(&osArgs, flags.IgnoreUnknown)
74+
_, errParsing := parser.Parse() //nolint:ifshort
75+
if errParsing != nil {
76+
suite.T().Fatal(errParsing)
77+
}
78+
79+
s := store.NewK8sStore(osArgs)
80+
os.Setenv("POD_NAME", "haproxy-kubernetes-ingress-68c9fc6d86-zn9qz")
81+
82+
haproxyEnv := env.Env{
83+
CfgDir: suite.test.TempDir,
84+
Proxies: env.Proxies{
85+
FrontHTTP: "http",
86+
FrontHTTPS: "https",
87+
FrontSSL: "ssl",
88+
BackSSL: "ssl",
89+
},
90+
}
91+
haproxyConfig, err := os.ReadFile("../../../../fs/usr/local/etc/haproxy/haproxy.cfg")
92+
if err != nil {
93+
//nolint:testifylint
94+
assert.Failf(suite.T(), "error in opening init haproxy configuration file", err.Error())
95+
}
96+
97+
eventChan = make(chan k8ssync.SyncDataEvent, watch.DefaultChanSize*6)
98+
controller := c.NewBuilder().
99+
WithHaproxyCfgFile(haproxyConfig).
100+
WithEventChan(eventChan).
101+
WithStore(s).
102+
WithHaproxyEnv(haproxyEnv).
103+
WithUpdateStatusManager(&FakeUpdateSatusManager{}).
104+
WithArgs(osArgs).Build()
105+
106+
go controller.Start()
107+
108+
backend := v1.Backend{
109+
ObjectMeta: metav1.ObjectMeta{
110+
Name: "backend1cr",
111+
Namespace: "ns1",
112+
},
113+
Spec: v1.BackendSpec{
114+
Config: &models.Backend{
115+
Name: "backend1",
116+
},
117+
HTTPRequests: models.HTTPRequestRules{
118+
{
119+
Index: utils.Ptr[int64](0),
120+
Type: "set-var",
121+
VarExpr: "str({{RUN.serviceId2}})",
122+
VarName: "admintenant",
123+
VarScope: "txn",
124+
},
125+
{
126+
Index: utils.Ptr[int64](1),
127+
Cond: "if",
128+
CondTest: "cookie_found",
129+
TrackSc1Key: "txn.key",
130+
TrackSc1Table: "connected.local",
131+
Type: "track-sc1",
132+
},
133+
},
134+
},
135+
}
136+
eventChan <- k8ssync.SyncDataEvent{SyncType: k8ssync.CR_BACKEND, Namespace: backend.Namespace, Name: backend.Name, Data: &backend}
137+
138+
// Now sending store events for test setup
139+
ns := store.Namespace{Name: "ns", Status: store.ADDED}
140+
eventChan <- k8ssync.SyncDataEvent{SyncType: k8ssync.NAMESPACE, Namespace: ns.Name, Data: &ns}
141+
142+
endpoints := &store.Endpoints{
143+
SliceName: "myappservice",
144+
Service: "myappservice",
145+
Namespace: ns.Name,
146+
Ports: map[string]*store.PortEndpoints{
147+
"https": {
148+
Port: int64(3001),
149+
Addresses: map[string]struct{}{"10.244.0.9": {}},
150+
},
151+
},
152+
Status: store.ADDED,
153+
}
154+
155+
eventChan <- k8ssync.SyncDataEvent{SyncType: k8ssync.ENDPOINTS, Namespace: endpoints.Namespace, Data: endpoints}
156+
157+
service := &store.Service{
158+
Name: "myappservice",
159+
Namespace: ns.Name,
160+
Annotations: map[string]string{"cr-backend": backend.Namespace + "/" + backend.Name},
161+
Ports: []store.ServicePort{
162+
{
163+
Name: "https",
164+
Protocol: "TCP",
165+
Port: 8443,
166+
Status: store.ADDED,
167+
},
168+
},
169+
Status: store.ADDED,
170+
}
171+
eventChan <- k8ssync.SyncDataEvent{SyncType: k8ssync.SERVICE, Namespace: service.Namespace, Data: service}
172+
173+
ingress := &store.Ingress{
174+
IngressCore: store.IngressCore{
175+
APIVersion: store.NETWORKINGV1,
176+
Name: "myapping",
177+
Namespace: ns.Name,
178+
Annotations: map[string]string{"haproxy.org/ingress.class": "haproxy"},
179+
Rules: map[string]*store.IngressRule{
180+
"": {
181+
Paths: map[string]*store.IngressPath{
182+
string(networkingv1.PathTypePrefix) + "-/": {
183+
Path: "/",
184+
PathTypeMatch: string(networkingv1.PathTypePrefix),
185+
SvcNamespace: service.Namespace,
186+
SvcPortString: "https",
187+
SvcName: service.Name,
188+
},
189+
},
190+
},
191+
},
192+
},
193+
Status: store.ADDED,
194+
}
195+
196+
eventChan <- k8ssync.SyncDataEvent{SyncType: k8ssync.INGRESS, Namespace: ingress.Namespace, Data: ingress}
197+
controllerHasWorked := make(chan struct{})
198+
eventChan <- k8ssync.SyncDataEvent{SyncType: k8ssync.COMMAND}
199+
eventChan <- k8ssync.SyncDataEvent{EventProcessed: controllerHasWorked}
200+
<-controllerHasWorked
201+
return
202+
}

0 commit comments

Comments
 (0)