mirror of
https://github.com/eclipse-aspectj/aspectj.git
synced 2024-07-23 05:19:41 +02:00
596 lines
17 KiB
Java
596 lines
17 KiB
Java
/* *******************************************************************
|
|
* Copyright (c) 2004 IBM Corporation
|
|
* All rights reserved.
|
|
* This program and the accompanying materials are made available
|
|
* under the terms of the Common Public License v1.0
|
|
* which accompanies this distribution and is available at
|
|
* http://www.eclipse.org/legal/cpl-v10.html
|
|
*
|
|
* Contributors:
|
|
* Noel Markham, Matthew Webster initial implementation
|
|
* ******************************************************************/
|
|
|
|
import java.io.BufferedOutputStream;
|
|
import java.io.File;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
|
|
/**
|
|
* @author Noel Markham
|
|
*/
|
|
public class WeaveTests {
|
|
|
|
private static final String OUTPUT_PACKAGE = "out";
|
|
|
|
private static final int WEAVE_FAST = 1;
|
|
private static final int WEAVE_MED = 2;
|
|
private static final int WEAVE_SLOW = 3;
|
|
|
|
public static final String EXECUTION_SLOW = "execution(void *(..))";
|
|
public static final String EXECUTION_MED = "args(" + OUTPUT_PACKAGE + ".C0) && execution(void m0(..))";
|
|
public static final String EXECUTION_FAST = "within(" + OUTPUT_PACKAGE + ".C0) && execution(void m0(..))";
|
|
|
|
public static final String GET_SLOW = "get(int *)";
|
|
public static final String GET_MED = "target(" + OUTPUT_PACKAGE + ".C0) && get(int i0)";
|
|
public static final String GET_FAST = "get(int " + OUTPUT_PACKAGE + ".C0.i0)";
|
|
|
|
// Defaults, can be changed with command-line args
|
|
private static int NUMCLASSES = 5;
|
|
private static int ITERATIONS = 3;
|
|
private static int METHODLINES = 20;
|
|
private static int NUMMETHODS = 100;
|
|
private static boolean INCLUDE_TEST_CLASSES = false;
|
|
private static boolean TEST_GET = true;
|
|
private static boolean TEST_EXECUTION = true;
|
|
|
|
private static boolean ALL_POINTCUT_TESTS = true;
|
|
private static boolean TEST_ONE = false;
|
|
private static boolean TEST_ONE_SEARCH_ALL = false;
|
|
private static boolean TEST_ALL = false;
|
|
private static boolean ECHO = false;
|
|
|
|
public static long[] compileTimes = new long[ITERATIONS];
|
|
public static long[] executionSlowTimes = new long[ITERATIONS];
|
|
public static long[] executionMedTimes = new long[ITERATIONS];
|
|
public static long[] executionFastTimes = new long[ITERATIONS];
|
|
public static long[] getSlowTimes = new long[ITERATIONS];
|
|
public static long[] getMedTimes = new long[ITERATIONS];
|
|
public static long[] getFastTimes = new long[ITERATIONS];
|
|
|
|
private static final String NL = System.getProperty("line.separator", "\n");
|
|
|
|
private static final File outputDir = new File(System.getProperty("user.dir") + File.separatorChar + OUTPUT_PACKAGE);
|
|
|
|
static {
|
|
outputDir.mkdirs();
|
|
}
|
|
|
|
public static void main(String[] args) throws IOException {
|
|
|
|
//if (args.length > 0) parseArgs(args);
|
|
parseArgs(args);
|
|
|
|
if(ECHO) System.out.println("Weave-time Test");
|
|
if(ECHO) System.out.println("---------------");
|
|
|
|
if(ECHO) System.out.println("Number of classes: " + NUMCLASSES);
|
|
if(ECHO) System.out.println("Number of methods: " + NUMMETHODS);
|
|
if(ECHO) System.out.println("Number of method lines: " + METHODLINES);
|
|
if(ECHO) System.out.println("Number of test iterations: " + ITERATIONS);
|
|
if(ECHO)
|
|
if(INCLUDE_TEST_CLASSES) System.out.println("Including advice test classes");
|
|
if(ECHO)
|
|
if(TEST_GET && !TEST_EXECUTION) System.out.println("Weaving only get advice");
|
|
if(ECHO)
|
|
if(TEST_EXECUTION && !TEST_GET) System.out.println("Weaving only execution advice");
|
|
if(ECHO) {
|
|
if(!ALL_POINTCUT_TESTS) {
|
|
if(TEST_ONE) System.out.println("Weaving one poinctcut");
|
|
if(TEST_ONE_SEARCH_ALL) System.out.println("Weaving one pointcut, searching all");
|
|
if(TEST_ALL) System.out.println("Weaving all");
|
|
}
|
|
}
|
|
|
|
if(ECHO) System.out.println();
|
|
|
|
createClasses();
|
|
compileClasses();
|
|
|
|
boolean warm = false;
|
|
|
|
if (TEST_EXECUTION) {
|
|
String advice = "execution";
|
|
createAspects(advice);
|
|
|
|
//Warm up the weaver
|
|
weaveAllAspects(advice, WEAVE_FAST);
|
|
warm = true;
|
|
|
|
weaveAspects(advice);
|
|
}
|
|
|
|
if (TEST_GET) {
|
|
String advice = "get";
|
|
createAspects(advice);
|
|
|
|
if(!warm) weaveAllAspects(advice, WEAVE_FAST);
|
|
weaveAspects(advice);
|
|
}
|
|
}
|
|
|
|
private static void parseArgs(String[] args) {
|
|
|
|
if(args == null || args.length <= 0) return;
|
|
|
|
int i = 0;
|
|
boolean error = false;
|
|
|
|
while(i < args.length) {
|
|
String arg = args[i++];
|
|
|
|
try {
|
|
if(arg.equals("-c")) { // Number of classes
|
|
if(i < args.length)
|
|
NUMCLASSES = Integer.parseInt(args[i++]);
|
|
else error = true;
|
|
}
|
|
else if(arg.equals("-m")) { // Number of methods
|
|
if(i < args.length)
|
|
NUMMETHODS = Integer.parseInt(args[i++]);
|
|
else error = true;
|
|
}
|
|
else if(arg.equals("-l")) { // Number of method lines
|
|
if(i < args.length)
|
|
METHODLINES = Integer.parseInt(args[i++]);
|
|
else error = true;
|
|
}
|
|
else if(arg.equals("-i")) { // Number of iterations
|
|
if(i < args.length)
|
|
ITERATIONS = Integer.parseInt(args[i++]);
|
|
else error = true;
|
|
}
|
|
else if(arg.equals("-include-tests")) {
|
|
if(i < args.length) {
|
|
arg = args[i++];
|
|
if(arg.equalsIgnoreCase("y")) INCLUDE_TEST_CLASSES = true;
|
|
else if(arg.equalsIgnoreCase("n")) INCLUDE_TEST_CLASSES = false;
|
|
else error = true;
|
|
}
|
|
}
|
|
else if(arg.equals("-advice")) {
|
|
String advice = args[i++];
|
|
if(advice.equals("get")){
|
|
TEST_GET = true;
|
|
TEST_EXECUTION = false;
|
|
}
|
|
else if(advice.equals("execution")){
|
|
TEST_EXECUTION = true;
|
|
TEST_GET = false;
|
|
}
|
|
else error = true;
|
|
}
|
|
else if(arg.equals("-pointcut")) {
|
|
ALL_POINTCUT_TESTS = false;
|
|
String advice = args[i++];
|
|
if(advice.equals("fast")) TEST_ONE = true;
|
|
else if(advice.equals("meduim")) TEST_ONE_SEARCH_ALL = true;
|
|
else if(advice.equals("slow")) TEST_ALL = true;
|
|
else error = true;
|
|
}
|
|
else if(arg.equals("-echo")) {
|
|
ECHO = true;
|
|
}
|
|
else if (arg.equals("-help")) {
|
|
usage();
|
|
}
|
|
else error = true;
|
|
} catch (NumberFormatException e) {
|
|
usage();
|
|
}
|
|
|
|
if(error) usage();
|
|
|
|
compileTimes = new long[ITERATIONS];
|
|
executionSlowTimes = new long[ITERATIONS];
|
|
executionMedTimes = new long[ITERATIONS];
|
|
executionFastTimes = new long[ITERATIONS];
|
|
getSlowTimes = new long[ITERATIONS];
|
|
getMedTimes = new long[ITERATIONS];
|
|
getFastTimes = new long[ITERATIONS];
|
|
|
|
}
|
|
}
|
|
|
|
private static void usage() {
|
|
System.err.println("Usage:");
|
|
System.err.println("\tjava WeaveTests [-c num_of_classes] [-m num_of_methods] " +
|
|
"[-l num_of_method_lines] [-i num_of_iterations]" +
|
|
"\n\t\t[-include-tests y|n] [-advice get|execution] [-pointcut fast|medium|slow] [-echo] [-help]");
|
|
|
|
System.exit(-1);
|
|
}
|
|
|
|
/**
|
|
* Will create a number of classes of the following form:
|
|
*
|
|
* public class C0 {
|
|
*
|
|
* int i0;
|
|
* ...
|
|
* int iN;
|
|
*
|
|
* void m0(C0 arg) {
|
|
* i0++;
|
|
* ...
|
|
* iN++;
|
|
* }
|
|
* ...
|
|
* void mN(C0 arg) {
|
|
* ...
|
|
* }
|
|
*
|
|
*/
|
|
public static void createClasses() throws IOException {
|
|
|
|
if(ECHO) System.out.println("Creating classes");
|
|
|
|
for(int classcounter = 0; classcounter < NUMCLASSES; classcounter++) {
|
|
|
|
StringBuffer classfile = new StringBuffer(1000);
|
|
|
|
classfile.append("// Auto-generated" + NL);
|
|
classfile.append("package " + OUTPUT_PACKAGE + ";" + NL + NL);
|
|
|
|
classfile.append("public class C" + classcounter + " {" + NL + NL);
|
|
|
|
for(int intdeclaration = 0; intdeclaration < METHODLINES; intdeclaration++) {
|
|
classfile.append("\tint i" + intdeclaration + ";" + NL);
|
|
}
|
|
classfile.append("\tint getter;" + NL);
|
|
|
|
classfile.append(NL);
|
|
|
|
for(int methodcounter = 0; methodcounter < NUMMETHODS; methodcounter++) {
|
|
classfile.append("\tvoid m" + methodcounter + "(C" + classcounter + " arg) {" + NL);
|
|
|
|
for(int methodbody = 0; methodbody < METHODLINES; methodbody++) {
|
|
classfile.append("\t\ti" + methodbody + "++;" + NL);
|
|
}
|
|
|
|
classfile.append("\t}" + NL + NL);
|
|
}
|
|
|
|
classfile.append("}" + NL);
|
|
|
|
try {
|
|
|
|
File f = new File(outputDir, ("C" + classcounter + ".java"));
|
|
FileOutputStream fos = new FileOutputStream(f);
|
|
BufferedOutputStream bos = new BufferedOutputStream(fos);
|
|
|
|
bos.write(new String(classfile).getBytes());
|
|
|
|
bos.close();
|
|
fos.close();
|
|
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
System.exit(-1);
|
|
}
|
|
}
|
|
|
|
if (INCLUDE_TEST_CLASSES) {
|
|
StringBuffer testFiles = new StringBuffer(1000);
|
|
|
|
try {
|
|
testFiles.append("// Auto generated" + NL);
|
|
testFiles.append("package " + OUTPUT_PACKAGE + ";" + NL + NL);
|
|
|
|
testFiles.append("public class TestGet {" + NL + NL);
|
|
testFiles.append(
|
|
"\tpublic static void main(String args[]) {" + NL);
|
|
testFiles.append("\t\tC0 tester = new C0();" + NL);
|
|
testFiles.append("\t\tint i = tester.i0;" + NL);
|
|
testFiles.append("\t}" + NL);
|
|
testFiles.append("}" + NL);
|
|
|
|
File f = new File(outputDir, "TestGet.java");
|
|
FileOutputStream fos = new FileOutputStream(f);
|
|
BufferedOutputStream bos = new BufferedOutputStream(fos);
|
|
|
|
bos.write(new String(testFiles).getBytes());
|
|
bos.close();
|
|
fos.close();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
System.exit(-1);
|
|
}
|
|
|
|
testFiles = new StringBuffer(1000);
|
|
|
|
try {
|
|
testFiles.append("// Auto generated" + NL);
|
|
testFiles.append("package " + OUTPUT_PACKAGE + ";" + NL + NL);
|
|
|
|
testFiles.append("public class TestExecution {" + NL + NL);
|
|
testFiles.append(
|
|
"\tpublic static void main(String args[]) {" + NL);
|
|
testFiles.append("\t\tC0 tester = new C0();" + NL);
|
|
testFiles.append("\t\ttester.m0(tester);" + NL);
|
|
testFiles.append("\t}" + NL);
|
|
testFiles.append("}" + NL);
|
|
|
|
File f = new File(outputDir, "TestExecution.java");
|
|
FileOutputStream fos = new FileOutputStream(f);
|
|
BufferedOutputStream bos = new BufferedOutputStream(fos);
|
|
|
|
bos.write(new String(testFiles).getBytes());
|
|
bos.close();
|
|
fos.close();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
System.exit(-1);
|
|
}
|
|
}
|
|
|
|
StringBuffer buildList = new StringBuffer(100);
|
|
|
|
for(int i = 0; i < NUMCLASSES; i++)
|
|
buildList.append("C" + i + ".java" + NL);
|
|
|
|
if (INCLUDE_TEST_CLASSES) {
|
|
buildList.append("TestGet.java" + NL);
|
|
buildList.append("TestExecution.java" + NL);
|
|
}
|
|
|
|
try {
|
|
File f = new File(outputDir, "build.lst");
|
|
FileOutputStream fos = new FileOutputStream(f);
|
|
BufferedOutputStream bos = new BufferedOutputStream(fos);
|
|
|
|
bos.write(new String(buildList).getBytes());
|
|
|
|
bos.close();
|
|
fos.close();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
System.exit(-1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param adviceType Either "get" or "execution" depending on which test.
|
|
*
|
|
* Will create an aspect such as the following:
|
|
*
|
|
* public aspect GetAdviceWeaveOne {
|
|
*
|
|
* before() : get(int output.C0.getter) {
|
|
* System.out.println("In the aspect");
|
|
* }
|
|
* }
|
|
*/
|
|
public static void createAspects(String adviceType) {
|
|
|
|
adviceType = adviceType.toLowerCase();
|
|
|
|
if((!adviceType.equals("get")) && (!adviceType.equals("execution"))) {
|
|
System.err.println("Only get and execution advice is supported");
|
|
System.exit(-1);
|
|
}
|
|
|
|
if(ECHO) System.out.println("Creating aspects");
|
|
|
|
if(ALL_POINTCUT_TESTS || TEST_ONE)
|
|
createAllAspects(adviceType, WEAVE_FAST);
|
|
if(ALL_POINTCUT_TESTS || TEST_ONE_SEARCH_ALL)
|
|
createAllAspects(adviceType, WEAVE_MED);
|
|
if(ALL_POINTCUT_TESTS || TEST_ALL)
|
|
createAllAspects(adviceType, WEAVE_SLOW);
|
|
}
|
|
|
|
private static void createAllAspects(String adviceType, int pointcut) {
|
|
|
|
StringBuffer aspectFile = new StringBuffer(1000);
|
|
|
|
// Capitalises the first char in the adviceType String, and then adds "Advice" to it.
|
|
String adviceName = (char)(adviceType.charAt(0) - 32) + adviceType.substring(1) + "Advice";
|
|
|
|
switch(pointcut) {
|
|
case WEAVE_FAST:
|
|
adviceName += "WeaveFast";
|
|
break;
|
|
case WEAVE_MED:
|
|
adviceName += "WeaveMedium";
|
|
break;
|
|
case WEAVE_SLOW:
|
|
adviceName += "WeaveSlow";
|
|
break;
|
|
}
|
|
|
|
aspectFile.append("// Auto-generated" + NL + NL);
|
|
|
|
aspectFile.append("public aspect " + adviceName + " {" + NL + NL);
|
|
aspectFile.append("\tbefore() : ");
|
|
|
|
if(adviceType.equals("execution")) {
|
|
switch(pointcut) {
|
|
case WEAVE_FAST:
|
|
aspectFile.append(EXECUTION_FAST);
|
|
break;
|
|
case WEAVE_MED:
|
|
aspectFile.append(EXECUTION_MED);
|
|
break;
|
|
case WEAVE_SLOW:
|
|
aspectFile.append(EXECUTION_SLOW);
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
switch(pointcut) {
|
|
case WEAVE_FAST:
|
|
aspectFile.append(GET_FAST);
|
|
break;
|
|
case WEAVE_MED:
|
|
aspectFile.append(GET_MED);
|
|
break;
|
|
case WEAVE_SLOW:
|
|
aspectFile.append(GET_SLOW);
|
|
break;
|
|
}
|
|
}
|
|
|
|
aspectFile.append(" {" + NL);
|
|
|
|
aspectFile.append("\t\tSystem.out.println(\"In the aspect\");" + NL);
|
|
aspectFile.append("\t}" + NL);
|
|
aspectFile.append("}" + NL);
|
|
|
|
// Create the file
|
|
try {
|
|
File f = new File(outputDir, (adviceName + ".aj"));
|
|
FileOutputStream fos = new FileOutputStream(f);
|
|
BufferedOutputStream bos = new BufferedOutputStream(fos);
|
|
|
|
bos.write(new String(aspectFile).getBytes());
|
|
|
|
bos.close();
|
|
fos.close();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
System.exit(-1);
|
|
}
|
|
}
|
|
|
|
public static void compileClasses() throws IOException {
|
|
|
|
if(ECHO) System.out.print("Compiling: ");
|
|
|
|
long average = 0;
|
|
|
|
for (int i = 0; i < ITERATIONS; i++) {
|
|
long time = performCompile();
|
|
compileTimes[i] = time;
|
|
average += time;
|
|
}
|
|
|
|
if(ECHO) System.out.println((average / ITERATIONS) + " millis");
|
|
}
|
|
|
|
private static long performCompile() throws IOException {
|
|
|
|
String ajcargs =
|
|
"-noExit -outjar " + OUTPUT_PACKAGE + File.separatorChar + "classes.jar " +
|
|
"-argfile " + OUTPUT_PACKAGE + File.separatorChar + "build.lst";
|
|
|
|
// split method creates a String array delimited on a space
|
|
String[] parsedArgs = RunWeaveTests.split(ajcargs);
|
|
|
|
|
|
long start = System.currentTimeMillis();
|
|
|
|
org.aspectj.tools.ajc.Main.main(parsedArgs);
|
|
|
|
long stop = System.currentTimeMillis();
|
|
|
|
return stop - start;
|
|
}
|
|
|
|
|
|
public static void weaveAspects(String adviceType) throws IOException {
|
|
|
|
adviceType = adviceType.toLowerCase();
|
|
|
|
if((!adviceType.equals("get")) && (!adviceType.equals("execution"))) {
|
|
System.err.println("Only get and execution advice is supported");
|
|
System.exit(-1);
|
|
}
|
|
|
|
long average = 0;
|
|
|
|
if(ECHO) System.out.println((char)(adviceType.charAt(0) - 32) + adviceType.substring(1));
|
|
|
|
if (ALL_POINTCUT_TESTS || TEST_ONE) {
|
|
if(ECHO) System.out.print("Weave Fast:");
|
|
for (int i = 0; i < ITERATIONS; i++) {
|
|
long time = weaveAllAspects(adviceType, WEAVE_FAST);
|
|
|
|
if(adviceType.equals("execution")) executionFastTimes[i] = time;
|
|
else getFastTimes[i] = time;
|
|
|
|
average += time;
|
|
if(ECHO) System.out.print(".");
|
|
}
|
|
if(ECHO) System.out.println(" " + (average / ITERATIONS) + " millis");
|
|
}
|
|
|
|
|
|
average = 0;
|
|
|
|
if (ALL_POINTCUT_TESTS || TEST_ONE_SEARCH_ALL) {
|
|
if(ECHO) System.out.print("Weave Medium:");
|
|
for (int i = 0; i < ITERATIONS; i++) {
|
|
long time = weaveAllAspects(adviceType, WEAVE_MED);
|
|
|
|
if(adviceType.equals("execution")) executionMedTimes[i] = time;
|
|
else getMedTimes[i] = time;
|
|
|
|
average += time;
|
|
if(ECHO) System.out.print(".");
|
|
}
|
|
if(ECHO) System.out.println(" " + (average / ITERATIONS) + " millis");
|
|
}
|
|
|
|
|
|
average = 0;
|
|
|
|
if (ALL_POINTCUT_TESTS || TEST_ALL) {
|
|
if(ECHO) System.out.print("Weave Slow:");
|
|
for (int i = 0; i < ITERATIONS; i++) {
|
|
long time = weaveAllAspects(adviceType, WEAVE_SLOW);
|
|
|
|
if(adviceType.equals("execution")) executionSlowTimes[i] = time;
|
|
else getSlowTimes[i] = time;
|
|
|
|
average += time;
|
|
if(ECHO) System.out.print(".");
|
|
}
|
|
if(ECHO) System.out.println(" " + (average / ITERATIONS) + " millis");
|
|
}
|
|
|
|
if(ECHO) System.out.println();
|
|
}
|
|
|
|
private static long weaveAllAspects(String adviceType, int pointcut) throws IOException {
|
|
|
|
// Capitalises the first char in the adviceType String, to keep to Java naming convention
|
|
String adviceName = (char)(adviceType.charAt(0) - 32) + adviceType.substring(1) + "Advice";
|
|
|
|
switch(pointcut) {
|
|
case WEAVE_FAST:
|
|
adviceName += "WeaveFast";
|
|
break;
|
|
case WEAVE_MED:
|
|
adviceName += "WeaveMedium";
|
|
break;
|
|
case WEAVE_SLOW:
|
|
adviceName += "WeaveSlow";
|
|
break;
|
|
}
|
|
|
|
String ajcargs =
|
|
"-noExit -injars " + OUTPUT_PACKAGE + File.separatorChar + "classes.jar " +
|
|
"-outjar " + OUTPUT_PACKAGE + File.separatorChar + adviceName + ".jar " +
|
|
OUTPUT_PACKAGE + File.separatorChar + adviceName + ".aj";
|
|
|
|
String[] parsedArgs = RunWeaveTests.split(ajcargs);
|
|
|
|
long start = System.currentTimeMillis();
|
|
|
|
org.aspectj.tools.ajc.Main.main(parsedArgs);
|
|
|
|
long stop = System.currentTimeMillis();
|
|
|
|
return stop - start;
|
|
}
|
|
} |