package biz.artemis.confluence.xmlrpcwrapper;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Properties;
import java.util.Vector;
import javax.net.ssl.SSLHandshakeException;
import junit.framework.TestCase;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.xmlrpc.XmlRpcClient;
import org.apache.xmlrpc.XmlRpcException;
/**
* Test class for RemoteWikiBroker methods that should remain protected.
* (RemoteWikiBrokerTest in other package can only access public methods.)
* XXX Remember to set test.properties to local settings
* XXX Many of these methods interfere with each other. I haven't been able
* to figure out a way to reset the xmlrpc connection in such a way that
* we can test different SSL Connection settings during the same run.
* So what we're doing is that I'm requiring at the beginning of each method that
* has this problem that you run them one at a time as a reminder that they won't
* actually work correctly if you try to run them at the same time.
*/
public class RemoteWikiBrokerProtectedTest extends TestCase {
//test objects
RemoteWikiBroker tester = null;
private ConfluenceServerSettings confSettings;
private String sslUrl;
private String sslSpace;
private Properties props;
private String badtrust;
private String badtrustpass;
//logging
Logger log = Logger.getLogger(this.getClass());
//test properties keys - used to load local test settings
private static final String TEST_URL = "test.url";
private static final String TEST_SSL_URL = "test.ssl.url";
private static final String TEST_USER_LOGIN = "test.user.login";
private static final String TEST_PASS = "test.user.pass";
private static final String TEST_SPACE = "test.space.key";
private static final String TEST_SSL_SPACE = "test.space.ssl";
private static final String TEST_TRUST_LOCATION = "test.trust.location";
private static final String TEST_TRUST_PASS = "test.trust.pass";
private static final String TEST_TRUST_BAD = "test.trust.bad.location";
private static final String TEST_TRUST_BADPASS = "test.trust.bad.pass";
private static int numExclusiveTests = 0;
protected void setUp() throws Exception {
//test obj
tester = RemoteWikiBroker.getInstance();
//logging
PropertyConfigurator.configure("log4j.properties");
//test properties - we don't need to do this every time. The settings aren't going to change
confSettings = new ConfluenceServerSettings();
props = new Properties();
try {
props.load(new FileInputStream("test.properties"));
} catch (IOException e) {
e.printStackTrace();
fail();
}
confSettings.login = props.getProperty(TEST_USER_LOGIN);
confSettings.password = props.getProperty(TEST_PASS);
confSettings.spaceKey = props.getProperty(TEST_SPACE);
confSettings.url = props.getProperty(TEST_URL);
confSettings.truststore = props.getProperty(TEST_TRUST_LOCATION);
confSettings.trustpass = props.getProperty(TEST_TRUST_PASS);
sslUrl = props.getProperty(TEST_SSL_URL);
sslSpace = props.getProperty(TEST_SSL_SPACE);
badtrust = props.getProperty(TEST_TRUST_BAD);
badtrustpass = props.getProperty(TEST_TRUST_BADPASS);
}
public void tearDown() throws Exception {
super.tearDown();
tester = null;
confSettings = null;
props = null;
System.clearProperty("java.protocol.handler.pkgs");
System.clearProperty("javax.net.ssl.trustStore");
System.clearProperty("javax.net.ssl.trustStorePassword");
}
public void testCreateConnectionUrl() {
String input, expected, actual;
input = "localhost";
expected = "http://localhost/rpc/xmlrpc";
actual = tester.createConnectionUrl(input);
assertNotNull(actual);
assertEquals(expected, actual);
input = "localhost:8082";
expected = "http://" + input + "/rpc/xmlrpc";
actual = tester.createConnectionUrl(input);
assertNotNull(actual);
assertEquals(expected, actual);
input = "localhost:8082/";
//expected stays the same
actual = tester.createConnectionUrl(input);
assertNotNull(actual);
assertEquals(expected, actual);
input = "http://localhost:8082";
//expected stays the same
actual = tester.createConnectionUrl(input);
assertNotNull(actual);
assertEquals(expected, actual);
input = "https://localhost:8443";
expected = "https://localhost:8443/rpc/xmlrpc";
actual = tester.createConnectionUrl(input);
assertNotNull(actual);
assertEquals(expected, actual);
input = "foobar.com/confluence";
expected = "http://" + input + "/rpc/xmlrpc";
actual = tester.createConnectionUrl(input);
assertNotNull(actual);
assertEquals(expected, actual);
}
public void testIsSslUrl() {
String input;
boolean expected, actual;
input = "http://foobar.com/rpc/xmlrpc";
expected = false;
actual = tester.isSslUrl(input);
assertNotNull(actual);
assertEquals(expected, actual);
input = "http://localhost:8082/rpc/xmlrpc";
expected = false;
actual = tester.isSslUrl(input);
assertNotNull(actual);
assertEquals(expected, actual);
input = "https://localhost/rpc/xmlrpc";
expected = true;
actual = tester.isSslUrl(input);
assertNotNull(actual);
assertEquals(expected, actual);
}
//FIXME The following 5 tests interfere with each other.
//In order to test each one, you must only run them one at a time.
public void testAddSSLSettings_Succeed() {
if (numExclusiveTests++ > 0) fail("Only one 'exclusive' test can be run at a time.");
confSettings.url = sslUrl;
confSettings.spaceKey = sslSpace;
String connectionURL = "https://" + sslUrl + "/rpc/xmlrpc";
XmlRpcClient client = null;
try {
client = new XmlRpcClient(connectionURL);
} catch (MalformedURLException e) {
e.printStackTrace();
fail();
}
assertNotNull(client);
Vector loginParams = new Vector(2);
loginParams.add(confSettings.login);
loginParams.add(confSettings.password);
String loginToken;
//and here's what a proper ssl connection looks like
tester.needNewLogin();
tester.addSSLSettings(confSettings);
try {
loginToken = (String) client.execute("confluence1.login", loginParams);
assertNotNull(loginToken);
assertTrue(!"".equals(loginToken));
} catch (Exception e) {
e.printStackTrace();
fail();
}
//what if the truststore is not a valid file
confSettings.setTruststore(badtrust);
try {
tester.addSSLSettings(confSettings);
fail();
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().startsWith("Location of truststore is not a valid file"));
}
confSettings.setTruststore(null);
try {
tester.addSSLSettings(confSettings);
fail();
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().startsWith("Location of truststore is not a valid file"));
}
}
public void testAddSslSettings_Fail() {
if (numExclusiveTests++ > 0) fail("Only one 'exclusive' test can be run at a time.");
confSettings.url = sslUrl;
confSettings.spaceKey = sslSpace;
String connectionURL = "https://" + sslUrl + "/rpc/xmlrpc";
XmlRpcClient client = null;
try {
client = new XmlRpcClient(connectionURL);
} catch (MalformedURLException e) {
e.printStackTrace();
fail();
}
assertNotNull(client);
Vector loginParams = new Vector(2);
loginParams.add(confSettings.login);
loginParams.add(confSettings.password);
String loginToken;
//establish what it looks like to connect to an SSL url without ssl settings
try {
loginToken = (String) client.execute("confluence1.login", loginParams);
fail();
} catch (SSLHandshakeException e) {
//This is the correct code path
} catch (XmlRpcException e) {
fail();
} catch (IOException e) {
if (e.getMessage().contains("Connection refused")) {
log.fatal("You must turn on the SSL Confluence to test it.");
}
fail(e.getMessage());
}
}
public void testGetXmlRpcClient_Ssl() {
if (numExclusiveTests++ > 0) fail("Only one 'exclusive' test can be run at a time.");
SpaceForXmlRpc space = null;
confSettings.url = "https://" + sslUrl; //have to indicate SSL explicitly
confSettings.spaceKey = sslSpace;
confSettings.login = "laura.kolker";
confSettings.password = "r5bhpoi";
try {
space = tester.getSpace(confSettings, confSettings.spaceKey);
assertNotNull(space);
assertEquals(confSettings.spaceKey, space.getSpaceKey());
} catch (Exception e) {
fail();
}
}
public void testGetXmlRpcClient() {
if (numExclusiveTests++ > 0) fail("Only one 'exclusive' test can be run at a time.");
SpaceForXmlRpc space = null;
try {
space = tester.getSpace(confSettings, confSettings.spaceKey);
assertNotNull(space);
assertEquals(confSettings.spaceKey, space.getSpaceKey());
} catch (Exception e) {
fail();
}
}
public void testAddSSLSettings_TrustAll_Fail() {
if (numExclusiveTests++ > 0) fail("Only one 'exclusive' test can be run at a time.");
confSettings.url = sslUrl;
confSettings.spaceKey = sslSpace;
confSettings.trustallcerts = "false";
confSettings.truststore = "log4j.properties"; //valid file, but not a valid truststore
confSettings.trustpass = "";
String connectionURL = "https://" + sslUrl + "/rpc/xmlrpc";
XmlRpcClient client = null;
try {
client = new XmlRpcClient(connectionURL);
} catch (MalformedURLException e) {
e.printStackTrace();
fail();
}
assertNotNull(client);
Vector loginParams = new Vector(2);
loginParams.add(confSettings.login);
loginParams.add(confSettings.password);
String loginToken;
//this should not connect. We have neither trustall set to true, nor valid truststore
tester.addSSLSettings(confSettings);
try {
loginToken = (String) client.execute("confluence1.login", loginParams);
fail();
} catch (Exception e) {
}
}
public void testAddSSLSettings_TrustAll_Success() {
if (numExclusiveTests++ > 0) fail("Only one 'exclusive' test can be run at a time.");
confSettings.url = sslUrl;
confSettings.spaceKey = sslSpace;
confSettings.trustallcerts = "true";
confSettings.truststore = "log4j.properties"; //valid file, but not a valid truststore
confSettings.trustpass = "";
String connectionURL = "https://" + sslUrl + "/rpc/xmlrpc";
XmlRpcClient client = null;
try {
client = new XmlRpcClient(connectionURL);
} catch (MalformedURLException e) {
e.printStackTrace();
fail();
}
assertNotNull(client);
Vector loginParams = new Vector(2);
loginParams.add(confSettings.login);
loginParams.add(confSettings.password);
String loginToken;
//and here's what a proper ssl connection looks like
tester.addSSLSettings(confSettings);
try {
loginToken = (String) client.execute("confluence1.login", loginParams);
assertNotNull(loginToken);
assertTrue(!"".equals(loginToken));
} catch (Exception e) {
e.printStackTrace();
fail();
}
}
}