Skip to content

Commit

Permalink
migrate run.sh to pytest
Browse files Browse the repository at this point in the history
  • Loading branch information
Tajudeen committed Feb 16, 2025
1 parent e6690be commit dc8f3e1
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 0 deletions.
119 changes: 119 additions & 0 deletions app-tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import pytest
import os
import subprocess
import time
import requests
import docker
import shutil
from pathlib import Path


@pytest.fixture(scope="session")
def generate_opal_keys():
"""Generate OPAL keys and create an .env file."""
print("- Generating OPAL keys")

opal_private_key_passphrase = "123456"
subprocess.run([
"ssh-keygen", "-q", "-t", "rsa", "-b", "4096", "-m", "pem",
"-f", "opal_crypto_key", "-N", opal_private_key_passphrase
], check=True)

with open("opal_crypto_key.pub") as f:
opal_auth_public_key = f.read().strip()
with open("opal_crypto_key") as f:
opal_auth_private_key = f.read().replace('\n', '_')

os.remove("opal_crypto_key.pub")
os.remove("opal_crypto_key")

opal_auth_master_token = subprocess.run(
["openssl", "rand", "-hex", "16"], capture_output=True, text=True
).stdout.strip()

env_vars = {
"OPAL_AUTH_PRIVATE_KEY_PASSPHRASE": opal_private_key_passphrase,
"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_REPO_WATCHER_ENABLED": "0",
"OPAL_STATISTICS_ENABLED": "true"
}

opal_server = subprocess.Popen(["opal-server", "run"], env={**os.environ, **env_vars})
time.sleep(2)

opal_client_token = subprocess.run(
["opal-client", "obtain-token", opal_auth_master_token, "--type", "client"],
capture_output=True, text=True
).stdout.strip()

opal_data_source_token = subprocess.run(
["opal-client", "obtain-token", opal_auth_master_token, "--type", "datasource"],
capture_output=True, text=True
).stdout.strip()

opal_server.terminate()
opal_server.wait()
time.sleep(5)

# Create .env file
with open(".env", "w") as f:
f.write(f"OPAL_AUTH_PUBLIC_KEY=\"{opal_auth_public_key}\"\n")
f.write(f"OPAL_AUTH_PRIVATE_KEY=\"{opal_auth_private_key}\"\n")
f.write(f"OPAL_AUTH_MASTER_TOKEN=\"{opal_auth_master_token}\"\n")
f.write(f"OPAL_CLIENT_TOKEN=\"{opal_client_token}\"\n")
f.write(f"OPAL_AUTH_PRIVATE_KEY_PASSPHRASE=\"{opal_private_key_passphrase}\"\n")
f.write("OPAL_STATISTICS_ENABLED=true\n")

os.environ["OPAL_STATISTICS_ENABLED"] = "true"
yield

if Path(".env").exists():
os.remove(".env")


@pytest.fixture(scope="session")
def prepare_policy_repo():
"""Clone and configure the policy repo for testing."""
print("- Setting up policy repository")
repo_url = os.getenv("OPAL_POLICY_REPO_URL", "[email protected]:permitio/opal-tests-policy-repo.git")
policy_repo_branch = f"test-{os.getpid()}"

if os.path.exists("opal-tests-policy-repo"):
shutil.rmtree("opal-tests-policy-repo")

result = subprocess.run(["git", "clone", repo_url, "opal-tests-policy-repo"], capture_output=True, text=True)

if result.returncode != 0:
print("❌ Error cloning repository:", result.stderr)
pytest.fail("Failed to clone the policy repo")

os.chdir("opal-tests-policy-repo")
subprocess.run(["git", "checkout", "-b", policy_repo_branch], check=True)
subprocess.run(["git", "push", "--set-upstream", "origin", policy_repo_branch], check=True)
os.chdir("..")

yield policy_repo_branch

os.chdir("opal-tests-policy-repo")
subprocess.run(["git", "push", "-d", "origin", policy_repo_branch], check=True)
os.chdir("..")
shutil.rmtree("opal-tests-policy-repo")


@pytest.fixture(scope="session")
def docker_services():
"""Start OPAL containers."""
client = docker.from_env()
print("- Starting Docker containers")
client.containers.run("permitio/opal-server:latest", detach=True, ports={"7002": 7002})
client.containers.run("permitio/opal-client:latest", detach=True, ports={"7766": 7766})
time.sleep(10)

yield client

print("- Stopping Docker containers")
for container in client.containers.list():
container.stop()
container.remove()
1 change: 1 addition & 0 deletions app-tests/docker-compose-app-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ services:

opal_server:
image: permitio/opal-server:${OPAL_IMAGE_TAG:-latest}
env_file: .env
deploy:
mode: replicated
replicas: 2
Expand Down
Empty file added app-tests/pytest.ini
Empty file.
Empty file added app-tests/tests/__init__.py
Empty file.
56 changes: 56 additions & 0 deletions app-tests/tests/test_opal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import pytest
import time
import requests
import subprocess

def test_push_policy(prepare_policy_repo):
"""Test pushing a new policy to OPAL."""
repo_branch = prepare_policy_repo
policy_name = "test_policy"
rego_file = f"{policy_name}.rego"

subprocess.run(["touch", f"opal-tests-policy-repo/{rego_file}"], check=True)
subprocess.run(["git", "add", rego_file], cwd="opal-tests-policy-repo", check=True)
subprocess.run(["git", "commit", "-m", f"Add {rego_file}"], cwd="opal-tests-policy-repo", check=True)
subprocess.run(["git", "push"], cwd="opal-tests-policy-repo", check=True)

webhook_data = {
"gitEvent": "git.push",
"repository": {"git_url": "[email protected]:permitio/opal-tests-policy-repo.git"}
}

response = requests.post(
"http://localhost:7002/webhook",
json=webhook_data,
headers={"Content-Type": "application/json", "x-webhook-token": "xxxxx"}
)
time.sleep(5)

assert response.status_code == 200


def test_data_publish():
"""Test publishing data via OPAL client."""
user = "bob"
response = subprocess.run(
["opal-client", "publish-data-update", "--src-url", "https://api.country.is/23.54.6.78",
"-t", "policy_data", "--dst-path", f"/users/{user}/location"],
capture_output=True, text=True
)
time.sleep(5)

assert "Event Published Successfully" in response.stdout, f"Unexpected response: {response.stdout}"


def test_statistics():
"""Test statistics API."""
for port in range(7002, 7004):
response = requests.get(
f"http://localhost:{port}/stats",
headers={"Authorization": "Bearer xxxxx"}
)
print("📌 Debug: OPAL Server Response ->", response.text)
assert response.status_code == 200, f"Unexpected response: {response.text}"
assert '"client_count":' in response.text, "Statistics response does not contain expected client count"
assert '"server_count":' in response.text, "Statistics response does not contain expected server count"

0 comments on commit dc8f3e1

Please sign in to comment.