Compare commits

..
Author SHA1 Message Date
Alexandre Teixeira d237c3fbba perf(tests): reuse immutable admin auth configuration 2026-10-29 17:35:59 +00:00
10 changed files with 53 additions and 29 deletions
+5 -5
View File
@@ -76,7 +76,7 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with: with:
persist-credentials: false persist-credentials: false
- uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0 - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with: with:
python-version: "3.11" python-version: "3.11"
# Byte-compile sources — catches syntax errors without installing deps. # Byte-compile sources — catches syntax errors without installing deps.
@@ -91,7 +91,7 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with: with:
persist-credentials: false persist-credentials: false
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with: with:
node-version: "22.23.4" node-version: "22.23.4"
- run: npm ci --ignore-scripts --no-audit --no-fund - run: npm ci --ignore-scripts --no-audit --no-fund
@@ -151,7 +151,7 @@ jobs:
echo "docs_only=false" >> "$GITHUB_OUTPUT" echo "docs_only=false" >> "$GITHUB_OUTPUT"
fi fi
- uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0 - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
if: steps.docs-check.outputs.docs_only != 'true' if: steps.docs-check.outputs.docs_only != 'true'
with: with:
python-version: "3.11" python-version: "3.11"
@@ -168,7 +168,7 @@ jobs:
# uv resolves the same versions as pip but installs ~5x faster, and its # uv resolves the same versions as pip but installs ~5x faster, and its
# cache keeps each shard from re-downloading the whole requirement set. # cache keeps each shard from re-downloading the whole requirement set.
- uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
if: steps.docs-check.outputs.docs_only != 'true' if: steps.docs-check.outputs.docs_only != 'true'
with: with:
version: "0.13.5" version: "0.13.5"
@@ -180,7 +180,7 @@ jobs:
python scripts/check_ca_trust.py --python python scripts/check_ca_trust.py --python
uv pip install --system -r requirements.txt uv pip install --system -r requirements.txt
if: steps.docs-check.outputs.docs_only != 'true' if: steps.docs-check.outputs.docs_only != 'true'
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
if: steps.docs-check.outputs.docs_only != 'true' if: steps.docs-check.outputs.docs_only != 'true'
with: with:
node-version: "22.23.4" node-version: "22.23.4"
+2 -2
View File
@@ -31,11 +31,11 @@ jobs:
with: with:
persist-credentials: false persist-credentials: false
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1 uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
build-mode: none build-mode: none
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1 uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with: with:
category: "/language:${{ matrix.language }}" category: "/language:${{ matrix.language }}"
+1 -1
View File
@@ -42,7 +42,7 @@ jobs:
persist-credentials: false persist-credentials: false
- name: Lint Dockerfile - name: Lint Dockerfile
uses: hadolint/hadolint-action@06be81baf89a55ffd0e24b8f04a4185738dd3387 # v3.5.0 uses: hadolint/hadolint-action@2a66e89f53d0771bb131a7fa31f3136336094aa6 # v3.4.0
with: with:
dockerfile: Dockerfile dockerfile: Dockerfile
# DL3008: pinning apt package versions is impractical on a -slim base # DL3008: pinning apt package versions is impractical on a -slim base
+5 -5
View File
@@ -61,14 +61,14 @@ jobs:
persist-credentials: false persist-credentials: false
- name: Set up Buildx - name: Set up Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
with: with:
driver: docker driver: docker
# Build without pushing so a broken Dockerfile is caught here, and the # Build without pushing so a broken Dockerfile is caught here, and the
# exact image we ship is what gets scanned. # exact image we ship is what gets scanned.
- name: Build image - name: Build image
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with: with:
context: . context: .
push: false push: false
@@ -107,12 +107,12 @@ jobs:
persist-credentials: false persist-credentials: false
- name: Set up Buildx - name: Set up Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
with: with:
driver: docker driver: docker
- name: Build image - name: Build image
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with: with:
context: . context: .
push: false push: false
@@ -133,7 +133,7 @@ jobs:
TRIVY_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-db:2 TRIVY_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-db:2
- name: Upload Trivy results - name: Upload Trivy results
uses: github/codeql-action/upload-sarif@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1 uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with: with:
sarif_file: trivy-results.sarif sarif_file: trivy-results.sarif
category: trivy-image category: trivy-image
+1 -1
View File
@@ -63,7 +63,7 @@ jobs:
persist-credentials: false persist-credentials: false
- name: Set up Python - name: Set up Python
uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0 uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with: with:
python-version: '3.12' python-version: '3.12'
+1 -1
View File
@@ -47,4 +47,4 @@ jobs:
steps: steps:
- name: Deploy to GitHub Pages - name: Deploy to GitHub Pages
id: deployment id: deployment
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
+7 -7
View File
@@ -55,16 +55,16 @@ jobs:
shell: bash shell: bash
run: echo "IMAGE_NAME=${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV" run: echo "IMAGE_NAME=${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV"
- name: Set up Buildx - name: Set up Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
- name: Log in to GHCR - name: Log in to GHCR
uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0 uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push by digest - name: Build and push by digest
id: build id: build
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with: with:
context: . context: .
pull: true pull: true
@@ -78,7 +78,7 @@ jobs:
digest="${{ steps.build.outputs.digest }}" digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}" touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest - name: Upload digest
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: digest-${{ matrix.arch }} name: digest-${{ matrix.arch }}
path: /tmp/digests/* path: /tmp/digests/*
@@ -107,15 +107,15 @@ jobs:
echo "version=$v" >> "$GITHUB_OUTPUT" echo "version=$v" >> "$GITHUB_OUTPUT"
echo "short=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT" echo "short=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
- name: Download digests - name: Download digests
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with: with:
path: /tmp/digests path: /tmp/digests
pattern: digest-* pattern: digest-*
merge-multiple: true merge-multiple: true
- name: Set up Buildx - name: Set up Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
- name: Log in to GHCR - name: Log in to GHCR
uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0 uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
+2 -2
View File
@@ -62,9 +62,9 @@ jobs:
env: env:
SEARXNG_TEST_IMAGE: ${{ steps.image.outputs.image }} SEARXNG_TEST_IMAGE: ${{ steps.image.outputs.image }}
run: docker pull "$SEARXNG_TEST_IMAGE" run: docker pull "$SEARXNG_TEST_IMAGE"
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 - uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
- name: Check unmodified upstream trust and actual entrypoint offline - name: Check unmodified upstream trust and actual entrypoint offline
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with: with:
context: . context: .
file: docker/searxng/Dockerfile file: docker/searxng/Dockerfile
+1 -1
View File
@@ -66,7 +66,7 @@ jobs:
persist-credentials: false persist-credentials: false
- name: Set up Python - name: Set up Python
uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0 uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with: with:
python-version: '3.12' python-version: '3.12'
+28 -4
View File
@@ -14,12 +14,22 @@ from routes.auth_routes import SESSION_COOKIE
from tests.helpers.database import disposable_database from tests.helpers.database import disposable_database
@pytest.fixture @pytest.fixture(scope="module")
def authenticated_app(tmp_path, monkeypatch): def auth_configuration(tmp_path_factory):
monkeypatch.setenv("AUTH_ENABLED", "true") """Hash real fixture passwords once; only immutable bytes are reused."""
auth = AuthManager(str(tmp_path / "auth.json")) path = tmp_path_factory.mktemp("admin-auth-seed") / "auth.json"
auth = AuthManager(str(path))
for user, admin in (("member", False), ("admin", True)): for user, admin in (("member", False), ("admin", True)):
assert auth.create_user(user, "disposable-test-password", is_admin=admin) assert auth.create_user(user, "disposable-test-password", is_admin=admin)
return path.read_bytes()
@pytest.fixture
def authenticated_app(tmp_path, monkeypatch, auth_configuration):
monkeypatch.setenv("AUTH_ENABLED", "true")
path = tmp_path / "auth.json"
path.write_bytes(auth_configuration)
auth = AuthManager(str(path))
app = FastAPI() app = FastAPI()
app.state.auth_manager = auth app.state.auth_manager = auth
@@ -133,3 +143,17 @@ def test_diagnostics_require_real_admin_before_sensitive_work(
for operation in (stats, rag.get_stats, research.call_research_service, for operation in (stats, rag.get_stats, research.call_research_service,
extract_id, transcript, collect, read_log): extract_id, transcript, collect, read_log):
operation.assert_not_called() operation.assert_not_called()
@pytest.mark.parametrize("instance", [0, 1])
def test_authenticated_fixture_has_private_users_sessions_and_file(authenticated_app, instance):
app, client_for = authenticated_app
auth = app.state.auth_manager
assert set(auth.users) == {"member", "admin"}
assert not auth._sessions
with client_for("member") as client:
assert auth.get_username_for_token(client.cookies.get(SESSION_COOKIE)) == "member"
assert auth.create_user("fixture-local", "disposable-test-password")
# Both parameter cases mutate their own file. Any shared manager, mutable
# users/sessions or written-back seed makes the next case fail, in any order.
assert "fixture-local" in auth.users