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 make file #2554

Closed
wants to merge 36 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
e53ac13
Add make file compatible with Mac and fix tests that filed on re-runs.
Jul 3, 2024
d7a18f4
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Jul 3, 2024
dc997f0
Fix for pytests.
Jul 3, 2024
bc19a4c
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Jul 3, 2024
8efa3fb
Check for OS before running brew command.
Jul 3, 2024
fbeaa70
If not mac setup docker on unix.
Jul 3, 2024
eff9f98
Update local integration test workflow in CI to use Makefile.
Jul 3, 2024
f9d6e36
Set host for CI.
Jul 3, 2024
3f9215a
Fix pre-init-checks.
Jul 3, 2024
4c1de2c
Setup tmate for testing.
Jul 3, 2024
0dcbbef
Run kind only on mac.
Jul 3, 2024
2b2c4b3
Remove mac specific steps.
Jul 3, 2024
fd1720c
Fix make file for mac again.
Jul 4, 2024
6d3d851
Add debugging.
Jul 4, 2024
c97782d
Ignore errors on mac filters.
Jul 4, 2024
a715cd9
Remove tmate.
Jul 4, 2024
97ced6c
Add debugging and tmate.
Jul 4, 2024
e40f2da
Add ./scripts/create_test_user.sh.
Jul 4, 2024
b6325ba
Fix playwright tests target name.
Jul 4, 2024
f93bf1c
Headless playwright-tests.
Jul 4, 2024
0a0fe8d
Save playwright test video artifact.
Jul 4, 2024
1e6d46b
Remove tmate.
Jul 4, 2024
d3a1982
Fix NEBARI_CONFIG_PATH.
Jul 4, 2024
d8115d7
CI refactor and re-enable cypress.
Jul 4, 2024
d9c20ed
Enable cypress tests.
Jul 4, 2024
8901f6d
Remove Cypress tests.
Jul 4, 2024
c446b97
Merge branch 'develop' into add-makefile
pt247 Jul 4, 2024
4764886
Run pytest before playwrite tests.
Jul 4, 2024
b5d2cd9
Fix playwright tets.
Jul 5, 2024
ffc4e94
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Jul 5, 2024
6754ff9
Add debug logs.
Jul 5, 2024
af5ae29
Fix ruff error.
Jul 5, 2024
8b834d5
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Jul 5, 2024
c027089
Remove logging changes in tests.
Jul 8, 2024
f6dac5a
Remove logging changes in tests.
Jul 8, 2024
cb2b94a
Merge branch 'develop' into add-makefile
pt247 Jul 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 12 additions & 100 deletions .github/workflows/test_local_integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,132 +71,44 @@ jobs:
python-version: "3.11"
miniconda-version: "latest"

- name: Install Nebari and playwright

- name: Install Nebari and playwright and initialize Nebari
run: |
pip install .[dev]
playwright install
make init

- uses: azure/[email protected]
with:
version: v1.19.16

- name: Enable docker permissions for user
run: |
sudo docker ps
sudo usermod -aG docker $USER && newgrp docker

docker info
docker ps

- name: Get routing table for docker pods
run: |
ip route

- name: Initialize Nebari Cloud
run: |
mkdir -p local-deployment
cd local-deployment
nebari init local --project=thisisatest --domain github-actions.nebari.dev --auth-provider=password

# Need smaller profiles on Local Kind
sed -i -E 's/(cpu_guarantee):\s+[0-9\.]+/\1: 0.25/g' "nebari-config.yaml"
sed -i -E 's/(mem_guarantee):\s+[A-Za-z0-9\.]+/\1: 0.25G/g' "nebari-config.yaml"

# Change default JupyterLab theme
cat >> nebari-config.yaml <<- EOM
jupyterlab:
default_settings:
"@jupyterlab/apputils-extension:themes":
theme: JupyterLab Dark
EOM

# Change default value for minio persistence size
cat >> nebari-config.yaml <<- EOM
monitoring:
enabled: true
overrides:
minio:
persistence:
size: 1Gi
EOM

cat nebari-config.yaml

- name: Deploy Nebari
working-directory: local-deployment
- name: Deploy Nebari and create user
run: |
nebari deploy --config nebari-config.yaml --disable-prompt

- name: Basic kubectl checks after deployment
if: always()
run: |
kubectl get all,cm,secret,pv,pvc,ing -A

