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_URL: ${{ vars.ELASTIC_URL }} ELASTIC_PORT: ${{ vars.ELASTIC_PORT }} ELASTIC_USER: ${{ vars.ELASTIC_USER }} ELASTIC_PASSWORD: ${{ vars.ELASTIC_PASSWORD }} uses: redhat-chaos/actions/elastic@main - name: Install Python uses: actions/setup-python@v4 with: python-version: '3.9' architecture: 'x64' - name: Install environment run: | sudo apt-get install build-essential python3-dev pip install --upgrade pip pip install -r requirements.txt - name: Deploy test workloads run: | es_pod_name=$(kubectl get pods -l "app.kubernetes.io/instance=elasticsearch" -o 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 & 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 - name: Get Kind nodes run: | kubectl get nodes --show-labels=true # Pull request only steps - name: Run unit tests if: github.event_name == 'pull_request' run: python -m coverage run -a -m unittest discover -s tests -v - name: Setup Pull Request Functional Tests if: | github.event_name == 'pull_request' run: | yq -i '.kraken.port="8081"' CI/config/common_test_config.yaml yq -i '.kraken.signal_address="0.0.0.0"' CI/config/common_test_config.yaml 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=True' CI/config/common_test_config.yaml yq -i '.performance_monitoring.prometheus_url="http://localhost:9090"' CI/config/common_test_config.yaml echo "test_service_hijacking" > ./CI/tests/functional_tests echo "test_app_outages" >> ./CI/tests/functional_tests echo "test_container" >> ./CI/tests/functional_tests echo "test_pod" >> ./CI/tests/functional_tests echo "test_namespace" >> ./CI/tests/functional_tests echo "test_net_chaos" >> ./CI/tests/functional_tests echo "test_time" >> ./CI/tests/functional_tests echo "test_cpu_hog" >> ./CI/tests/functional_tests echo "test_memory_hog" >> ./CI/tests/functional_tests echo "test_io_hog" >> ./CI/tests/functional_tests echo "test_pod_network_filter" >> ./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 '.kraken.port="8081"' CI/config/common_test_config.yaml yq -i '.kraken.signal_address="0.0.0.0"' CI/config/common_test_config.yaml yq -i '.kraken.performance_monitoring="localhost:9090"' CI/config/common_test_config.yaml yq -i '.elastic.enable_elastic=True' 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 '.performance_monitoring.prometheus_url="http://localhost:9090"' CI/config/common_test_config.yaml 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 echo "test_service_hijacking" >> ./CI/tests/functional_tests echo "test_app_outages" >> ./CI/tests/functional_tests echo "test_container" >> ./CI/tests/functional_tests echo "test_pod" >> ./CI/tests/functional_tests echo "test_namespace" >> ./CI/tests/functional_tests echo "test_net_chaos" >> ./CI/tests/functional_tests echo "test_time" >> ./CI/tests/functional_tests echo "test_cpu_hog" >> ./CI/tests/functional_tests echo "test_memory_hog" >> ./CI/tests/functional_tests echo "test_io_hog" >> ./CI/tests/functional_tests echo "test_pod_network_filter" >> ./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: ${{ success() || failure() }} uses: actions/upload-artifact@v4 with: name: ci-logs path: CI/out if-no-files-found: error - name: Collect coverage report if: ${{ success() || failure() }} run: | python -m coverage html python -m coverage json - name: Publish coverage report to job summary if: ${{ success() || failure() }} run: | pip install html2text html2text --ignore-images --ignore-links -b 0 htmlcov/index.html >> $GITHUB_STEP_SUMMARY - name: Upload coverage data if: ${{ success() || failure() }} uses: actions/upload-artifact@v4 with: name: coverage path: htmlcov if-no-files-found: error - name: Upload json coverage if: ${{ success() || failure() }} uses: actions/upload-artifact@v4 with: name: coverage.json path: coverage.json if-no-files-found: error - name: Check CI results if: ${{ success() || failure() }} 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.9 - 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