Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
147 changes: 147 additions & 0 deletions .github/workflows/functional-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
name: Functional Tests

on:
pull_request:
branches: [main]

permissions:
contents: read

jobs:
functional-tests:
name: "Pulp Functional Tests"
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Build dev container
uses: docker/build-push-action@v7
with:
context: .
file: dev-container/Dockerfile
load: true
tags: pulp-dev:test
cache-from: type=gha,scope=dev-container
cache-to: type=gha,mode=max,scope=dev-container

- name: Start dev container
run: |
docker run -d \
--name pulp-dev \
-e PULP_API_WORKERS=1 \
-e PULP_CONTENT_WORKERS=1 \
-e PULP_WORKERS=2 \
pulp-dev:test

- name: Wait for Pulp API
run: |
echo "Waiting for Pulp API to become ready..."
for i in $(seq 1 120); do
if docker exec pulp-dev curl -sf http://localhost:24817/api/pulp/api/v3/status/ > /dev/null 2>&1; then
echo "API ready after ${i}s"
exit 0
fi
sleep 1
done
echo "ERROR: API not ready after 120s"
docker logs pulp-dev
exit 1

- name: Install test dependencies and generate bindings
run: |
docker exec pulp-dev bash -c "pip install 'pytest<8' pytest-django gnupg 2>&1 | tail -1"
docker exec pulp-dev bash -c "\
curl -sf -o /tmp/functest_requirements.txt \
https://raw.githubusercontent.com/pulp/pulp_rpm/main/functest_requirements.txt && \
curl -sf -o /tmp/unittest_requirements.txt \
https://raw.githubusercontent.com/pulp/pulp_rpm/main/unittest_requirements.txt && \
pip install -r /tmp/functest_requirements.txt -r /tmp/unittest_requirements.txt 2>&1 | tail -1"
docker exec pulp-dev pulp-test --bindings-only

- name: "Test 1/6: pulp_rpm parallel (test_download_content)"
run: |
docker exec pulp-dev bash -c "\
API_PROTOCOL=http API_HOST=localhost API_PORT=24817 \
ADMIN_USERNAME=admin ADMIN_PASSWORD=password \
pytest -v -r sx --color=yes \
--suppress-no-test-exit-code \
--pyargs pulp_rpm.tests.functional \
-m parallel -n 4 -k 'test_download_content' \
--junitxml=/tmp/junit-rpm-parallel.xml"

- name: "Test 2/6: pulp_rpm serial (test_download_policies)"
run: |
docker exec pulp-dev bash -c "\
API_PROTOCOL=http API_HOST=localhost API_PORT=24817 \
ADMIN_USERNAME=admin ADMIN_PASSWORD=password \
pytest -v -r sx --color=yes \
--pyargs pulp_rpm.tests.functional \
-m 'not parallel' -k 'test_download_policies' \
--junitxml=/tmp/junit-rpm-serial.xml"

- name: "Test 3/6: pulpcore (test_jq_header_remote_auth)"
run: |
docker exec pulp-dev bash -c "\
API_PROTOCOL=http API_HOST=localhost API_PORT=24817 \
ADMIN_USERNAME=admin ADMIN_PASSWORD=password \
pytest -v -r sx --color=yes \
--pyargs pulpcore.tests.functional \
-m parallel -n 4 -k 'test_jq_header_remote_auth' \
--junitxml=/tmp/junit-core.xml"

- name: "Test 4/6: pulp_maven (test_download_content)"
run: |
docker exec pulp-dev bash -c "\
API_PROTOCOL=http API_HOST=localhost API_PORT=24817 \
ADMIN_USERNAME=admin ADMIN_PASSWORD=password \
pytest -v -r sx --color=yes \
--pyargs pulp_maven.tests.functional.api.test_download_content \
--junitxml=/tmp/junit-maven.xml"

- name: "Test 5/6: pulp_npm (test_pull_through_install)"
run: |
docker exec pulp-dev bash -c "\
API_PROTOCOL=http API_HOST=localhost API_PORT=24817 \
ADMIN_USERNAME=admin ADMIN_PASSWORD=password \
pytest -v -r sx --color=yes \
--pyargs pulp_npm.tests.functional \
-k 'test_pull_through_install' \
--junitxml=/tmp/junit-npm.xml"

