Skip to content

Commit

Permalink
Add Unit Test and Integration Test for SSL support feature
Browse files Browse the repository at this point in the history
This commit added UT and IT to cover the SSL support featre. Namely:
  * Introduced RestAssured as the client to simplify the testing code
  * Create a set of PKI and CA for testing different combinations of keystore and turststore in local environment
  * Added UT to cover HttpsSettings, WireMockConfiguration and CommandLineOptions class
  * Added IT to cover the case where WireMock server quires client auth
  • Loading branch information
Jay Zhu authored and find3kan0 committed Dec 7, 2014
1 parent 1ee59d2 commit 13ed9bf
Show file tree
Hide file tree
Showing 27 changed files with 856 additions and 111 deletions.
1 change: 1 addition & 0 deletions build.gradle
Expand Up @@ -44,6 +44,7 @@ dependencies {
exclude group: "org.hamcrest", module: "hamcrest-core"
exclude group: "org.hamcrest", module: "hamcrest-library"
}
testCompile "com.jayway.restassured:rest-assured:2.4.0"
testCompile "net.sf.json-lib:json-lib:2.4:jdk15"
testCompile "com.googlecode.jarjar:jarjar:1.3"
testCompile "commons-io:commons-io:2.4"
Expand Down
Expand Up @@ -18,24 +18,24 @@
public class HttpsSettings {

private final int port;
private final String keyStorePath;
private final String keyStorePassword;
private final String trustStorePath;
private final String trustStorePassword;
private final String keystore;
private final String keyPassword;
private final String truststore;
private final String trustPassword;

private final boolean needClientAuth;

public HttpsSettings(int port, String keyStorePath, String keyStorePassword, String trustStorePath, String trustStorePassword, boolean needClientAuth) {
public HttpsSettings(int port, String keystore, String keyPassword, String truststore, String trustPassword, boolean needClientAuth) {
this.port = port;
this.keyStorePath = keyStorePath;
this.keyStorePassword = keyStorePassword;
this.trustStorePath = trustStorePath;
this.trustStorePassword = trustStorePassword;
this.keystore = keystore;
this.keyPassword = keyPassword;
this.truststore = truststore;
this.trustPassword = trustPassword;
this.needClientAuth = needClientAuth;
}

public HttpsSettings(int port, String keyStorePath, String keyStorePassword) {
this(port, keyStorePath, keyStorePassword, null, null, false);
public HttpsSettings(int port, String keystore, String keyPassword) {
this(port, keystore, keyPassword, null, null, false);
}

public static final HttpsSettings NO_HTTPS = new HttpsSettings(0, null, null);
Expand All @@ -44,24 +44,24 @@ public int port() {
return port;
}

public String keyStorePath() {
return keyStorePath;
public String keystore() {
return keystore;
}

public boolean enabled() {
return this != NO_HTTPS;
}

public String getKeyStorePassword() {
return keyStorePassword;
public String keyPassword() {
return keyPassword;
}

public String getTrustStorePath() {
return trustStorePath;
public String truststore() {
return truststore;
}

public String getTrustStorePassword() {
return trustStorePassword;
public String trustPassword() {
return trustPassword;
}

public boolean needClientAuth() {
Expand All @@ -72,10 +72,10 @@ public boolean needClientAuth() {
public String toString() {
return "HttpsSettings{" +
"port=" + port +
", keyStorePath='" + keyStorePath + '\'' +
", keyStorePassword='" + keyStorePassword + '\'' +
", trustStorePath='" + trustStorePath + '\'' +
", trustStorePassword='" + trustStorePassword + '\'' +
", keystore='" + keystore + '\'' +
", keyPassword='" + keyPassword + '\'' +
", truststore='" + truststore + '\'' +
", trustPassword='" + trustPassword + '\'' +
", needClientAuth=" + needClientAuth +
'}';
}
Expand Down
Expand Up @@ -18,6 +18,7 @@
import com.github.tomakehurst.wiremock.common.*;
import com.github.tomakehurst.wiremock.http.CaseInsensitiveKey;
import com.google.common.io.Resources;
import org.apache.commons.lang.StringUtils;

import java.util.List;

Expand Down Expand Up @@ -59,23 +60,23 @@ public WireMockConfiguration httpsPort(Integer httpsPort) {
return this;
}

public WireMockConfiguration keystorePath(String path) {
this.keyStorePath = path;
public WireMockConfiguration keystore(String keystore) {
this.keyStorePath = keystore;
return this;
}

public WireMockConfiguration keystorePass(String path) {
this.keyStorePassword = path;
public WireMockConfiguration keyPassword(String password) {
this.keyStorePassword = password;
return this;
}

public WireMockConfiguration truststorePath(String path) {
this.trustStorePath = path;
public WireMockConfiguration truststore(String truststore) {
this.trustStorePath = truststore;
return this;
}

public WireMockConfiguration truststorePass(String path) {
this.trustStorePassword = path;
public WireMockConfiguration trustPassword(String password) {
this.trustStorePassword = password;
return this;
}

Expand Down Expand Up @@ -164,11 +165,31 @@ public HttpsSettings httpsSettings() {
return HttpsSettings.NO_HTTPS;
}

if (keyStorePath == null) {
return new HttpsSettings(httpsPort, Resources.getResource("keystore").toString(), "password");
final String keyStorePath;
if (StringUtils.isEmpty(this.keyStorePath)) {
keyStorePath = Resources.getResource("keystore").toString();
} else {
keyStorePath = this.keyStorePath;
}

return new HttpsSettings(httpsPort, keyStorePath, keyStorePassword, trustStorePath, trustStorePassword, needClientAuth);

final String keyStorePassword;
if (StringUtils.isEmpty(this.keyStorePassword)) {
keyStorePassword = "password";
} else {
keyStorePassword = this.keyStorePassword;
}

if (StringUtils.isEmpty(keyStorePath)) {
throw new IllegalArgumentException("Try to enable HTTPS port but missing a valid Keystore. " +
"Please either specify a valid keystore path, " +
"or put the keystore in resource with name 'keystore'");
}

return new HttpsSettings(httpsPort,
keyStorePath, keyStorePassword,
trustStorePath, trustStorePassword,
needClientAuth);
}

@Override
Expand Down
Expand Up @@ -54,7 +54,6 @@ class Jetty6HttpServer implements HttpServer {
StubRequestHandler stubRequestHandler,
RequestDelayControl requestDelayControl
) {

jettyServer = new Server();
httpConnector = createHttpConnector(
requestDelayControl,
Expand Down Expand Up @@ -138,12 +137,12 @@ private DelayableSslSocketConnector createHttpsConnector(
connector.setHost(bindAddress);
connector.setPort(httpsSettings.port());
connector.setHeaderBufferSize(8192);
connector.setKeystore(httpsSettings.keyStorePath());
connector.setKeyPassword(httpsSettings.getKeyStorePassword());
connector.setKeystore(httpsSettings.keystore());
connector.setKeyPassword(httpsSettings.keyPassword());

connector.setTruststore(httpsSettings.getTrustStorePath());
if (httpsSettings.getTrustStorePassword() != null) {
connector.setTrustPassword(httpsSettings.getTrustStorePassword());
connector.setTruststore(httpsSettings.truststore());
if (httpsSettings.trustPassword() != null) {
connector.setTrustPassword(httpsSettings.trustPassword());
}

connector.setNeedClientAuth(httpsSettings.needClientAuth());
Expand Down
Expand Up @@ -27,6 +27,7 @@
import com.google.common.io.Resources;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import org.apache.commons.lang.StringUtils;

import java.io.IOException;
import java.io.StringWriter;
Expand Down Expand Up @@ -158,16 +159,19 @@ public HttpsSettings httpsSettings() {
return HttpsSettings.NO_HTTPS;
}

if (optionSet.has(HTTPS_KEYSTORE)) {
return new HttpsSettings(httpsPortNumber(),
(String) optionSet.valueOf(HTTPS_KEYSTORE),
(String) optionSet.valueOf(HTTPS_KEYSTORE_PASS),
(String) optionSet.valueOf(HTTPS_TRUSTSTORE),
(String) optionSet.valueOf(HTTPS_TRUSTSTORE_PASS),
Boolean.valueOf( (String) optionSet.valueOf(HTTPS_NEED_CLIENT_AUTH)));
final String keyStorePath = optionSet.has(HTTPS_KEYSTORE) ? (String) optionSet.valueOf(HTTPS_KEYSTORE) : Resources.getResource("keystore").toString();
final String keyStorePassword = optionSet.has(HTTPS_KEYSTORE_PASS) ? (String) optionSet.valueOf(HTTPS_KEYSTORE_PASS) : "password";

if (StringUtils.isEmpty(keyStorePath)) {
throw new IllegalArgumentException("Try to enable HTTPS port but missing a valid Keystore. " +
"Please either specify keystore path with --https-keystore argument, " +
"or put the keystore in resource with name 'keystore'");
}

return new HttpsSettings(httpsPortNumber(), Resources.getResource("keystore").toString(), "password");
return new HttpsSettings(httpsPortNumber(), keyStorePath, keyStorePassword,
(String) optionSet.valueOf(HTTPS_TRUSTSTORE),
(String) optionSet.valueOf(HTTPS_TRUSTSTORE_PASS),
Boolean.valueOf((String) optionSet.valueOf(HTTPS_NEED_CLIENT_AUTH)));
}

private int httpsPortNumber() {
Expand Down Expand Up @@ -238,7 +242,7 @@ public String toString() {

if (httpsSettings().enabled()) {
builder.put(HTTPS_PORT, nullToString(httpsSettings().port()))
.put(HTTPS_KEYSTORE, nullToString(httpsSettings().keyStorePath()));
.put(HTTPS_KEYSTORE, nullToString(httpsSettings().keystore()));
}

if (!(proxyVia() == NO_PROXY)) {
Expand Down

0 comments on commit 13ed9bf

Please sign in to comment.