Skip to content

Commit

Permalink
test: add multiple things
Browse files Browse the repository at this point in the history
Signed-off-by: Allain Magyar <[email protected]>
  • Loading branch information
amagyar-iohk committed Jun 26, 2024
1 parent 7022677 commit 9be12ab
Show file tree
Hide file tree
Showing 16 changed files with 162 additions and 99 deletions.
12 changes: 11 additions & 1 deletion .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
runs-on: ubuntu-latest
if: ${{ !contains(github.event.pull_request.title, '[skip ci]') }}
env:
LOGS_DIR: "tests/integration-tests/target/logs"
REPORTS_DIR: "tests/integration-tests/target/site/serenity"
steps:
- name: Checkout
Expand Down Expand Up @@ -131,12 +132,21 @@ jobs:
comment_title: "Integration Test Results"
check_name: "Integration Test Results"

- name: Upload artifacts
- name: Upload serenity report
if: github.ref_name == 'main' || failure()
uses: actions/upload-artifact@v4
with:
name: integration-tests-result
path: ${{ env.REPORTS_DIR }}
compression-level: 9

- name: Upload logs
if: github.ref_name == 'main' || failure()
uses: actions/upload-artifact@v4
with:
name: docker-logs
path: ${{ env.LOGS_DIR }}
compression-level: 9

