package net.sourceforge.cruisecontrol.webtest;
import junit.framework.TestCase;
import org.apache.tools.ant.util.FileUtils;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
public class ConfigReloadingTest extends TestCase {
private MBeanServerConnection server;
protected void setUp() throws Exception {
super.setUp();
JMXServiceURL address = new JMXServiceURL("service:jmx:rmi://localhost:7856/jndi/jrmp");
Map environment = new HashMap();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
environment.put(Context.PROVIDER_URL, "rmi://localhost:7856");
JMXConnector cntor = JMXConnectorFactory.connect(address, environment);
server = cntor.getMBeanServerConnection();
}
public void testChangingConfigFileOnDisk() throws Exception {
ObjectName ccMgr = ObjectName.getInstance("CruiseControl Manager:id=unique");
ObjectName ccProj = ObjectName.getInstance("CruiseControl Project:name=connectfour");
//Look at the current interval value in JMX.
long currentJMXInterval = ((Long) server.getAttribute(ccProj, "BuildInterval")).longValue() / 1000;
//Look at the current interval value in the config file on disk
String pathToConfig = (String) server.getAttribute(ccMgr, "ConfigFileName");
File configFile = new File(pathToConfig);
String cruiseConfiguration = FileUtils.readFully(new FileReader(configFile));
int currentFileInterval = getInterval(cruiseConfiguration);
assertEquals("Build interval from JMX does not match interval from config file.", currentJMXInterval,
currentFileInterval);
//Increment and set the interval value in the config file on disk
int newInterval = currentFileInterval + 100;
PrintWriter configWriter = new PrintWriter(new FileOutputStream(configFile));
configWriter.println(cruiseConfiguration.replaceFirst("interval=\"" + currentFileInterval + "\"",
"interval=\"" + newInterval + "\""));
configWriter.flush();
configWriter.close();
//Force a build, to trigger CruiseControl to reload the config file
server.invoke(ccProj, "build", null, null);
//Look at the current interval value in JMX
long timeToStopWaiting = System.currentTimeMillis() + 30000;
long newJMXInterval = ((Long) server.getAttribute(ccProj, "BuildInterval")).longValue() / 1000;
while (timeToStopWaiting > System.currentTimeMillis()
&& newJMXInterval != newInterval) {
Thread.sleep(1000);
newJMXInterval = ((Long) server.getAttribute(ccProj, "BuildInterval")).longValue() / 1000;
}
assertEquals(
"CruiseControl hasn't reloaded the configuration file. The schedule interval is still the OLD value.",
newInterval, newJMXInterval);
}
private int getInterval(String cruiseConfiguration) {
int startIndex = cruiseConfiguration.indexOf("interval=\"") + 10;
int endIndex = cruiseConfiguration.substring(startIndex).indexOf("\"") + startIndex;
return Integer.parseInt(cruiseConfiguration.substring(startIndex, endIndex));
}
}