- name: "Test 6/6: pulp_service functional"
run: |
docker exec pulp-dev bash -c "\
API_PROTOCOL=http API_HOST=localhost API_PORT=24817 \
ADMIN_USERNAME=admin ADMIN_PASSWORD=password \
pytest -v -r sx --color=yes \
--pyargs pulp_service.tests.functional \
-m 'not parallel' \
-k 'not test_forbidden_feature_service and not test_entitled_feature_service' \
--junitxml=/tmp/junit-service.xml"

- name: Collect test results
if: always()
run: |
mkdir -p test-results
docker cp pulp-dev:/tmp/junit-rpm-parallel.xml test-results/ 2>/dev/null || true
docker cp pulp-dev:/tmp/junit-rpm-serial.xml test-results/ 2>/dev/null || true
docker cp pulp-dev:/tmp/junit-core.xml test-results/ 2>/dev/null || true
docker cp pulp-dev:/tmp/junit-maven.xml test-results/ 2>/dev/null || true
docker cp pulp-dev:/tmp/junit-npm.xml test-results/ 2>/dev/null || true
docker cp pulp-dev:/tmp/junit-service.xml test-results/ 2>/dev/null || true

- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: junit-results
path: test-results/
retention-days: 14

- name: Dump container logs on failure
if: failure()
run: docker logs pulp-dev
128 changes: 1 addition & 127 deletions .tekton/pulp-deploy-and-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -697,132 +697,6 @@ spec:
cat __tmp_init__.py | cmd_stdin_prefix bash -c "cat > /tmp/home/.local/lib/python3.11/site-packages/pulpcore/__init__.py"
cat __tmp_init__.py | cmd_stdin_prefix bash -c "cat > /tmp/home/.local/lib/python3.11/site-packages/pulpcore/client/__init__.py"

- name: pulp-functional-tests
when:
- input: '$(tasks.test-metadata.results.test-event-type)'
operator: in
values: ["pull_request"]
runAfter:
- install-bindings
params:
- name: BONFIRE_IMAGE
value: "$(params.BONFIRE_IMAGE)"
- name: NS
value: "$(tasks.reserve-namespace.results.NS)"
- name: EPHEMERAL_ENV_PROVIDER_SECRET
value: "$(params.EPHEMERAL_ENV_PROVIDER_SECRET)"
taskSpec:
params:
- name: BONFIRE_IMAGE
type: string
description: The container Bonfire image to use for the tekton tasks
default: quay.io/redhat-user-workloads/hcc-devprod-tenant/hcc-cicd-tools/cicd-tools:834176766e3f911ffa24bfacff59dd15126e4b3a
- name: EPHEMERAL_ENV_PROVIDER_SECRET
type: string
default: ephemeral-env-provider
- name: NS
type: string
description: Namespace name to deploy the application to
steps:
- name: functional-tests
image: "$(params.BONFIRE_IMAGE)"
env:
- name: OC_LOGIN_TOKEN
valueFrom:
secretKeyRef:
name: $(params.EPHEMERAL_ENV_PROVIDER_SECRET)
key: token
- name: OC_LOGIN_SERVER
valueFrom:
secretKeyRef:
name: $(params.EPHEMERAL_ENV_PROVIDER_SECRET)
key: url
- name: NS
value: $(params.NS)
script: |
set -ex

login.sh

if [ -n "$NS" ]; then
oc_wrapper project $NS
else
export NS=$(oc_wrapper project | grep -oE 'ephemeral-......')
fi
echo "Namespace is $NS"

PASSWORD=$(oc_wrapper extract secret/pulp-admin-password --to=-)

POD=$(oc_wrapper get pod | grep -oE "pulp-api\S*")
echo $POD
oc_wrapper get pod $POD -o yaml | grep memory:

oc_wrapper get clowdenvironment env-$(oc_wrapper project | grep -oE 'ephemeral-......') -o yaml

