Multi Tenancy Integration Test π #174
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Multi Tenancy Integration Test π | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| cf_space: | |
| description: 'Specify the Cloud Foundry space to run integration tests on' | |
| required: true | |
| default: developcap | |
| branch_name: | |
| description: 'Specify the branch to use for integration tests' | |
| required: true | |
| default: develop | |
| jobs: | |
| # Parallel integration tests using matrix strategy | |
| integration-test: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| tokenFlow: [namedUser, technicalUser] | |
| tenant: [TENANT1, TENANT2] | |
| testClass: | |
| - IntegrationTest_SingleFacet | |
| - IntegrationTest_MultipleFacet | |
| - IntegrationTest_Chapters_MultipleFacet | |
| steps: | |
| - name: Checkout repository β | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.inputs.branch_name }} | |
| - name: Set up Java 17 β | |
| uses: actions/setup-java@v3 | |
| with: | |
| java-version: 17 | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Cache CF CLI π¦ | |
| id: cache-cf-cli | |
| uses: actions/cache@v4 | |
| with: | |
| path: /usr/bin/cf8 | |
| key: cf-cli-v8-${{ runner.os }} | |
| - name: Install Cloud Foundry CLI and jq π¦ | |
| if: steps.cache-cf-cli.outputs.cache-hit != 'true' | |
| run: | | |
| echo "π§ Installing Cloud Foundry CLI..." | |
| wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add - | |
| echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list | |
| sudo apt-get update | |
| sudo apt-get install cf8-cli | |
| - name: Install jq π¦ | |
| run: | | |
| if ! command -v jq &> /dev/null; then | |
| sudo apt-get update && sudo apt-get install -y jq | |
| fi | |
| - name: Determine Cloud Foundry Space π | |
| id: determine_space | |
| run: | | |
| if [ "${{ github.event.inputs.cf_space }}" == "developcap" ]; then | |
| space="${{ secrets.CF_SPACE }}" | |
| else | |
| space="${{ github.event.inputs.cf_space }}" | |
| fi | |
| echo "π Space determined: $space" | |
| echo "space=$space" >> $GITHUB_OUTPUT | |
| - name: Login to Cloud Foundry π | |
| run: | | |
| echo "π Logging in to Cloud Foundry using space: ${{ steps.determine_space.outputs.space }}" | |
| cf login -a ${{ secrets.CF_API }} \ | |
| -u ${{ secrets.CF_USER }} \ | |
| -p ${{ secrets.CF_PASSWORD }} \ | |
| -o ${{ secrets.CF_ORG }} \ | |
| -s ${{ steps.determine_space.outputs.space }} | |
| - name: Fetch and Escape Client Details for single tenant π | |
| id: fetch_credentials | |
| run: | | |
| echo "Fetching client details for single tenant..." | |
| service_instance_guid=$(cf service demoappjava-public-uaa --guid) | |
| if [ -z "$service_instance_guid" ]; then | |
| echo "β Error: Unable to retrieve service instance GUID"; exit 1; | |
| fi | |
| bindings_response=$(cf curl "/v3/service_credential_bindings?service_instance_guids=${service_instance_guid}") | |
| binding_guid=$(echo "$bindings_response" | jq -r '.resources[0].guid') | |
| if [ -z "$binding_guid" ]; then | |
| echo "β Error: Unable to retrieve binding GUID"; exit 1; | |
| fi | |
| binding_details=$(cf curl "/v3/service_credential_bindings/${binding_guid}/details") | |
| clientSecret=$(echo "$binding_details" | jq -r '.credentials.clientsecret') | |
| if [ -z "$clientSecret" ] || [ "$clientSecret" == "null" ]; then | |
| echo "β Error: clientSecret is not set or is null"; exit 1; | |
| fi | |
| escapedClientSecret=$(echo "$clientSecret" | sed 's/\$/\\$/g') | |
| echo "::add-mask::$escapedClientSecret" | |
| clientID=$(echo "$binding_details" | jq -r '.credentials.clientid') | |
| if [ -z "$clientID" ] || [ "$clientID" == "null" ]; then | |
| echo "β Error: clientID is not set or is null"; exit 1; | |
| fi | |
| echo "::add-mask::$clientID" | |
| echo "CLIENT_SECRET=$escapedClientSecret" >> $GITHUB_OUTPUT | |
| echo "CLIENT_ID=$clientID" >> $GITHUB_OUTPUT | |
| echo "β Client details fetched successfully!" | |
| - name: Fetch and Escape Client Details for multi tenant π | |
| id: fetch_credentials_mt | |
| run: | | |
| echo "Fetching client details for multi tenant..." | |
| service_instance_guid=$(cf service bookshop-mt-uaa --guid) | |
| if [ -z "$service_instance_guid" ]; then | |
| echo "β Error: Unable to retrieve service instance GUID"; exit 1; | |
| fi | |
| bindings_response=$(cf curl "/v3/service_credential_bindings?service_instance_guids=${service_instance_guid}") | |
| binding_guid=$(echo "$bindings_response" | jq -r '.resources[0].guid') | |
| if [ -z "$binding_guid" ]; then | |
| echo "β Error: Unable to retrieve binding GUID"; exit 1; | |
| fi | |
| binding_details=$(cf curl "/v3/service_credential_bindings/${binding_guid}/details") | |
| clientSecret_mt=$(echo "$binding_details" | jq -r '.credentials.clientsecret') | |
| if [ -z "$clientSecret_mt" ] || [ "$clientSecret_mt" == "null" ]; then | |
| echo "β Error: clientSecret_mt is not set or is null"; exit 1; | |
| fi | |
| escapedClientSecret_mt=$(echo "$clientSecret_mt" | sed 's/\$/\\$/g') | |
| echo "::add-mask::$escapedClientSecret_mt" | |
| clientID_mt=$(echo "$binding_details" | jq -r '.credentials.clientid') | |
| if [ -z "$clientID_mt" ] || [ "$clientID_mt" == "null" ]; then | |
| echo "β Error: clientID_mt is not set or is null"; exit 1; | |
| fi | |
| echo "::add-mask::$clientID_mt" | |
| echo "CLIENT_SECRET_MT=$escapedClientSecret_mt" >> $GITHUB_OUTPUT | |
| echo "CLIENT_ID_MT=$clientID_mt" >> $GITHUB_OUTPUT | |
| echo "β Multi-tenant client details fetched successfully!" | |
| - name: Prepare credentials file π | |
| env: | |
| CLIENT_SECRET: ${{ steps.fetch_credentials.outputs.CLIENT_SECRET }} | |
| CLIENT_ID: ${{ steps.fetch_credentials.outputs.CLIENT_ID }} | |
| CLIENT_SECRET_MT: ${{ steps.fetch_credentials_mt.outputs.CLIENT_SECRET_MT }} | |
| CLIENT_ID_MT: ${{ steps.fetch_credentials_mt.outputs.CLIENT_ID_MT }} | |
| CMIS_CLIENT_ID: ${{ secrets.CMISCLIENTID }} | |
| CMIS_CLIENT_SECRET: ${{ secrets.CMISCLIENTSECRET }} | |
| run: | | |
| echo "π Preparing credentials for ${{ matrix.tokenFlow }} - ${{ matrix.tenant }}..." | |
| set -e | |
| PROPERTIES_FILE="sdm/src/test/resources/credentials.properties" | |
| appUrl="${{ secrets.CF_ORG }}-${{ steps.determine_space.outputs.space }}-demoappjava-srv.cfapps.eu12.hana.ondemand.com" | |
| appUrlMT="${{ secrets.CF_ORG }}-${{ steps.determine_space.outputs.space }}-bookshop-mt-srv.cfapps.eu12.hana.ondemand.com" | |
| authUrl="${{ secrets.CAPAUTH_URL }}" | |
| authUrlMT1="${{ secrets.AUTHURLMT1 }}" | |
| authUrlMT2="${{ secrets.AUTHURLMT2 }}" | |
| clientID="${{ env.CLIENT_ID }}" | |
| clientSecret="${{ env.CLIENT_SECRET }}" | |
| clientIDMT="${{ env.CLIENT_ID_MT }}" | |
| clientSecretMT="${{ env.CLIENT_SECRET_MT }}" | |
| username="${{ secrets.CF_USER }}" | |
| password="${{ secrets.CF_PASSWORD }}" | |
| noSDMRoleUsername="${{ secrets.NOSDMROLEUSERNAME }}" | |
| noSDMRoleUserPassword="${{ secrets.NOSDMROLEUSERPASSWORD }}" | |
| CMIS_URL="${{ secrets.CMIS_URL }}" | |
| cmisClientID="$CMIS_CLIENT_ID" | |
| cmisClientSecret="$CMIS_CLIENT_SECRET" | |
| defaultRepositoryID="${{ secrets.DEFAULTREPOSITORYID }}" | |
| defaultRepositoryIDMT="${{ secrets.DEFAULTREPOSITORYIDMT }}" | |
| echo "::add-mask::$clientSecret" | |
| echo "::add-mask::$clientID" | |
| echo "::add-mask::$clientSecretMT" | |
| echo "::add-mask::$clientIDMT" | |
| echo "::add-mask::$username" | |
| echo "::add-mask::$password" | |
| echo "::add-mask::$noSDMRoleUsername" | |
| echo "::add-mask::$noSDMRoleUserPassword" | |
| echo "::add-mask::$CMIS_URL" | |
| echo "::add-mask::$cmisClientID" | |
| echo "::add-mask::$cmisClientSecret" | |
| if [ -z "$appUrl" ]; then echo "β Error: appUrl is not set"; exit 1; fi | |
| if [ -z "$appUrlMT" ]; then echo "β Error: appUrlMT is not set"; exit 1; fi | |
| if [ -z "$authUrl" ]; then echo "β Error: authUrl is not set"; exit 1; fi | |
| if [ -z "$authUrlMT1" ]; then echo "β Error: authUrlMT1 is not set"; exit 1; fi | |
| if [ -z "$authUrlMT2" ]; then echo "β Error: authUrlMT2 is not set"; exit 1; fi | |
| if [ -z "$clientID" ]; then echo "β Error: clientID is not set"; exit 1; fi | |
| if [ -z "$clientSecret" ]; then echo "β Error: clientSecret is not set"; exit 1; fi | |
| if [ -z "$clientIDMT" ]; then echo "β Error: clientIDMT is not set"; exit 1; fi | |
| if [ -z "$clientSecretMT" ]; then echo "β Error: clientSecretMT is not set"; exit 1; fi | |
| if [ -z "$username" ]; then echo "β Error: username is not set"; exit 1; fi | |
| if [ -z "$password" ]; then echo "β Error: password is not set"; exit 1; fi | |
| if [ -z "$noSDMRoleUsername" ]; then echo "β Error: noSDMRoleUsername is not set"; exit 1; fi | |
| if [ -z "$noSDMRoleUserPassword" ]; then echo "β Error: noSDMRoleUserPassword is not set"; exit 1; fi | |
| if [ -z "$CMIS_URL" ]; then echo "β Error: CMIS_URL is not set"; exit 1; fi | |
| if [ -z "$cmisClientID" ]; then echo "β Error: cmisClientID is not set"; exit 1; fi | |
| if [ -z "$cmisClientSecret" ]; then echo "β Error: cmisClientSecret is not set"; exit 1; fi | |
| cat > "$PROPERTIES_FILE" <<EOL | |
| appUrl=$appUrl | |
| appUrlMT=$appUrlMT | |
| authUrl=$authUrl | |
| authUrlMT1=$authUrlMT1 | |
| authUrlMT2=$authUrlMT2 | |
| clientID=$clientID | |
| clientSecret=$clientSecret | |
| clientIDMT=$clientIDMT | |
| clientSecretMT=$clientSecretMT | |
| username=$username | |
| password=$password | |
| noSDMRoleUsername=$noSDMRoleUsername | |
| noSDMRoleUserPassword=$noSDMRoleUserPassword | |
| CMIS_URL=$CMIS_URL | |
| cmisClientID=$cmisClientID | |
| cmisClientSecret=$cmisClientSecret | |
| defaultRepositoryID=$defaultRepositoryID | |
| defaultRepositoryIDMT=$defaultRepositoryIDMT | |
| EOL | |
| echo "β Credentials file prepared!" | |
| - name: Download virus test file π₯ | |
| run: | | |
| curl -fSL "http://www.eicar.org/download/eicar.com.txt" -o "sdm/eicar.com.txt" | |
| sleep 5 | |
| if [ -f "sdm/eicar.com.txt" ]; then | |
| FILE_SIZE=$(stat -c '%s' "sdm/eicar.com.txt") | |
| echo "File exists β Size: $FILE_SIZE bytes" | |
| else | |
| echo "β File NOT found at path: sdm/eicar.com.txt" | |
| exit 1 | |
| fi | |
| - name: Run integration tests (${{ matrix.testClass }} - ${{ matrix.tokenFlow }} - ${{ matrix.tenant }}) π― | |
| run: | | |
| echo "π― Running Maven integration tests: testClass=${{ matrix.testClass }}, tokenFlow=${{ matrix.tokenFlow }}, tenant=${{ matrix.tenant }}" | |
| mvn clean verify -P integration-tests -DtokenFlow=${{ matrix.tokenFlow }} -DtenancyModel=multi -Dtenant=${{ matrix.tenant }} -DskipUnitTests -Deicar.file.path=eicar.com.txt -Dfailsafe.includes="**/${{ matrix.testClass }}.java" | |
| echo "β Integration tests completed for ${{ matrix.testClass }} - ${{ matrix.tokenFlow }} - ${{ matrix.tenant }}!" | |
| - name: Upload test results π | |
| if: "!cancelled()" | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: test-results-${{ matrix.testClass }}-${{ matrix.tokenFlow }}-${{ matrix.tenant }} | |
| path: | | |
| sdm/target/surefire-reports/ | |
| sdm/target/failsafe-reports/ | |
| retention-days: 7 | |
| # Single self-contained job: switch to versioned repo, run all test combos, revert | |
| versioned-test: | |
| runs-on: ubuntu-latest | |
| needs: integration-test | |
| if: "!cancelled()" | |
| steps: | |
| - name: Checkout repository π | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.inputs.branch_name }} | |
| - name: Set up Java 17 β | |
| uses: actions/setup-java@v3 | |
| with: | |
| java-version: 17 | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Cache CF CLI π¦ | |
| id: cache-cf-cli | |
| uses: actions/cache@v4 | |
| with: | |
| path: /usr/bin/cf8 | |
| key: cf-cli-v8-${{ runner.os }} | |
| - name: Install Cloud Foundry CLI π§ | |
| if: steps.cache-cf-cli.outputs.cache-hit != 'true' | |
| run: | | |
| wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add - | |
| echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list | |
| sudo apt-get update | |
| sudo apt-get install cf8-cli | |
| - name: Install jq π¦ | |
| run: | | |
| if ! command -v jq &> /dev/null; then | |
| sudo apt-get update && sudo apt-get install -y jq | |
| fi | |
| - name: Determine Cloud Foundry Space π | |
| id: determine_space | |
| run: | | |
| if [ "${{ github.event.inputs.cf_space }}" == "developcap" ]; then | |
| space="${{ secrets.CF_SPACE }}" | |
| else | |
| space="${{ github.event.inputs.cf_space }}" | |
| fi | |
| echo "space=$space" >> $GITHUB_OUTPUT | |
| - name: Login to Cloud Foundry π | |
| run: | | |
| cf login -a ${{ secrets.CF_API }} \ | |
| -u ${{ secrets.CF_USER }} \ | |
| -p ${{ secrets.CF_PASSWORD }} \ | |
| -o ${{ secrets.CF_ORG }} \ | |
| -s ${{ steps.determine_space.outputs.space }} | |
| - name: Fetch and Escape Client Details for single tenant π | |
| id: fetch_credentials | |
| run: | | |
| service_instance_guid=$(cf service demoappjava-public-uaa --guid) | |
| if [ -z "$service_instance_guid" ]; then | |
| echo "β Error: Unable to retrieve service instance GUID"; exit 1; | |
| fi | |
| bindings_response=$(cf curl "/v3/service_credential_bindings?service_instance_guids=${service_instance_guid}") | |
| binding_guid=$(echo "$bindings_response" | jq -r '.resources[0].guid') | |
| if [ -z "$binding_guid" ]; then | |
| echo "β Error: Unable to retrieve binding GUID"; exit 1; | |
| fi | |
| binding_details=$(cf curl "/v3/service_credential_bindings/${binding_guid}/details") | |
| clientSecret=$(echo "$binding_details" | jq -r '.credentials.clientsecret') | |
| if [ -z "$clientSecret" ] || [ "$clientSecret" == "null" ]; then | |
| echo "β Error: clientSecret is not set or is null"; exit 1; | |
| fi | |
| escapedClientSecret=$(echo "$clientSecret" | sed 's/\$/\\$/g') | |
| echo "::add-mask::$escapedClientSecret" | |
| clientID=$(echo "$binding_details" | jq -r '.credentials.clientid') | |
| if [ -z "$clientID" ] || [ "$clientID" == "null" ]; then | |
| echo "β Error: clientID is not set or is null"; exit 1; | |
| fi | |
| echo "::add-mask::$clientID" | |
| echo "CLIENT_SECRET=$escapedClientSecret" >> $GITHUB_OUTPUT | |
| echo "CLIENT_ID=$clientID" >> $GITHUB_OUTPUT | |
| - name: Fetch and Escape Client Details for multi tenant π | |
| id: fetch_credentials_mt | |
| run: | | |
| service_instance_guid=$(cf service bookshop-mt-uaa --guid) | |
| if [ -z "$service_instance_guid" ]; then | |
| echo "β Error: Unable to retrieve service instance GUID"; exit 1; | |
| fi | |
| bindings_response=$(cf curl "/v3/service_credential_bindings?service_instance_guids=${service_instance_guid}") | |
| binding_guid=$(echo "$bindings_response" | jq -r '.resources[0].guid') | |
| if [ -z "$binding_guid" ]; then | |
| echo "β Error: Unable to retrieve binding GUID"; exit 1; | |
| fi | |
| binding_details=$(cf curl "/v3/service_credential_bindings/${binding_guid}/details") | |
| clientSecret_mt=$(echo "$binding_details" | jq -r '.credentials.clientsecret') | |
| if [ -z "$clientSecret_mt" ] || [ "$clientSecret_mt" == "null" ]; then | |
| echo "β Error: clientSecret_mt is not set or is null"; exit 1; | |
| fi | |
| escapedClientSecret_mt=$(echo "$clientSecret_mt" | sed 's/\$/\\$/g') | |
| echo "::add-mask::$escapedClientSecret_mt" | |
| clientID_mt=$(echo "$binding_details" | jq -r '.credentials.clientid') | |
| if [ -z "$clientID_mt" ] || [ "$clientID_mt" == "null" ]; then | |
| echo "β Error: clientID_mt is not set or is null"; exit 1; | |
| fi | |
| echo "::add-mask::$clientID_mt" | |
| echo "CLIENT_SECRET_MT=$escapedClientSecret_mt" >> $GITHUB_OUTPUT | |
| echo "CLIENT_ID_MT=$clientID_mt" >> $GITHUB_OUTPUT | |
| - name: Switch to Versioned Repository π | |
| run: | | |
| echo "π Switching REPOSITORY_ID to versioned repository..." | |
| cf set-env bookshop-mt-srv REPOSITORY_ID "${{ secrets.VERSIONEDREPOSITORYID }}" | |
| echo "π Restaging application..." | |
| cf restage bookshop-mt-srv > /dev/null 2>&1 | |
| echo "β Switched to versioned repository!" | |
| - name: Run all versioned integration tests π― | |
| id: run_tests | |
| env: | |
| CLIENT_SECRET: ${{ steps.fetch_credentials.outputs.CLIENT_SECRET }} | |
| CLIENT_ID: ${{ steps.fetch_credentials.outputs.CLIENT_ID }} | |
| CLIENT_SECRET_MT: ${{ steps.fetch_credentials_mt.outputs.CLIENT_SECRET_MT }} | |
| CLIENT_ID_MT: ${{ steps.fetch_credentials_mt.outputs.CLIENT_ID_MT }} | |
| CMIS_CLIENT_ID: ${{ secrets.CMISCLIENTID }} | |
| CMIS_CLIENT_SECRET: ${{ secrets.CMISCLIENTSECRET }} | |
| run: | | |
| set -e | |
| PROPERTIES_FILE="sdm/src/test/resources/credentials.properties" | |
| appUrl="${{ secrets.CF_ORG }}-${{ steps.determine_space.outputs.space }}-demoappjava-srv.cfapps.eu12.hana.ondemand.com" | |
| appUrlMT="${{ secrets.CF_ORG }}-${{ steps.determine_space.outputs.space }}-bookshop-mt-srv.cfapps.eu12.hana.ondemand.com" | |
| authUrl="${{ secrets.CAPAUTH_URL }}" | |
| authUrlMT1="${{ secrets.AUTHURLMT1 }}" | |
| authUrlMT2="${{ secrets.AUTHURLMT2 }}" | |
| clientID="${{ env.CLIENT_ID }}" | |
| clientSecret="${{ env.CLIENT_SECRET }}" | |
| clientIDMT="${{ env.CLIENT_ID_MT }}" | |
| clientSecretMT="${{ env.CLIENT_SECRET_MT }}" | |
| username="${{ secrets.CF_USER }}" | |
| password="${{ secrets.CF_PASSWORD }}" | |
| noSDMRoleUsername="${{ secrets.NOSDMROLEUSERNAME }}" | |
| noSDMRoleUserPassword="${{ secrets.NOSDMROLEUSERPASSWORD }}" | |
| versionedRepositoryID="${{ secrets.VERSIONEDREPOSITORYID }}" | |
| virusScanRepositoryID="${{ secrets.VIRUSSCANREPOSITORYID }}" | |
| defaultRepositoryID="${{ secrets.DEFAULTREPOSITORYID }}" | |
| defaultRepositoryIDMT="${{ secrets.DEFAULTREPOSITORYIDMT }}" | |
| CMIS_URL="${{ secrets.CMIS_URL }}" | |
| cmisClientID="$CMIS_CLIENT_ID" | |
| cmisClientSecret="$CMIS_CLIENT_SECRET" | |
| cat > "$PROPERTIES_FILE" <<EOL | |
| appUrl=$appUrl | |
| appUrlMT=$appUrlMT | |
| authUrl=$authUrl | |
| authUrlMT1=$authUrlMT1 | |
| authUrlMT2=$authUrlMT2 | |
| clientID=$clientID | |
| clientSecret=$clientSecret | |
| clientIDMT=$clientIDMT | |
| clientSecretMT=$clientSecretMT | |
| username=$username | |
| password=$password | |
| noSDMRoleUsername=$noSDMRoleUsername | |
| noSDMRoleUserPassword=$noSDMRoleUserPassword | |
| versionedRepositoryID=$versionedRepositoryID | |
| virusScanRepositoryID=$virusScanRepositoryID | |
| defaultRepositoryID=$defaultRepositoryID | |
| defaultRepositoryIDMT=$defaultRepositoryIDMT | |
| CMIS_URL=$CMIS_URL | |
| cmisClientID=$cmisClientID | |
| cmisClientSecret=$cmisClientSecret | |
| EOL | |
| FAILED=0 | |
| for tokenFlow in namedUser technicalUser; do | |
| for tenant in TENANT1 TENANT2; do | |
| for testClass in IntegrationTest_SingleFacet_VersionedRepository IntegrationTest_MultipleFacet_VersionedRepository IntegrationTest_Chapters_MultipleFacet_VersionedRepository; do | |
| echo "π― Running: $testClass - $tokenFlow - $tenant" | |
| if ! mvn clean verify -P integration-tests \ | |
| -DtokenFlow=$tokenFlow -DtenancyModel=multi -Dtenant=$tenant \ | |
| -DskipUnitTests -Dfailsafe.includes="**/${testClass}.java"; then | |
| echo "β FAILED: $testClass - $tokenFlow - $tenant" | |
| FAILED=$((FAILED + 1)) | |
| else | |
| echo "β PASSED: $testClass - $tokenFlow - $tenant" | |
| fi | |
| done | |
| done | |
| done | |
| if [ $FAILED -gt 0 ]; then | |
| echo "β $FAILED test combination(s) failed" | |
| echo "test_failed=true" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Revert to Default Repository π | |
| if: always() | |
| run: | | |
| echo "π Reverting REPOSITORY_ID to default repository..." | |
| cf set-env bookshop-mt-srv REPOSITORY_ID "${{ secrets.DEFAULTREPOSITORYIDMT }}" | |
| echo "π Restaging application..." | |
| cf restage bookshop-mt-srv > /dev/null 2>&1 | |
| echo "β Reverted to default repository!" | |
| - name: Fail if tests failed β | |
| if: steps.run_tests.outputs.test_failed == 'true' | |
| run: | | |
| echo "β Some versioned integration tests failed. Check logs above for details." | |
| exit 1 | |
| # Single self-contained job: switch to virusscan repo, run all test combos, revert | |
| virusscan-test: | |
| runs-on: ubuntu-latest | |
| needs: versioned-test | |
| if: "!cancelled()" | |
| steps: | |
| - name: Checkout repository π | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.inputs.branch_name }} | |
| - name: Set up Java 17 β | |
| uses: actions/setup-java@v3 | |
| with: | |
| java-version: 17 | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Cache CF CLI π¦ | |
| id: cache-cf-cli | |
| uses: actions/cache@v4 | |
| with: | |
| path: /usr/bin/cf8 | |
| key: cf-cli-v8-${{ runner.os }} | |
| - name: Install Cloud Foundry CLI π§ | |
| if: steps.cache-cf-cli.outputs.cache-hit != 'true' | |
| run: | | |
| wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add - | |
| echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list | |
| sudo apt-get update | |
| sudo apt-get install cf8-cli | |
| - name: Install jq π¦ | |
| run: | | |
| if ! command -v jq &> /dev/null; then | |
| sudo apt-get update && sudo apt-get install -y jq | |
| fi | |
| - name: Determine Cloud Foundry Space π | |
| id: determine_space | |
| run: | | |
| if [ "${{ github.event.inputs.cf_space }}" == "developcap" ]; then | |
| space="${{ secrets.CF_SPACE }}" | |
| else | |
| space="${{ github.event.inputs.cf_space }}" | |
| fi | |
| echo "space=$space" >> $GITHUB_OUTPUT | |
| - name: Login to Cloud Foundry π | |
| run: | | |
| cf login -a ${{ secrets.CF_API }} \ | |
| -u ${{ secrets.CF_USER }} \ | |
| -p ${{ secrets.CF_PASSWORD }} \ | |
| -o ${{ secrets.CF_ORG }} \ | |
| -s ${{ steps.determine_space.outputs.space }} | |
| - name: Fetch and Escape Client Details for single tenant π | |
| id: fetch_credentials | |
| run: | | |
| service_instance_guid=$(cf service demoappjava-public-uaa --guid) | |
| if [ -z "$service_instance_guid" ]; then | |
| echo "β Error: Unable to retrieve service instance GUID"; exit 1; | |
| fi | |
| bindings_response=$(cf curl "/v3/service_credential_bindings?service_instance_guids=${service_instance_guid}") | |
| binding_guid=$(echo "$bindings_response" | jq -r '.resources[0].guid') | |
| if [ -z "$binding_guid" ]; then | |
| echo "β Error: Unable to retrieve binding GUID"; exit 1; | |
| fi | |
| binding_details=$(cf curl "/v3/service_credential_bindings/${binding_guid}/details") | |
| clientSecret=$(echo "$binding_details" | jq -r '.credentials.clientsecret') | |
| if [ -z "$clientSecret" ] || [ "$clientSecret" == "null" ]; then | |
| echo "β Error: clientSecret is not set or is null"; exit 1; | |
| fi | |
| escapedClientSecret=$(echo "$clientSecret" | sed 's/\$/\\$/g') | |
| echo "::add-mask::$escapedClientSecret" | |
| clientID=$(echo "$binding_details" | jq -r '.credentials.clientid') | |
| if [ -z "$clientID" ] || [ "$clientID" == "null" ]; then | |
| echo "β Error: clientID is not set or is null"; exit 1; | |
| fi | |
| echo "::add-mask::$clientID" | |
| echo "CLIENT_SECRET=$escapedClientSecret" >> $GITHUB_OUTPUT | |
| echo "CLIENT_ID=$clientID" >> $GITHUB_OUTPUT | |
| - name: Fetch and Escape Client Details for multi tenant π | |
| id: fetch_credentials_mt | |
| run: | | |
| service_instance_guid=$(cf service bookshop-mt-uaa --guid) | |
| if [ -z "$service_instance_guid" ]; then | |
| echo "β Error: Unable to retrieve service instance GUID"; exit 1; | |
| fi | |
| bindings_response=$(cf curl "/v3/service_credential_bindings?service_instance_guids=${service_instance_guid}") | |
| binding_guid=$(echo "$bindings_response" | jq -r '.resources[0].guid') | |
| if [ -z "$binding_guid" ]; then | |
| echo "β Error: Unable to retrieve binding GUID"; exit 1; | |
| fi | |
| binding_details=$(cf curl "/v3/service_credential_bindings/${binding_guid}/details") | |
| clientSecret_mt=$(echo "$binding_details" | jq -r '.credentials.clientsecret') | |
| if [ -z "$clientSecret_mt" ] || [ "$clientSecret_mt" == "null" ]; then | |
| echo "β Error: clientSecret_mt is not set or is null"; exit 1; | |
| fi | |
| escapedClientSecret_mt=$(echo "$clientSecret_mt" | sed 's/\$/\\$/g') | |
| echo "::add-mask::$escapedClientSecret_mt" | |
| clientID_mt=$(echo "$binding_details" | jq -r '.credentials.clientid') | |
| if [ -z "$clientID_mt" ] || [ "$clientID_mt" == "null" ]; then | |
| echo "β Error: clientID_mt is not set or is null"; exit 1; | |
| fi | |
| echo "::add-mask::$clientID_mt" | |
| echo "CLIENT_SECRET_MT=$escapedClientSecret_mt" >> $GITHUB_OUTPUT | |
| echo "CLIENT_ID_MT=$clientID_mt" >> $GITHUB_OUTPUT | |
| - name: Switch to Virus Scan Repository π | |
| run: | | |
| echo "π Switching REPOSITORY_ID to virus scan repository..." | |
| cf set-env bookshop-mt-srv REPOSITORY_ID "${{ secrets.VIRUSSCANREPOSITORYID }}" | |
| echo "π Restaging application..." | |
| cf restage bookshop-mt-srv > /dev/null 2>&1 | |
| echo "β Switched to virus scan repository!" | |
| - name: Download virus test file π₯ | |
| run: | | |
| curl -fSL "http://www.eicar.org/download/eicar.com.txt" -o "sdm/eicar.com.txt" | |
| sleep 5 | |
| if [ -f "sdm/eicar.com.txt" ]; then | |
| FILE_SIZE=$(stat -c '%s' "sdm/eicar.com.txt") | |
| echo "File exists β Size: $FILE_SIZE bytes" | |
| else | |
| echo "β File NOT found at path: sdm/eicar.com.txt" | |
| exit 1 | |
| fi | |
| - name: Run all virus scan integration tests π― | |
| id: run_tests | |
| env: | |
| CLIENT_SECRET: ${{ steps.fetch_credentials.outputs.CLIENT_SECRET }} | |
| CLIENT_ID: ${{ steps.fetch_credentials.outputs.CLIENT_ID }} | |
| CLIENT_SECRET_MT: ${{ steps.fetch_credentials_mt.outputs.CLIENT_SECRET_MT }} | |
| CLIENT_ID_MT: ${{ steps.fetch_credentials_mt.outputs.CLIENT_ID_MT }} | |
| CMIS_CLIENT_ID: ${{ secrets.CMISCLIENTID }} | |
| CMIS_CLIENT_SECRET: ${{ secrets.CMISCLIENTSECRET }} | |
| run: | | |
| set -e | |
| PROPERTIES_FILE="sdm/src/test/resources/credentials.properties" | |
| appUrl="${{ secrets.CF_ORG }}-${{ steps.determine_space.outputs.space }}-demoappjava-srv.cfapps.eu12.hana.ondemand.com" | |
| appUrlMT="${{ secrets.CF_ORG }}-${{ steps.determine_space.outputs.space }}-bookshop-mt-srv.cfapps.eu12.hana.ondemand.com" | |
| authUrl="${{ secrets.CAPAUTH_URL }}" | |
| authUrlMT1="${{ secrets.AUTHURLMT1 }}" | |
| authUrlMT2="${{ secrets.AUTHURLMT2 }}" | |
| clientID="${{ env.CLIENT_ID }}" | |
| clientSecret="${{ env.CLIENT_SECRET }}" | |
| clientIDMT="${{ env.CLIENT_ID_MT }}" | |
| clientSecretMT="${{ env.CLIENT_SECRET_MT }}" | |
| username="${{ secrets.CF_USER }}" | |
| password="${{ secrets.CF_PASSWORD }}" | |
| noSDMRoleUsername="${{ secrets.NOSDMROLEUSERNAME }}" | |
| noSDMRoleUserPassword="${{ secrets.NOSDMROLEUSERPASSWORD }}" | |
| versionedRepositoryID="${{ secrets.VERSIONEDREPOSITORYID }}" | |
| virusScanRepositoryID="${{ secrets.VIRUSSCANREPOSITORYID }}" | |
| defaultRepositoryID="${{ secrets.DEFAULTREPOSITORYID }}" | |
| defaultRepositoryIDMT="${{ secrets.DEFAULTREPOSITORYIDMT }}" | |
| CMIS_URL="${{ secrets.CMIS_URL }}" | |
| cmisClientID="$CMIS_CLIENT_ID" | |
| cmisClientSecret="$CMIS_CLIENT_SECRET" | |
| cat > "$PROPERTIES_FILE" <<EOL | |
| appUrl=$appUrl | |
| appUrlMT=$appUrlMT | |
| authUrl=$authUrl | |
| authUrlMT1=$authUrlMT1 | |
| authUrlMT2=$authUrlMT2 | |
| clientID=$clientID | |
| clientSecret=$clientSecret | |
| clientIDMT=$clientIDMT | |
| clientSecretMT=$clientSecretMT | |
| username=$username | |
| password=$password | |
| noSDMRoleUsername=$noSDMRoleUsername | |
| noSDMRoleUserPassword=$noSDMRoleUserPassword | |
| versionedRepositoryID=$versionedRepositoryID | |
| virusScanRepositoryID=$virusScanRepositoryID | |
| defaultRepositoryID=$defaultRepositoryID | |
| defaultRepositoryIDMT=$defaultRepositoryIDMT | |
| CMIS_URL=$CMIS_URL | |
| cmisClientID=$cmisClientID | |
| cmisClientSecret=$cmisClientSecret | |
| EOL | |
| FAILED=0 | |
| for tokenFlow in namedUser technicalUser; do | |
| for tenant in TENANT1 TENANT2; do | |
| for testClass in IntegrationTest_SingleFacet_Virus IntegrationTest_MultipleFacet_Virus IntegrationTest_Chapters_MultipleFacet_Virus; do | |
| echo "π― Running: $testClass - $tokenFlow - $tenant" | |
| if ! mvn clean verify -P integration-tests \ | |
| -DtokenFlow=$tokenFlow -DtenancyModel=multi -Dtenant=$tenant \ | |
| -DskipUnitTests -Deicar.file.path=eicar.com.txt \ | |
| -Dfailsafe.includes="**/${testClass}.java"; then | |
| echo "β FAILED: $testClass - $tokenFlow - $tenant" | |
| FAILED=$((FAILED + 1)) | |
| else | |
| echo "β PASSED: $testClass - $tokenFlow - $tenant" | |
| fi | |
| done | |
| done | |
| done | |
| if [ $FAILED -gt 0 ]; then | |
| echo "β $FAILED test combination(s) failed" | |
| echo "test_failed=true" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Revert to Default Repository π | |
| if: always() | |
| run: | | |
| echo "π Reverting REPOSITORY_ID to default repository..." | |
| cf set-env bookshop-mt-srv REPOSITORY_ID "${{ secrets.DEFAULTREPOSITORYIDMT }}" | |
| echo "π Restaging application..." | |
| cf restage bookshop-mt-srv > /dev/null 2>&1 | |
| echo "β Reverted to default repository!" | |
| - name: Fail if tests failed β | |
| if: steps.run_tests.outputs.test_failed == 'true' | |
| run: | | |
| echo "β Some virus scan integration tests failed. Check logs above for details." | |
| exit 1 | |
| # Single self-contained job: run all repo-specific test combos sequentially | |
| repospecific-test: | |
| runs-on: ubuntu-latest | |
| needs: virusscan-test | |
| if: "!cancelled()" | |
| steps: | |
| - name: Checkout repository π | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.inputs.branch_name }} | |
| - name: Set up Java 17 β | |
| uses: actions/setup-java@v3 | |
| with: | |
| java-version: 17 | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Cache CF CLI π¦ | |
| id: cache-cf-cli | |
| uses: actions/cache@v4 | |
| with: | |
| path: /usr/bin/cf8 | |
| key: cf-cli-v8-${{ runner.os }} | |
| - name: Install Cloud Foundry CLI π§ | |
| if: steps.cache-cf-cli.outputs.cache-hit != 'true' | |
| run: | | |
| wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add - | |
| echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list | |
| sudo apt-get update | |
| sudo apt-get install cf8-cli | |
| - name: Install jq π¦ | |
| run: | | |
| if ! command -v jq &> /dev/null; then | |
| sudo apt-get update && sudo apt-get install -y jq | |
| fi | |
| - name: Determine Cloud Foundry Space π | |
| id: determine_space | |
| run: | | |
| if [ "${{ github.event.inputs.cf_space }}" == "developcap" ]; then | |
| space="${{ secrets.CF_SPACE }}" | |
| else | |
| space="${{ github.event.inputs.cf_space }}" | |
| fi | |
| echo "space=$space" >> $GITHUB_OUTPUT | |
| - name: Login to Cloud Foundry π | |
| run: | | |
| cf login -a ${{ secrets.CF_API }} \ | |
| -u ${{ secrets.CF_USER }} \ | |
| -p ${{ secrets.CF_PASSWORD }} \ | |
| -o ${{ secrets.CF_ORG }} \ | |
| -s ${{ steps.determine_space.outputs.space }} | |
| - name: Fetch and Escape Client Details for single tenant π | |
| id: fetch_credentials | |
| run: | | |
| service_instance_guid=$(cf service demoappjava-public-uaa --guid) | |
| if [ -z "$service_instance_guid" ]; then | |
| echo "β Error: Unable to retrieve service instance GUID"; exit 1; | |
| fi | |
| bindings_response=$(cf curl "/v3/service_credential_bindings?service_instance_guids=${service_instance_guid}") | |
| binding_guid=$(echo "$bindings_response" | jq -r '.resources[0].guid') | |
| if [ -z "$binding_guid" ]; then | |
| echo "β Error: Unable to retrieve binding GUID"; exit 1; | |
| fi | |
| binding_details=$(cf curl "/v3/service_credential_bindings/${binding_guid}/details") | |
| clientSecret=$(echo "$binding_details" | jq -r '.credentials.clientsecret') | |
| if [ -z "$clientSecret" ] || [ "$clientSecret" == "null" ]; then | |
| echo "β Error: clientSecret is not set or is null"; exit 1; | |
| fi | |
| escapedClientSecret=$(echo "$clientSecret" | sed 's/\$/\\$/g') | |
| echo "::add-mask::$escapedClientSecret" | |
| clientID=$(echo "$binding_details" | jq -r '.credentials.clientid') | |
| if [ -z "$clientID" ] || [ "$clientID" == "null" ]; then | |
| echo "β Error: clientID is not set or is null"; exit 1; | |
| fi | |
| echo "::add-mask::$clientID" | |
| echo "CLIENT_SECRET=$escapedClientSecret" >> $GITHUB_OUTPUT | |
| echo "CLIENT_ID=$clientID" >> $GITHUB_OUTPUT | |
| - name: Fetch and Escape Client Details for multi tenant π | |
| id: fetch_credentials_mt | |
| run: | | |
| service_instance_guid=$(cf service bookshop-mt-uaa --guid) | |
| if [ -z "$service_instance_guid" ]; then | |
| echo "β Error: Unable to retrieve service instance GUID"; exit 1; | |
| fi | |
| bindings_response=$(cf curl "/v3/service_credential_bindings?service_instance_guids=${service_instance_guid}") | |
| binding_guid=$(echo "$bindings_response" | jq -r '.resources[0].guid') | |
| if [ -z "$binding_guid" ]; then | |
| echo "β Error: Unable to retrieve binding GUID"; exit 1; | |
| fi | |
| binding_details=$(cf curl "/v3/service_credential_bindings/${binding_guid}/details") | |
| clientSecret_mt=$(echo "$binding_details" | jq -r '.credentials.clientsecret') | |
| if [ -z "$clientSecret_mt" ] || [ "$clientSecret_mt" == "null" ]; then | |
| echo "β Error: clientSecret_mt is not set or is null"; exit 1; | |
| fi | |
| escapedClientSecret_mt=$(echo "$clientSecret_mt" | sed 's/\$/\\$/g') | |
| echo "::add-mask::$escapedClientSecret_mt" | |
| clientID_mt=$(echo "$binding_details" | jq -r '.credentials.clientid') | |
| if [ -z "$clientID_mt" ] || [ "$clientID_mt" == "null" ]; then | |
| echo "β Error: clientID_mt is not set or is null"; exit 1; | |
| fi | |
| echo "::add-mask::$clientID_mt" | |
| echo "CLIENT_SECRET_MT=$escapedClientSecret_mt" >> $GITHUB_OUTPUT | |
| echo "CLIENT_ID_MT=$clientID_mt" >> $GITHUB_OUTPUT | |
| - name: Run all repo-specific integration tests π― | |
| id: run_tests | |
| env: | |
| CLIENT_SECRET: ${{ steps.fetch_credentials.outputs.CLIENT_SECRET }} | |
| CLIENT_ID: ${{ steps.fetch_credentials.outputs.CLIENT_ID }} | |
| CLIENT_SECRET_MT: ${{ steps.fetch_credentials_mt.outputs.CLIENT_SECRET_MT }} | |
| CLIENT_ID_MT: ${{ steps.fetch_credentials_mt.outputs.CLIENT_ID_MT }} | |
| CMIS_CLIENT_ID: ${{ secrets.CMISCLIENTID }} | |
| CMIS_CLIENT_SECRET: ${{ secrets.CMISCLIENTSECRET }} | |
| run: | | |
| set -e | |
| PROPERTIES_FILE="sdm/src/test/resources/credentials.properties" | |
| appUrl="${{ secrets.CF_ORG }}-${{ steps.determine_space.outputs.space }}-demoappjava-srv.cfapps.eu12.hana.ondemand.com" | |
| appUrlMT="${{ secrets.CF_ORG }}-${{ steps.determine_space.outputs.space }}-bookshop-mt-srv.cfapps.eu12.hana.ondemand.com" | |
| authUrl="${{ secrets.CAPAUTH_URL }}" | |
| authUrlMT1="${{ secrets.AUTHURLMT1 }}" | |
| authUrlMT2="${{ secrets.AUTHURLMT2 }}" | |
| clientID="${{ env.CLIENT_ID }}" | |
| clientSecret="${{ env.CLIENT_SECRET }}" | |
| clientIDMT="${{ env.CLIENT_ID_MT }}" | |
| clientSecretMT="${{ env.CLIENT_SECRET_MT }}" | |
| username="${{ secrets.CF_USER }}" | |
| password="${{ secrets.CF_PASSWORD }}" | |
| noSDMRoleUsername="${{ secrets.NOSDMROLEUSERNAME }}" | |
| noSDMRoleUserPassword="${{ secrets.NOSDMROLEUSERPASSWORD }}" | |
| versionedRepositoryID="${{ secrets.VERSIONEDREPOSITORYID }}" | |
| virusScanRepositoryID="${{ secrets.VIRUSSCANREPOSITORYID }}" | |
| defaultRepositoryID="${{ secrets.DEFAULTREPOSITORYID }}" | |
| defaultRepositoryIDMT="${{ secrets.DEFAULTREPOSITORYIDMT }}" | |
| CMIS_URL="${{ secrets.CMIS_URL }}" | |
| cmisClientID="$CMIS_CLIENT_ID" | |
| cmisClientSecret="$CMIS_CLIENT_SECRET" | |
| FAILED=0 | |
| for tokenFlow in namedUser technicalUser; do | |
| for tenant in TENANT1 TENANT2; do | |
| for testClass in IntegrationTest_SingleFacet_RepoSpecific IntegrationTest_MultipleFacet_RepoSpecific IntegrationTest_Chapters_MultipleFacet_RepoSpecific; do | |
| echo "π― Running: $testClass - $tokenFlow - $tenant" | |
| cat > "$PROPERTIES_FILE" <<EOL | |
| appUrl=$appUrl | |
| appUrlMT=$appUrlMT | |
| authUrl=$authUrl | |
| authUrlMT1=$authUrlMT1 | |
| authUrlMT2=$authUrlMT2 | |
| clientID=$clientID | |
| clientSecret=$clientSecret | |
| clientIDMT=$clientIDMT | |
| clientSecretMT=$clientSecretMT | |
| username=$username | |
| password=$password | |
| noSDMRoleUsername=$noSDMRoleUsername | |
| noSDMRoleUserPassword=$noSDMRoleUserPassword | |
| versionedRepositoryID=$versionedRepositoryID | |
| virusScanRepositoryID=$virusScanRepositoryID | |
| defaultRepositoryID=$defaultRepositoryID | |
| defaultRepositoryIDMT=$defaultRepositoryIDMT | |
| CMIS_URL=$CMIS_URL | |
| cmisClientID=$cmisClientID | |
| cmisClientSecret=$cmisClientSecret | |
| EOL | |
| if ! mvn clean verify -P integration-tests \ | |
| -DtokenFlow=$tokenFlow -DtenancyModel=multi -Dtenant=$tenant \ | |
| -DskipUnitTests -Dfailsafe.includes="**/${testClass}.java"; then | |
| echo "β FAILED: $testClass - $tokenFlow - $tenant" | |
| FAILED=$((FAILED + 1)) | |
| else | |
| echo "β PASSED: $testClass - $tokenFlow - $tenant" | |
| fi | |
| done | |
| done | |
| done | |
| if [ $FAILED -gt 0 ]; then | |
| echo "β $FAILED test combination(s) failed" | |
| exit 1 | |
| fi | |
| # Single self-contained job: run subscription tests for both tenants | |
| subscription-test: | |
| runs-on: ubuntu-latest | |
| needs: virusscan-test | |
| if: "!cancelled()" | |
| steps: | |
| - name: Checkout repository π | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.inputs.branch_name }} | |
| - name: Set up Java 17 β | |
| uses: actions/setup-java@v3 | |
| with: | |
| java-version: 17 | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Cache CF CLI π¦ | |
| id: cache-cf-cli | |
| uses: actions/cache@v4 | |
| with: | |
| path: /usr/bin/cf8 | |
| key: cf-cli-v8-${{ runner.os }} | |
| - name: Install Cloud Foundry CLI π§ | |
| if: steps.cache-cf-cli.outputs.cache-hit != 'true' | |
| run: | | |
| wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add - | |
| echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list | |
| sudo apt-get update | |
| sudo apt-get install cf8-cli | |
| - name: Install jq π¦ | |
| run: | | |
| if ! command -v jq &> /dev/null; then | |
| sudo apt-get update && sudo apt-get install -y jq | |
| fi | |
| - name: Install BTP CLI π§ | |
| run: | | |
| echo "π Installing SAP BTP CLI..." | |
| curl -fsSL https://cli.btp.cloud.sap/btpcli-install.sh | bash | |
| BTP_BIN=$(find "$HOME/bin" /usr/local/bin -maxdepth 1 -name 'btp' -type f 2>/dev/null | head -1) | |
| if [ -z "$BTP_BIN" ]; then | |
| echo "β btp binary not found after install script." | |
| exit 1 | |
| fi | |
| if [ "$BTP_BIN" != "/usr/local/bin/btp" ]; then | |
| sudo install -m 755 "$BTP_BIN" /usr/local/bin/btp | |
| fi | |
| btp --version | |
| echo "β BTP CLI installed successfully!" | |
| - name: Determine Cloud Foundry Space π | |
| id: determine_space | |
| run: | | |
| if [ "${{ github.event.inputs.cf_space }}" == "developcap" ]; then | |
| space="${{ secrets.CF_SPACE }}" | |
| else | |
| space="${{ github.event.inputs.cf_space }}" | |
| fi | |
| echo "space=$space" >> $GITHUB_OUTPUT | |
| - name: Login to Cloud Foundry π | |
| run: | | |
| cf login -a ${{ secrets.CF_API }} \ | |
| -u ${{ secrets.CF_USER }} \ | |
| -p ${{ secrets.CF_PASSWORD }} \ | |
| -o ${{ secrets.CF_ORG }} \ | |
| -s ${{ steps.determine_space.outputs.space }} | |
| - name: Fetch and Escape Client Details for single tenant π | |
| id: fetch_credentials | |
| run: | | |
| service_instance_guid=$(cf service demoappjava-public-uaa --guid) | |
| if [ -z "$service_instance_guid" ]; then | |
| echo "β Error: Unable to retrieve service instance GUID"; exit 1; | |
| fi | |
| bindings_response=$(cf curl "/v3/service_credential_bindings?service_instance_guids=${service_instance_guid}") | |
| binding_guid=$(echo "$bindings_response" | jq -r '.resources[0].guid') | |
| if [ -z "$binding_guid" ]; then | |
| echo "β Error: Unable to retrieve binding GUID"; exit 1; | |
| fi | |
| binding_details=$(cf curl "/v3/service_credential_bindings/${binding_guid}/details") | |
| clientSecret=$(echo "$binding_details" | jq -r '.credentials.clientsecret') | |
| if [ -z "$clientSecret" ] || [ "$clientSecret" == "null" ]; then | |
| echo "β Error: clientSecret is not set or is null"; exit 1; | |
| fi | |
| escapedClientSecret=$(echo "$clientSecret" | sed 's/\$/\\$/g') | |
| echo "::add-mask::$escapedClientSecret" | |
| clientID=$(echo "$binding_details" | jq -r '.credentials.clientid') | |
| if [ -z "$clientID" ] || [ "$clientID" == "null" ]; then | |
| echo "β Error: clientID is not set or is null"; exit 1; | |
| fi | |
| echo "::add-mask::$clientID" | |
| echo "CLIENT_SECRET=$escapedClientSecret" >> $GITHUB_OUTPUT | |
| echo "CLIENT_ID=$clientID" >> $GITHUB_OUTPUT | |
| - name: Fetch and Escape Client Details for multi tenant π | |
| id: fetch_credentials_mt | |
| run: | | |
| service_instance_guid=$(cf service bookshop-mt-uaa --guid) | |
| if [ -z "$service_instance_guid" ]; then | |
| echo "β Error: Unable to retrieve service instance GUID"; exit 1; | |
| fi | |
| bindings_response=$(cf curl "/v3/service_credential_bindings?service_instance_guids=${service_instance_guid}") | |
| binding_guid=$(echo "$bindings_response" | jq -r '.resources[0].guid') | |
| if [ -z "$binding_guid" ]; then | |
| echo "β Error: Unable to retrieve binding GUID"; exit 1; | |
| fi | |
| binding_details=$(cf curl "/v3/service_credential_bindings/${binding_guid}/details") | |
| clientSecret_mt=$(echo "$binding_details" | jq -r '.credentials.clientsecret') | |
| if [ -z "$clientSecret_mt" ] || [ "$clientSecret_mt" == "null" ]; then | |
| echo "β Error: clientSecret_mt is not set or is null"; exit 1; | |
| fi | |
| escapedClientSecret_mt=$(echo "$clientSecret_mt" | sed 's/\$/\\$/g') | |
| echo "::add-mask::$escapedClientSecret_mt" | |
| clientID_mt=$(echo "$binding_details" | jq -r '.credentials.clientid') | |
| if [ -z "$clientID_mt" ] || [ "$clientID_mt" == "null" ]; then | |
| echo "β Error: clientID_mt is not set or is null"; exit 1; | |
| fi | |
| echo "::add-mask::$clientID_mt" | |
| echo "CLIENT_SECRET_MT=$escapedClientSecret_mt" >> $GITHUB_OUTPUT | |
| echo "CLIENT_ID_MT=$clientID_mt" >> $GITHUB_OUTPUT | |
| - name: Run all subscription integration tests π― | |
| id: run_tests | |
| env: | |
| CLIENT_SECRET: ${{ steps.fetch_credentials.outputs.CLIENT_SECRET }} | |
| CLIENT_ID: ${{ steps.fetch_credentials.outputs.CLIENT_ID }} | |
| CLIENT_SECRET_MT: ${{ steps.fetch_credentials_mt.outputs.CLIENT_SECRET_MT }} | |
| CLIENT_ID_MT: ${{ steps.fetch_credentials_mt.outputs.CLIENT_ID_MT }} | |
| CMIS_CLIENT_ID: ${{ secrets.CMISCLIENTID }} | |
| CMIS_CLIENT_SECRET: ${{ secrets.CMISCLIENTSECRET }} | |
| run: | | |
| set -e | |
| PROPERTIES_FILE="sdm/src/test/resources/credentials.properties" | |
| appUrl="${{ secrets.CF_ORG }}-${{ steps.determine_space.outputs.space }}-demoappjava-srv.cfapps.eu12.hana.ondemand.com" | |
| appUrlMT="${{ secrets.CF_ORG }}-${{ steps.determine_space.outputs.space }}-bookshop-mt-srv.cfapps.eu12.hana.ondemand.com" | |
| authUrl="${{ secrets.CAPAUTH_URL }}" | |
| authUrlMT1="${{ secrets.AUTHURLMT1 }}" | |
| authUrlMT2="${{ secrets.AUTHURLMT2 }}" | |
| clientID="${{ env.CLIENT_ID }}" | |
| clientSecret="${{ env.CLIENT_SECRET }}" | |
| clientIDMT="${{ env.CLIENT_ID_MT }}" | |
| clientSecretMT="${{ env.CLIENT_SECRET_MT }}" | |
| username="${{ secrets.CF_USER }}" | |
| password="${{ secrets.CF_PASSWORD }}" | |
| noSDMRoleUsername="${{ secrets.NOSDMROLEUSERNAME }}" | |
| noSDMRoleUserPassword="${{ secrets.NOSDMROLEUSERPASSWORD }}" | |
| versionedRepositoryID="${{ secrets.VERSIONEDREPOSITORYID }}" | |
| virusScanRepositoryID="${{ secrets.VIRUSSCANREPOSITORYID }}" | |
| defaultRepositoryID="${{ secrets.DEFAULTREPOSITORYID }}" | |
| defaultRepositoryIDMT="${{ secrets.DEFAULTREPOSITORYIDMT }}" | |
| consumerSubaccountIdMT1="${{ secrets.CONSUMERSUBACCOUNTIDMT1 }}" | |
| consumerSubdomainMT1="${{ secrets.CONSUMERSUBDOMAINMT1 }}" | |
| consumerSubaccountIdMT2="${{ secrets.CONSUMERSUBACCOUNTIDMT2 }}" | |
| consumerSubdomainMT2="${{ secrets.CONSUMERSUBDOMAINMT2 }}" | |
| consumerSubdomainMT="${{ secrets.CONSUMERSUBDOMAINMT }}" | |
| CMIS_URL="${{ secrets.CMIS_URL }}" | |
| cmisClientID="$CMIS_CLIENT_ID" | |
| cmisClientSecret="$CMIS_CLIENT_SECRET" | |
| SAAS_APP_NAME="bookshop-mt-sdmgoogleworkspacedev-${{ steps.determine_space.outputs.space }}" | |
| ROLE_COLLECTION_NAME="ak-test" | |
| APP_ROLE_FILTER="bookshop-mt-sdmgoogleworkspacedev-${{ steps.determine_space.outputs.space }}" | |
| BTP_CLI_URL="${{ secrets.BTP_CLI_URL }}" | |
| BTP_GLOBAL_ACCOUNT_SUBDOMAIN="${{ secrets.BTP_GLOBAL_ACCOUNT_SUBDOMAIN }}" | |
| FAILED=0 | |
| for tenant in TENANT1 TENANT2; do | |
| echo "π― Running subscription test for $tenant" | |
| cat > "$PROPERTIES_FILE" <<EOL | |
| appUrl=$appUrl | |
| appUrlMT=$appUrlMT | |
| authUrl=$authUrl | |
| authUrlMT1=$authUrlMT1 | |
| authUrlMT2=$authUrlMT2 | |
| clientID=$clientID | |
| clientSecret=$clientSecret | |
| clientIDMT=$clientIDMT | |
| clientSecretMT=$clientSecretMT | |
| username=$username | |
| password=$password | |
| noSDMRoleUsername=$noSDMRoleUsername | |
| noSDMRoleUserPassword=$noSDMRoleUserPassword | |
| versionedRepositoryID=$versionedRepositoryID | |
| virusScanRepositoryID=$virusScanRepositoryID | |
| defaultRepositoryID=$defaultRepositoryID | |
| defaultRepositoryIDMT=$defaultRepositoryIDMT | |
| consumerSubaccountIdMT1=$consumerSubaccountIdMT1 | |
| consumerSubdomainMT1=$consumerSubdomainMT1 | |
| consumerSubaccountIdMT2=$consumerSubaccountIdMT2 | |
| consumerSubdomainMT2=$consumerSubdomainMT2 | |
| CMIS_URL=$CMIS_URL | |
| cmisClientID=$cmisClientID | |
| cmisClientSecret=$cmisClientSecret | |
| SAAS_APP_NAME=$SAAS_APP_NAME | |
| ROLE_COLLECTION_NAME=$ROLE_COLLECTION_NAME | |
| APP_ROLE_FILTER=$APP_ROLE_FILTER | |
| BTP_CLI_URL=$BTP_CLI_URL | |
| BTP_GLOBAL_ACCOUNT_SUBDOMAIN=$BTP_GLOBAL_ACCOUNT_SUBDOMAIN | |
| EOL | |
| if ! mvn clean verify -P integration-tests \ | |
| -DtokenFlow=technicalUser -DtenancyModel=multi -Dtenant=$tenant \ | |
| -DskipUnitTests -Dfailsafe.includes="**/IntegrationTest_Subscription.java"; then | |
| echo "β FAILED: subscription test - $tenant" | |
| FAILED=$((FAILED + 1)) | |
| else | |
| echo "β PASSED: subscription test - $tenant" | |
| fi | |
| done | |
| if [ $FAILED -gt 0 ]; then | |
| echo "β $FAILED subscription test(s) failed" | |
| exit 1 | |
| fi | |
| # Summary job to aggregate results | |
| test-summary: | |
| runs-on: ubuntu-latest | |
| needs: [integration-test, versioned-test, virusscan-test, repospecific-test, subscription-test] | |
| if: "!cancelled()" | |
| steps: | |
| - name: Check test results π | |
| run: | | |
| echo "Integration test: ${{ needs.integration-test.result }}" | |
| echo "Versioned test: ${{ needs.versioned-test.result }}" | |
| echo "Virus scan test: ${{ needs.virusscan-test.result }}" | |
| echo "Repo-specific test: ${{ needs.repospecific-test.result }}" | |
| echo "Subscription test: ${{ needs.subscription-test.result }}" | |
| if [ "${{ needs.integration-test.result }}" == "success" ] && \ | |
| [ "${{ needs.versioned-test.result }}" == "success" ] && \ | |
| [ "${{ needs.virusscan-test.result }}" == "success" ] && \ | |
| [ "${{ needs.repospecific-test.result }}" == "success" ] && \ | |
| [ "${{ needs.subscription-test.result }}" == "success" ]; then | |
| echo "β All integration tests passed!" | |
| else | |
| echo "β Some integration tests failed. Check individual job results for details." | |
| exit 1 | |
| fi |