diff --git a/.github/workflows/verify_consumer_pacts.yaml b/.github/workflows/verify_consumer_pacts.yaml index 5085510049..c624a5d8bb 100644 --- a/.github/workflows/verify_consumer_pacts.yaml +++ b/.github/workflows/verify_consumer_pacts.yaml @@ -17,7 +17,6 @@ name: Verify consumer pacts # They are managed by Atlantis and were added to Terraform here: # https://github.com/broadinstitute/terraform-ap-deployments/pull/1086 env: - PACT_BROKER_URL: https://pact-broker.dsp-eng-tools.broadinstitute.org spring_profiles_active: human-readable-logging on: pull_request: diff --git a/README.md b/README.md index c8f2bcf9ac..3e5f549311 100644 --- a/README.md +++ b/README.md @@ -698,6 +698,39 @@ The integration tests live in the `integration` project. Consult the integration In the early days of the project, there were JUnit-based integration tests. We are in process of migrating them to Test Runner. + +### Pact Tests + +Pact testing ensures workspace manager's APIs are compatible with the assumptions made +by its clients and that workspace manager's assumptions about its dependency APIs are +also correct. + +Pact testing involves interacting with a pact-broker which requires a little setup. + +To run pact tests locally: + +``` +# Get pactbroker credentials +./service/src/test/render-pact-configs.sh +# Reload your environment variables, e.g. src ~/.zshrc + +# Pact contract test settings +export PACT_BROKER_USERNAME=$(cat /tmp/pact-ro-username.key) +export PACT_BROKER_PASSWORD=$(cat /tmp/pact-ro-password.key) + +./gradlew verifyPacts +``` + +If you're working on adding new pacts and making local changes to them, it might be helpful to use a local +pactbroker instead. To set up a local pactbroker, see: +[Contract Test Local Development](https://broadworkbench.atlassian.net/wiki/spaces/IRT/pages/2829680649/Contract+Test+Local+Development). + +Once you have a local pactbroker, you can override the `PACT_BROKER_URL` environment variable: + +``` +PACT_BROKER_URL=http://localhost:9292 ./gradlew verifyPacts +``` + ### Making tests fast #### Create one workspace/context/resource for entire test diff --git a/service/gradle/testing.gradle b/service/gradle/testing.gradle index ed97cb5428..f75c798d86 100644 --- a/service/gradle/testing.gradle +++ b/service/gradle/testing.gradle @@ -218,6 +218,9 @@ task verifyPacts(type: Test) { useJUnitPlatform { includeTags "pact-verification" } + testLogging { + events = ["passed", "failed", "skipped", "started", "standard_out"] + } outputs.upToDateWhen { false } if (isCiServer) { systemProperty 'pact.verifier.publishResults', true diff --git a/service/src/test/java/bio/terra/workspace/pact/WdsContractVerificationTest.java b/service/src/test/java/bio/terra/workspace/pact/WdsContractVerificationTest.java index 73f0be842b..535c11c9a9 100644 --- a/service/src/test/java/bio/terra/workspace/pact/WdsContractVerificationTest.java +++ b/service/src/test/java/bio/terra/workspace/pact/WdsContractVerificationTest.java @@ -9,6 +9,8 @@ import au.com.dius.pact.provider.junitsupport.Provider; import au.com.dius.pact.provider.junitsupport.State; import au.com.dius.pact.provider.junitsupport.loader.PactBroker; +import au.com.dius.pact.provider.junitsupport.loader.PactBrokerConsumerVersionSelectors; +import au.com.dius.pact.provider.junitsupport.loader.SelectorBuilder; import au.com.dius.pact.provider.spring.junit5.MockMvcTestTarget; import au.com.dius.pact.provider.spring.junit5.PactVerificationSpringProvider; import bio.terra.policy.model.TpsPaoConflict; @@ -37,9 +39,10 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; -// set ActiveProfile to "unit-test" to disable some unnecessary dependencies (like -// GoogleCredentials) that would otherwise require mocking -@ActiveProfiles("unit-test") +@ActiveProfiles({ + "unit-test" /* disable some unnecessary dependencies that would otherwise require mocking */, + "pact-test" /* set pact broker URL */ +}) @Tag("pact-verification") @Provider("workspacemanager") // should match the terra chart name @PactBroker() @@ -54,10 +57,14 @@ public class WdsContractVerificationTest extends BaseUnitTestMocks { @MockBean private AuthenticatedUserRequestFactory mockAuthenticatedUserRequestFactory; @MockBean private ReferencedResourceService mockReferencedResourceService; - @TestTemplate - @ExtendWith(PactVerificationSpringProvider.class) - void pactVerificationTestTemplate(PactVerificationContext context) { - context.verifyInteraction(); + @PactBrokerConsumerVersionSelectors + public static SelectorBuilder consumerVersionSelectors() { + // Select consumer pacts published from default branch or pacts marked as deployed or released. + // If you wish to pick up Pacts from a consumer's feature branch for development purposes or PR + // runs, and your consumer is publishing such Pacts under their feature branch name, you can add + // the following to the SelectorBuilder: + // .branch("consumer-feature-branch-name") + return new SelectorBuilder().mainBranch().deployedOrReleased(); } @BeforeEach @@ -65,7 +72,13 @@ void setPactVerificationContext(PactVerificationContext context) { context.setTarget(new MockMvcTestTarget(mockMvc)); } - @State({"authenticated with the given email"}) + @TestTemplate + @ExtendWith(PactVerificationSpringProvider.class) + void pactVerificationTestTemplate(PactVerificationContext context) { + context.verifyInteraction(); + } + + @State("authenticated with the given email") public void authenticatedAsAccount(Map parameters) throws InterruptedException { var authenticatedEmail = parameters.get("email").toString(); var stubbedAuthenticatedRequest = new AuthenticatedUserRequest().email(authenticatedEmail); diff --git a/service/src/test/render-pact-configs.sh b/service/src/test/render-pact-configs.sh new file mode 100755 index 0000000000..7e76ebcb35 --- /dev/null +++ b/service/src/test/render-pact-configs.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +LOCAL_TOKEN=$(cat ~/.vault-token) +export VAULT_TOKEN=${1:-$LOCAL_TOKEN} + +vault read -field=basic_auth_read_only_username secret/dsp/pact-broker/users/read-only \ + > /tmp/pact-ro-username.key + +vault read -field=basic_auth_read_only_password secret/dsp/pact-broker/users/read-only \ + > /tmp/pact-ro-password.key diff --git a/service/src/test/resources/application-pact-test.properties b/service/src/test/resources/application-pact-test.properties new file mode 100644 index 0000000000..0860bf6723 --- /dev/null +++ b/service/src/test/resources/application-pact-test.properties @@ -0,0 +1 @@ +pactbroker.url=https://pact-broker.dsp-eng-tools.broadinstitute.org diff --git a/service/src/test/resources/application-test.yml b/service/src/test/resources/application-test.yml index fe3e3f974a..b9b484b6ed 100644 --- a/service/src/test/resources/application-test.yml +++ b/service/src/test/resources/application-test.yml @@ -64,5 +64,3 @@ landingzone: landingzone-stairway-database: poolMaxIdle: 1 uri: jdbc:${env.db.local-db}/landingzone_stairway_db -pactbroker: - url: https://pact-broker.dsp-eng-tools.broadinstitute.org