oc_wrapper get clowdapp pulp -o yaml

### Adapted from ./.github/workflows/scripts/utils.sh
# Run a command
cmd_prefix() {
oc_wrapper exec -c pulp-api deployment/pulp-api -- "$@"
}

# Run a command, and pass STDIN
cmd_stdin_prefix() {
oc_wrapper exec -c pulp-api -i deployment/pulp-api -- "$@"
}
### END Adapted from ./.github/workflows/scripts/utils.sh

debug_and_fail() {
oc_wrapper logs $(oc_wrapper get pod | grep -oE "pulp-content\S*")
oc_wrapper logs $(oc_wrapper get pod | grep -oE "pulp-api\S*")
for pod in $(oc_wrapper get pod | grep -oE "pulp-worker\S*"); do
oc_wrapper logs "$pod"
done
echo "CURL OUTPUT"
curl https://env-${NS}.apps.crc-eph.r9lp.p1.openshiftapps.com/api/pulp-content/default/
echo "ROUTES"
oc_wrapper get route
exit 1
}

cmd_prefix bash -c "HOME=/tmp/home pip3 install pytest\<8 gnupg"

curl -o functest_requirements.txt https://raw.githubusercontent.com/pulp/pulp_rpm/main/functest_requirements.txt
curl -o unittest_requirements.txt https://raw.githubusercontent.com/pulp/pulp_rpm/main/unittest_requirements.txt

### Adapted from ./.github/workflows/scripts/script.sh
cat unittest_requirements.txt | cmd_stdin_prefix bash -c "cat > /tmp/unittest_requirements.txt"
cat functest_requirements.txt | cmd_stdin_prefix bash -c "cat > /tmp/functest_requirements.txt"
cmd_prefix bash -c "HOME=/tmp/home pip3 install -r /tmp/unittest_requirements.txt -r /tmp/functest_requirements.txt"
# Because we pass the path to pytest -o cache_dir=/tmp/home/.cache/pytest_cache, pulpcore-manager must be in the same dir
cmd_prefix bash -c "ln -s /usr/local/lib/pulp/bin/pulpcore-manager /tmp/home/.local/bin/pulpcore-manager || /bin/true"
echo "CURL OUTPUT"
curl https://env-${NS}.apps.crc-eph.r9lp.p1.openshiftapps.com/api/pulp-content/default/
echo "ROUTES"
oc_wrapper get route
set +e
# Only testing test_download_content because it is a very thorough test that tests that all the components of pulp can work
cmd_prefix bash -c "HOME=/tmp/home PYTHONPATH=/tmp/home/.local/lib/python3.11/site-packages/ XDG_CONFIG_HOME=/tmp/home/.config API_PROTOCOL=http API_HOST=pulp-api API_PORT=8000 ADMIN_USERNAME=admin ADMIN_PASSWORD=$PASSWORD /tmp/home/.local/bin/pytest -o cache_dir=/tmp/home/.cache/pytest_cache -v -r sx --color=yes --suppress-no-test-exit-code --pyargs pulp_rpm.tests.functional -m parallel -n 8 -k 'test_download_content' --junitxml=/tmp/home/junit-pulp-parallel.xml" || debug_and_fail
# Never test test_package_manager_consume because they require sudo
# Do not test test_domain_create because it requires more than 2GB of RAM
# Only testing test_download_policies because they are very thorough tests that test that all the components of pulp can work
cmd_prefix bash -c "HOME=/tmp/home PYTHONPATH=/tmp/home/.local/lib/python3.11/site-packages/ XDG_CONFIG_HOME=/tmp/home/.config API_PROTOCOL=http API_HOST=pulp-api API_PORT=8000 ADMIN_USERNAME=admin ADMIN_PASSWORD=$PASSWORD /tmp/home/.local/bin/pytest -o cache_dir=/tmp/home/.cache/pytest_cache -v -r sx --color=yes --pyargs pulp_rpm.tests.functional -m 'not parallel' -k 'test_download_policies' --junitxml=/tmp/home/junit-pulp-serial.xml" || debug_and_fail

