name: Functional & Unit Tests on: pull_request: push: branches: - main jobs: tests: # Common steps name: Functional & Unit Tests runs-on: ubuntu-latest steps: - name: Check out code uses: actions/checkout@v3 - name: Create multi-node KinD cluster uses: redhat-chaos/actions/kind@main - name: Deploy prometheus & Port Forwarding uses: redhat-chaos/actions/prometheus@main - name: Deploy Elasticsearch with: ELASTIC_PORT: ${{ env.ELASTIC_PORT }} RUN_ID: ${{ github.run_id }} uses: redhat-chaos/actions/elastic@main - name: Download elastic password uses: actions/download-artifact@v4 with: name: elastic_password_${{ github.run_id }} - name: Set elastic password on env run: | ELASTIC_PASSWORD=$(cat elastic_password.txt) echo "ELASTIC_PASSWORD=$ELASTIC_PASSWORD" >> "$GITHUB_ENV" - name: Install Python uses: actions/setup-python@v4 with: python-version: '3.11' architecture: 'x64' - name: Install environment run: | sudo apt-get install build-essential python3-dev pip install --upgrade pip pip install -r requirements.txt pip install coverage - name: Deploy test workloads run: | # es_pod_name=$(kubectl get pods -l "app=elasticsearch-master" -o name) # echo "POD_NAME: $es_pod_name" # kubectl --namespace default port-forward $es_pod_name 9200 & # prom_name=$(kubectl get pods -n monitoring -l "app.kubernetes.io/name=prometheus" -o name) # kubectl --namespace monitoring port-forward $prom_name 9090 & # Wait for Elasticsearch to be ready echo "Waiting for Elasticsearch to be ready..." for i in {1..30}; do if curl -k -s -u elastic:$ELASTIC_PASSWORD https://localhost:9200/_cluster/health > /dev/null 2>&1; then echo "Elasticsearch is ready!" break fi echo "Attempt $i: Elasticsearch not ready yet, waiting..." sleep 2 done kubectl apply -f CI/templates/outage_pod.yaml kubectl wait --for=condition=ready pod -l scenario=outage --timeout=300s kubectl apply -f CI/templates/container_scenario_pod.yaml kubectl wait --for=condition=ready pod -l scenario=container --timeout=300s kubectl create namespace namespace-scenario kubectl apply -f CI/templates/time_pod.yaml kubectl wait --for=condition=ready pod -l scenario=time-skew --timeout=300s kubectl apply -f CI/templates/service_hijacking.yaml kubectl wait --for=condition=ready pod -l "app.kubernetes.io/name=proxy" --timeout=300s kubectl apply -f CI/legacy/scenarios/volume_scenario.yaml kubectl wait --for=condition=ready pod kraken-test-pod -n kraken --timeout=300s - name: Get Kind nodes run: | kubectl get nodes --show-labels=true # Pull request only steps - name: Run unit tests run: python -m coverage run -a -m unittest discover -s tests -v - name: Setup Functional Tests run: | yq -i '.kraken.performance_monitoring="localhost:9090"' CI/config/common_test_config.yaml yq -i '.elastic.elastic_port=9200' CI/config/common_test_config.yaml yq -i '.elastic.elastic_url="https://localhost"' CI/config/common_test_config.yaml yq -i '.elastic.enable_elastic=False' CI/config/common_test_config.yaml yq -i '.elastic.password="${{env.ELASTIC_PASSWORD}}"' CI/config/common_test_config.yaml yq -i '.performance_monitoring.prometheus_url="http://localhost:9090"' CI/config/common_test_config.yaml echo "test_app_outages" > ./CI/tests/functional_tests echo "test_container" >> ./CI/tests/functional_tests echo "test_cpu_hog" >> ./CI/tests/functional_tests echo "test_customapp_pod" >> ./CI/tests/functional_tests echo "test_io_hog" >> ./CI/tests/functional_tests echo "test_memory_hog" >> ./CI/tests/functional_tests echo "test_namespace" >> ./CI/tests/functional_tests echo "test_net_chaos" >> ./CI/tests/functional_tests echo "test_node" >> ./CI/tests/functional_tests echo "test_service_hijacking" >> ./CI/tests/functional_tests echo "test_pod_network_filter" >> ./CI/tests/functional_tests echo "test_pod_server" >> ./CI/tests/functional_tests echo "test_time" >> ./CI/tests/functional_tests echo "test_node_network_chaos" >> ./CI/tests/functional_tests echo "test_pod_network_chaos" >> ./CI/tests/functional_tests echo "test_cerberus_unhealthy" >> ./CI/tests/functional_tests echo "test_pod_error" >> ./CI/tests/functional_tests echo "test_pod" >> ./CI/tests/functional_tests # echo "test_pvc" >> ./CI/tests/functional_tests # Push on main only steps + all other functional to collect coverage # for the badge - name: Configure AWS Credentials if: github.ref == 'refs/heads/main' && github.event_name == 'push' uses: aws-actions/configure-aws-credentials@v4 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region : ${{ secrets.AWS_REGION }} - name: Setup Post Merge Request Functional Tests if: github.ref == 'refs/heads/main' && github.event_name == 'push' run: | yq -i '.telemetry.username="${{secrets.TELEMETRY_USERNAME}}"' CI/config/common_test_config.yaml yq -i '.telemetry.password="${{secrets.TELEMETRY_PASSWORD}}"' CI/config/common_test_config.yaml echo "test_telemetry" >> ./CI/tests/functional_tests # Final common steps - name: Run Functional tests env: AWS_BUCKET: ${{ secrets.AWS_BUCKET }} run: | ./CI/run.sh cat ./CI/results.markdown >> $GITHUB_STEP_SUMMARY echo >> $GITHUB_STEP_SUMMARY - name: Upload CI logs if: ${{ always() }} uses: actions/upload-artifact@v4 with: name: ci-logs path: CI/out if-no-files-found: error - name: Collect coverage report if: ${{ always() }} run: | python -m coverage html python -m coverage json - name: Publish coverage report to job summary if: ${{ always() }} run: | pip install html2text html2text --ignore-images --ignore-links -b 0 htmlcov/index.html >> $GITHUB_STEP_SUMMARY - name: Upload coverage data if: ${{ always() }} uses: actions/upload-artifact@v4 with: name: coverage path: htmlcov if-no-files-found: error - name: Upload json coverage if: ${{ always() }} uses: actions/upload-artifact@v4 with: name: coverage.json path: coverage.json if-no-files-found: error - name: Check CI results if: ${{ always() }} run: "! grep Fail CI/results.markdown" badge: permissions: contents: write name: Generate Coverage Badge runs-on: ubuntu-latest needs: - tests if: github.ref == 'refs/heads/main' && github.event_name == 'push' steps: - name: Check out doc repo uses: actions/checkout@master with: repository: krkn-chaos/krkn-lib-docs path: krkn-lib-docs ssh-key: ${{ secrets.KRKN_LIB_DOCS_PRIV_KEY }} - name: Download json coverage uses: actions/download-artifact@v4 with: name: coverage.json - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.11' - name: Copy badge on GitHub Page Repo env: COLOR: yellow run: | # generate coverage badge on previously calculated total coverage # and copy in the docs page export TOTAL=$(python -c "import json;print(json.load(open('coverage.json'))['totals']['percent_covered_display'])") [[ $TOTAL > 40 ]] && COLOR=green echo "TOTAL: $TOTAL" echo "COLOR: $COLOR" curl "https://img.shields.io/badge/coverage-$TOTAL%25-$COLOR" > ./krkn-lib-docs/coverage_badge_krkn.svg - name: Push updated Coverage Badge run: | cd krkn-lib-docs git add . git config user.name "krkn-chaos" git config user.email "krkn-actions@users.noreply.github.com" git commit -m "[KRKN] Coverage Badge ${GITHUB_REF##*/}" || echo "no changes to commit" git push