Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Functional tests for UpstreamSettings Policy #2869

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading