From 6aff84e05df93ad7e0f9774aae86c2c634fdab1e Mon Sep 17 00:00:00 2001 From: Allain Magyar Date: Thu, 14 Mar 2024 07:38:02 -0300 Subject: [PATCH] test: enhancements + vault token test (#924) Signed-off-by: Allain Magyar --- .../src/test/kotlin/features/Init.kt | 171 ------------------ .../kotlin/features/common/CommonSteps.kt | 93 ---------- .../kotlin/features/system/SystemSteps.kt | 52 ------ .../src/test/resources/configs/mt_vault.conf | 58 ------ 4 files changed, 374 deletions(-) delete mode 100644 tests/integration-tests/src/test/kotlin/features/Init.kt delete mode 100644 tests/integration-tests/src/test/kotlin/features/common/CommonSteps.kt delete mode 100644 tests/integration-tests/src/test/kotlin/features/system/SystemSteps.kt delete mode 100644 tests/integration-tests/src/test/resources/configs/mt_vault.conf diff --git a/tests/integration-tests/src/test/kotlin/features/Init.kt b/tests/integration-tests/src/test/kotlin/features/Init.kt deleted file mode 100644 index 77b6579987..0000000000 --- a/tests/integration-tests/src/test/kotlin/features/Init.kt +++ /dev/null @@ -1,171 +0,0 @@ -package features - -import abilities.ListenToEvents -import com.sksamuel.hoplite.ConfigException -import com.sksamuel.hoplite.ConfigLoader -import common.TestConstants -import config.AgentRole -import config.Config -import io.cucumber.java.AfterAll -import io.cucumber.java.BeforeAll -import io.iohk.atala.prism.models.CreateWalletRequest -import io.iohk.atala.prism.models.CreateWebhookNotification -import io.restassured.RestAssured -import io.restassured.builder.RequestSpecBuilder -import net.serenitybdd.screenplay.Actor -import net.serenitybdd.screenplay.actors.Cast -import net.serenitybdd.screenplay.actors.OnStage -import net.serenitybdd.screenplay.rest.abilities.CallAnApi -import org.apache.http.HttpStatus -import java.util.* - -val config = ConfigLoader().loadConfigOrThrow(TestConstants.TESTS_CONFIG) - -/** - * This function starts all services and actors before all tests. - */ -fun initServices() { - config.services?.keycloak?.start(config.roles) - config.services?.prismNode?.start() - config.services?.vault?.start() - config.agents?.forEach { agent -> - agent.start() - } -} - -/** - * This function initializes all actors and sets the stage. - */ -fun initActors() { - /** - * This function initializes a wallet for an actor when Keycloak is used. - * - * @param actor The actor for which the wallet should be initialized. - */ - fun initializeWallet(actor: Actor) { - RestAssured - .given() - .baseUri(actor.usingAbilityTo(CallAnApi::class.java).resolve("/")) - .auth().oauth2(actor.recall("BEARER_TOKEN")) - .body( - CreateWalletRequest( - name = UUID.randomUUID().toString(), - ), - ) - .post("/wallets") - .then().statusCode(HttpStatus.SC_CREATED) - } - - /** - * This function registers a webhook for an actor. - * - * @param actor The actor for which the webhook should be registered. - * @param webhookUrl The url of the webhook. - */ - fun registerWebhook(actor: Actor, webhookUrl: String) { - val spec = RequestSpecBuilder() - .setBaseUri(actor.usingAbilityTo(CallAnApi::class.java).resolve("/")) - if (actor.recall("AUTH_KEY") != null) { - spec.addHeader(actor.recall("AUTH_HEADER"), actor.recall("AUTH_KEY")) - } - if (actor.recall("BEARER_TOKEN") != null) { - spec.addHeader("Authorization", "Bearer ${actor.recall("BEARER_TOKEN")}") - } - val response = RestAssured - .given().spec(spec.build()) - .body(CreateWebhookNotification(url = webhookUrl)) - .post("/events/webhooks") - .thenReturn() - response.then().statusCode(HttpStatus.SC_OK) - actor.remember("WEBHOOK_ID", response.body.jsonPath().getString("id")) - } - - val cast = Cast() - config.roles.forEach { role -> - cast.actorNamed( - role.name, - CallAnApi.at(role.url.toExternalForm()), - ) - } - if (config.services?.keycloak != null) { - config.roles.forEach { role -> - val actor = cast.actorNamed(role.name) - try { - actor.remember("BEARER_TOKEN", config.services.keycloak.getKeycloakAuthToken(actor.name, actor.name)) - } catch (e: NullPointerException) { - throw ConfigException("Keycloak is configured, but no token found for user ${actor.name}!") - } - if (role.agentRole != AgentRole.Admin) { - initializeWallet(actor) - } - } - } - config.roles.forEach { role -> - val actor = cast.actorNamed(role.name) - if (role.apikey != null) { - actor.remember("AUTH_KEY", role.apikey) - actor.remember("AUTH_HEADER", role.authHeader) - } - if (role.token != null) { - actor.remember("BEARER_TOKEN", role.token) - } - if (role.webhook != null) { - actor.whoCan(ListenToEvents.at(role.webhook.url, role.webhook.localPort)) - if (role.webhook.initRequired) { - registerWebhook(actor, role.webhook.url.toExternalForm()) - } - } - } - OnStage.setTheStage(cast) -} - -/** - * This function destroys all actors and clears the stage. - */ -fun destroyActors() { - /** - * This function deletes a webhook for an actor. - * - * @param actor The actor for which the webhook should be deleted. - */ - fun deleteWebhook(actor: Actor) { - val spec = RequestSpecBuilder() - .setBaseUri(actor.usingAbilityTo(CallAnApi::class.java).resolve("/")) - if (actor.recall("AUTH_KEY") != null) { - spec.addHeader(actor.recall("AUTH_HEADER"), actor.recall("AUTH_KEY")) - } - if (actor.recall("BEARER_TOKEN") != null) { - spec.addHeader("Authorization", "Bearer ${actor.recall("BEARER_TOKEN")}") - } - RestAssured - .given().spec(spec.build()) - .delete("/events/webhooks/${actor.recall("WEBHOOK_ID")}") - .then().statusCode(HttpStatus.SC_OK) - } - - // Delete webhooks - config.roles.forEach { role -> - val actor = OnStage.theActorCalled(role.name) - if (role.webhook != null && role.webhook.initRequired) { - deleteWebhook(actor) - } - } - OnStage.drawTheCurtain() -} - -@BeforeAll -fun init() { - initServices() - initActors() -} - -@AfterAll -fun clearStage() { - destroyActors() - config.agents?.forEach { agent -> - agent.stop() - } - config.services?.keycloak?.stop() - config.services?.prismNode?.stop() - config.services?.vault?.stop() -} diff --git a/tests/integration-tests/src/test/kotlin/features/common/CommonSteps.kt b/tests/integration-tests/src/test/kotlin/features/common/CommonSteps.kt deleted file mode 100644 index 147fe2f179..0000000000 --- a/tests/integration-tests/src/test/kotlin/features/common/CommonSteps.kt +++ /dev/null @@ -1,93 +0,0 @@ -package features.common - -import features.connection.ConnectionSteps -import features.credentials.IssueCredentialsSteps -import features.did.PublishDidSteps -import interactions.Get -import io.cucumber.java.ParameterType -import io.cucumber.java.en.Given -import io.iohk.atala.automation.extensions.get -import io.iohk.atala.automation.serenity.ensure.Ensure -import io.iohk.atala.prism.models.Connection -import io.iohk.atala.prism.models.ConnectionsPage -import io.iohk.atala.prism.models.IssueCredentialRecord -import io.iohk.atala.prism.models.IssueCredentialRecordPage -import net.serenitybdd.rest.SerenityRest -import net.serenitybdd.screenplay.Actor -import net.serenitybdd.screenplay.actors.OnStage -import org.apache.http.HttpStatus - -class CommonSteps { - @ParameterType(".*") - fun actor(actorName: String): Actor { - return OnStage.theActorCalled(actorName) - } - - @Given("{actor} has an issued credential from {actor}") - fun holderHasIssuedCredentialFromIssuer(holder: Actor, issuer: Actor) { - holder.attemptsTo( - Get.resource("/issue-credentials/records") - ) - holder.attemptsTo( - Ensure.thatTheLastResponse().statusCode().isEqualTo(HttpStatus.SC_OK) - ) - val receivedCredential = SerenityRest.lastResponse().get().contents!!.findLast { credential -> - credential.protocolState == IssueCredentialRecord.ProtocolState.CREDENTIAL_RECEIVED && - credential.credentialFormat == IssueCredentialRecord.CredentialFormat.JWT - } - - if (receivedCredential != null) { - holder.remember("issuedCredential", receivedCredential) - } else { - val publishDidSteps = PublishDidSteps() - val issueSteps = IssueCredentialsSteps() - actorsHaveExistingConnection(issuer, holder) - publishDidSteps.createsUnpublishedDid(holder) - publishDidSteps.createsUnpublishedDid(issuer) - publishDidSteps.hePublishesDidToLedger(issuer) - issueSteps.acmeOffersACredential(issuer, holder, "short") - issueSteps.holderReceivesCredentialOffer(holder) - issueSteps.holderAcceptsCredentialOfferForJwt(holder) - issueSteps.acmeIssuesTheCredential(issuer) - issueSteps.bobHasTheCredentialIssued(holder) - } - } - - @Given("{actor} and {actor} have an existing connection") - fun actorsHaveExistingConnection(inviter: Actor, invitee: Actor) { - inviter.attemptsTo( - Get.resource("/connections") - ) - inviter.attemptsTo( - Ensure.thatTheLastResponse().statusCode().isEqualTo(HttpStatus.SC_OK) - ) - val inviterConnection = SerenityRest.lastResponse().get().contents!!.firstOrNull { - it.label == "Connection with ${invitee.name}" && it.state == Connection.State.CONNECTION_RESPONSE_SENT - } - - var inviteeConnection: Connection? = null - if (inviterConnection != null) { - invitee.attemptsTo( - Get.resource("/connections") - ) - invitee.attemptsTo( - Ensure.thatTheLastResponse().statusCode().isEqualTo(HttpStatus.SC_OK) - ) - inviteeConnection = SerenityRest.lastResponse().get().contents!!.firstOrNull { - it.theirDid == inviterConnection.myDid && it.state == Connection.State.CONNECTION_RESPONSE_RECEIVED - } - } - - if (inviterConnection != null && inviteeConnection != null) { - inviter.remember("connection-with-${invitee.name}", inviterConnection) - invitee.remember("connection-with-${inviter.name}", inviteeConnection) - } else { - val connectionSteps = ConnectionSteps() - connectionSteps.inviterGeneratesAConnectionInvitation(inviter, invitee) - connectionSteps.inviteeSendsAConnectionRequestToInviter(invitee, inviter) - connectionSteps.inviterReceivesTheConnectionRequest(inviter) - connectionSteps.inviteeReceivesTheConnectionResponse(invitee) - connectionSteps.inviterAndInviteeHaveAConnection(inviter, invitee) - } - } -} diff --git a/tests/integration-tests/src/test/kotlin/features/system/SystemSteps.kt b/tests/integration-tests/src/test/kotlin/features/system/SystemSteps.kt deleted file mode 100644 index c9db4a12c2..0000000000 --- a/tests/integration-tests/src/test/kotlin/features/system/SystemSteps.kt +++ /dev/null @@ -1,52 +0,0 @@ -package features.system - -import interactions.Get -import io.cucumber.java.en.Then -import io.cucumber.java.en.When -import io.iohk.atala.automation.extensions.get -import io.iohk.atala.automation.serenity.ensure.Ensure -import io.iohk.atala.prism.models.HealthInfo -import net.serenitybdd.rest.SerenityRest -import net.serenitybdd.screenplay.Actor -import org.apache.http.HttpStatus - -class SystemSteps { - @When("{actor} makes a request to the health endpoint") - fun actorRequestsHealthEndpoint(actor: Actor) { - actor.attemptsTo( - Get.resource("/_system/health") - ) - actor.attemptsTo( - Ensure.thatTheLastResponse().statusCode().isEqualTo(HttpStatus.SC_OK) - ) - } - - @Then("{actor} knows what version of the service is running") - fun actorUnderstandsVersion(actor: Actor) { - val healthResponse = SerenityRest.lastResponse().get() - actor.attemptsTo( - Ensure.that(healthResponse.version).isNotBlank() - ) - } - - @When("{actor} makes a request to the metrics endpoint") - fun actorRequestsMetricEndpoint(actor: Actor) { - actor.attemptsTo( - Get.resource("/_system/metrics") - ) - actor.attemptsTo( - Ensure.thatTheLastResponse().statusCode().isEqualTo(HttpStatus.SC_OK) - ) - } - - @Then("{actor} sees that the metrics contain background job stats") - fun actorSeesMetrics(actor: Actor) { - val metricsResponse = SerenityRest.lastResponse() - actor.attemptsTo( - Ensure.that(metricsResponse.body.asString()).contains("present_proof_flow_did_com_exchange_job_ms_gauge"), - Ensure.that(metricsResponse.body.asString()).contains("connection_flow_did_com_exchange_job_ms_gauge"), - Ensure.that(metricsResponse.body.asString()).contains("issuance_flow_did_com_exchange_job_ms_gauge") - ) - } - -} diff --git a/tests/integration-tests/src/test/resources/configs/mt_vault.conf b/tests/integration-tests/src/test/resources/configs/mt_vault.conf deleted file mode 100644 index 4b40259412..0000000000 --- a/tests/integration-tests/src/test/resources/configs/mt_vault.conf +++ /dev/null @@ -1,58 +0,0 @@ -# Specify shared services that are used by all agents (if any) -services = { - prism_node = { - http_port = 50053 - version = "${PRISM_NODE_VERSION}" - } - vault = { - http_port = 8200 - } -} - -# Specify agents that are required to be created before running tests -agents = [ - { - version = "${OPEN_ENTERPRISE_AGENT_VERSION}" - http_port = 8080 - didcomm_port = 7080 - auth_enabled = true - prism_node = ${services.prism_node} - vault = ${services.vault} - } -] - -roles = [ - { - name = "Admin" - url = "${ADMIN_AGENT_URL:-http://localhost:8080}" - apikey = "${ADMIN_API_KEY:-admin}" - auth_header = "x-admin-api-key" - } - { - name = "Issuer" - url = "${ISSUER_AGENT_URL:-http://localhost:8080}" - apikey = "${ISSUER_API_KEY:-${random.string(16)}}" - webhook = { - url = "${ISSUER_WEBHOOK_URL:-http://host.docker.internal:9955}" - init_required = true - } - }, - { - name = "Holder" - url = "${HOLDER_AGENT_URL:-http://localhost:8080}" - apikey = "${HOLDER_API_KEY:-${random.string(16)}}" - webhook = { - url = "${HOLDER_WEBHOOK_URL:-http://host.docker.internal:9956}" - init_required = true - } - }, - { - name = "Verifier" - url = "${VERIFIER_AGENT_URL:-http://localhost:8080}" - apikey = "${VERIFIER_API_KEY:-${random.string(16)}}" - webhook = { - url = "${VERIFIER_WEBHOOK_URL:-http://host.docker.internal:9957}" - init_required = true - } - } -]