- name: Check github-actions.nebari.dev resolves
run: |
nslookup github-actions.nebari.dev

- name: Curl jupyterhub login page
run: |
curl -k https://github-actions.nebari.dev/hub/home -i

- name: Create example-user
working-directory: local-deployment
run: |
nebari keycloak adduser --user "${TEST_USERNAME}" "${TEST_PASSWORD}" --config nebari-config.yaml
nebari keycloak listusers --config nebari-config.yaml
make deploy

- uses: actions/setup-node@v4
with:
node-version: 20

- name: Get nebari-config.yaml full path
run: echo "NEBARI_CONFIG_PATH=`realpath ./local-deployment/nebari-config.yaml`" >> "$GITHUB_ENV"

- name: Cypress run
uses: cypress-io/github-action@v6
env:
CYPRESS_EXAMPLE_USER_NAME: ${{ env.TEST_USERNAME }}
CYPRESS_EXAMPLE_USER_PASSWORD: ${{ env.TEST_PASSWORD }}
CYPRESS_BASE_URL: https://github-actions.nebari.dev/
with:
working-directory: tests/tests_e2e
- name: Deployment Pytests
run: |
make pytest

- name: Playwright Tests
env:
KEYCLOAK_USERNAME: ${{ env.TEST_USERNAME }}
KEYCLOAK_PASSWORD: ${{ env.TEST_PASSWORD }}
NEBARI_FULL_URL: https://github-actions.nebari.dev/
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
make playwright-tests

- name: Save Cypress screenshots and videos
- name: Save playwright videos.
if: always()
uses: actions/[email protected]
with:
name: e2e-cypress
name: e2e-playwright
path: |
./tests/tests_e2e/cypress/screenshots/
./tests/tests_e2e/cypress/videos/
./tests/tests_e2e/playwright/videos/

- name: Deployment Pytests
env:
KEYCLOAK_USERNAME: ${{ env.TEST_USERNAME }}
KEYCLOAK_PASSWORD: ${{ env.TEST_PASSWORD }}
run: |
pytest tests/tests_deployment/ -v -s

### CLEANUP AFTER TESTS
- name: Cleanup nebari deployment
# Since this is not critical for most pull requests and takes more than half of the time
# in the CI, it makes sense to only run on merge to main or workflow_dispatch to speed
# up feedback cycle
if: github.ref_name == 'develop' || github.event_name == 'workflow_dispatch'
working-directory: local-deployment
run: |
nebari destroy --config nebari-config.yaml --disable-prompt
make clean
108 changes: 108 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
all: init deploy test
build: init deploy

SHELL = /bin/bash
TARGET := local-deployment/nebari-config.yaml
TEST_USERNAME := "test-user"
TEST_PASSWORD := "P@sswo3d"
NEBARI_CONFIG_PATH = `realpath ./local-deployment/nebari-config.yaml`
UNAME_S := $(shell uname -s)

ifeq ($(UNAME_S),Darwin)
IS_MAC := true
HOST := local-deployment.nebari.dev
else
IS_MAC := false
HOST := github-actions.nebari.dev
endif

clean: nebari-destroy delete-cluster

nebari-destroy:
nebari destroy -c local-deployment/nebari-config.yaml --disable-prompt
rm $(TARGET)

delete-cluster:
-@$(IS_MAC) && kind delete clusters test-cluster
rm -rf local-deployment/stages

pre-init-checks:
@echo Checking prerequsits
@docker --version
-@$(IS_MAC) && ping $(HOST) | head -1 | grep '172.18.1.100'
-@$(IS_MAC) && brew services info chipmk/tap/docker-mac-net-connect
-@$(IS_MAC) && kind --version
-@echo $(SHELL)
-@$(IS_MAC) || sudo usermod -aG docker $USER newgrp docker

install:
pip install .[dev]
playwright install
@echo "Initialize Nebari Cloud."

