-
-
Notifications
You must be signed in to change notification settings - Fork 313
Establish an e2e backend instance locally and in CI/CD #2429
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
Changes from 43 commits
b5c57b4
1e9254b
69092ce
4002a19
0a05fdf
58507cc
36258b5
4119c73
0688a77
a66029c
9846482
f8be096
fbac331
837c665
143ce39
1a42d21
f619928
93f3180
8893db1
1e39448
a659f0a
009b32c
54f09ee
f1b0af0
3376a65
3f76de1
0300e4e
89ad0a6
ee3055f
8c73507
e2f1162
bf347ef
c5909b3
fae06b4
78cd6c8
d054d25
dcd91be
913ffcb
ba9671b
c080a41
f43728e
14178dd
70562bf
2e7dd25
61551c3
eb0af68
55f717f
da0bb58
6de7222
ff08b13
d3e48dd
fc9f270
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| name: Set up E2E environment | ||
| description: Sets up the environment for end-to-end testing. | ||
|
|
||
| runs: | ||
| using: composite | ||
| steps: | ||
| - name: Wait for database to be ready | ||
| run: | | ||
| until docker exec ${{ job.services.db.id }} pg_isready -U nest_user_e2e -d nest_db_e2e; do | ||
| echo "Waiting for database..." | ||
| sleep 5 | ||
| done | ||
ahmedxgouda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| shell: bash | ||
ahmedxgouda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| - name: Install PostgreSQL client | ||
| run: sudo apt-get install -y postgresql-client | ||
| shell: bash | ||
|
|
||
| - name: Load Postgres data | ||
| env: | ||
| PGPASSWORD: nest_user_e2e_password | ||
ahmedxgouda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| run: | | ||
| gunzip -c backend/data/nest-e2e.sql.gz | psql -h localhost -U nest_user_e2e -d nest_db_e2e | ||
| shell: bash | ||
|
Comment on lines
+20
to
+25
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical security risk: Hardcoded database password in source code. Line 22 embeds the database password Define the action input and replace the hardcoded value: +inputs:
+ db-password:
+ description: 'PostgreSQL password for e2e environment (use GitHub secret)'
+ required: true
+
runs:
using: composite
steps:
- name: Load Postgres data
env:
- PGPASSWORD: nest_user_e2e_password
+ PGPASSWORD: ${{ inputs.db-password }}
run: |
gunzip -c backend/data/nest-e2e.sql.gz | psql -h localhost -U nest_user_e2e -d nest_db_e2eThen update the caller in - name: Setup E2E environment
uses: ./.github/workflows/setup-e2e-environment
with:
db-password: ${{ secrets.NEST_E2E_DB_PASSWORD }}Ensure 🤖 Prompt for AI Agents |
||
|
|
||
| - name: Build backend e2e image | ||
| uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 | ||
| with: | ||
| cache-from: | | ||
| type=gha | ||
| cache-to: | | ||
| type=gha,compression=zstd | ||
| context: backend | ||
| file: backend/docker/Dockerfile | ||
| load: true | ||
| platforms: linux/amd64 | ||
| tags: owasp/nest:test-backend-e2e-latest | ||
|
|
||
| - name: Start Backend in the background | ||
| run: | | ||
| docker run -d --rm --name e2e-nest-backend \ | ||
| --env-file backend/.env.e2e.example \ | ||
| --network host \ | ||
| -e DJANGO_DB_HOST=localhost \ | ||
| -p 8000:8000 \ | ||
| owasp/nest:test-backend-e2e-latest \ | ||
| sh -c ' | ||
| gunicorn wsgi:application --bind 0.0.0.0:8000 | ||
| ' | ||
| shell: bash | ||
|
|
||
| - name: Waiting for the backend to be ready | ||
| run: | | ||
| until wget --spider http://localhost:8000/a; do | ||
| echo "Waiting for backend..." | ||
| sleep 3 | ||
| done | ||
| echo "Backend is up!" | ||
| shell: bash | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ __pycache__ | |
| .DS_Store | ||
| .env* | ||
| !.env.example | ||
| !.env.e2e.example | ||
| .idea | ||
| .lighthouseci/ | ||
| .local | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -415,6 +415,30 @@ make test | |
| This command runs tests and checks that coverage threshold requirements are satisfied for both backend and frontend. | ||
| **Please note your PR won't be merged if it fails the code tests checks.** | ||
|
|
||
| ### Setting Up e2e Testing Environment | ||
|
|
||
| Follow these steps to setup your e2e testing environment: | ||
|
|
||
| 1. Run the e2e backend instance with the following command: | ||
|
|
||
| ```bash | ||
| make run-backend-e2e | ||
| ``` | ||
|
|
||
| 2. Load the data into the e2e db with the following command (in another terminal session): | ||
|
|
||
| ```bash | ||
| make load-data-e2e | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This approach works for the initial set up. What about the following e2e dump data updates? Is it compact enough to include the data loading as part of e2e test run process?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It takes a few seconds to load the data with postgres command.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have updated the docs in PR on how to update the data |
||
| ``` | ||
|
|
||
| 3. Now, you can stop the backend instance, and run the frontend e2e tests with the following command: | ||
|
|
||
| ```bash | ||
| make test-frontend-e2e | ||
| ``` | ||
|
|
||
| **Please note that you only need to do these steps once.** | ||
|
|
||
| ### Test Coverage | ||
|
|
||
| - There is a **minimum test coverage requirement** for the **backend** code -- see [pyproject.toml](https://github.com/OWASP/Nest/blob/main/backend/pyproject.toml). | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| DJANGO_ALGOLIA_APPLICATION_ID=None | ||
| DJANGO_ALGOLIA_EXCLUDED_LOCAL_INDEX_NAMES=None | ||
| DJANGO_ALGOLIA_WRITE_API_KEY=None | ||
| DJANGO_ALLOWED_HOSTS=* | ||
| DJANGO_AWS_ACCESS_KEY_ID=None | ||
| DJANGO_AWS_SECRET_ACCESS_KEY=None | ||
| DJANGO_SETTINGS_MODULE=settings.e2e | ||
| DJANGO_CONFIGURATION=E2E | ||
| DJANGO_DB_HOST=None | ||
| DJANGO_DB_NAME=nest_db_e2e | ||
| DJANGO_DB_USER=nest_user_e2e | ||
| DJANGO_DB_PASSWORD=nest_user_e2e_password | ||
| DJANGO_DB_PORT=5432 | ||
| DJANGO_OPEN_AI_SECRET_KEY=None | ||
| DJANGO_PUBLIC_IP_ADDRESS="127.0.0.1" | ||
ahmedxgouda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| DJANGO_REDIS_HOST=None | ||
| DJANGO_REDIS_PASSWORD=None | ||
| DJANGO_RELEASE_VERSION=None | ||
| DJANGO_SECRET_KEY=None | ||
| DJANGO_SENTRY_DSN=None | ||
| DJANGO_SLACK_BOT_TOKEN=None | ||
| DJANGO_SLACK_SIGNING_SECRET=None | ||
| GITHUB_TOKEN=None | ||
ahmedxgouda marked this conversation as resolved.
Show resolved
Hide resolved
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How was this dump created and what data is already there?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we can add a command to dump the local backend instance |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,4 +64,4 @@ RUN rm -rf /home/owasp/.cache && \ | |
|
|
||
| USER owasp | ||
|
|
||
| CMD ["/home/owasp/entrypoint.sh"] | ||
| EXPOSE 8000 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| """OWASP Nest end-to-end testing configuration.""" | ||
|
|
||
| from configurations import values | ||
|
|
||
| from settings.base import Base | ||
|
|
||
|
|
||
| class E2E(Base): | ||
| """End-to-end testing configuration.""" | ||
|
|
||
| APP_NAME = "OWASP Nest E2E Testing" | ||
|
|
||
| ALLOWED_ORIGINS = ( | ||
| "http://frontend:3000", | ||
| "http://localhost:3000", | ||
| ) | ||
| CORS_ALLOWED_ORIGINS = ALLOWED_ORIGINS | ||
| CSRF_TRUSTED_ORIGINS = ALLOWED_ORIGINS | ||
|
|
||
| DEBUG = False | ||
| IS_E2E_ENVIRONMENT = True | ||
| LOGGING = {} | ||
| PUBLIC_IP_ADDRESS = values.Value() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| services: | ||
| backend: | ||
| container_name: e2e-nest-backend | ||
| command: > | ||
| sh -c ' | ||
| gunicorn wsgi:application --bind 0.0.0.0:8000 | ||
| ' | ||
| build: | ||
| context: ../backend | ||
| dockerfile: docker/Dockerfile | ||
| depends_on: | ||
| db: | ||
| condition: service_healthy | ||
| env_file: ../backend/.env.e2e | ||
| environment: | ||
| DJANGO_DB_HOST: ${DJANGO_DB_HOST:-db} | ||
| DJANGO_DB_NAME: ${DJANGO_DB_NAME:-nest_db_e2e} | ||
| DJANGO_DB_PASSWORD: ${DJANGO_DB_PASSWORD:-nest_user_e2e_password} | ||
| DJANGO_DB_PORT: ${DJANGO_DB_PORT:-5432} | ||
| DJANGO_DB_USER: ${DJANGO_DB_USER:-nest_user_e2e} | ||
| networks: | ||
| - nest-network | ||
| ports: | ||
| - 8000:8000 | ||
| healthcheck: | ||
| interval: 10s | ||
| retries: 10 | ||
| test: > | ||
| sh -c ' | ||
| wget --spider http://backend:8000/a | ||
| ' | ||
| timeout: 10s | ||
| start_period: 5s | ||
| db: | ||
| container_name: e2e-nest-db | ||
| image: pgvector/pgvector:pg16 | ||
| environment: | ||
| POSTGRES_DB: ${DJANGO_DB_NAME:-nest_db_e2e} | ||
| POSTGRES_PASSWORD: ${DJANGO_DB_PASSWORD:-nest_user_e2e_password} | ||
| POSTGRES_USER: ${DJANGO_DB_USER:-nest_user_e2e} | ||
| healthcheck: | ||
| interval: 5s | ||
| retries: 5 | ||
| test: [CMD-SHELL, pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB -h localhost -p 5432] | ||
| timeout: 5s | ||
| networks: | ||
| - nest-network | ||
| volumes: | ||
| - db-e2e-data:/var/lib/postgresql/data | ||
| ports: | ||
| - 5433:5432 | ||
|
|
||
| frontend: | ||
| container_name: e2e-nest-frontend | ||
| build: | ||
| context: ../frontend | ||
| dockerfile: docker/Dockerfile.e2e.test | ||
| command: > | ||
| sh -c ' | ||
| pnpm run test:e2e | ||
ahmedxgouda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ' | ||
| depends_on: | ||
| backend: | ||
| condition: service_healthy | ||
| env_file: ../frontend/.env.e2e | ||
| networks: | ||
| - nest-network | ||
|
|
||
| volumes: | ||
| db-e2e-data: | ||
|
|
||
| networks: | ||
| nest-network: | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| services: | ||
| production-nest-backend: | ||
| container_name: production-nest-backend | ||
| entrypoint: /home/owasp/entrypoint.sh | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainVerify the entrypoint script exists and is properly configured. The production service now explicitly calls
Run the following script to verify the entrypoint is present in the backend image: 🏁 Script executed: #!/bin/bash
# Verify entrypoint script exists in the backend production image
docker run --rm --entrypoint ls owasp/nest:backend-production -la /home/owasp/entrypoint.sh 2>&1 || echo "Entrypoint script not found or image not available locally"Length of output: 103 🏁 Script executed: #!/bin/bash
# Search for entrypoint.sh in the repository
fd -t f entrypoint.shLength of output: 28 🏁 Script executed: #!/bin/bash
# Find Dockerfile for the backend service
fd -t f -e Dockerfile | grep -i "backend\|nest" || fd -t f -e DockerfileLength of output: 0 🏁 Script executed: #!/bin/bash
# Search for references to the entrypoint path in docker-compose and Dockerfiles
rg -n "entrypoint.sh|/home/owasp" --type yaml --type dockerfileLength of output: 34 🏁 Script executed: #!/bin/bash
# Examine the entrypoint script content
cat backend/docker/entrypoint.shLength of output: 160 🏁 Script executed: #!/bin/bash
# Find all Dockerfiles (remove type filter to avoid errors)
fd -t f "Dockerfile" -o "Dockerfile.*"Length of output: 143 🏁 Script executed: #!/bin/bash
# Look for Docker-related files in backend/docker directory
ls -la backend/docker/ 2>/dev/null || echo "Directory not found"Length of output: 365 🏁 Script executed: #!/bin/bash
# Search for COPY and ADD commands that reference entrypoint in any files
rg -n "COPY|ADD" -A 1 -B 1 | grep -A 2 -B 2 "entrypoint\|/home/owasp"Length of output: 1355 🏁 Script executed: #!/bin/bash
# View full backend/docker/Dockerfile to understand working directory and path resolution
cat backend/docker/DockerfileLength of output: 1731 🏁 Script executed: #!/bin/bash
# Check if entrypoint.sh is marked executable in git
git ls-files -s backend/docker/entrypoint.shLength of output: 78 Add signal handlers to entrypoint script for graceful shutdown in production. The script exists at Location: Fix: Add signal forwarding before gunicorn: #!/bin/sh
set -e
python manage.py migrate
python manage.py collectstatic --noinput
python manage.py clear_cache
exec gunicorn wsgi:application --bind 0.0.0.0:8000The 🤖 Prompt for AI Agents |
||
| image: owasp/nest:backend-production | ||
| env_file: .env.backend | ||
| depends_on: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| NEXT_PUBLIC_API_URL=http://localhost:8000/ | ||
| NEXT_PUBLIC_CSRF_URL=http://localhost:8000/csrf/ | ||
| NEXT_PUBLIC_ENVIRONMENT=local | ||
| NEXT_PUBLIC_GRAPHQL_URL=http://localhost:8000/graphql/ | ||
| NEXT_PUBLIC_GTM_ID= | ||
| NEXT_PUBLIC_IDX_URL=http://localhost:8000/idx/ | ||
| NEXT_PUBLIC_IS_PROJECT_HEALTH_ENABLED=true | ||
| NEXT_PUBLIC_RELEASE_VERSION= | ||
| NEXT_PUBLIC_SENTRY_DSN= | ||
| NEXT_SERVER_CSRF_URL=http://localhost:8000/csrf/ | ||
| NEXT_SERVER_DISABLE_SSR=false | ||
| NEXT_SERVER_GITHUB_CLIENT_ID=your-github-client-id | ||
| NEXT_SERVER_GITHUB_CLIENT_SECRET=your-github-client-secret | ||
| NEXT_SERVER_GRAPHQL_URL=http://localhost:8000/graphql/ | ||
| NEXTAUTH_SECRET=<your-nextauth-secret> | ||
| NEXTAUTH_URL=http://localhost:3000/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,11 +57,8 @@ test-frontend: \ | |
| test-frontend-e2e | ||
|
|
||
| test-frontend-e2e: | ||
| @DOCKER_BUILDKIT=1 NEXT_PUBLIC_ENVIRONMENT=local docker build \ | ||
| --cache-from nest-test-frontend-e2e \ | ||
| -f frontend/docker/Dockerfile.e2e.test frontend \ | ||
| -t nest-test-frontend-e2e | ||
| @docker run --env-file frontend/.env.example --rm nest-test-frontend-e2e pnpm run test:e2e | ||
| @DOCKER_BUILDKIT=1 NEXT_PUBLIC_ENVIRONMENT=local \ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be a good time to think about introducing |
||
| docker compose --project-name nest-e2e -f docker-compose/e2e.yaml up --build --remove-orphans --abort-on-container-exit | ||
|
|
||
| test-frontend-unit: | ||
| @DOCKER_BUILDKIT=1 NEXT_PUBLIC_ENVIRONMENT=local docker build \ | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.