Skip to content

Commit

Permalink
Merge pull request #317 from wojciechbulaty/master
Browse files Browse the repository at this point in the history
Created a VersionedPactUrl to be used to reference versioned pacts.
  • Loading branch information
Ronald Holshausen authored Sep 15, 2016
2 parents 9550ee4 + 83da230 commit 555c0d8
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package au.com.dius.pact.provider.junit.loader;

import au.com.dius.pact.provider.junit.PactRunner;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Used to point {@link PactRunner} to a versioned source of pacts for contract tests.
* <p>
* Use ${any.variable} in the url and specify any.variable as a system property.
* </p>
* <p>
* For example, when you annotate a provider test class with:
* <pre><code>{@literal @}VersionedPactUrl(urls = {"http://artifactory:8081/artifactory/consumercontracts/foo-bar/${foo.version}/foo-bar-${foo.version}.json"})</code></pre>
* And pass a system property foo.version to the JVM, for example -Dfoo.version=123
* </p>
* <p>
* Then the pact tests will fetch the following contract:
* <pre><code>http://artifactory:8081/artifactory/consumercontracts/foo-bar/123/foo-bar-123.json</code></pre>
* </p>
*
* @see VersionedPactUrlLoader pact loader
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@PactSource(VersionedPactUrlLoader.class)
public @interface VersionedPactUrl {
/**
* @return a list of urls to pact files
*/
String[] urls();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package au.com.dius.pact.provider.junit.loader;

import au.com.dius.pact.model.Pact;
import com.google.common.annotations.VisibleForTesting;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.lang.String.format;
import static java.util.Arrays.stream;

/**
* Implementation of {@link PactLoader} that downloads pacts from given urls containing versions to be filtered in from system properties.
*
* @see VersionedPactUrl usage instructions
*/
public class VersionedPactUrlLoader implements PactLoader {
private final String[] urls;

public VersionedPactUrlLoader(String[] urls) {
this.urls = urls;
}

@SuppressWarnings("unused")
public VersionedPactUrlLoader(VersionedPactUrl pactUrl) {
this(pactUrl.urls());
}

@Override
public List<Pact> load(String providerName) throws IOException {
return new PactUrlLoader(expandVariables(urls)).load(providerName);
}

@VisibleForTesting
static String[] expandVariables(String[] urls) throws IOException {
return stream(urls)
.map(VersionedPactUrlLoader::expandVariables)
.collect(Collectors.toList())
.toArray(new String[urls.length]);
}

private static String expandVariables(String urlWithVariables) {
String urlWithVersions = urlWithVariables;
for (Map.Entry<Object, Object> property : System.getProperties().entrySet()) {
urlWithVersions = urlWithVersions.replace(format("${%s}", property.getKey()), property.getValue().toString());
}
if (urlWithVersions.matches(".*\\$\\{[a-z\\.]+\\}.*")) {
throw new IllegalArgumentException(urlWithVersions + " contains variables that could not be any of the system properties. Define a system property to replace them or remove the variables from the URL.");
}
return urlWithVersions;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package au.com.dius.pact.provider.junit.loader;

import org.junit.Test;

import static java.lang.String.format;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class VersionedPactUrlLoaderTest {
@Test
public void replacesVersion() throws Exception {
String versionVariable = "jupiter.version";
System.setProperty(versionVariable, "555");

String[] strings = VersionedPactUrlLoader
.expandVariables(new String[]{format("http://artifactory:8081/jupiter-hydra/${%1$s}/jupiter-hydra-${%1$s}.json", versionVariable)});

assertEquals("http://artifactory:8081/jupiter-hydra/555/jupiter-hydra-555.json", strings[0]);
assertEquals(1, strings.length);
}

@Test
public void replacesVersions() throws Exception {
String versionVariable1 = "jupiter.version";
String versionVariable2 = "saturn.version";
System.setProperty(versionVariable1, "555");
System.setProperty(versionVariable2, "666");

String[] strings = VersionedPactUrlLoader
.expandVariables(new String[]{format("http://artifactory:8081/jupiter-hydra/${%s}/jupiter-hydra-${%s}.json", versionVariable1, versionVariable2)});

assertEquals("http://artifactory:8081/jupiter-hydra/555/jupiter-hydra-666.json", strings[0]);
assertEquals(1, strings.length);
}

@Test
public void failsWhenNoVersionSpecified() throws Exception {
String versionVariable = "jupiter.version";
System.clearProperty(versionVariable);

try {
VersionedPactUrlLoader.expandVariables(new String[]{format("http://artifactory:8081/jupiter-hydra/${%s}/jupiter-hydra-${%s}.json", versionVariable, versionVariable)});
fail();
} catch (Exception e) {
assertEquals("http://artifactory:8081/jupiter-hydra/${jupiter.version}/jupiter-hydra-${jupiter.version}.json contains variables that could not be any of the system properties. Define a system property to replace them or remove the variables from the URL.", e.getMessage());
}
}
}

0 comments on commit 555c0d8

Please sign in to comment.