diff --git a/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslRequestWithPathSpec.groovy b/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslRequestWithPathSpec.groovy index d017359060..20886f6bb6 100644 --- a/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslRequestWithPathSpec.groovy +++ b/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslRequestWithPathSpec.groovy @@ -159,10 +159,10 @@ class PactDslRequestWithPathSpec extends Specification { when: def pact = consumerPactBuilder - .uponReceiving("a request") - .path("/api/myrequest") - .method("POST") - .queryMatchingDatetime("startDateTime", "yyyy-MM-dd'T'hh:mm:ss'Z'") + .uponReceiving('a request') + .path('/api/request') + .method('POST') + .queryMatchingDatetime('startDateTime', "yyyy-MM-dd'T'hh:mm:ss'Z'") .willRespondWith() .status(200) .toPact() diff --git a/provider/junit/src/main/kotlin/au/com/dius/pact/provider/junit/PactRunner.kt b/provider/junit/src/main/kotlin/au/com/dius/pact/provider/junit/PactRunner.kt index 8ce888e85e..67614ebe39 100644 --- a/provider/junit/src/main/kotlin/au/com/dius/pact/provider/junit/PactRunner.kt +++ b/provider/junit/src/main/kotlin/au/com/dius/pact/provider/junit/PactRunner.kt @@ -2,7 +2,10 @@ package au.com.dius.pact.provider.junit import au.com.dius.pact.core.model.Interaction import au.com.dius.pact.core.model.Pact +import au.com.dius.pact.core.support.expressions.DataType +import au.com.dius.pact.core.support.expressions.ExpressionParser import au.com.dius.pact.core.support.expressions.SystemPropertyResolver +import au.com.dius.pact.core.support.expressions.ValueResolver import au.com.dius.pact.core.support.json.JsonException import au.com.dius.pact.provider.ProviderUtils import au.com.dius.pact.provider.ProviderUtils.findAnnotation @@ -57,7 +60,7 @@ import java.io.IOException open class PactRunner(private val clazz: Class<*>) : ParentRunner>(clazz) where I : Interaction { private val children = mutableListOf>() - private var valueResolver = SystemPropertyResolver + private var valueResolver: ValueResolver = SystemPropertyResolver private var initialized = false private fun initialize() { @@ -68,16 +71,8 @@ open class PactRunner(private val clazz: Class<*>) : ParentRunner(private val clazz: Class<*>) : ParentRunner { + val consumerInfo = findAnnotation(clazz, Consumer::class.java) + return if (consumerInfo != null) { + logger.debug { "Found annotation $consumerInfo" } + val consumerName = ExpressionParser.parseExpression(consumerInfo.value, DataType.STRING, valueResolver)?.toString() + Pair(consumerInfo, consumerName) + } else { + Pair(null, null) + } + } + + private fun lookupProviderInfo(): Pair { + val providerInfo = findAnnotation(clazz, Provider::class.java) ?: throw InitializationError( + "Provider name should be specified by using ${Provider::class.java.simpleName} annotation" + ) + logger.debug { "Found annotation $providerInfo" } + val serviceName = ExpressionParser.parseExpression(providerInfo.value, DataType.STRING, valueResolver)?.toString() + if (serviceName.isNullOrEmpty()) { + throw InitializationError( + "Provider name specified by ${Provider::class.java.simpleName} annotation is null or empty" + ) + } + return Pair(providerInfo, serviceName) + } + private fun checkIgnoreIoException(ignoreIoErrors: String, e: Exception) = if (ignoreIoErrors == "true") { logger.warn { "\n" + WARNING_ON_IGNORED_IOERROR.trimIndent() } logger.debug(e) { "Failed to load pact files" } diff --git a/provider/junit/src/test/groovy/au/com/dius/pact/provider/junit/PactRunnerSpec.groovy b/provider/junit/src/test/groovy/au/com/dius/pact/provider/junit/PactRunnerSpec.groovy index e19de3b89b..d5e38b7c16 100644 --- a/provider/junit/src/test/groovy/au/com/dius/pact/provider/junit/PactRunnerSpec.groovy +++ b/provider/junit/src/test/groovy/au/com/dius/pact/provider/junit/PactRunnerSpec.groovy @@ -3,6 +3,7 @@ package au.com.dius.pact.provider.junit import au.com.dius.pact.core.model.Pact import au.com.dius.pact.core.model.RequestResponsePact import au.com.dius.pact.core.model.UrlSource +import au.com.dius.pact.provider.junitsupport.Consumer import au.com.dius.pact.provider.junitsupport.IgnoreNoPactsToVerify import au.com.dius.pact.provider.junitsupport.Provider import au.com.dius.pact.provider.junitsupport.loader.PactFolder @@ -14,7 +15,9 @@ import au.com.dius.pact.provider.junitsupport.target.Target import au.com.dius.pact.provider.junitsupport.target.TestTarget import org.junit.runner.notification.RunNotifier import org.junit.runners.model.InitializationError +import spock.lang.Issue import spock.lang.Specification +import spock.util.environment.RestoreSystemProperties @SuppressWarnings('UnusedObject') class PactRunnerSpec extends Specification { @@ -116,6 +119,21 @@ class PactRunnerSpec extends Specification { Target target } + @Provider('${provider.name}') + @PactFolder('pacts') + class ProviderFromSystemPropTestClass { + @TestTarget + Target target + } + + @Provider('myAwesomeService') + @Consumer('${consumer.name}') + @PactFolder('pacts') + class ConsumerFromSystemPropTestClass { + @TestTarget + Target target + } + def 'PactRunner throws an exception if there is no @Provider annotation on the test class'() { when: new PactRunner(PactRunnerSpec).run(new RunNotifier()) @@ -219,4 +237,31 @@ class PactRunnerSpec extends Specification { !runner.children.empty } + @Issue('#528') + @RestoreSystemProperties + def 'PactRunner supports getting the provider name from a system property or environment variable'() { + given: + System.setProperty('provider.name', 'myAwesomeService') + + when: + def runner = new PactRunner(ProviderFromSystemPropTestClass) + runner.run(new RunNotifier()) + + then: + !runner.children.empty + } + + @Issue('#528') + @RestoreSystemProperties + def 'PactRunner supports getting the consumer name from a system property or environment variable'() { + given: + System.setProperty('consumer.name', 'anotherService') + + when: + def runner = new PactRunner(ConsumerFromSystemPropTestClass) + runner.run(new RunNotifier()) + + then: + !runner.children.empty + } } diff --git a/provider/src/main/java/au/com/dius/pact/provider/junitsupport/Provider.java b/provider/src/main/java/au/com/dius/pact/provider/junitsupport/Provider.java deleted file mode 100644 index b90be64ae3..0000000000 --- a/provider/src/main/java/au/com/dius/pact/provider/junitsupport/Provider.java +++ /dev/null @@ -1,20 +0,0 @@ -package au.com.dius.pact.provider.junitsupport; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Used to pass provider name to Pact runner - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Inherited -public @interface Provider { - /** - * @return provider name for pact test running - */ - String value() default ""; -} diff --git a/provider/src/main/kotlin/au/com/dius/pact/provider/junitsupport/Consumer.kt b/provider/src/main/kotlin/au/com/dius/pact/provider/junitsupport/Consumer.kt index 494e53845c..7e7214e396 100644 --- a/provider/src/main/kotlin/au/com/dius/pact/provider/junitsupport/Consumer.kt +++ b/provider/src/main/kotlin/au/com/dius/pact/provider/junitsupport/Consumer.kt @@ -4,7 +4,8 @@ import java.lang.annotation.Inherited import kotlin.annotation.Retention /** - * Used to pass consumer name to Pact runner + * Used to pass consumer name to Pact runner. Can use expressions (in `${}` form) to get the value from Java system + * properties or environment variables. */ @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.CLASS, AnnotationTarget.FILE) diff --git a/provider/src/main/kotlin/au/com/dius/pact/provider/junitsupport/Provider.kt b/provider/src/main/kotlin/au/com/dius/pact/provider/junitsupport/Provider.kt new file mode 100644 index 0000000000..8d21ba672e --- /dev/null +++ b/provider/src/main/kotlin/au/com/dius/pact/provider/junitsupport/Provider.kt @@ -0,0 +1,18 @@ +package au.com.dius.pact.provider.junitsupport + +import java.lang.annotation.Inherited +import kotlin.annotation.Retention + +/** + * Used to pass provider name to Pact runner. Can use expressions (in `${}` form) to get the value from Java system + * properties or environment variables. + */ +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.CLASS, AnnotationTarget.FILE) +@Inherited +annotation class Provider( + /** + * @return provider name for pact test running + */ + val value: String = "" +)