Skip to content

Commit

Permalink
Merge pull request #1886 from govuk-one-login/PYIC-5836-provider-test…
Browse files Browse the repository at this point in the history
…-verification

Pyic 5836 provider test verification
  • Loading branch information
DanCorderIPV authored May 9, 2024
2 parents 481acbb + 0fcbf35 commit a6abf9d
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 57 deletions.
28 changes: 24 additions & 4 deletions .github/workflows/contract-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ env:
# The branch name for a pull request is in a property that only exists on pull request runs. If it doesn't exist
# fall back to the branch name property for pushes.
GIT_BRANCH: ${{ github.head_ref || github.ref_name }}
CONSUMER_APP_VERSION: ${{ github.sha }}
GIT_SHA: ${{ github.sha }}

on:
push:
Expand All @@ -35,8 +35,28 @@ jobs:
java-version: '17'
distribution: 'temurin'
cache: 'gradle'
- name: Run contract tests
run: ./gradlew --parallel contractTests
- name: Run consumer contract tests
run: ./gradlew --parallel pactConsumerTests
- name: Upload pacts to broker with gradle
if: ${{ github.actor != 'dependabot[bot]' && github.event_name != 'merge_group' }}
run: ./gradlew pactPublish
run: ./gradlew pactPublish
# The initial call to the pact broker starts a 30 second timer where calls will succeed. As uploading the pacts and
# verifying the pacts together takes over 30s we need to wait for the timer to expire so that the pact verification
# call starts its own timer.
- name: Sleep for 30 seconds
run: sleep 30s
shell: bash
- name: Verify pacts
run: ./gradlew pactProviderTests
- name: Upload build-user-identity provider pact test report
if: '!cancelled()'
uses: actions/upload-artifact@v4
with:
name: build-user-identity provider pact test report
path: /home/runner/work/ipv-core-back/ipv-core-back/lambdas/build-user-identity/build/reports/tests/pactProviderTests/
- name: Upload issue-client-access-token provider pact test report
if: '!cancelled()'
uses: actions/upload-artifact@v4
with:
name: issue-client-access-token provider pact test report
path: /home/runner/work/ipv-core-back/ipv-core-back/lambdas/issue-client-access-token/build/reports/tests/pactProviderTests/
20 changes: 10 additions & 10 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -197,21 +197,21 @@
"filename": "lambdas/build-user-identity/src/test/java/uk/gov/di/ipv/core/builduseridentity/pact/BuildUserIdentityHandlerTest.java",
"hashed_secret": "85d1e7563098941624848ca8a7c731a6c013235b",
"is_verified": false,
"line_number": 215
"line_number": 220
},
{
"type": "Base64 High Entropy String",
"filename": "lambdas/build-user-identity/src/test/java/uk/gov/di/ipv/core/builduseridentity/pact/BuildUserIdentityHandlerTest.java",
"hashed_secret": "69facda46567909882c049ea59985c33000974b3",
"is_verified": false,
"line_number": 298
"line_number": 303
},
{
"type": "Base64 High Entropy String",
"filename": "lambdas/build-user-identity/src/test/java/uk/gov/di/ipv/core/builduseridentity/pact/BuildUserIdentityHandlerTest.java",
"hashed_secret": "1bb4f6b3cf1f8b05e40be98e555120bbac8bb8a8",
"is_verified": false,
"line_number": 351
"line_number": 356
}
],
"lambdas/call-ticf-cri/src/main/java/uk/gov/di/ipv/core/callticfcri/service/TicfCriService.java": [
Expand Down Expand Up @@ -314,42 +314,42 @@
"filename": "lambdas/issue-client-access-token/src/test/java/uk/gov/di/ipv/core/issueclientaccesstoken/pact/IssueClientAccessTokenHandlerTest.java",
"hashed_secret": "85b64b6097e8bdbbf9c4e2cab9df0c237aae2dca",
"is_verified": false,
"line_number": 119
"line_number": 124
},
{
"type": "Base64 High Entropy String",
"filename": "lambdas/issue-client-access-token/src/test/java/uk/gov/di/ipv/core/issueclientaccesstoken/pact/IssueClientAccessTokenHandlerTest.java",
"hashed_secret": "90972d09acf28b39b53f2ea5a145b3fd5017167e",
"is_verified": false,
"line_number": 119
"line_number": 124
},
{
"type": "Base64 High Entropy String",
"filename": "lambdas/issue-client-access-token/src/test/java/uk/gov/di/ipv/core/issueclientaccesstoken/pact/IssueClientAccessTokenHandlerTest.java",
"hashed_secret": "c1305006857ab69a99734702cf8dbf6c71817857",
"is_verified": false,
"line_number": 119
"line_number": 124
},
{
"type": "Base64 High Entropy String",
"filename": "lambdas/issue-client-access-token/src/test/java/uk/gov/di/ipv/core/issueclientaccesstoken/pact/IssueClientAccessTokenHandlerTest.java",
"hashed_secret": "01c2ef0ba40b5ac6268fb58d724ef0418536e5cb",
"is_verified": false,
"line_number": 123
"line_number": 128
},
{
"type": "Base64 High Entropy String",
"filename": "lambdas/issue-client-access-token/src/test/java/uk/gov/di/ipv/core/issueclientaccesstoken/pact/IssueClientAccessTokenHandlerTest.java",
"hashed_secret": "256c2b82b396574d931fb1fe5977cb470bdc53e8",
"is_verified": false,
"line_number": 123
"line_number": 128
},
{
"type": "Base64 High Entropy String",
"filename": "lambdas/issue-client-access-token/src/test/java/uk/gov/di/ipv/core/issueclientaccesstoken/pact/IssueClientAccessTokenHandlerTest.java",
"hashed_secret": "daa586bb42bc7f31bf51be59b3dda26c8c71f1d9",
"is_verified": false,
"line_number": 123
"line_number": 128
}
],
"lambdas/process-async-cri-credential/src/test/java/uk/gov/di/ipv/core/processasynccricredential/pact/f2fCri/ContractTest.java": [
Expand Down Expand Up @@ -1879,5 +1879,5 @@
}
]
},
"generated_at": "2024-05-08T13:30:08Z"
"generated_at": "2024-05-09T09:06:08Z"
}
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pact {
pactBrokerUrl = "${System.env.PACT_URL}?testSource=${System.env.PACT_BROKER_SOURCE_SECRET_DEV}"
pactBrokerUsername = "${System.env.PACT_USER}"
pactBrokerPassword = "${System.env.PACT_PASSWORD}"
consumerVersion = "${System.env.CONSUMER_APP_VERSION}"
consumerVersion = "${System.env.GIT_SHA}"
consumerBranch = "${System.env.GIT_BRANCH}"
}
}
10 changes: 10 additions & 0 deletions lambdas/build-user-identity/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ test {
environment "LAMBDA_TASK_ROOT", "handler"
useJUnitPlatform ()
finalizedBy jacocoTestReport
exclude 'uk/gov/di/ipv/core/builduseridentity/pact/**'
}

task pactProviderTests (type: Test) {
useJUnitPlatform()
include 'uk/gov/di/ipv/core/builduseridentity/pact/**'
systemProperties['pact.verifier.publishResults'] = "true"
systemProperties['pact.provider.branch'] = "${System.env.GIT_BRANCH}"
systemProperties['pact.provider.version'] = "${System.env.GIT_SHA}"
systemProperties['pact.consumerversionselectors.rawjson'] = "{ \"mainBranch\": true, \"deployedOrReleased\": true }"
}

jacocoTestReport {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
import au.com.dius.pact.provider.junit5.PactVerificationInvocationContextProvider;
import au.com.dius.pact.provider.junitsupport.Provider;
import au.com.dius.pact.provider.junitsupport.State;
import au.com.dius.pact.provider.junitsupport.loader.PactFolder;
import au.com.dius.pact.provider.junitsupport.loader.PactBroker;
import au.com.dius.pact.provider.junitsupport.loader.PactBrokerAuth;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
Expand All @@ -29,7 +29,7 @@
import uk.gov.di.ipv.core.library.persistence.DataStore;
import uk.gov.di.ipv.core.library.persistence.item.ClientOAuthSessionItem;
import uk.gov.di.ipv.core.library.persistence.item.IpvSessionItem;
import uk.gov.di.ipv.core.library.persistence.item.VcStoreItem;
import uk.gov.di.ipv.core.library.persistence.item.SessionCredentialItem;
import uk.gov.di.ipv.core.library.service.AuditService;
import uk.gov.di.ipv.core.library.service.CiMitService;
import uk.gov.di.ipv.core.library.service.CiMitUtilityService;
Expand All @@ -50,28 +50,34 @@
import static uk.gov.di.ipv.core.library.domain.CriConstants.ADDRESS_CRI;
import static uk.gov.di.ipv.core.library.domain.CriConstants.DCMAW_CRI;

@PactFolder("pacts")
@Disabled("PACT tests should not be run in build pipelines at this time")
// To run these tests locally you need to:
// - Obtain the relevant pact file (from the pact broker or another team) and put it in
// /lambdas/build-user-identity/pacts
// - Comment out the @PactBroker annotation below
// - Uncomment @PactFolder annotation below
@Provider("IpvCoreBackUserIdentityProvider")
@PactBroker(
url = "${PACT_URL}?testSource=${PACT_BROKER_SOURCE_SECRET_DEV}",
authentication = @PactBrokerAuth(username = "${PACT_USER}", password = "${PACT_PASSWORD}"))
// @PactFolder("pacts")
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class BuildUserIdentityHandlerTest {

private static final int PORT = 5050;
private static final String IPV_SESSION_ID = "dummyIpvSessionId";

private LambdaHttpServer httpServer;
@Mock private ConfigService mockConfigService;
@Mock private AuditService mockAuditService;
@Mock private DataStore<IpvSessionItem> mockIpvSessionDataStore;
@Mock private DataStore<VcStoreItem> mockVcStore;
@Mock private DataStore<SessionCredentialItem> mockSessionCredentialItemStore;
@Mock private DataStore<ClientOAuthSessionItem> mockOAuthSessionStore;
@Mock private CiMitService mockCiMitService;
@Mock private CiMitUtilityService mockCiMitUtilityService;
@Mock private SessionCredentialsService mockSessionCredentialsService;

@BeforeAll
static void setupServer() {
System.setProperty("pact.verifier.publishResults", "true");
System.setProperty("pact.content_type.override.application/jwt", "text");
}

Expand Down Expand Up @@ -104,28 +110,27 @@ void pactSetup(PactVerificationContext context)
// 2099-01-01 00:00:00 is 4070908800 in epoch seconds
Instant theFuture = Instant.ofEpochSecond(1577836800);

List<VcStoreItem> vcs = new ArrayList<>();
var passportVcBuilder =
new PactJwtBuilder(
VC_HEADER, VALID_UK_PASSPORT_VC_BODY, VALID_UK_PASSPORT_VC_SIGNATURE);
var addressVcBuilder =
new PactJwtBuilder(VC_HEADER, VALID_ADDRESS_VC_BODY, VALID_ADDRESS_VC_SIGNATURE);
var passportItem = new VcStoreItem();
passportItem.setUserId("dummyOAuthUserId");
passportItem.setCredential(passportVcBuilder.buildJwt());
passportItem.setCredentialIssuer(DCMAW_CRI);
passportItem.setDateCreated(thePast);
passportItem.setExpirationTime(theFuture);
vcs.add(passportItem);
var addressItem = new VcStoreItem();
addressItem.setUserId("dummyOAuthUserId");
addressItem.setCredential(addressVcBuilder.buildJwt());
addressItem.setCredentialIssuer(ADDRESS_CRI);
addressItem.setDateCreated(thePast);
addressItem.setExpirationTime(theFuture);
vcs.add(addressItem);

when(mockVcStore.getItems("dummyOAuthUserId")).thenReturn(vcs);

List<SessionCredentialItem> sessionCredentials = new ArrayList<>();
var passportCredential =
new SessionCredentialItem(
IPV_SESSION_ID, DCMAW_CRI, passportVcBuilder.buildSignedJwt(), true);
var addressCredential =
new SessionCredentialItem(
IPV_SESSION_ID, ADDRESS_CRI, addressVcBuilder.buildSignedJwt(), true);
sessionCredentials.add(passportCredential);
sessionCredentials.add(addressCredential);

when(mockSessionCredentialItemStore.getItems(IPV_SESSION_ID))
.thenReturn(sessionCredentials);

var sessionCredentialService =
new SessionCredentialsService(mockSessionCredentialItemStore);

// Set up the web server for the tests
var handler =
Expand All @@ -137,12 +142,12 @@ void pactSetup(PactVerificationContext context)
clientOAuthSessionDetailsService,
mockCiMitService,
mockCiMitUtilityService,
mockSessionCredentialsService);
sessionCredentialService);

