Skip to content

Commit

Permalink
Functional tests for UpstreamSettings Policy (#2869)
Browse files Browse the repository at this point in the history
Functional Tests for UpstreamSettings Policy.
  • Loading branch information
salonichf5 authored and kate-osborn committed Dec 20, 2024
1 parent 939aee6 commit b0ed7e2
Show file tree
Hide file tree
Showing 12 changed files with 943 additions and 27 deletions.
64 changes: 46 additions & 18 deletions tests/framework/crossplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ type ExpectedNginxField struct {
File string
// Location is the location name that the directive should exist in.
Location string
// Servers are the server names that the directive should exist in.
Servers []string
// Server is the server name that the directive should exist in.
Server string
// Upstream is the upstream name that the directive should exist in.
Upstream string
// ValueSubstringAllowed allows the expected value to be a substring of the real value.
// This makes it easier for cases when real values are complex file names or contain things we
// don't care about, and we just want to check if a substring exists.
Expand All @@ -39,40 +41,66 @@ type ExpectedNginxField struct {
// ValidateNginxFieldExists accepts the nginx config and the configuration for the expected field,
// and returns whether or not that field exists where it should.
func ValidateNginxFieldExists(conf *Payload, expFieldCfg ExpectedNginxField) error {
b, err := json.Marshal(conf)
if err != nil {
return fmt.Errorf("error marshaling nginx config: %w", err)
}

for _, config := range conf.Config {
if !strings.Contains(config.File, expFieldCfg.File) {
continue
}

for _, directive := range config.Parsed {
if len(expFieldCfg.Servers) == 0 {
if expFieldCfg.Server == "" && expFieldCfg.Upstream == "" {
if expFieldCfg.fieldFound(directive) {
return nil
}
continue
}

for _, serverName := range expFieldCfg.Servers {
if directive.Directive == "server" && getServerName(directive.Block) == serverName {
for _, serverDirective := range directive.Block {
if expFieldCfg.Location == "" && expFieldCfg.fieldFound(serverDirective) {
return nil
} else if serverDirective.Directive == "location" &&
fieldExistsInLocation(serverDirective, expFieldCfg) {
return nil
}
}
}
if expFieldCfg.Server != "" && fieldExistsInServer(expFieldCfg, *directive) {
return nil
}

if expFieldCfg.Upstream != "" && fieldExistsInUpstream(expFieldCfg, *directive) {
return nil
}
}
}

b, err := json.Marshal(conf)
if err != nil {
return fmt.Errorf("error marshaling nginx config: %w", err)
return fmt.Errorf("directive %s not found in: nginx config %s", expFieldCfg.Directive, string(b))
}

func fieldExistsInServer(
expFieldCfg ExpectedNginxField,
directive Directive,
) bool {
if directive.Directive == "server" && getServerName(directive.Block) == expFieldCfg.Server {
for _, serverDirective := range directive.Block {
if expFieldCfg.Location == "" && expFieldCfg.fieldFound(serverDirective) {
return true
} else if serverDirective.Directive == "location" &&
fieldExistsInLocation(serverDirective, expFieldCfg) {
return true
}
}
}
return false
}

return fmt.Errorf("field not found; expected: %+v\nNGINX conf: %s", expFieldCfg, string(b))
func fieldExistsInUpstream(
expFieldCfg ExpectedNginxField,
directive Directive,
) bool {
if directive.Directive == "upstream" && directive.Args[0] == expFieldCfg.Upstream {
for _, directive := range directive.Block {
if expFieldCfg.fieldFound(directive) {
return true
}
}
}
return false
}

func getServerName(serverBlock Directives) string {
Expand Down
16 changes: 11 additions & 5 deletions tests/suite/client_settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,13 @@ var _ = Describe("ClientSettingsPolicy", Ordered, Label("functional", "cspolicy"
Directive: "include",
Value: fmt.Sprintf("%s_gw-csp.conf", filePrefix),
File: "http.conf",
Servers: []string{"*.example.com", "cafe.example.com"},
Server: "*.example.com",
},
{
Directive: "include",
Value: fmt.Sprintf("%s_gw-csp.conf", filePrefix),
File: "http.conf",
Server: "cafe.example.com",
},
{
Directive: "client_max_body_size",
Expand Down Expand Up @@ -150,7 +156,7 @@ var _ = Describe("ClientSettingsPolicy", Ordered, Label("functional", "cspolicy"
Directive: "include",
Value: fmt.Sprintf("%s_coffee-route-csp.conf", filePrefix),
File: "http.conf",
Servers: []string{"cafe.example.com"},
Server: "cafe.example.com",
Location: "/coffee",
},
{
Expand All @@ -164,7 +170,7 @@ var _ = Describe("ClientSettingsPolicy", Ordered, Label("functional", "cspolicy"
Directive: "include",
Value: fmt.Sprintf("%s_tea-route-csp.conf", filePrefix),
File: "http.conf",
Servers: []string{"cafe.example.com"},
Server: "cafe.example.com",
Location: "/tea",
},
{
Expand All @@ -178,7 +184,7 @@ var _ = Describe("ClientSettingsPolicy", Ordered, Label("functional", "cspolicy"
Directive: "include",
Value: fmt.Sprintf("%s_soda-route-csp.conf", filePrefix),
File: "http.conf",
Servers: []string{"cafe.example.com"},
Server: "cafe.example.com",
Location: "/soda",
},
{
Expand All @@ -192,7 +198,7 @@ var _ = Describe("ClientSettingsPolicy", Ordered, Label("functional", "cspolicy"
Directive: "include",
Value: fmt.Sprintf("%s_grpc-route-csp.conf", filePrefix),
File: "http.conf",
Servers: []string{"*.example.com"},
Server: "*.example.com",
Location: "/helloworld.Greeter/SayHello",
},
{
Expand Down
66 changes: 66 additions & 0 deletions tests/suite/manifests/upstream-settings-policy/cafe.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee
spec:
replicas: 1
selector:
matchLabels:
app: coffee
template:
metadata:
labels:
app: coffee
spec:
containers:
- name: coffee
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: coffee
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: coffee
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tea
spec:
replicas: 1
selector:
matchLabels:
app: tea
template:
metadata:
labels:
app: tea
spec:
containers:
- name: tea
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: tea
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: tea
---
11 changes: 11 additions & 0 deletions tests/suite/manifests/upstream-settings-policy/gateway.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: gateway
spec:
gatewayClassName: nginx
listeners:
- name: http
port: 80
protocol: HTTP
hostname: "*.example.com"
39 changes: 39 additions & 0 deletions tests/suite/manifests/upstream-settings-policy/grpc-backend.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
apiVersion: v1
kind: Service
metadata:
name: grpc-backend
spec:
selector:
app: grpc-backend
ports:
- protocol: TCP
port: 8080
targetPort: 50051
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grpc-backend
labels:
app: grpc-backend
spec:
replicas: 1
selector:
matchLabels:
app: grpc-backend
template:
metadata:
labels:
app: grpc-backend
spec:
containers:
- name: grpc-backend
image: ghcr.io/nginxinc/kic-test-grpc-server:0.2.3
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
resources:
requests:
cpu: 10m
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: gateway.nginx.org/v1alpha1
kind: UpstreamSettingsPolicy
metadata:
name: usps-target-not-found
spec:
zoneSize: 512k
targetRefs:
- group: core
kind: Service
name: targeted-svc-dne
keepAlive:
connections: 10
requests: 3
time: 10s
timeout: 50s
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: gateway-not-valid
spec:
gatewayClassName: nginx
addresses:
- value: "10.0.0.1"
listeners:
- name: http
port: 80
protocol: HTTP
hostname: "soda.example.com"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: soda
spec:
replicas: 1
selector:
matchLabels:
app: soda
template:
metadata:
labels:
app: soda
spec:
containers:
- name: soda
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: soda
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: soda
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: soda
spec:
parentRefs:
- name: gateway-not-valid
sectionName: http
hostnames:
- "soda.example.com"
rules:
- matches:
- path:
type: Exact
value: /soda
backendRefs:
- name: soda
port: 80
---
apiVersion: gateway.nginx.org/v1alpha1
kind: UpstreamSettingsPolicy
metadata:
name: soda-svc-usp
spec:
zoneSize: 512k
targetRefs:
- group: core
kind: Service
name: soda
keepAlive:
connections: 10
requests: 3
time: 10s
timeout: 50s
Loading

0 comments on commit b0ed7e2

Please sign in to comment.