Skip to content

Commit

Permalink
e2e: unreachable service
Browse files Browse the repository at this point in the history
Signed-off-by: Eguzki Astiz Lezaun <[email protected]>
  • Loading branch information
eguzki committed Nov 6, 2024
1 parent 484de09 commit d72321e
Show file tree
Hide file tree
Showing 7 changed files with 389 additions and 1 deletion.
24 changes: 24 additions & 0 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,27 @@ jobs:
- name: Execute tests in the running services
run: |
make -f ./e2e/parallel-requests/Makefile test
unreachable-service:
name: Unreachable service integration test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
target: wasm32-unknown-unknown
- uses: arduino/setup-protoc@v1
with:
version: '3.x'
- uses: actions-rs/cargo@v1
with:
command: build
args: --target wasm32-unknown-unknown
- name: Run docker compose
run: |
docker compose -f ./e2e/unreachable-service/docker-compose.yaml run start_services
- name: Execute tests in the running services
run: |
make -f ./e2e/unreachable-service/Makefile test
2 changes: 1 addition & 1 deletion e2e/missing-cluster/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Check Envoy logs:
docker compose logs -f envoy
```

The test will run one request and expect it to fail because `failureMode` is set to `deny`.
The test will run two requests and expect them to fail because `failureMode` is set to `deny`.

### Run Manually

Expand Down
27 changes: 27 additions & 0 deletions e2e/unreachable-service/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec
.DEFAULT_GOAL := gateway
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
WORKDIR := $(patsubst %/,%,$(dir $(MKFILE_PATH)))
DOCKER ?= $(shell which docker 2> /dev/null || echo "docker")

run:
$(DOCKER) compose -f docker-compose.yaml run start_services

test:
@{ \
set -e ;\
STATUSCODE=$(shell curl --silent --output /dev/null --write-out "%{http_code}" --max-time 5 --resolve fail-on-first-action.example.com:18000:127.0.0.1 http://fail-on-first-action.example.com:18000) && \
echo "received status code $${STATUSCODE}" && \
test $${STATUSCODE} -ne 200 ;\
}
@{ \
set -e ;\
STATUSCODE=$(shell curl --silent --output /dev/null --write-out "%{http_code}" --max-time 5 --resolve fail-on-second-action.example.com:18000:127.0.0.1 http://fail-on-second-action.example.com:18000) && \
echo "received status code $${STATUSCODE}" && \
test $${STATUSCODE} -ne 200 ;\
}

clean:
$(DOCKER) compose down --volumes --remove-orphans
$(DOCKER) compose -f docker-compose.yaml down --volumes --remove-orphans
118 changes: 118 additions & 0 deletions e2e/unreachable-service/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
## Basic integration test

This is a integration test to validate when envoy cluster exists but it is not reachable.

The test configures unreachable envoy cluster on the fist action `fail-on-first-action.example.com`,
as well as on the second action `fail-on-second-action.example.com`. Reason being to validate
error handling on the `on_grpc_call_response` event.

This test is being added to the CI test suite

### Description

```yaml
"services": {
"limitadorA": {
"type": "ratelimit",
"endpoint": "limitador",
"failureMode": "deny"
},
"limitador-unreachable": {
"type": "ratelimit",
"endpoint": "unreachable-cluster",
"failureMode": "deny"
}
},
"actionSets": [
{
"name": "envoy-cluster-unreachable-on-first-action",
"routeRuleConditions": {
"hostnames": [
"fail-on-first-action.example.com"
]
},
"actions": [
{
"service": "limitador-unreachable",
"scope": "a",
"data": [
{
"expression": {
"key": "a",
"value": "1"
}
}
]
}
]
},
{
"name": "envoy-cluster-unreachable-on-second-action",
"routeRuleConditions": {
"hostnames": [
"fail-on-second-action.example.com"
]
},
"actions": [
{
"service": "limitadorA",
"scope": "b",
"data": [
{
"expression": {
"key": "limit_to_be_activated",
"value": "1"
}
}
]
},
{
"service": "limitador-unreachable",
"scope": "b",
"data": [
{
"expression": {
"key": "limit_to_be_activated",
"value": "1"
}
}
]
}
]
}
]
```

And a new limit configuration

```yaml
- namespace: basic
max_value: 30
seconds: 60
conditions:
- "a == '1'"
variables: []
```
The test will run two requests and expect them to fail because `failureMode` is set to `deny`.

### Run Manually

It requires Wasm module being built at `target/wasm32-unknown-unknown/debug/wasm_shim.wasm`.
Check *Makefile* at the root of the project to build the module.

```
make run
```
Run the test
```
make test
```
### Clean up
```
make clean
```
56 changes: 56 additions & 0 deletions e2e/unreachable-service/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
services:
envoy:
image: envoyproxy/envoy:v1.31-latest
depends_on:
- limitador
- upstream
command:
- /usr/local/bin/envoy
- --config-path
- /etc/envoy.yaml
- --log-level
- info
- --component-log-level
- wasm:debug,http:debug,router:debug
- --service-cluster
- proxy
expose:
- "80"
- "8001"
ports:
- "18000:80"
- "18001:8001"
volumes:
- ./envoy.yaml:/etc/envoy.yaml
- ../../target/wasm32-unknown-unknown/debug/wasm_shim.wasm:/opt/kuadrant/wasm/wasm_shim.wasm
limitador:
image: quay.io/kuadrant/limitador:latest
command: ["limitador-server", "-vvv", "/opt/kuadrant/limits/limits.yaml"]
ports:
- "18080:8080"
- "18081:8081"
expose:
- "8080"
- "8081"
volumes:
- ./limits.yaml:/opt/kuadrant/limits/limits.yaml
upstream:
image: quay.io/kuadrant/authorino-examples:talker-api
environment:
PORT: 3000
expose:
- "3000"
start_services:
image: alpine
depends_on:
- envoy
command: >
/bin/sh -c "
while ! nc -z envoy 80;
do
echo sleeping;
sleep 1;
done;
echo Connected!
"
156 changes: 156 additions & 0 deletions e2e/unreachable-service/envoy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
---
static_resources:
listeners:
- name: main
address:
socket_address:
address: 0.0.0.0
port_value: 80
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
use_remote_address: true
xff_num_trusted_hops: 1
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: upstream
http_filters:
- name: envoy.filters.http.wasm
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
config:
name: kuadrant_wasm
root_id: kuadrant_wasm
vm_config:
vm_id: vm.sentinel.kuadrant_wasm
runtime: envoy.wasm.runtime.v8
code:
local:
filename: /opt/kuadrant/wasm/wasm_shim.wasm
allow_precompiled: true
configuration:
"@type": "type.googleapis.com/google.protobuf.StringValue"
value: >
{
"services": {
"limitador": {
"type": "ratelimit",
"endpoint": "limitador",
"failureMode": "deny"
},
"limitador-unreachable": {
"type": "ratelimit",
"endpoint": "unreachable-cluster",
"failureMode": "deny"
}
},
"actionSets": [
{
"name": "envoy-cluster-unreachable-on-first-action",
"routeRuleConditions": {
"hostnames": [
"fail-on-first-action.example.com"
]
},
"actions": [
{
"service": "limitador-unreachable",
"scope": "a",
"data": [
{
"expression": {
"key": "a",
"value": "1"
}
}
]
}
]
},
{
"name": "envoy-cluster-unreachable-on-second-action",
"routeRuleConditions": {
"hostnames": [
"fail-on-second-action.example.com"
]
},
"actions": [
{
"service": "limitador",
"scope": "a",
"data": [
{
"expression": {
"key": "a",
"value": "1"
}
}
]
},
{
"service": "limitador-unreachable",
"scope": "a",
"data": [
{
"expression": {
"key": "a",
"value": "1"
}
}
]
}
]
}
]
}
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: upstream
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: round_robin
load_assignment:
cluster_name: upstream
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: upstream
port_value: 3000
- name: limitador
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: round_robin
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http2_protocol_options: {}
load_assignment:
cluster_name: limitador
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: limitador
port_value: 8081
admin:
address:
socket_address:
address: 0.0.0.0
port_value: 8001
Loading

0 comments on commit d72321e

Please sign in to comment.