init: pre-init-checks install
@echo "Initializing deployment."
mkdir -p local-deployment
rm -rf loca-deployment/*
cd local-deployment && nebari init local --project=thisisatest --domain $(HOST) --auth-provider=password
#sed -i -E 's/(cpu_guarantee):\s+[0-9\.]+/\1: 0.25/g' "nebari-config.yaml"
#sed -i -E 's/(mem_guarantee):\s+[A-Za-z0-9\.]+/\1: 0.25G/g' "nebari-config.yaml"
@echo "Change default JupyterLab theme."
@echo "jupyterlab:" >> $(TARGET)
@echo " default_settings:" >> $(TARGET)
@echo ' "@jupyterlab/apputils-extension:themes":' >> $(TARGET)
@echo " theme: JupyterLab Dark" >> $(TARGET)
@echo "monitoring:" >> $(TARGET)
@echo " enabled: true" >> $(TARGET)
@echo " overrides:" >> $(TARGET)
@echo " minio:" >> $(TARGET)
@echo " persistence:" >> $(TARGET)
@echo " size: 1Gi" >> $(TARGET)
-@$(IS_MAC) && echo "conda_store:" >> $(TARGET)
-@$(IS_MAC) && echo " image: quay.io/aktech/conda-store-server" >> $(TARGET)
-@$(IS_MAC) && echo " image_tag: sha-558beb8" >> $(TARGET)
-@$(IS_MAC) && awk -v n=13 -v s=' overrides:' 'NR == n {print s} {print}' $(TARGET) > tmp && mv tmp $(TARGET)
-@$(IS_MAC) && awk -v n=14 -v s=' image:' 'NR == n {print s} {print}' $(TARGET) > tmp && mv tmp $(TARGET)
-@$(IS_MAC) && awk -v n=15 -v s=' repository: quay.io/aktech/keycloak' 'NR == n {print s} {print}' $(TARGET) > tmp && mv tmp $(TARGET)
@cat local-deployment/nebari-config.yaml

deploy:
cd local-deployment && nebari deploy -c nebari-config.yaml
@echo "Create example-user"
@pwd
@ls
./scripts/create_test_user.sh $(TEST_USERNAME) $(TEST_PASSWORD) $(NEBARI_CONFIG_PATH)
@echo "Basic kubectl checks after deployment"
kubectl get all,cm,secret,pv,pvc,ing -A
@echo "Curl jupyterhub login page"
curl -k "https://$(HOST)/hub/home" -i
@echo "Get nebari-config.yaml full path"
@echo "NEBARI_CONFIG_PATH = $(NEBARI_CONFIG_PATH)"

cypress-run:
@echo "CYPRESS_EXAMPLE_USER_NAME=$(TEST_USERNAME) CYPRESS_EXAMPLE_USER_PASSWORD=$(TEST_PASSWORD) CYPRESS_BASE_URL=https://$(HOST)/"
cd tests/tests_e2e/ && \
npm install && \
CYPRESS_EXAMPLE_USER_NAME=$(TEST_USERNAME) \
CYPRESS_EXAMPLE_USER_PASSWORD=$(TEST_PASSWORD) \
CYPRESS_BASE_URL=https://$(HOST) \
NEBARI_CONFIG_PATH=$(NEBARI_CONFIG_PATH) \
npx cypress run # --headed

playwright-tests:
@echo "Run playwright pytest tests in headed mode with the chromium browser"
cd tests/tests_e2e/playwright && envsubst < .env.tpl > .env
cd tests/tests_e2e/playwright && \
KEYCLOAK_USERNAME=${TEST_USERNAME} \
KEYCLOAK_PASSWORD=${TEST_PASSWORD} \
NEBARI_FULL_URL=https://$(HOST) \
pytest --browser chromium # --headed

pytest:
KEYCLOAK_USERNAME=${TEST_USERNAME} \
KEYCLOAK_PASSWORD=${TEST_PASSWORD} \
NEBARI_HOSTNAME=${HOST} \
NEBARI_CONFIG_PATH=$(NEBARI_CONFIG_PATH) \
pytest tests/tests_deployment/ -v -s

test: playwright-tests pytest # SKIPPED cypress-run
16 changes: 16 additions & 0 deletions scripts/create_test_user.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
TEST_USERNAME=$1
TEST_PASSWORD=$2
NEBARI_CONFIG_PATH=$3
count="$(nebari keycloak listusers --config "$NEBARI_CONFIG_PATH" | grep test-user | wc -l | tr -d '[:blank:]')"
echo "TEST_USERNAME: $TEST_USERNAME, TEST_PASSWORD: ${TEST_PASSWORD}"
cd
if [[ $count == "0" ]]; then
nebari keycloak adduser \
--user "${TEST_USERNAME}" "${TEST_PASSWORD}" \
--config "$NEBARI_CONFIG_PATH"
else
echo 'Nebari users already created.'
echo `pwd`
nebari keycloak listusers --config "$NEBARI_CONFIG_PATH"
fi
17 changes: 12 additions & 5 deletions tests/common/navigator.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,11 @@ def start_server(self) -> None:
we look for html elements that exist when no server is running, if
they aren't visible, we check for an existing server start option.
"""
# wait for the page to load
logout_button = self.page.get_by_text("Logout", exact=True)
logout_button.wait_for(state="attached", timeout=90000)
self.page.get_by_text("Logout", exact=True)
file_menu = self.page.get_by_text("File", exact=True)
if file_menu.is_visible():
logger.debug("Server is already up!")
return

# if the server is already running
start_locator = self.page.get_by_role("button", name="My Server", exact=True)
Expand Down Expand Up @@ -255,7 +257,9 @@ def reset_workspace(self):
if popup:
self._set_environment_via_popup(kernel=None)

# go to Kernel menu
dialog = self.page.get_by_role("dialog")
if dialog.is_visible():
dialog.get_by_role("button", name="No Kernel").click()
kernel_menuitem = self.page.get_by_role("menuitem", name="Kernel", exact=True)
kernel_menuitem.click()
# shut down multiple running kernels
Expand Down Expand Up @@ -284,8 +288,11 @@ def reset_workspace(self):
self.page.get_by_role("menuitem", name="Close All Tabs", exact=True).click()

# there may be a popup to save your work, don't save
time.sleep(2)
if self.page.get_by_text("Save your work", exact=True).is_visible():
self.page.get_by_role("button", name="Discard", exact=True).click()
self.page.get_by_role(
"button", name="Discard changes to file", exact=True
).click()

# wait to ensure that the Launcher is showing
self.page.get_by_text("VS Code [↗]", exact=True).wait_for(
Expand Down
3 changes: 2 additions & 1 deletion tests/common/playwright_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ def _navigator_session(request, browser_name, pytestconfig):
nav.stop_server()
except Exception as e:
logger.debug(e)
nav.teardown()
finally:
nav.teardown()


@pytest.fixture(scope="function")
Expand Down
4 changes: 4 additions & 0 deletions tests/common/run_notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ def run(
# navigate to specific notebook
self.open_notebook(path)
# make sure the focus is on the dashboard tab we want to run
time.sleep(retry_wait_time)
dialog = self.nav.page.get_by_role("dialog")
if dialog.is_visible():
dialog.get_by_role("button", name="No Kernel").click()
self.nav.page.get_by_role("tab", name=filename).get_by_text(filename).click()
self.nav.set_environment(kernel=conda_env)

Expand Down
13 changes: 11 additions & 2 deletions tests/tests_deployment/test_jupyterhub_api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
from requests.cookies import CookieConflictError

from tests.tests_deployment import constants
from tests.tests_deployment.keycloak_utils import (
Expand All @@ -10,9 +11,14 @@


@pytest.mark.filterwarnings("ignore::urllib3.exceptions.InsecureRequestWarning")
@pytest.mark.filterwarnings("ignore::ResourceWarning")
def test_jupyterhub_loads_roles_from_keycloak():
session = get_jupyterhub_session()
xsrf_token = session.cookies.get("_xsrf")
try:
xsrf_token = session.cookies.get("_xsrf")
except CookieConflictError:
xsrf_token = session.cookies.get("_xsrf", path="/hub/")

response = session.get(
f"https://{constants.NEBARI_HOSTNAME}/hub/api/users/{constants.KEYCLOAK_USERNAME}",
headers={"X-XSRFToken": xsrf_token},
Expand Down Expand Up @@ -105,7 +111,10 @@ def test_keycloak_roles_attributes_parsed_as_jhub_scopes(
@pytest.mark.filterwarnings("ignore::urllib3.exceptions.InsecureRequestWarning")
def test_jupyterhub_loads_groups_from_keycloak():
session = get_jupyterhub_session()
xsrf_token = session.cookies.get("_xsrf")
try:
xsrf_token = session.cookies.get("_xsrf")
except CookieConflictError:
xsrf_token = session.cookies.get("_xsrf", path="/hub/")
response = session.get(
f"https://{constants.NEBARI_HOSTNAME}/hub/api/users/{constants.KEYCLOAK_USERNAME}",
headers={"X-XSRFToken": xsrf_token},
Expand Down
Loading