httpServer = new LambdaHttpServer(handler, "/user-identity", PORT);
httpServer = new LambdaHttpServer(handler, "/user-identity");
httpServer.startServer();

context.setTarget(new HttpTestTarget("localhost", PORT));
context.setTarget(new HttpTestTarget("localhost", httpServer.getPort()));
}

@AfterEach
Expand All @@ -157,7 +162,7 @@ public void setAuthCode() {}
public void setAccessToken() {
var accessTokenMetaData = new AccessTokenMetadata();
var ipvSession = new IpvSessionItem();
ipvSession.setIpvSessionId("dummyIpvSessionId");
ipvSession.setIpvSessionId(IPV_SESSION_ID);
ipvSession.setClientOAuthSessionId("dummyClientOAuthSessionId");
ipvSession.setVot(Vot.P2);

Expand Down
2 changes: 1 addition & 1 deletion lambdas/call-ticf-cri/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ test {
exclude 'uk/gov/di/ipv/core/callticfcri/pact/**'
}

task contractTests (type: Test) {
task pactConsumerTests (type: Test) {
useJUnitPlatform()
include 'uk/gov/di/ipv/core/callticfcri/pact/**'
systemProperties['pact.rootDir'] = "$rootDir/build/pacts"
Expand Down
10 changes: 10 additions & 0 deletions lambdas/issue-client-access-token/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ test {
environment "LAMBDA_TASK_ROOT", "handler"
useJUnitPlatform ()
finalizedBy jacocoTestReport
exclude 'uk/gov/di/ipv/core/issueclientaccesstoken/pact/**'
}

task pactProviderTests (type: Test) {
useJUnitPlatform()
include 'uk/gov/di/ipv/core/issueclientaccesstoken/pact/**'
systemProperties['pact.verifier.publishResults'] = "true"
systemProperties['pact.provider.branch'] = "${System.env.GIT_BRANCH}"
systemProperties['pact.provider.version'] = "${System.env.GIT_SHA}"
systemProperties['pact.consumerversionselectors.rawjson'] = "{ \"mainBranch\": true, \"deployedOrReleased\": true }"
}

jacocoTestReport {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
import au.com.dius.pact.provider.junit5.PactVerificationInvocationContextProvider;
import au.com.dius.pact.provider.junitsupport.Provider;
import au.com.dius.pact.provider.junitsupport.State;
import au.com.dius.pact.provider.junitsupport.loader.PactFolder;
import au.com.dius.pact.provider.junitsupport.loader.PactBroker;
import au.com.dius.pact.provider.junitsupport.loader.PactBrokerAuth;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
Expand Down Expand Up @@ -39,15 +39,20 @@
import static uk.gov.di.ipv.core.library.config.ConfigurationVariable.MAX_ALLOWED_AUTH_CLIENT_TTL;
import static uk.gov.di.ipv.core.library.config.ConfigurationVariable.PUBLIC_KEY_MATERIAL_FOR_CORE_TO_VERIFY;

@PactFolder("pacts")
@Disabled("PACT tests should not be run in build pipelines at this time")
// To run these tests locally you need to:
// - Obtain the relevant pact file (from the pact broker or another team) and put it in
// /lambdas/build-user-identity/pacts
// - Comment out the @PactBroker annotation below
// - Uncomment @PactFolder annotation below
@Provider("IpvCoreBackTokenProvider")
@PactBroker(
url = "${PACT_URL}?testSource=${PACT_BROKER_SOURCE_SECRET_DEV}",
authentication = @PactBrokerAuth(username = "${PACT_USER}", password = "${PACT_PASSWORD}"))
// @PactFolder("pacts")
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class IssueClientAccessTokenHandlerTest {

private static final int PORT = 5050;

private LambdaHttpServer httpServer;
private IpvSessionItem ipvSessionItem;
@Mock private ConfigService configService;
Expand Down Expand Up @@ -95,10 +100,10 @@ void pactSetup(PactVerificationContext context) throws IOException {
clientOAuthSessionService,
tokenRequestValidator);

httpServer = new LambdaHttpServer(handler, "/token", PORT);
httpServer = new LambdaHttpServer(handler, "/token");
httpServer.startServer();

context.setTarget(new HttpTestTarget("localhost", PORT));
context.setTarget(new HttpTestTarget("localhost", httpServer.getPort()));
}

@AfterEach
Expand Down
2 changes: 1 addition & 1 deletion lambdas/process-cri-callback/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ test {
exclude 'uk/gov/di/ipv/core/processcricallback/pact/**'
}

task contractTests (type: Test) {
task pactConsumerTests (type: Test) {
useJUnitPlatform()
include 'uk/gov/di/ipv/core/processcricallback/pact/**'
systemProperties['pact.rootDir'] = "$rootDir/build/pacts"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,17 @@ public class LambdaHttpServer {

public LambdaHttpServer(
RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> handler,
String path,
int port)
String path)
throws IOException {
server = HttpServer.create(new InetSocketAddress(port), 0);
server = HttpServer.create(new InetSocketAddress(0), 0);
server.createContext(path, new LambdaHandlerWrapper(handler));
server.setExecutor(Executors.newCachedThreadPool()); // creates a default executor
}

public int getPort() {
return server.getAddress().getPort();
}

public void startServer() {
server.start();
}
Expand Down

0 comments on commit a6abf9d

Please sign in to comment.