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

Add workflow to run conda-store user journey tests #2895

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
110 changes: 85 additions & 25 deletions .github/workflows/test_local_integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ env:
TEST_USERNAME: "test-user"
TEST_PASSWORD: "P@sswo3d"
NEBARI_IMAGE_TAG: "main"
PYTHON_VERSION: "3.11"

on:
pull_request:
Expand Down Expand Up @@ -70,7 +71,7 @@ jobs:
CONDA: /home/runnerx/miniconda3
with:
auto-update-conda: true
python-version: "3.11"
python-version: ${{ env.PYTHON_VERSION }}
miniconda-version: "latest"

- name: Install JQ
Expand Down Expand Up @@ -99,7 +100,7 @@ jobs:
- name: Create example-user
working-directory: ${{ steps.init.outputs.directory }}
run: |
nebari keycloak adduser --user "${TEST_USERNAME}" "${TEST_PASSWORD}" --config ${{ steps.init.outputs.config }}
nebari keycloak adduser --user "${TEST_USERNAME}" "${TEST_PASSWORD}" --config ${{ steps.init.outputs.config }} --groups superadmin
nebari keycloak listusers --config ${{ steps.init.outputs.config }}

- name: Await Workloads
Expand All @@ -111,38 +112,97 @@ jobs:
max-restarts: 3

### DEPLOYMENT TESTS
- name: Deployment Pytests
# - name: Deployment Pytests
# env:
# NEBARI_CONFIG_PATH: ${{ steps.init.outputs.config }}
# KEYCLOAK_USERNAME: ${{ env.TEST_USERNAME }}
# KEYCLOAK_PASSWORD: ${{ env.TEST_PASSWORD }}
# run: |
# pytest tests/tests_deployment/ -v -s

# ### USER-JOURNEY TESTS
# - uses: actions/setup-node@v4
# with:
# node-version: 20

# - name: Playwright Tests
# env:
# KEYCLOAK_USERNAME: ${{ env.TEST_USERNAME }}
# KEYCLOAK_PASSWORD: ${{ env.TEST_PASSWORD }}
# NEBARI_FULL_URL: "https://${{ steps.init.outputs.domain }}/"
# working-directory: tests/tests_e2e/playwright
# run: |
# # create environment file
# envsubst < .env.tpl > .env
# # run playwright pytest tests in headed mode with the chromium browser
# xvfb-run pytest --browser chromium --slowmo 300 --headed

# - name: Save Playwright recording artifacts
# if: always()
# uses: actions/[email protected]
# with:
# name: e2e-playwright
# path: |
# ./tests/tests_e2e/playwright/videos/

### CONDA-STORE TESTS
- name: "Checkout conda-store"
uses: actions/checkout@main
with:
fetch-depth: 0
repository: conda-incubator/conda-store
ref: main
path: conda-store

- name: "Set up conda-store conda env"
uses: conda-incubator/setup-miniconda@v3
env:
NEBARI_CONFIG_PATH: ${{ steps.init.outputs.config }}
CONDA: /home/runnerx/miniconda3
with:
environment-file: conda-store/conda-store-server/environment-dev.yaml
miniforge-version: latest
auto-activate-base: false
activate-environment: conda-store-server-dev
python-version: ${{ env.PYTHON_VERSION }}
conda-remove-defaults: "true"

- name: Install conda-store dependencies
run: |
which python
# install conda-store-server
python -m pip install conda-store/conda-store-server

- name: Get conda store token from login
id: conda-store-token
env:
CONDA_STORE_BASE_URL: https://${{ steps.init.outputs.domain }}
KEYCLOAK_USERNAME: ${{ env.TEST_USERNAME }}
KEYCLOAK_PASSWORD: ${{ env.TEST_PASSWORD }}
working-directory: ${{ steps.init.outputs.directory }}
run: |
pytest tests/tests_deployment/ -v -s

