1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
/********************************************************************
* Copyright (c) 2006 Contributors. All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors: IBM Corporation - initial API and implementation
* Helen Hawkins - initial version
*******************************************************************/
package org.aspectj.systemtest.model;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.aspectj.asm.AsmManager;
import org.aspectj.asm.IElementHandleProvider;
import org.aspectj.asm.IModelFilter;
import org.aspectj.testing.XMLBasedAjcTestCase;
import org.aspectj.util.FileUtil;
/**
* This class provides an extension to the XMLBasedAjcTestCase to manage testing the model. It assumes the testdata is in
* ../tests/model/<testid> and that the expected model against which to do the comparison is in the file
* ../tests/model/expected/<testid>.txt. One test ensures that both the model and the relationship map are as expected for the given
* testdata.
*
* To write a testcase, create a testdata directory containing the data for the test run and a file containing the expected model
* (this can be generated by setting the regenerate flag to true). Add the required configuration to model.xml. Finally, create a
* testcase in either ModelTests or Model5Tests (depending on whether the testcase has a requirement on Java5) and call
* runModelTest(<title of test>,<testid>).
*/
public abstract class ModelTestCase extends XMLBasedAjcTestCase {
protected static boolean regenerate = false;
protected static boolean debugTest = false;
private final String expectedOutDir = "../tests/model/expected" + File.separator;
private String testid;
private String modelFilename;
private IElementHandleProvider handleProvider;
/*
* (non-Javadoc)
*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
// using the JDTLikeHandleProvider because this produces consistent handles
// over different compiles
// We are about to create a sandbox for the model output file, don't let the
// following compile wipe it.
ajc.setShouldEmptySandbox(false);
// report all information - model, relationships delta processing
modelFilename = ajc.getSandboxDirectory().getAbsolutePath() + File.separator + "model.txt";
AsmManager.setReporting(modelFilename, true, true, true, false,
new TestFilter(ajc.getSandboxDirectory().getCanonicalPath()));
}
static class TestFilter implements IModelFilter {
String sandboxDirectory;
public TestFilter(String sandboxDirectory) {
this.sandboxDirectory = sandboxDirectory;
}
public String processFilelocation(String loc) {
if (loc.toLowerCase().startsWith(sandboxDirectory.toLowerCase())) {
String sub = loc.substring(sandboxDirectory.length());
int forwardSlash = sub.indexOf("/");
// replace all "/" with "\" - to ensure platform independence
if (forwardSlash != -1) {
sub = sub.replace('/', '\\');
}
// don't report the column number since this is sometimes
// different on windows and linux
int column = sub.lastIndexOf(':');
if (column != -1) {
return "TEST_SANDBOX" + sub.substring(0, column);
}
return "TEST_SANDBOX" + sub;
}
return loc;
}
public boolean wantsHandleIds() {
return false;
}
}
/*
* (non-Javadoc)
*
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
super.tearDown();
AsmManager.setDontReport();
ajc.setShouldEmptySandbox(true);
}
/**
* Firstly sets the testid which is both the name of the expected output file and the name of the testdata directory. It then
* invokes XMLBasedAjcTestCase.runTest(String) with the given title and finally verifies that the model file created from this
* test run is the same as the expected output (includes model information, the relationship map and various properties about
* the model) contained in ../tests/model/expected/<testid>.txt
*/
protected void runModelTest(String title, String testid) {
this.testid = testid;
runTest(title);
verifyModel();
}
private void verifyModel() {
File expectedOutput = new File(expectedOutDir + testid + ".txt");
if (regenerate) {
// Create the file
saveModel(expectedOutput);
} else {
// Verify the file matches what we have
compareModel(expectedOutput);
}
}
private void compareModel(File expectedF) {
if (debugTest)
System.out.println("comparing with model in file " + expectedF.getAbsolutePath());
List<String> fileContents = new ArrayList<>();
try {
// String sandboxDir = ajc.getSandboxDirectory().getAbsolutePath();
String modelOutput = modelFilename;
// Load the file with the expected output
BufferedReader expect = new BufferedReader(new FileReader(expectedF));
// String tempDir = expect.readLine();
String expectedLine = null;
while ((expectedLine = expect.readLine()) != null) {
fileContents.add(expectedLine);
}
List<String> expectedFileContents = new ArrayList<>();
expectedFileContents.addAll(fileContents);
// Load the file with the output from this test run
BufferedReader found = new BufferedReader(new FileReader(new File(modelOutput)));
String foundLine = null;
List<String> foundFileContents = new ArrayList<>();
while ((foundLine = found.readLine()) != null) {
// int i = foundLine.indexOf(sandboxDir);
// if (i == -1) {
// int j = foundLine.indexOf("(targets=");
// if (j == -1) {
foundFileContents.add(foundLine);
// } else {
// foundFileContents.add(foundLine.substring(j));
// }
// } else {
// String newLine = foundLine.substring(0,i) + tempDir
// + foundLine.substring(i + sandboxDir.length());
// foundFileContents.add(newLine);
// }
}
// iterate over what we found
for (String line : foundFileContents) {
if (debugTest)
System.err.println("looking at model entry: " + line);
if (!fileContents.contains(line)) {
// if (!((String)fileContents.get(lineNumber)).equals(line)) {
if (debugTest) {
System.err.println("couldn't find: " + line);
for (String element : fileContents) {
System.err.println("compared with: " + element);
}
}
// StringBuffer errorData = new StringBuffer();
// errorData.append("Problem with comparison at line number: "+)
fail("couldn't find model entry '" + line + "' in expected output");
} else {
fileContents.remove(line);
}
}
if (debugTest && !fileContents.isEmpty()) {
for (String element : fileContents) {
System.err.println("remaining: " + element);
}
}
assertTrue("should have found all expected model output: " + fileContents, fileContents.isEmpty());
} catch (Exception e) {
fail("Unexpected exception comparing model files:" + e);
}
}
private void saveModel(File f) {
if (debugTest)
System.out.println("Saving model into " + f.getAbsolutePath());
File modelFile = new File(modelFilename);
try {
FileUtil.copyFile(modelFile, f);
} catch (IOException ioe) {
ioe.printStackTrace();
fail("Couldn't copy file to " + f.toString());
}
}
}
|