Groundwork for performance related tests
This commit is contained in:
@@ -12,4 +12,4 @@ java.util.logging.ConsoleHandler.formatter = org.springsource.loaded.infra.SLFor
|
||||
# java.util.logging.ConsoleHandler.level = OFF
|
||||
|
||||
# Set the default logging level for the logger named com.mycompany
|
||||
org.springsource.level = ALL
|
||||
org.springsource.level = FINEST
|
||||
|
||||
@@ -159,6 +159,10 @@ public class SpringLoadedPreProcessor implements Constants {
|
||||
|
||||
boolean isReloadableTypeName = typeRegistry.isReloadableTypeName(slashedClassName, protectionDomain, bytes);
|
||||
|
||||
if (isReloadableTypeName && GlobalConfiguration.explainMode && log.isLoggable(Level.INFO)) {
|
||||
log.info("[explanation] Based on the name, type "+slashedClassName+" is considered to be reloadable");
|
||||
}
|
||||
|
||||
// logging causes a ClassCircularity problem when reporting on:
|
||||
// SL: Type 'org/codehaus/groovy/grails/cli/logging/GrailsConsolePrintStream' is not being made reloadable
|
||||
// if (GlobalConfiguration.verboseMode && isReloadableTypeName) {
|
||||
|
||||
@@ -77,6 +77,21 @@ public class ReloadableTypeTests extends SpringLoadedTests {
|
||||
assertEquals(7, r.returnValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removingStaticMethod() throws Exception {
|
||||
String t = "remote.Perf1";
|
||||
TypeRegistry typeRegistry = getTypeRegistry(t);
|
||||
byte[] sc = loadBytesForClass(t);
|
||||
ReloadableType rtype = typeRegistry.addType(t, sc);
|
||||
|
||||
Class<?> clazz = rtype.getClazz();
|
||||
runUnguarded(clazz, "time");
|
||||
|
||||
rtype.loadNewVersion("002", retrieveRename(t, "remote.Perf2"));
|
||||
|
||||
runUnguarded(clazz, "time");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void protectedFieldAccessors() throws Exception {
|
||||
TypeRegistry tr = getTypeRegistry("prot.SubOne");
|
||||
|
||||
@@ -37,6 +37,7 @@ public class ReloadingJVM {
|
||||
String javaclasspath;
|
||||
File testdataDirectory;
|
||||
Process process;
|
||||
private boolean debug = false;
|
||||
DataInputStream reader;
|
||||
DataOutputStream writer;
|
||||
DataInputStream readerErrors;
|
||||
@@ -65,8 +66,9 @@ public class ReloadingJVM {
|
||||
agentJarLocation = search(searchLocation);
|
||||
}
|
||||
|
||||
private ReloadingJVM(String agentOptions) {
|
||||
private ReloadingJVM(String agentOptions, boolean debug) {
|
||||
try {
|
||||
this.debug = debug;
|
||||
javaclasspath = System.getProperty("java.class.path");
|
||||
|
||||
// Create a temporary folder where we can load/replace class files for the file watcher to observe
|
||||
@@ -81,7 +83,7 @@ public class ReloadingJVM {
|
||||
if (DEBUG_CLIENT_SIDE) {
|
||||
System.out.println("(client) Classpath for JVM that is being launched: " + javaclasspath);
|
||||
}
|
||||
String OPTS = "";//"-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=y";
|
||||
String OPTS = debug?"-Xdebug -Xrunjdwp:transport=dt_socket,address=5100,server=y,suspend=y":"";
|
||||
String AGENT_OPTION_STRING = "";
|
||||
if (agentOptions!=null && agentOptions.length()>0) {
|
||||
AGENT_OPTION_STRING = "-Dspringloaded="+agentOptions;
|
||||
@@ -93,6 +95,9 @@ public class ReloadingJVM {
|
||||
writer = new DataOutputStream(process.getOutputStream());
|
||||
reader = new DataInputStream(process.getInputStream());
|
||||
readerErrors = new DataInputStream(process.getErrorStream());
|
||||
if (debug) {
|
||||
System.out.println("Debugging launched VM, port 5000");
|
||||
}
|
||||
JVMOutput text = waitFor("ReloadingJVM:started");
|
||||
if (DEBUG_CLIENT_SIDE) {
|
||||
System.out.println(text);
|
||||
@@ -103,9 +108,14 @@ public class ReloadingJVM {
|
||||
}
|
||||
|
||||
public static ReloadingJVM launch(String options) {
|
||||
return new ReloadingJVM(options);
|
||||
return new ReloadingJVM(options,false);
|
||||
}
|
||||
|
||||
public static ReloadingJVM launch(String options,boolean debug) {
|
||||
return new ReloadingJVM(options,debug);
|
||||
}
|
||||
|
||||
|
||||
private JVMOutput waitFor(String message) {
|
||||
return captureOutput(message);
|
||||
}
|
||||
@@ -144,25 +154,28 @@ public class ReloadingJVM {
|
||||
private JVMOutput captureOutput(String terminationString) {
|
||||
try {
|
||||
long time = System.currentTimeMillis();
|
||||
int timeout = 1000; // 1s timeout
|
||||
int timeout = 1000+(debug?60000:0); // 1s timeout
|
||||
byte[] buf = new byte[1024];
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
while ((System.currentTimeMillis() - time) < timeout) {
|
||||
while (reader.available() != 0) {
|
||||
int read = reader.read(buf);
|
||||
boolean found = false;
|
||||
while ((System.currentTimeMillis() - time) < timeout && !found) {
|
||||
// System.out.println("Waiting on ["+terminationString+"] so far: ["+baos.toString()+"]");
|
||||
while (readerErrors.available() != 0) {
|
||||
int read = readerErrors.read(buf);
|
||||
baos.write(buf, 0, read);
|
||||
if (baos.toString().indexOf(terminationString) != -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
String stdout = baos.toString();
|
||||
baos = new ByteArrayOutputStream();
|
||||
while (readerErrors.available() != 0) {
|
||||
int read = readerErrors.read(buf);
|
||||
baos.write(buf, 0, read);
|
||||
if (baos.toString().indexOf(terminationString) != -1) {
|
||||
found = true;
|
||||
}
|
||||
try { Thread.sleep(100); } catch (Exception e) {}
|
||||
}
|
||||
String stderr = baos.toString();
|
||||
baos = new ByteArrayOutputStream();
|
||||
while (reader.available() != 0) {
|
||||
int read = reader.read(buf);
|
||||
baos.write(buf, 0, read);
|
||||
}
|
||||
String stdout = baos.toString();
|
||||
if (DEBUG_CLIENT_SIDE) {
|
||||
System.out.println("(client) >> received \n== STDOUT ==\n" + stdout + "\n== STDERR==\n" + stderr);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ import org.springsource.loaded.TypeRegistry;
|
||||
*/
|
||||
public class ReloadingJVMCommandProcess {
|
||||
public static void main(String[] argv) throws IOException {
|
||||
System.err.println("(jvm) started");
|
||||
System.err.println("ReloadingJVM:started");System.err.flush();
|
||||
try {
|
||||
DataInputStream br = new DataInputStream((System.in));
|
||||
do {
|
||||
@@ -52,6 +52,7 @@ public class ReloadingJVMCommandProcess {
|
||||
// String[] args = (arguments.size() > 0 ? arguments.toArray(new String[arguments.size()]) : null);
|
||||
if (commandName.equals("exit")) {
|
||||
System.err.println("ReloadingJVM:terminating!!");
|
||||
System.exit(0);
|
||||
return;
|
||||
} else if (commandName.equals("echo")) {
|
||||
echoCommand(arguments);
|
||||
@@ -133,6 +134,7 @@ public class ReloadingJVMCommandProcess {
|
||||
Class<?> clazz = o.getClass();
|
||||
Method m = clazz.getDeclaredMethod(methodName);
|
||||
m.invoke(o);
|
||||
System.err.println("!!");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(System.out);
|
||||
}
|
||||
@@ -148,6 +150,7 @@ public class ReloadingJVMCommandProcess {
|
||||
if (!b) {
|
||||
throw new IllegalStateException("Failed to reload new verion of "+classname);
|
||||
}
|
||||
System.err.println("!!");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(System.out);
|
||||
}
|
||||
@@ -167,9 +170,9 @@ public class ReloadingJVMCommandProcess {
|
||||
System.err.println("(jvm) creating new instance '" + instanceName + "' of type '" + classname + "'");
|
||||
Class<?> clazz = Class.forName(classname);
|
||||
instances.put(instanceName, clazz.newInstance());
|
||||
System.err.println("(jvm) instance successfully created");
|
||||
System.err.println("(jvm) instance successfully created!!");
|
||||
} catch (Exception e) {
|
||||
System.out.println("(jvm) failed to create instance " + e.getMessage());
|
||||
System.out.println("(jvm) failed to create instance " + e.getMessage()+"!!");
|
||||
e.printStackTrace(System.out);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,6 +95,8 @@ public abstract class SpringLoadedTests implements Constants {
|
||||
protected String GroovyTestDataPath = TestUtils.getPathToClasses("../testdata-groovy");
|
||||
protected String AspectjrtJar = "../testdata/aspectjrt.jar";
|
||||
protected String CodeJar = "../testdata/code.jar";
|
||||
// TODO [java8] replace this with project dependency when Java8 is out
|
||||
protected String Java8CodeJar = "../testdata-java8/build/libs/testdata-java8.jar";
|
||||
protected String GroovyrtJar = "../testdata-groovy/groovy-1.8.2.jar";
|
||||
protected Result result;
|
||||
protected TypeRegistry registry;
|
||||
@@ -103,7 +105,7 @@ public abstract class SpringLoadedTests implements Constants {
|
||||
public void setup() throws Exception {
|
||||
SpringLoadedPreProcessor.disabled = true;
|
||||
NameRegistry.reset();
|
||||
binLoader = new TestClassLoader(toURLs(TestDataPath, AspectjrtJar,CodeJar), this.getClass().getClassLoader());
|
||||
binLoader = new TestClassLoader(toURLs(TestDataPath, AspectjrtJar, CodeJar, Java8CodeJar), this.getClass().getClassLoader());
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
@@ -80,6 +80,36 @@ public class SpringLoadedTestsInSeparateJVM extends SpringLoadedTests {
|
||||
assertStdout("jvmtwo.Runner.run1() running", jvm.call("a", "run1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reloadedPerformance() throws Exception {
|
||||
// debug();
|
||||
jvm.newInstance("a","remote.Perf1");
|
||||
JVMOutput jo = jvm.call("a","time"); // 75ms
|
||||
jo = jvm.call("a","time"); // 75ms
|
||||
pause(5);
|
||||
jvm.updateClass("remote.Perf1",retrieveRename("remote.Perf1","remote.Perf2"));
|
||||
pause(2);
|
||||
// In Perf2 the static method is gone, why does it give us a NSME?
|
||||
jo = jvm.call("a","time"); // 150ms
|
||||
System.out.println(jo);
|
||||
}
|
||||
|
||||
private final static void debug() {
|
||||
jvm.shutdown();
|
||||
jvm = ReloadingJVM.launch("",true);
|
||||
}
|
||||
|
||||
private final static void debug(String options) {
|
||||
jvm = ReloadingJVM.launch(options,true);
|
||||
}
|
||||
|
||||
private final static void pause(int seconds) {
|
||||
try {
|
||||
Thread.sleep(seconds*1000);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testReloadingInOtherVM() throws Exception {
|
||||
jvm.newInstance("a", "remote.One");
|
||||
|
||||
55
testdata/src/main/java/remote/Perf1.java
vendored
Normal file
55
testdata/src/main/java/remote/Perf1.java
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
package remote;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class Perf1 {
|
||||
|
||||
int repeats = 100;
|
||||
|
||||
public static void main(String[] args) {
|
||||
time();
|
||||
}
|
||||
|
||||
public static void time() {
|
||||
timedrun();
|
||||
timedrun();
|
||||
timedrun();
|
||||
}
|
||||
|
||||
private static void timedrun() {
|
||||
long stime = System.currentTimeMillis();
|
||||
System.out.println(computepi(10000000));
|
||||
long etime = System.currentTimeMillis();
|
||||
System.out.println("took "+(etime-stime)+"ms");
|
||||
}
|
||||
|
||||
public static double computepi(int iterations) {
|
||||
Random randomGen = new Random(System.currentTimeMillis());
|
||||
int insideCount = 0;
|
||||
for (int i = 1; i <= iterations; i++) {
|
||||
insideCount += doOneIteration(randomGen);
|
||||
}
|
||||
return calc(iterations, insideCount);
|
||||
}
|
||||
|
||||
private static int doOneIteration(Random randomGen) {
|
||||
double xPos = getRandom(randomGen);
|
||||
double yPos = getRandom(randomGen);
|
||||
return isInside( xPos, yPos);
|
||||
}
|
||||
|
||||
private static int isInside( double xPos, double yPos) {
|
||||
double distance = Math.sqrt((xPos * xPos) + (yPos * yPos));
|
||||
if (distance<1.0) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
private static double getRandom(Random randomGen) {
|
||||
return (randomGen.nextDouble()) * 2 - 1.0;
|
||||
}
|
||||
|
||||
private static double calc(int iterations, int insideCount) {
|
||||
return 4.0 * (insideCount / (double)iterations);
|
||||
}
|
||||
|
||||
}
|
||||
49
testdata/src/main/java/remote/Perf2.java
vendored
Normal file
49
testdata/src/main/java/remote/Perf2.java
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
package remote;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class Perf2 {
|
||||
|
||||
int repeats = 100;
|
||||
|
||||
public static void main(String[] args) {
|
||||
time();
|
||||
}
|
||||
|
||||
public static void time() {
|
||||
long stime = System.currentTimeMillis();
|
||||
System.out.println(computepi(1000000));
|
||||
long etime = System.currentTimeMillis();
|
||||
System.out.println("took "+(etime-stime)+"ms");
|
||||
}
|
||||
|
||||
public static double computepi(int iterations) {
|
||||
Random randomGen = new Random(System.currentTimeMillis());
|
||||
int insideCount = 0;
|
||||
for (int i = 1; i <= iterations; i++) {
|
||||
insideCount += doOneIteration(randomGen);
|
||||
}
|
||||
return calc(iterations, insideCount);
|
||||
}
|
||||
|
||||
private static int doOneIteration(Random randomGen) {
|
||||
double xPos = getRandom(randomGen);
|
||||
double yPos = getRandom(randomGen);
|
||||
return isInside( xPos, yPos);
|
||||
}
|
||||
|
||||
private static int isInside( double xPos, double yPos) {
|
||||
double distance = Math.sqrt((xPos * xPos) + (yPos * yPos));
|
||||
if (distance<1.0) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
private static double getRandom(Random randomGen) {
|
||||
return (randomGen.nextDouble()) * 2 - 1.0;
|
||||
}
|
||||
|
||||
private static double calc(int iterations, int insideCount) {
|
||||
return 4.0 * (insideCount / (double)iterations);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user