### USER-JOURNEY TESTS
- uses: actions/setup-node@v4
with:
node-version: 20
echo "${KEYCLOAK_USERNAME}"
LOGIN_URL=$(curl -c /tmp/nebari-session --insecure -Ls ${CONDA_STORE_BASE_URL}/conda-store/login/\?next= | grep auth/realms/nebari/login-actions/authenticate | grep -oP '(?<=action=")([^"]+)' | sed 's/\&amp\;/\&/g')
echo "${LOGIN_URL}"
curl -X POST --insecure -b /tmp/nebari-session -H "Content-Type: application/x-www-form-urlencoded" -vv --data '{"credentialId":"", "username": "${KEYCLOAK_USERNAME}", "password": "${KEYCLOAK_PASSWORD}"}' $LOGIN_URL
echo "CONDA_STORE_TOKEN=$(curl --insecure -L -X POST -b /tmp/conda-store-cookie ${CONDA_STORE_BASE_URL}/conda-store/api/v1/token | jq --raw-output .data.token)" >> "$GITHUB_OUTPUT"

- name: Playwright Tests
- name: Run conda-store-server user_journey tests
env:
NEBARI_CONFIG_PATH: ${{ steps.init.outputs.config }}
KEYCLOAK_USERNAME: ${{ env.TEST_USERNAME }}
KEYCLOAK_PASSWORD: ${{ env.TEST_PASSWORD }}
NEBARI_FULL_URL: "https://${{ steps.init.outputs.domain }}/"
working-directory: tests/tests_e2e/playwright
CONDA_STORE_BASE_URL: https://${{ steps.init.outputs.domain }}
CONDA_STORE_TEST_VERIFY_SSL: 0
CONDA_STORE_TOKEN: ${{ steps.conda-store-token.outputs.CONDA_STORE_TOKEN }}
run: |
# create environment file
envsubst < .env.tpl > .env
# run playwright pytest tests in headed mode with the chromium browser
xvfb-run pytest --browser chromium --slowmo 300 --headed

- name: Save Playwright recording artifacts
if: always()
uses: actions/[email protected]
with:
name: e2e-playwright
path: |
./tests/tests_e2e/playwright/videos/
curl --insecure --header "Authorization: Bearer ${CONDA_STORE_TOKEN}" ${CONDA_STORE_BASE_URL}/conda-store/api/v1/permission/ | jq
cd conda-store/conda-store-server
python -m pytest -m "user_journey"

- name: Get conda-store-server logs
if: ${{ failure() }}
run: |
kubectl logs -n dev deployment/nebari-conda-store-server

### CLEANUP AFTER TESTS
- name: Cleanup nebari deployment
Expand Down
5 changes: 4 additions & 1 deletion src/_nebari/keycloak.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ def do_keycloak(config: schema.Main, *args):

username = args[1]
password = args[2] if len(args) >= 3 else None
create_user(keycloak_admin, username, password, domain=config.domain)
groups = args[3] if len(args) >= 4 else None
create_user(
keycloak_admin, username, password, domain=config.domain, groups=groups
)
elif args[0] == "listusers":
list_users(keycloak_admin)
else:
Expand Down
12 changes: 10 additions & 2 deletions src/_nebari/subcommands/keycloak.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import json
import pathlib
from typing import Tuple
from typing import List, Tuple

import typer
from typing_extensions import Annotated

from _nebari.config import read_configuration
from _nebari.keycloak import do_keycloak, export_keycloak_users
Expand Down Expand Up @@ -36,11 +37,18 @@ def add_user(
"--config",
help="nebari configuration file path",
),
groups: Annotated[
List[str],
typer.Option(
"--groups",
help="Role to give the user. Can be specified multiple times for multiple groups",
),
] = None,
):
"""Add a user to Keycloak. User will be automatically added to the [italic]analyst[/italic] group."""
from nebari.plugins import nebari_plugin_manager

args = ["adduser", add_users[0], add_users[1]]
args = ["adduser", add_users[0], add_users[1], groups]
config_schema = nebari_plugin_manager.config_schema
config = read_configuration(config_filename, config_schema)
do_keycloak(config, *args)
Expand Down
Loading