# Run the jq header auth test
cmd_prefix bash -c "HOME=/tmp/home PYTHONPATH=/tmp/home/.local/lib/python3.11/site-packages/ XDG_CONFIG_HOME=/tmp/home/.config API_PROTOCOL=http API_HOST=pulp-api API_PORT=8000 ADMIN_USERNAME=admin ADMIN_PASSWORD=$PASSWORD /tmp/home/.local/bin/pytest -o cache_dir=/tmp/home/.cache/pytest_cache -v -r sx --color=yes --pyargs pulpcore.tests.functional -m 'parallel' -n 8 -k 'test_jq_header_remote_auth' --junitxml=/tmp/home/junit-pulp-serial.xml" || debug_and_fail

### END Adapted from ./.github/workflows/scripts/script.sh

# Run pulp_maven functional tests
cmd_prefix bash -c "HOME=/tmp/home PYTHONPATH=/tmp/home/.local/lib/python3.11/site-packages/ XDG_CONFIG_HOME=/tmp/home/.config API_PROTOCOL=http API_HOST=pulp-api API_PORT=8000 ADMIN_USERNAME=admin ADMIN_PASSWORD=$PASSWORD /tmp/home/.local/bin/pytest -o cache_dir=/tmp/home/.cache/pytest_cache -v -r sx --color=yes --pyargs pulp_maven.tests.functional.api.test_download_content --junitxml=/tmp/home/junit-pulp-serial.xml" || debug_and_fail

# Run pulp_npm functional tests
cmd_prefix bash -c "HOME=/tmp/home PYTHONPATH=/tmp/home/.local/lib/python3.11/site-packages/ XDG_CONFIG_HOME=/tmp/home/.config API_PROTOCOL=http API_HOST=pulp-api API_PORT=8000 ADMIN_USERNAME=admin ADMIN_PASSWORD=$PASSWORD /tmp/home/.local/bin/pytest -o cache_dir=/tmp/home/.cache/pytest_cache -v -r sx --color=yes --pyargs pulp_npm.tests.functional -k 'test_pull_through_install' --junitxml=/tmp/home/junit-pulp-serial.xml" || debug_and_fail

# Run pulp_service functional tests
cmd_prefix bash -c "HOME=/tmp/home PYTHONPATH=/tmp/home/.local/lib/python3.11/site-packages/ XDG_CONFIG_HOME=/tmp/home/.config API_PROTOCOL=http API_HOST=pulp-api API_PORT=8000 ADMIN_USERNAME=admin ADMIN_PASSWORD=$PASSWORD /tmp/home/.local/bin/pytest -o cache_dir=/tmp/home/.cache/pytest_cache -v -r sx --color=yes --pyargs pulp_service.tests.functional -m 'not parallel' --junitxml=/tmp/home/junit-pulp-serial.xml" || debug_and_fail

- name: push-api-json-files-to-pulp
when:
- input: '$(tasks.test-metadata.results.test-event-type)'
Expand All @@ -838,7 +712,7 @@ spec:
- name: SNAPSHOT
value: "$(params.SNAPSHOT)"
runAfter:
- pulp-functional-tests
- install-bindings
taskSpec:
params:
- name: BONFIRE_IMAGE
Expand Down
3 changes: 2 additions & 1 deletion dev-container/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ from cryptography.hazmat.primitives import serialization; \
key = rsa.generate_private_key(65537, 4096); \
open('/etc/pki/attestation/test-key-private.pem','wb').write(key.private_bytes(serialization.Encoding.PEM, serialization.PrivateFormat.PKCS8, serialization.NoEncryption())); \
open('/etc/pki/attestation/test-key.pem','wb').write(key.public_key().public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo))" && \
chmod 600 /etc/pki/attestation/test-key-private.pem && \
chown -R 700:0 /etc/pki/attestation && \
chmod 640 /etc/pki/attestation/test-key-private.pem && \
chmod 644 /etc/pki/attestation/test-key.pem

RUN dnf -y install java-17-openjdk-headless && dnf clean all
Expand Down
Loading