Skip to content

Commit

Permalink
test: add test for webhook check
Browse files Browse the repository at this point in the history
  • Loading branch information
adityathebe committed Oct 31, 2023
1 parent 92bebcd commit bcab637
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 2 deletions.
43 changes: 43 additions & 0 deletions .github/workflows/webhook-check-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
on:
push:
tags:
- v*
branches:
- master
paths:
- "**.go"
- "Makefile"
- "**.yaml"
- "**.yml"
- "test/**"
pull_request:
paths:
- "**.go"
- "Makefile"
- "**.yaml"
- "**.yml"
- "test/**"
name: Webhook Check Test
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@bfdd3570ce990073878bf10f6b2d79082de49492 # v2.2.0
with:
go-version: 1.20.x
- name: Checkout code
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
- uses: actions/cache@8492260343ad570701412c2f464a5877dc76bace # v2
with:
path: |
~/go/pkg/mod
~/.cache/go-build
.bin
key: cache-${{ hashFiles('**/go.sum') }}-${{ hashFiles('.bin/*') }}
restore-keys: |
cache-
- name: Test
run: ./test/e2e-webook.sh
4 changes: 3 additions & 1 deletion fixtures/external/alertmanager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ spec:
schedule: "@every 1m"
webhook:
name: my-webhook
token:
value: webhook-auth-token
transform:
expr: |
results.json.alerts.map(r,
Expand All @@ -17,6 +19,6 @@ spec:
'icon': 'alert',
'message': r.annotations.summary,
'description': r.annotations.description,
'deletedAt': r.endsAt,
'deletedAt': has(r.endsAt) ? r.endsAt : null,
}
).toJSON()
2 changes: 1 addition & 1 deletion pkg/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func ParseConfig(configfile string, datafile string) ([]v1.Canary, error) {
return nil, err
}