- name: Slack Notification
if: github.ref_name == 'main' && failure()
Expand Down
4 changes: 2 additions & 2 deletions tests/integration-tests/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ afterEvaluate {
tasks.register<Test>("test_$fileName") {
group = "verification"
testLogging.showStandardStreams = true
systemProperty("context", fileName)
systemProperty("TESTS_CONFIG", "/configs/$fileName.conf")
systemProperty("PRISM_NODE_VERSION", System.getenv("PRISM_NODE_VERSION") ?: "")
systemProperty("AGENT_VERSION", System.getenv("AGENT_VERSION") ?: "")
systemProperty("cucumber.filter.tags", System.getProperty("cucumber.filter.tags"))
dependsOn("cleanTarget")
finalizedBy("aggregate", "reports")
outputs.upToDateWhen { false }
}
Expand All @@ -100,7 +100,7 @@ afterEvaluate {
* Runs the integration suite for each config file present
* Restrictions: aggregation of all executions doesn't work because of serenity configuration
*/
tasks.register("regression") {
tasks.register<Test>("regression") {
dependsOn("cleanTarget")
group = "verification"
configFiles.forEach {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,15 @@ enum class CredentialSchema {
tags = listOf("school", "students"),
version = "1.0.0",
)
override val claims: Map<String, Any> = linkedMapOf(
"name" to "Name",
"age" to 18,
)
}, ;

abstract val credentialSchema: CredentialSchemaInput
abstract val schema: JsonSchema
abstract val credentialSchemaType: String
abstract val schemaType: String
abstract val claims: Map<String, Any>
}
12 changes: 6 additions & 6 deletions tests/integration-tests/src/test/kotlin/config/services/Agent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import com.sksamuel.hoplite.ConfigAlias
import config.VaultAuthType
import org.testcontainers.containers.ComposeContainer
import org.testcontainers.containers.wait.strategy.Wait
import java.io.File
import java.io.*


data class Agent(
val version: String,
Expand All @@ -13,12 +14,13 @@ data class Agent(
@ConfigAlias("didcomm_service_url") val didcommServiceUrl: String?,
@ConfigAlias("rest_service_url") val restServiceUrl: String?,
@ConfigAlias("auth_enabled") val authEnabled: Boolean,
@ConfigAlias("prism_node") val prismNode: PrismNode?,
@ConfigAlias("prism_node") val prismNode: VerifiableDataRegistry?,
val keycloak: Keycloak?,
val vault: Vault?,
@ConfigAlias("keep_running") override val keepRunning: Boolean = false,
) : ServiceBase {
) : ServiceBase() {

override val logServices = listOf("identus-cloud-agent")
override val container: ComposeContainer

init {
Expand Down Expand Up @@ -50,9 +52,7 @@ data class Agent(
env["VAULT_APPROLE_SECRET_ID"] = "agent-secret"
}

container = ComposeContainer(
File("src/test/resources/containers/agent.yml"),
)
container = ComposeContainer(File("src/test/resources/containers/agent.yml"))
.withEnv(env)
.waitingFor("identus-cloud-agent", Wait.forHealthcheck())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ data class Keycloak(
@ConfigAlias("client_id") val clientId: String = "prism-agent",
@ConfigAlias("client_secret") val clientSecret: String = "prism-agent-demo-secret",
@ConfigAlias("keep_running") override val keepRunning: Boolean = false,
) : ServiceBase {
) : ServiceBase() {
private val logger = Logger.get<Keycloak>()
private val keycloakComposeFile = "src/test/resources/containers/keycloak.yml"
private val keycloakEnvConfig: Map<String, String> = mapOf(
"KEYCLOAK_HTTP_PORT" to httpPort.toString(),
)
private val keycloakClientRoles: List<String> = AgentRole.values().map { it.roleName }
override val logServices: List<String> = listOf("keycloak")
private val keycloakClientRoles: List<String> = AgentRole.entries.map { it.roleName }
override val container: ComposeContainer =
ComposeContainer(File(keycloakComposeFile)).withEnv(keycloakEnvConfig)
.waitingFor("keycloak", Wait.forLogMessage(".*Running the server.*", 1))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package config.services
import com.sksamuel.hoplite.ConfigAlias

data class Service(
@ConfigAlias("prism_node") val prismNode: PrismNode?,
@ConfigAlias("prism_node") val prismNode: VerifiableDataRegistry?,
val keycloak: Keycloak?,
val vault: Vault?,
)
Original file line number Diff line number Diff line change
@@ -1,25 +1,46 @@
package config.services

import com.sksamuel.hoplite.ConfigAlias
import org.testcontainers.containers.ComposeContainer
import org.testcontainers.lifecycle.Startable
import java.io.*

interface ServiceBase : Startable {
abstract class ServiceBase : Startable {
companion object {
private val context = System.getProperties().getOrDefault("context", "")
private val logDir = File("target/logs/$context")
init {
logDir.deleteRecursively()
logDir.mkdirs()
}
}

val container: ComposeContainer
abstract val container: ComposeContainer
abstract val keepRunning: Boolean

@ConfigAlias("keep_running")
val keepRunning: Boolean
open val logServices: List<String> = emptyList()
private val logWriters: MutableList<Writer> = mutableListOf()

override fun start() {
logServices.forEach {
val output = File(logDir, "$it.log")
output.createNewFile()
val writer = FileOutputStream(output, true).bufferedWriter()
logWriters.add(writer)
container.withLogConsumer(it) { logLine ->
writer.append(logLine.utf8String)
}
}
container.start()
postStart()
}

fun postStart() {
open fun postStart() {
}

override fun stop() {
logWriters.forEach {
it.close()
}
if (!keepRunning) {
container.stop()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ import java.io.File

data class Vault(
@ConfigAlias("http_port") val httpPort: Int,
@ConfigAlias("keep_running") override val keepRunning: Boolean = false,
@ConfigAlias("vault_auth_type") val authType: VaultAuthType = VaultAuthType.APP_ROLE,
) : ServiceBase {
@ConfigAlias("keep_running") override val keepRunning: Boolean = false,
) : ServiceBase() {
private val logger = Logger.get<Vault>()
override val logServices: List<String> = listOf("vault")
private val vaultComposeFile: String = "src/test/resources/containers/vault.yml"
override val container: ComposeContainer = ComposeContainer(File(vaultComposeFile)).withEnv(
mapOf(
"VAULT_PORT" to httpPort.toString(),

),
),
).waitingFor(
"vault",
Wait.forHealthcheck(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import org.testcontainers.containers.ComposeContainer
import org.testcontainers.containers.wait.strategy.Wait
import java.io.File

data class PrismNode(
data class VerifiableDataRegistry(
@ConfigAlias("http_port") val httpPort: Int,
val version: String,
@ConfigAlias("keep_running") override val keepRunning: Boolean = false,
) : ServiceBase {
) : ServiceBase() {
override val logServices: List<String> = listOf("prism-node")
private val vdrComposeFile = "src/test/resources/containers/vdr.yml"
override val container: ComposeContainer = ComposeContainer(File(vdrComposeFile)).withEnv(
mapOf(
Expand Down
12 changes: 11 additions & 1 deletion tests/integration-tests/src/test/kotlin/steps/Setup.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,27 @@ import io.cucumber.java.AfterAll
import io.cucumber.java.BeforeAll
import io.restassured.RestAssured
import io.restassured.builder.RequestSpecBuilder
import net.serenitybdd.core.di.SerenityInfrastructure
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 net.thucydides.model.configuration.SystemPropertiesConfiguration
import org.apache.http.HttpStatus
import org.hyperledger.identus.client.models.CreateWalletRequest
import org.hyperledger.identus.client.models.CreateWebhookNotification
import java.util.UUID

object Setup {
val config = ConfigLoader().loadConfigOrThrow<Config>(TestConstants.TESTS_CONFIG)
private val config: Config

init {
try {
config = ConfigLoader().loadConfigOrThrow<Config>(TestConstants.TESTS_CONFIG)
} catch (e: Exception) {
throw RuntimeException(e)
}
}

/**
* This function starts all services and actors before all tests.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package steps.common

import common.CredentialSchema
import interactions.Get
import io.cucumber.java.DataTableType
import io.cucumber.java.ParameterType
Expand All @@ -14,6 +15,7 @@ import org.hyperledger.identus.client.models.*
import steps.connection.ConnectionSteps
import steps.credentials.IssueCredentialsSteps
import steps.did.PublishDidSteps
import steps.schemas.CredentialSchemasSteps

class CommonSteps {
@ParameterType(".*")
Expand Down Expand Up @@ -52,6 +54,25 @@ class CommonSteps {
issueSteps.bobHasTheCredentialIssued(holder)
}

@Given("{actor} has an issued credential with {} schema from {actor}")
fun holderHasIssuedCredentialFromIssuerWithSchema(holder: Actor, schema: CredentialSchema, issuer: Actor) {
actorsHaveExistingConnection(issuer, holder)

val publishDidSteps = PublishDidSteps()
publishDidSteps.createsUnpublishedDid(holder)
publishDidSteps.agentHasAPublishedDID(issuer)

val schemaSteps = CredentialSchemasSteps()
schemaSteps.agentHasAPublishedSchema(issuer, schema)

val issueSteps = IssueCredentialsSteps()
issueSteps.issuerOffersCredentialToHolderUsingSchema(issuer, holder, "short", schema)
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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,8 @@ class IssueCredentialsSteps {
format: String,
schema: CredentialSchema,
) {
val schemaGuid = issuer.recall<String>(schema.name)!!
val claims = linkedMapOf(
"name" to "Name",
"age" to 18,
)
val schemaGuid = issuer.recall<String>(schema.name)
val claims = schema.claims
sendCredentialOffer(issuer, holder, format, schemaGuid, claims)
saveCredentialOffer(issuer, holder)
}
Expand Down Expand Up @@ -144,13 +141,13 @@ class IssueCredentialsSteps {
fun holderReceivesCredentialOffer(holder: Actor) {
Wait.until(
errorMessage = "Holder was unable to receive the credential offer from Issuer! " +
"Protocol state did not achieve ${IssueCredentialRecord.ProtocolState.OFFER_RECEIVED} state.",
"Protocol state did not achieve ${IssueCredentialRecord.ProtocolState.OFFER_RECEIVED} state.",
) {
credentialEvent = ListenToEvents.with(holder).credentialEvents.lastOrNull {
it.data.thid == holder.recall<String>("thid")
}
credentialEvent != null &&
credentialEvent!!.data.protocolState == IssueCredentialRecord.ProtocolState.OFFER_RECEIVED
credentialEvent!!.data.protocolState == IssueCredentialRecord.ProtocolState.OFFER_RECEIVED
}

val recordId = ListenToEvents.with(holder).credentialEvents.last().data.recordId
Expand Down Expand Up @@ -196,7 +193,7 @@ class IssueCredentialsSteps {
it.data.thid == issuer.recall<String>("thid")
}
credentialEvent != null &&
credentialEvent!!.data.protocolState == IssueCredentialRecord.ProtocolState.REQUEST_RECEIVED
credentialEvent!!.data.protocolState == IssueCredentialRecord.ProtocolState.REQUEST_RECEIVED
}
val recordId = credentialEvent!!.data.recordId
issuer.attemptsTo(
Expand All @@ -209,37 +206,37 @@ class IssueCredentialsSteps {
Wait.until(
10.seconds,
errorMessage = "Issuer was unable to issue the credential! " +
"Protocol state did not achieve ${IssueCredentialRecord.ProtocolState.CREDENTIAL_SENT} state.",
"Protocol state did not achieve ${IssueCredentialRecord.ProtocolState.CREDENTIAL_SENT} state.",
) {
credentialEvent = ListenToEvents.with(issuer).credentialEvents.lastOrNull {
it.data.thid == issuer.recall<String>("thid")
}
issuer.remember("issuedCredential", credentialEvent!!.data)

credentialEvent != null &&
credentialEvent!!.data.protocolState == IssueCredentialRecord.ProtocolState.CREDENTIAL_SENT
credentialEvent!!.data.protocolState == IssueCredentialRecord.ProtocolState.CREDENTIAL_SENT
}
}

@Then("{actor} receives the issued credential")
fun bobHasTheCredentialIssued(holder: Actor) {
Wait.until(
errorMessage = "Holder was unable to receive the credential from Issuer! " +
"Protocol state did not achieve ${IssueCredentialRecord.ProtocolState.CREDENTIAL_RECEIVED} state.",
"Protocol state did not achieve ${IssueCredentialRecord.ProtocolState.CREDENTIAL_RECEIVED} state.",
) {
credentialEvent = ListenToEvents.with(holder).credentialEvents.lastOrNull {
it.data.thid == holder.recall<String>("thid")
}
credentialEvent != null &&
credentialEvent!!.data.protocolState == IssueCredentialRecord.ProtocolState.CREDENTIAL_RECEIVED
credentialEvent!!.data.protocolState == IssueCredentialRecord.ProtocolState.CREDENTIAL_RECEIVED
}
holder.remember("issuedCredential", ListenToEvents.with(holder).credentialEvents.last().data)
}

@Then("{actor} should see that credential issuance has failed")
fun issuerShouldSeeThatCredentialIssuanceHasFailed(issuer: Actor) {
issuer.attemptsTo(
Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_BAD_REQUEST),
Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_UNPROCESSABLE_ENTITY),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class RevokeCredentialSteps {
)
holder.attemptsTo(
Patch.to("/credential-status/revoke-credential/${receivedCredential.recordId}"),
Ensure.thatTheLastResponse().statusCode().isEqualTo(HttpStatus.SC_NOT_FOUND),
Ensure.thatTheLastResponse().statusCode().isEqualTo(HttpStatus.SC_UNPROCESSABLE_ENTITY),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class WalletsSteps {
fun acmeCreateNewWalletWithTheSameId(acme: Actor) {
createNewWallet(acme, id = acme.recall("uniqueId"))
acme.attemptsTo(
Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_BAD_REQUEST),
Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_UNPROCESSABLE_ENTITY),
)
}

Expand Down Expand Up @@ -124,7 +124,7 @@ class WalletsSteps {
@Then("{actor} should have only one wallet and second operation should fail")
fun acmeShouldHaveOnlyOneWalletAndSecondOperationShouldFail(acme: Actor) {
acme.attemptsTo(
Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_BAD_REQUEST),
Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_UNPROCESSABLE_ENTITY),
)
acme.attemptsTo(
Get.resource("/wallets"),
Expand Down
Loading

0 comments on commit 9be12ab

Please sign in to comment.