1 package org.melati.poem.test;
2
3 import junit.framework.*;
4 import org.melati.poem.*;
5
6 import java.io.*;
7 import java.lang.reflect.Method;
8 import java.lang.reflect.Modifier;
9 import java.sql.Connection;
10 import java.sql.Statement;
11 import java.util.Enumeration;
12 import java.util.Properties;
13
14
15
16
17
18
19
20 public class PoemTestCase extends TestCase implements Test {
21
22 protected static TestResult result;
23 private static String propertiesFileName = "org.melati.poem.test.PoemTestCase.properties";
24 protected int maxTrans = 0;
25 boolean problem = false;
26 String dbUrl = null;
27
28
29
30 private String fName;
31
32 private String databaseName = "melatijunit";
33 private AccessToken userToRunAs;
34
35
36
37 public PoemTestCase() {
38 super();
39 fName = null;
40 }
41
42 public PoemTestCase(String name) {
43 super(name);
44 fName = name;
45 }
46
47 static public void assertEquals(String message, int expected, int actual) {
48 try {
49 Assert.assertEquals(message, expected, actual);
50 } catch (Error e) {
51 result.stop();
52 throw e;
53 }
54 }
55
56
57
58
59
60
61
62
63
64 public static String getOrDie(Properties properties, String propertyName) {
65 String value = properties.getProperty(propertyName);
66 if (value == null)
67 throw new RuntimeException("Property " + propertyName + " not found in " + properties);
68 return value;
69 }
70
71
72
73
74
75
76
77
78
79
80
81
82 public static void assertEquals(String message,
83 File expected,
84 File actual) {
85 Assert.assertNotNull(expected);
86 Assert.assertNotNull(actual);
87
88 Assert.assertTrue("File does not exist [" + expected.getAbsolutePath() + "]", expected.exists());
89 Assert.assertTrue("File does not exist [" + actual.getAbsolutePath() + "]", actual.exists());
90
91 Assert.assertTrue("Expected file not readable", expected.canRead());
92 Assert.assertTrue("Actual file not readable", actual.canRead());
93
94 FileInputStream eis = null;
95 FileInputStream ais = null;
96
97 try {
98 try {
99 eis = new FileInputStream(expected);
100 ais = new FileInputStream(actual);
101
102 BufferedReader expData = new BufferedReader(new InputStreamReader(eis));
103 BufferedReader actData = new BufferedReader(new InputStreamReader(ais));
104
105 Assert.assertNotNull(message, expData);
106 Assert.assertNotNull(message, actData);
107
108 assertEquals(message, expData, actData);
109 } finally {
110 if (eis != null) eis.close();
111 if (ais != null) ais.close();
112 }
113 } catch (IOException e) {
114 throw new AssertionFailedError(e.toString());
115 }
116 }
117
118
119
120
121
122 public static void assertEquals(File expected,
123 File actual) {
124 assertEquals(null, expected, actual);
125 }
126
127 protected void setUp() throws Exception {
128 super.setUp();
129 problem = false;
130 int freeTrans = getDb().getFreeTransactionsCount();
131 assertEquals("Not all transactions free", maxTrans, freeTrans);
132 }
133
134 protected void tearDown() throws Exception {
135 if (!problem) {
136 checkDbUnchanged();
137 assertEquals("Not all transactions free", maxTrans, getDb().getFreeTransactionsCount());
138 }
139 }
140
141
142
143
144 public void run(TestResult resultIn) {
145 PoemTestCase.result = resultIn;
146 super.run(resultIn);
147 }
148
149
150
151
152
153
154 protected void runTest() throws Throwable {
155 assertNotNull(fName);
156 try {
157
158
159
160
161 final Method runMethod = getClass().getMethod(fName, (Class[])null);
162 if (!Modifier.isPublic(runMethod.getModifiers())) {
163 fail("Method \"" + fName + "\" should be public");
164 }
165
166
167 final Object _this = this;
168 getDb().inSession(getUserToRunAs(),
169 new PoemTask() {
170 public void run() {
171 try {
172 runMethod.invoke(_this, new Object[0]);
173 } catch (Throwable e) {
174 problem = true;
175 if (e.getCause() instanceof ComparisonFailure) {
176 throw (ComparisonFailure) e.getCause();
177 } else {
178 throw new RuntimeException(e);
179 }
180 }
181 }
182
183 public String toString() {
184 return "PoemTestCase:"+ fName;
185 }
186 });
187 } catch (NoSuchMethodException e) {
188 fail("Method \"" + fName + "\" not found");
189 }
190 }
191
192 protected void checkDbUnchanged() {
193 getDb().inSession(AccessToken.root,
194 new PoemTask() {
195 public void run() {
196 databaseUnchanged();
197 }
198 });
199
200 }
201
202 protected void databaseUnchanged() {
203
204 assertEquals("Group changed", 1, getDb().getGroupTable().count());
205 assertEquals("GroupMembership changed", 1, getDb().getGroupMembershipTable().count());
206 assertEquals("Capability changed", 5, getDb().getCapabilityTable().count());
207 assertEquals("GroupCapability changed", 1, getDb().getGroupCapabilityTable().count());
208 assertEquals("TableCategory changed", 3, getDb().getTableCategoryTable().count());
209 assertEquals("User changed", 2, getDb().getUserTable().count());
210 ColumnInfo newOne = null;
211 try{
212 newOne = (ColumnInfo)getDb().getColumnInfoTable().getObject(69);
213 } catch (Exception e) {
214 }
215 if (newOne != null) {
216 String errStr = "Extra column in " + getDb() + " " + newOne.getName() + " " + newOne.getTableinfo().getName();
217 newOne.delete();
218 fail(errStr);
219 } else {
220 if (getDb().getDbms().canDropColumns()) {
221 assertEquals("ColumnInfo changed", 69, getDb().getColumnInfoTable().count());
222 assertEquals("TableInfo changed", 9, getDb().getTableInfoTable().count());
223 checkTablesAndColumns(9,69);
224 }
225 }
226 }
227
228 protected void dropTable(String tableName) {
229 Connection c = getDb().getCommittedConnection();
230 Table<?> table = null;
231 try {
232 table = getDb().getTable(tableName);
233 Statement s = c.createStatement();
234 if (table != null && table.getTableInfo().statusExistent()) {
235 s.executeUpdate("DROP TABLE " + getDb().getDbms().getQuotedName(tableName));
236 }
237 s.close();
238 c.commit();
239 } catch (NoSuchTablePoemException e) {
240 e = null;
241 } catch (Exception e) {
242 e.printStackTrace();
243 fail("Something bombed");
244 }
245
246 }
247
248 protected void checkTablesAndColumns(int tableCount, int columnCount) {
249 checkTables(tableCount);
250 checkColumns(columnCount);
251 }
252
253 protected void checkTables(int tableCount) {
254 Enumeration<Table<?>> e = getDb().tables();
255 int count = 0;
256 while (e.hasMoreElements()) {
257 Table<?> t = e.nextElement();
258 if (t.getTableInfo().statusExistent()) count++;
259 }
260 if (count != tableCount) {
261 System.out.println(fName + " Additional tables - expected:" +
262 tableCount + " found:" + count);
263 e = getDb().tables();
264 while (e.hasMoreElements()) {
265 Table<?> t = e.nextElement();
266 System.out.println(t.getTableInfo().getTroid() + " " +
267 t.getTableInfo().statusExistent() + " " +
268 t);
269 }
270 }
271 assertEquals(tableCount, count);
272 }
273
274 protected void checkColumns(int columnCount) {
275 Enumeration<Column<?>> e = getDb().columns();
276 int count = 0;
277 while (e.hasMoreElements()) {
278 Column<?> c = e.nextElement();
279 if (c.getColumnInfo().statusExistent())
280 count++;
281 }
282 if (count != columnCount) {
283 System.out.println(fName + " Additional columns - expected:" +
284 columnCount + " found:" + count);
285 e = getDb().columns();
286 while (e.hasMoreElements()) {
287 System.out.println(e.nextElement());
288 }
289 }
290 assertEquals(columnCount, count);
291 }
292
293 protected <P extends Persistent> void dumpTable(Table<P> t) {
294 Enumeration<P> them = t.selection();
295 while (them.hasMoreElements()) {
296 P it = them.nextElement();
297 System.err.println(it.getTroid() + " " + it.getCooked("name") + " " +
298 it.getTable().getName());
299 }
300
301 }
302
303
304
305
306
307
308 public String getName() {
309 return fName;
310 }
311
312
313
314
315
316
317
318 public void setName(String name) {
319 fName = name;
320 }
321
322
323
324
325 public Database getDb() {
326 return getDb(getDatabaseName());
327 }
328
329
330
331
332
333 public Database getDb(String dbNameP) {
334 if (dbNameP == null)
335 throw new NullPointerException();
336 return getDatabase(dbNameP);
337 }
338
339
340
341
342
343 public Database getDatabase(String name){
344 Properties defs = getProperties();
345 String pref = "org.melati.poem.test.PoemTestCase." + name + ".";
346 maxTrans = new Integer(getOrDie(defs, pref + "maxtransactions")).intValue();
347 String url = getOrDie(defs, pref + "url");
348 return PoemDatabaseFactory.getDatabase(name,
349 url,
350 getOrDie(defs, pref + "user"),
351 getOrDie(defs, pref + "password"),
352 getOrDie(defs, pref + "class"),
353 getOrDie(defs, pref + "dbmsclass"),
354 new Boolean(getOrDie(defs, pref + "addconstraints")).booleanValue(),
355 new Boolean(getOrDie(defs, pref + "logsql")).booleanValue(),
356 new Boolean(getOrDie(defs, pref + "logcommits")).booleanValue(),
357 maxTrans);
358 }
359
360
361
362
363 public AccessToken getUserToRunAs() {
364 if (userToRunAs == null) return AccessToken.root;
365 return userToRunAs;
366 }
367
368
369
370
371 public void setUserToRunAs(AccessToken userToRunAs) {
372 if (userToRunAs == null)
373 this.userToRunAs = AccessToken.root;
374 else
375 this.userToRunAs = userToRunAs;
376 }
377
378
379
380
381 public Properties getProperties() {
382 InputStream is = PoemTestCase.class.getResourceAsStream(getPropertiesFileName());
383
384 if (is == null)
385 throw new RuntimeException(
386 new FileNotFoundException(getPropertiesFileName() + ": is it in CLASSPATH?"));
387
388 Properties them = new Properties();
389 try {
390 them.load(is);
391 is.close();
392 } catch (IOException e) {
393 throw new RuntimeException(
394 new IOException("Corrupt properties file `" + getPropertiesFileName() + "': " +
395 e.getMessage()));
396 }
397 return them;
398 }
399
400
401
402
403 public String getPropertiesFileName() {
404 return propertiesFileName;
405 }
406
407
408
409
410 public void setPropertiesFileName(String propertiesFileNameIn) {
411 PoemTestCase.propertiesFileName = propertiesFileNameIn;
412 }
413
414
415
416
417 public String getDatabaseName() {
418 return databaseName;
419 }
420
421
422
423
424 public void setDatabaseName(String databaseName) {
425 this.databaseName = databaseName;
426 }
427
428
429
430
431 public void testNothing() {
432
433 }
434 }