-
Notifications
You must be signed in to change notification settings - Fork 176
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #645 from permitio/roe/per-10476-write-opal-applic…
…ation-tests Introduce docker & bash based application tests
- Loading branch information
Showing
10 changed files
with
299 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# OPAL Application Tests | ||
|
||
To fully test OPAL's core features as part of our CI flow, | ||
We're using a bash script and a docker-compose configuration that enables most of OPAL's important features. | ||
|
||
## How To Run Locally | ||
|
||
### Controlling the image tag | ||
|
||
By default, tests would run with the `latest` image tag (for both server & client). | ||
|
||
To configure another specific version: | ||
|
||
```bash | ||
export OPAL_IMAGE_TAG=0.7.1 | ||
``` | ||
|
||
Or if you want to test locally built images | ||
```bash | ||
make docker-build-next | ||
export OPAL_IMAGE_TAG=next | ||
``` | ||
|
||
### Using a policy repo | ||
|
||
To test opal's git tracking capabilities, `run.sh` uses a dedicated GitHub repo ([opal-tests-policy-repo](https://github.com/permitio/opal-tests-policy-repo)) in which it creates branches and pushes new commits. | ||
|
||
If you're not accessible to that repo (not in `Permit.io`), Please fork our public [opal-example-policy-repo](https://github.com/permitio/opal-example-policy-repo), and override the repo URL to be used: | ||
```bash | ||
export [email protected]:your-org/your-repo.git | ||
``` | ||
|
||
As `run.sh` requires push permissions, and as `opal-server` itself might need to authenticate GitHub (if your repo is private). If your GitHub ssh private key is not stored at `~/.ssh/id_rsa`, provide it using: | ||
```bash | ||
# Use an absolute path | ||
export OPAL_POLICY_REPO_SSH_KEY_PATH=$(realpath ./your_github_ssh_private_key) | ||
``` | ||
|
||
|
||
### Putting it all together | ||
|
||
```bash | ||
make docker-build-next # To locally build opal images | ||
export OPAL_IMAGE_TAG=next # Otherwise would default to "latest" | ||
|
||
export [email protected]:your-org/your-repo.git # To use your own repo for testing (if you're not an Permit.io employee yet...) | ||
export OPAL_POLICY_REPO_SSH_KEY_PATH=$(realpath ./your_github_ssh_private_key) # If your GitHub ssh key isn't in "~.ssh/id_rsa" | ||
|
||
cd app-tests | ||
./run.sh | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
services: | ||
broadcast_channel: | ||
image: postgres:alpine | ||
environment: | ||
- POSTGRES_DB=postgres | ||
- POSTGRES_USER=postgres | ||
- POSTGRES_PASSWORD=postgres | ||
|
||
opal_server: | ||
image: permitio/opal-server:${OPAL_IMAGE_TAG:-latest} | ||
deploy: | ||
mode: replicated | ||
replicas: 2 | ||
endpoint_mode: vip | ||
environment: | ||
- OPAL_BROADCAST_URI=postgres://postgres:postgres@broadcast_channel:5432/postgres | ||
- UVICORN_NUM_WORKERS=4 | ||
- OPAL_POLICY_REPO_URL=${OPAL_POLICY_REPO_URL:[email protected]:permitio/opal-tests-policy-repo.git} | ||
- OPAL_POLICY_REPO_MAIN_BRANCH=${POLICY_REPO_BRANCH} | ||
- OPAL_POLICY_REPO_SSH_KEY=${OPAL_POLICY_REPO_SSH_KEY} | ||
- OPAL_DATA_CONFIG_SOURCES={"config":{"entries":[{"url":"http://opal_server:7002/policy-data","config":{"headers":{"Authorization":"Bearer ${OPAL_CLIENT_TOKEN}"}},"topics":["policy_data"],"dst_path":"/static"}]}} | ||
- OPAL_LOG_FORMAT_INCLUDE_PID=true | ||
- OPAL_POLICY_REPO_WEBHOOK_SECRET=xxxxx | ||
- OPAL_POLICY_REPO_WEBHOOK_PARAMS={"secret_header_name":"x-webhook-token","secret_type":"token","secret_parsing_regex":"(.*)","event_request_key":"gitEvent","push_event_value":"git.push"} | ||
- OPAL_AUTH_PUBLIC_KEY=${OPAL_AUTH_PUBLIC_KEY} | ||
- OPAL_AUTH_PRIVATE_KEY=${OPAL_AUTH_PRIVATE_KEY} | ||
- OPAL_AUTH_MASTER_TOKEN=${OPAL_AUTH_MASTER_TOKEN} | ||
- OPAL_AUTH_JWT_AUDIENCE=https://api.opal.ac/v1/ | ||
- OPAL_AUTH_JWT_ISSUER=https://opal.ac/ | ||
- OPAL_STATISTICS_ENABLED=true | ||
ports: | ||
- "7002-7003:7002" | ||
depends_on: | ||
- broadcast_channel | ||
|
||
opal_client: | ||
image: permitio/opal-client:${OPAL_IMAGE_TAG:-latest} | ||
deploy: | ||
mode: replicated | ||
replicas: 2 | ||
endpoint_mode: vip | ||
environment: | ||
- OPAL_SERVER_URL=http://opal_server:7002 | ||
- OPAL_LOG_FORMAT_INCLUDE_PID=true | ||
- OPAL_INLINE_OPA_LOG_FORMAT=http | ||
- OPAL_SHOULD_REPORT_ON_DATA_UPDATES=True | ||
- OPAL_DEFAULT_UPDATE_CALLBACKS={"callbacks":[["http://opal_server:7002/data/callback_report",{"method":"post","process_data":false,"headers":{"Authorization":"Bearer ${OPAL_CLIENT_TOKEN}","content-type":"application/json"}}]]} | ||
- OPAL_OPA_HEALTH_CHECK_POLICY_ENABLED=True | ||
- OPAL_CLIENT_TOKEN=${OPAL_CLIENT_TOKEN} | ||
- OPAL_AUTH_JWT_AUDIENCE=https://api.opal.ac/v1/ | ||
- OPAL_AUTH_JWT_ISSUER=https://opal.ac/ | ||
- OPAL_STATISTICS_ENABLED=true | ||
ports: | ||
- "7766-7767:7000" | ||
- "8181-8182:8181" | ||
depends_on: | ||
- opal_server | ||
command: sh -c "exec ./wait-for.sh opal_server:7002 --timeout=20 -- ./start.sh" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
#!/bin/bash | ||
set -e | ||
|
||
export OPAL_AUTH_PUBLIC_KEY | ||
export OPAL_AUTH_PRIVATE_KEY | ||
export OPAL_AUTH_MASTER_TOKEN | ||
export OPAL_CLIENT_TOKEN | ||
export OPAL_DATA_SOURCE_TOKEN | ||
|
||
function generate_opal_keys { | ||
echo "- Generating OPAL keys" | ||
|
||
ssh-keygen -q -t rsa -b 4096 -m pem -f opal_crypto_key -N "" | ||
OPAL_AUTH_PUBLIC_KEY="$(cat opal_crypto_key.pub)" | ||
OPAL_AUTH_PRIVATE_KEY="$(tr '\n' '_' < opal_crypto_key)" | ||
rm opal_crypto_key.pub opal_crypto_key | ||
|
||
OPAL_AUTH_MASTER_TOKEN="$(openssl rand -hex 16)" | ||
OPAL_AUTH_JWT_AUDIENCE=https://api.opal.ac/v1/ OPAL_AUTH_JWT_ISSUER=https://opal.ac/ OPAL_REPO_WATCHER_ENABLED=0 \ | ||
opal-server run & | ||
sleep 2; | ||
|
||
OPAL_CLIENT_TOKEN="$(opal-client obtain-token "$OPAL_AUTH_MASTER_TOKEN" --type client)" | ||
OPAL_DATA_SOURCE_TOKEN="$(opal-client obtain-token "$OPAL_AUTH_MASTER_TOKEN" --type datasource)" | ||
# shellcheck disable=SC2009 | ||
ps -ef | grep opal-server | grep -v grep | awk '{print $2}' | xargs kill | ||
sleep 5; | ||
|
||
echo "- Create .env file" | ||
rm -f .env | ||
( | ||
echo "OPAL_AUTH_PUBLIC_KEY=\"$OPAL_AUTH_PUBLIC_KEY\""; | ||
echo "OPAL_AUTH_PRIVATE_KEY=\"$OPAL_AUTH_PRIVATE_KEY\""; | ||
echo "OPAL_AUTH_MASTER_TOKEN=\"$OPAL_AUTH_MASTER_TOKEN\""; | ||
echo "OPAL_CLIENT_TOKEN=\"$OPAL_CLIENT_TOKEN\""; | ||
echo "OPAL_AUTH_PRIVATE_KEY_PASSPHRASE=\"$OPAL_AUTH_PRIVATE_KEY_PASSPHRASE\"" | ||
) > .env | ||
} | ||
|
||
function prepare_policy_repo { | ||
echo "- Clone tests policy repo to create test's branch" | ||
export OPAL_POLICY_REPO_URL | ||
export POLICY_REPO_BRANCH | ||
OPAL_POLICY_REPO_URL=${OPAL_POLICY_REPO_URL:-git@github.com:permitio/opal-tests-policy-repo.git} | ||
POLICY_REPO_BRANCH=test-$RANDOM$RANDOM | ||
rm -rf ./opal-tests-policy-repo | ||
git clone "$OPAL_POLICY_REPO_URL" | ||
cd opal-tests-policy-repo | ||
git checkout -b $POLICY_REPO_BRANCH | ||
git push --set-upstream origin $POLICY_REPO_BRANCH | ||
cd - | ||
|
||
# That's for the docker-compose to use, set ssh key from "~/.ssh/id_rsa", unless another path/key data was configured | ||
export OPAL_POLICY_REPO_SSH_KEY | ||
OPAL_POLICY_REPO_SSH_KEY_PATH=${OPAL_POLICY_REPO_SSH_KEY_PATH:-~/.ssh/id_rsa} | ||
OPAL_POLICY_REPO_SSH_KEY=${OPAL_POLICY_REPO_SSH_KEY:-$(cat "$OPAL_POLICY_REPO_SSH_KEY_PATH")} | ||
} | ||
|
||
function compose { | ||
docker compose -f ./docker-compose-app-tests.yml --env-file .env "$@" | ||
} | ||
|
||
function check_clients_logged { | ||
echo "- Looking for msg '$1' in client's logs" | ||
compose logs --index 1 opal_client | grep -q "$1" | ||
compose logs --index 2 opal_client | grep -q "$1" | ||
} | ||
|
||
function check_no_error { | ||
# Without index would output all replicas | ||
if compose logs opal_client | grep -q 'ERROR'; then | ||
echo "- Found error in logs" | ||
exit 1 | ||
fi | ||
} | ||
|
||
function clean_up { | ||
ARG=$? | ||
if [[ "$ARG" -ne 0 ]]; then | ||
echo "*** Test Failed ***" | ||
echo "" | ||
compose logs | ||
else | ||
echo "*** Test Passed ***" | ||
echo "" | ||
fi | ||
compose down | ||
cd opal-tests-policy-repo; git push -d origin $POLICY_REPO_BRANCH; cd - # Remove remote tests branch | ||
rm -rf ./opal-tests-policy-repo | ||
exit $ARG | ||
} | ||
|
||
function test_push_policy { | ||
echo "- Testing pushing policy $1" | ||
regofile="$1.rego" | ||
cd opal-tests-policy-repo | ||
echo "package $1" > "$regofile" | ||
git add "$regofile" | ||
git commit -m "Add $regofile" | ||
git push | ||
cd - | ||
|
||
curl -s --request POST 'http://localhost:7002/webhook' --header 'Content-Type: application/json' --header 'x-webhook-token: xxxxx' --data-raw '{"gitEvent":"git.push","repository":{"git_url":"'"$OPAL_POLICY_REPO_URL"'"}}' | ||
sleep 5 | ||
check_clients_logged "PUT /v1/policies/$regofile -> 200" | ||
} | ||
|
||
function test_data_publish { | ||
echo "- Testing data publish for user $1" | ||
user=$1 | ||
OPAL_CLIENT_TOKEN=$OPAL_DATA_SOURCE_TOKEN opal-client publish-data-update --src-url https://api.country.is/23.54.6.78 -t policy_data --dst-path "/users/$user/location" | ||
sleep 5 | ||
check_clients_logged "PUT /v1/data/users/$user/location -> 204" | ||
} | ||
|
||
function test_statistics { | ||
echo "- Testing statistics feature" | ||
# Make sure 2 servers & 2 clients (repeat few times cause different workers might response) | ||
for _ in {1..10}; do | ||
curl -s 'http://localhost:7002/stats' --header "Authorization: Bearer $OPAL_DATA_SOURCE_TOKEN" | grep '"client_count":2,"server_count":2' | ||
done | ||
} | ||
|
||
function main { | ||
# Setup | ||
generate_opal_keys | ||
prepare_policy_repo | ||
|
||
trap clean_up EXIT | ||
|
||
# Bring up OPAL containers | ||
compose down --remove-orphans | ||
compose up -d | ||
sleep 10 | ||
|
||
# Check containers started correctly | ||
check_clients_logged "Connected to PubSub server" | ||
check_clients_logged "Got policy bundle" | ||
check_clients_logged 'PUT /v1/data/static -> 204' | ||
check_no_error | ||
|
||
# Test functionality | ||
test_data_publish "bob" | ||
test_push_policy "something" | ||
test_statistics | ||
|
||
echo "- Testing broadcast channel disconnection" | ||
compose restart broadcast_channel | ||
sleep 10 | ||
|
||
test_data_publish "alice" | ||
test_push_policy "another" | ||
test_data_publish "sunil" | ||
test_data_publish "eve" | ||
test_push_policy "best_one_yet" | ||
# TODO: Test statistics feature again after broadcaster restart (should first fix statistics bug) | ||
} | ||
|
||
main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters