Skip to content

Commit

Permalink
Merge branch 'master' into buy-credits
Browse files Browse the repository at this point in the history
  • Loading branch information
ignapas committed Jan 9, 2024
2 parents 73e531e + f533257 commit 86ef13c
Show file tree
Hide file tree
Showing 13 changed files with 452 additions and 18 deletions.
67 changes: 67 additions & 0 deletions .github/workflows/ci-testing-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2184,6 +2184,72 @@ jobs:
if: always()
run: ./ci/github/system-testing/e2e.bash clean_up

system-test-e2e-playwright:
needs: [changes, build-test-images]
if: ${{ needs.changes.outputs.anything == 'true' || github.event_name == 'push' }}
timeout-minutes: 30 # if this timeout gets too small, then split the tests
name: "[sys] e2e-playwright"
runs-on: ${{ matrix.os }}
# NOTE: this is an interesting way, but generate a load of issues like not having docker installed, etc etc.
# container:
# image: mcr.microsoft.com/playwright/python:v1.39.0-jammy
strategy:
matrix:
python: ["3.10"]
os: [ubuntu-22.04]
docker_buildx: [v0.10.4]
fail-fast: false
steps:
- uses: actions/checkout@v4
- name: setup docker buildx
id: buildx
uses: docker/setup-buildx-action@v3
with:
version: ${{ matrix.docker_buildx }}
driver: docker-container
- name: setup python environment
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
cache: "pip"
cache-dependency-path: "tests/e2e-playwright/requirements/dev.txt"
- name: expose github runtime for buildx
uses: crazy-max/ghaction-github-runtime@v3
- name: download docker images
uses: actions/download-artifact@v4
with:
name: docker-buildx-images-${{ runner.os }}-${{ github.sha }}
path: /${{ runner.temp }}/build
- name: load docker images
run: make load-images local-src=/${{ runner.temp }}/build
- name: prepare devenv
run: make devenv
- name: show system version
run: ./ci/helpers/show_system_versions.bash
- name: setup
run: |
./ci/github/system-testing/e2e-playwright.bash install
- name: test
run: |
./ci/github/system-testing/e2e-playwright.bash test
- name: dump docker logs
id: docker_logs_dump
if: failure()
run: ./ci/github/system-testing/e2e-playwright.bash dump_docker_logs
- name: upload docker logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: ${{ github.job }}_docker_logs
path: ./tests/e2e-playwright/test_failures
- name: upload tracing if failed
if: always()
uses: actions/upload-artifact@v4
with:
name: ${{ github.job }}_tracing
path: tests/e2e-playwright/test-results


system-test-environment-setup:
timeout-minutes: 30 # if this timeout gets too small, then split the tests
name: "[sys] environment setup"
Expand Down Expand Up @@ -2224,6 +2290,7 @@ jobs:
needs:
[
system-test-e2e,
system-test-e2e-playwright,
system-test-environment-setup,
system-test-public-api,
system-test-swarm-deploy,
Expand Down
49 changes: 49 additions & 0 deletions ci/github/system-testing/e2e-playwright.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash
# http://redsymbol.net/articles/unofficial-bash-strict-mode/
# https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#running-puppeteer-on-travis-ci
set -o errexit # abort on nonzero exitstatus
set -o nounset # abort on unbound variable
set -o pipefail # don't hide errors within pipes
IFS=$'\n\t'

# in case it's a Pull request, the env are never available, default to itisfoundation to get a maybe not too old version for caching
DOCKER_IMAGE_TAG=$(exec ci/helpers/build_docker_image_tag.bash)
export DOCKER_IMAGE_TAG

install() {
make devenv
source .venv/bin/activate
pushd tests/e2e-playwright
make install-ci-up-simcore
popd
}

test() {
source .venv/bin/activate
pushd tests/e2e-playwright
make test-sleepers
popd
}

dump_docker_logs() {
# get docker logs
# NOTE: Timeout avoids issue with dumping logs that hang!
out_dir=tests/e2e-playwright/test_failures
mkdir --parents "$out_dir"

for service_id in $(docker service ls -q); do
service_name=$(docker service inspect "$service_id" --format="{{.Spec.Name}}")
echo "Dumping logs for $service_name"
(timeout 30 docker service logs --timestamps --tail=400 --details "$service_id" >"$out_dir/$service_name.log" 2>&1) || true
done
}

# Check if the function exists (bash specific)
if declare -f "$1" >/dev/null; then
# call arguments verbatim
"$@"
else
# Show a helpful error
echo "'$1' is not a known function name" >&2
exit 1
fi
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,10 @@ async def _publish_sidecar_log(
async def run(self, command: list[str]) -> TaskOutputData:
# ensure we pass the initial logs and progress
await self._publish_sidecar_log(
f"Starting task for {self.task_parameters.image}:{self.task_parameters.tag} on {socket.gethostname()}..."
f"Starting task {self.task_parameters.image}:{self.task_parameters.tag} on {socket.gethostname()}..."
)
# NOTE: this is for tracing purpose
_logger.info("Running task owner: %s", self.task_parameters.task_owner)

settings = Settings.create_from_envs()
run_id = f"{uuid4()}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ qx.Class.define("osparc.workbench.WorkbenchUI", {

__addDesktop: function() {
const desktop = this.__desktop = new qx.ui.window.Desktop(new qx.ui.window.Manager());
osparc.utils.Utils.setIdToWidget(desktop, "desktopWindow");
this.__workbenchLayout.add(desktop, {
left: 0,
top: 0,
Expand Down
58 changes: 56 additions & 2 deletions tests/e2e-playwright/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,40 @@ leave build:
$(MAKE_C) $(REPO_BASE_DIR) $@


SIMCORE_DOT_ENV = $(abspath $(CURDIR)/../../.env)

define _up_simcore
# set some parameters to allow for e2e to run
echo LOGIN_REGISTRATION_INVITATION_REQUIRED=0 >> $(SIMCORE_DOT_ENV)
echo LOGIN_REGISTRATION_CONFIRMATION_REQUIRED=0 >> $(SIMCORE_DOT_ENV)
echo DEFAULT_MAX_NANO_CPUS=1000000000 >> $(SIMCORE_DOT_ENV)
echo DEFAULT_MAX_MEMORY=134217728 >> $(SIMCORE_DOT_ENV)
echo SIDECAR_FORCE_CPU_NODE=1 >> $(SIMCORE_DOT_ENV)
$(MAKE_C) $(REPO_BASE_DIR) up-prod ops_ci=1
endef

SERVICE_IMAGE_NAME = "sleeper"
SERVICE_VERSION = "2.1.6"
SERVICE_IMAGE_TAG = $(SERVICE_IMAGE_NAME):$(SERVICE_VERSION)

define _transfer-images-to-registry
# pushing sleeper image
@docker pull itisfoundation/$(SERVICE_IMAGE_TAG)
@docker tag itisfoundation/$(SERVICE_IMAGE_TAG) registry:5000/simcore/services/comp/itis/$(SERVICE_IMAGE_TAG)
@docker push registry:5000/simcore/services/comp/itis/$(SERVICE_IMAGE_TAG)
# completed transfer of images
@curl -s registry:5000/v2/_catalog | jq '.repositories'
@curl -s http://registry:5000/v2/simcore/services/comp/itis/$(SERVICE_IMAGE_NAME)/tags/list?n=50 | jq '.'
endef

define _give_service_access_rights
docker exec \
$$(docker ps -q --filter="name=postgres") \
psql --user scu --dbname simcoredb --command \
"INSERT INTO services_access_rights (key, version, gid, execute_access, write_access, product_name) \
VALUES ('simcore/services/comp/itis/$(SERVICE_IMAGE_NAME)', '$(SERVICE_VERSION)', 1, TRUE, FALSE, 'osparc');"
endef

# LOCAL ------------------

.PHONY: requirements
Expand All @@ -27,6 +61,25 @@ install-dev install-prod install-ci: _check_venv_active ## install app in develo
@playwright install


RETRY_DURATION_SECONDS := 30
RETRY_INTERVAL_SECONDS := 1

install-ci-up-simcore: install-ci
@$(MAKE_C) $(REPO_BASE_DIR) local-registry
@$(_transfer-images-to-registry)
@$(_up_simcore)
@$(VENV_DIR)/bin/python utils/wait_for_services.py

# giving access rights to images (this might take some time until the catalog is ready)
@for ((i=0; i<$(RETRY_DURATION_SECONDS); i+=$(RETRY_INTERVAL_SECONDS))); do \
$(_give_service_access_rights) && echo "Access rights granted successfully" && break || true; \
echo "catalog not ready yet, retrying in ${RETRY_INTERVAL_SECONDS}..."; \
sleep $(RETRY_INTERVAL_SECONDS); \
done




get_my_ip := $(shell hostname --all-ip-addresses | cut --delimiter=" " --fields=1)

.PHONY: test-sleepers
Expand All @@ -38,7 +91,8 @@ test-sleepers: _check_venv_active ## runs sleepers test on local deploy
--pdb \
--product-url=http://$(get_my_ip):9081 \
--autoregister \
$(CURDIR)/tests/sleepers.py
--tracing=retain-on-failure \
$(CURDIR)/tests/sleepers/sleepers.py


.PHONY: test-sleepers-dev
Expand All @@ -50,7 +104,7 @@ test-sleepers-dev: _check_venv_active ## runs sleepers test on local deploy
--product-url=http://$(get_my_ip):9081 \
--headed \
--autoregister \
$(CURDIR)/tests/sleepers.py
$(CURDIR)/tests/sleepers/sleepers.py



Expand Down
3 changes: 3 additions & 0 deletions tests/e2e-playwright/requirements/_test.in
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
arrow
docker
faker
pydantic[email]
pytest-html
pytest-instafail
pytest-playwright
pytest-runner
pytest-sugar
pyyaml
tenacity
21 changes: 18 additions & 3 deletions tests/e2e-playwright/requirements/_test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@
#
annotated-types==0.6.0
# via pydantic
arrow==1.3.0
# via -r requirements/_test.in
certifi==2023.11.17
# via requests
charset-normalizer==3.3.2
# via requests
dnspython==2.4.2
# via email-validator
docker==7.0.0
# via -r requirements/_test.in
email-validator==2.1.0.post1
# via pydantic
exceptiongroup==1.2.0
Expand All @@ -32,6 +36,7 @@ markupsafe==2.1.3
# via jinja2
packaging==23.2
# via
# docker
# pytest
# pytest-sugar
playwright==1.40.0
Expand Down Expand Up @@ -67,11 +72,17 @@ pytest-runner==6.0.1
pytest-sugar==0.9.7
# via -r requirements/_test.in
python-dateutil==2.8.2
# via faker
# via
# arrow
# faker
python-slugify==8.0.1
# via pytest-playwright
pyyaml==6.0.1
# via -r requirements/_test.in
requests==2.31.0
# via pytest-base-url
# via
# docker
# pytest-base-url
six==1.16.0
# via python-dateutil
tenacity==8.2.3
Expand All @@ -82,10 +93,14 @@ text-unidecode==1.3
# via python-slugify
tomli==2.0.1
# via pytest
types-python-dateutil==2.8.19.20240106
# via arrow
typing-extensions==4.9.0
# via
# pydantic
# pydantic-core
# pyee
urllib3==2.1.0
# via requests
# via
# docker
# requests
1 change: 1 addition & 0 deletions tests/e2e-playwright/requirements/_tools.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ pyproject-hooks==1.0.0
pyyaml==6.0.1
# via
# -c requirements/../../../requirements/constraints.txt
# -c requirements/_test.txt
# pre-commit
ruff==0.1.8
# via -r requirements/../../../requirements/devenv.txt
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e-playwright/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def register(
product_url: AnyUrl,
user_name: str,
user_password: str,
) -> Iterator[Callable[[], AutoRegisteredUser]]:
) -> Callable[[], AutoRegisteredUser]:
def _do() -> AutoRegisteredUser:
print(
f"------> Registering in {product_url=} using {user_name=}/{user_password=}"
Expand Down
11 changes: 8 additions & 3 deletions tests/e2e-playwright/tests/sim4life.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import re
from http import HTTPStatus
from typing import Final

from playwright.sync_api import APIRequestContext, Page
from pydantic import AnyUrl
Expand All @@ -15,6 +16,10 @@
from tenacity.stop import stop_after_attempt
from tenacity.wait import wait_fixed

projects_uuid_pattern: Final[re.Pattern] = re.compile(
r"/projects/([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})"
)


def on_web_socket(ws) -> None:
print(f"WebSocket opened: {ws.url}")
Expand Down Expand Up @@ -42,7 +47,7 @@ def test_sim4life(
_textbox.press("Enter")
page.get_by_test_id(service_test_id).click()

with page.expect_response(re.compile(r"/projects/")) as response_info:
with page.expect_response(projects_uuid_pattern) as response_info:
# Project detail view pop-ups shows
page.get_by_test_id("openResource").click()
if product_billable:
Expand All @@ -51,8 +56,8 @@ def test_sim4life(
page.wait_for_timeout(1000)

# Get project uuid, will be used to delete this project in the end
uuid_pattern = re.compile(r"/projects/([0-9a-fA-F-]+)")
match = uuid_pattern.search(response_info.value.url)
print(f"projects uuid endpoint captured: {response_info.value.url}")
match = projects_uuid_pattern.search(response_info.value.url)
assert match
extracted_uuid = match.group(1)

Expand Down
Loading

0 comments on commit 86ef13c

Please sign in to comment.