if len(config.Spec.GetAllChecks()) == 0 {
if len(config.Spec.GetAllChecks()) == 0 && config.Spec.Webhook == nil {
// try just the specs:
spec := v1.CanarySpec{}

Expand Down
166 changes: 166 additions & 0 deletions test/e2e-webook.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#!/bin/bash

set -e

echo "::group::Prerequisites"
required_tools=("tr" "docker" "curl")
for tool in "${required_tools[@]}"; do
if ! command -v $tool &>/dev/null; then
echo "$tool is not installed. Please install it to run this script."
exit 1
fi
done
echo "All the required tools are installed."
echo "::endgroup::"

# https://cedwards.xyz/defer-for-shell/
DEFER=
defer() {
DEFER="$*; ${DEFER}"
trap "{ $DEFER }" EXIT
}

port=7676
container_name=webhook_postgres

## Summary
# - Fire up the canary checker HTTP server for webhook endpoint
# - Expect the checks to be created
# - Create resolved alert
# - Expect the checks to be deleted

echo "::group::Provisioning"
echo "Starting up postgres database"
docker run --rm -p 5433:5432 --name $container_name -e POSTGRES_PASSWORD=mysecretpassword -d postgres:14
defer docker container rm -f $container_name

echo "Starting canary-checker in the background"
go run main.go serve --httpPort=$port \
--db-migrations \
--disable-postgrest -vvv \
--db='postgres://postgres:mysecretpassword@localhost:5433/postgres?sslmode=disable' \
--maxStatusCheckCount=1 \
fixtures/external/alertmanager.yaml &>/dev/null &
PROC_ID=$!
echo "Started canary checker with PID $PROC_ID"

timeout=30
echo Waiting for the server to come up. timeout=$timeout seconds
for ((i = 1; i <= $timeout; i++)); do
if [ $(curl -s -o /dev/null -w "%{http_code}" "http://localhost:$port/health") == "200" ]; then
echo "Server healthy (HTTP 200 OK)."
break
fi

[ $i -eq $timeout ] && echo "Timeout: Server didn't return HTTP 200." && exit 1
sleep 1
done

# Not sure why killing PROC_ID doesn't kill the HTTP server.
# So had to get the process id this way
process_id=$(lsof -nti:$port)
echo "Running on port $process_id"
defer "kill -9 $process_id"
echo "::endgroup::"

echo "::group::Assertion"
echo Expect the check to be created by sync job
resp=$(docker exec $container_name psql "postgres://postgres:mysecretpassword@localhost:5432/postgres?sslmode=disable" -t -c "SELECT count(*) FROM checks WHERE name = 'my-webhook';" | tr -d '[:space:]')
if [ $resp -ne 1 ]; then
echo "Expected one webhook check to be created but $resp were created"
exit 1
fi

echo Attempt to call the webhook endpoint without the auth token
resp=$(curl -w "%{http_code}" -s -o /dev/null -X POST "localhost:$port/webhook/my-webhook")
if [ $resp -ne 401 ]; then
echo "Expected 401, got $resp"
exit 1
fi

echo Attempt to call the webhook endpoint with the auth token
resp=$(curl -w "%{http_code}" -s -o /dev/null -X POST "localhost:$port/webhook/my-webhook?token=webhook-auth-token")
if [ $resp -ne 200 ]; then
echo "Expected 200, got $resp"
exit 1
fi

echo Calling webhook endpoint with unresolved alert
curl -sL -o /dev/null -X POST -u 'admin@local:admin' --json '{
"version": "4",
"status": "firing",
"alerts": [
{
"status": "firing",
"name": "first",
"labels": {
"severity": "critical",
"alertName": "ServerDown",
"location": "DataCenterA"
},
"annotations": {
"summary": "Server in DataCenterA is down",
"description": "This alert indicates that a server in DataCenterA is currently down."
},
"startsAt": "2023-10-30T08:00:00Z",
"generatorURL": "http://example.com/generatorURL/serverdown",
"fingerprint": "a1b2c3d4e5f6"
},
{
"status": "resolved",
"labels": {
"severity": "warning",
"alertName": "HighCPUUsage",
"location": "DataCenterB"
},
"annotations": {
"summary": "High CPU Usage in DataCenterB",
"description": "This alert indicates that there was high CPU usage in DataCenterB, but it is now resolved."
},
"startsAt": "2023-10-30T09:00:00Z",
"generatorURL": "http://example.com/generatorURL/highcpuusage",
"name": "second",
"fingerprint": "x1y2z3w4v5"
}
]
}' localhost:$port/webhook/my-webhook?token=webhook-auth-token

resp=$(docker exec $container_name psql 'postgres://postgres:mysecretpassword@localhost:5432/postgres?sslmode=disable' -t -c "SELECT count(*) FROM checks WHERE type = 'webhook' AND deleted_at IS NULL;" | tr -d '[:space:]')
if [ $resp -ne 3 ]; then
echo "Expected 2 new checks to be created but $resp were found"
exit 1
fi

echo Calling webhook endpoint with a resolved alert
curl -sL -o /dev/null -X POST -u 'admin@local:admin' --json '{
"version": "4",
"status": "firing",
"alerts": [
{
"status": "firing",
"name": "first",
"labels": {
"severity": "critical",
"alertName": "ServerDown",
"location": "DataCenterA"
},
"annotations": {
"summary": "Server in DataCenterA is down",
"description": "This alert indicates that a server in DataCenterA is currently down."
},
"startsAt": "2023-10-30T08:00:00Z",
"generatorURL": "http://example.com/generatorURL/serverdown",
"fingerprint": "a1b2c3d4e5f6",
"endsAt": "2023-10-30T09:15:00Z"
}
]
}' localhost:$port/webhook/my-webhook?token=webhook-auth-token

resp=$(docker exec $container_name psql 'postgres://postgres:mysecretpassword@localhost:5432/postgres?sslmode=disable' -t -c "SELECT name FROM checks WHERE type = 'webhook' AND deleted_at IS NOT NULL;" | tr -d '[:space:]')
if [ "$resp" != 'firsta1b2c3d4e5f6' ]; then
echo "Expected "firsta1b2c3d4e5f6" check to be deleted."
exit 1
fi

echo "::endgroup::"
exit 0

0 comments on commit bcab637

Please sign in to comment.