View Javadoc
1   /*
2    *
3    * The DbUnit Database Testing Framework
4    * Copyright (C)2002-2004, DbUnit.org
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 2.1 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   *
20   */
21  
22  package org.dbunit.ant;
23  
24  import java.io.File;
25  import java.sql.SQLException;
26  import java.util.Hashtable;
27  import java.util.Iterator;
28  import java.util.List;
29  
30  import junit.framework.Test;
31  import junit.framework.TestSuite;
32  import junitx.framework.ArrayAssert;
33  
34  import org.apache.tools.ant.BuildException;
35  import org.apache.tools.ant.BuildFileTest;
36  import org.apache.tools.ant.Target;
37  import org.dbunit.DatabaseEnvironment;
38  import org.dbunit.DatabaseUnitException;
39  import org.dbunit.IDatabaseTester;
40  import org.dbunit.database.DatabaseConfig;
41  import org.dbunit.database.IDatabaseConnection;
42  import org.dbunit.dataset.FilteredDataSet;
43  import org.dbunit.dataset.IDataSet;
44  import org.dbunit.dataset.NoSuchTableException;
45  import org.dbunit.dataset.ITable;
46  import org.dbunit.dataset.datatype.IDataTypeFactory;
47  import org.dbunit.ext.mssql.InsertIdentityOperation;
48  import org.dbunit.ext.oracle.OracleDataTypeFactory;
49  import org.dbunit.operation.DatabaseOperation;
50  import org.dbunit.testutil.TestUtils;
51  import org.dbunit.util.FileHelper;
52  
53  /**
54   * Ant-based test class for the Dbunit ant task definition.
55   *
56   * @author Timothy Ruppert
57   * @author Ben Cox
58   * @author Last changed by: $Author$
59   * @version $Revision$ $Date$
60   * @since Jun 10, 2002
61   * @see org.dbunit.ant.AntTest
62   */
63  public class DbUnitTaskIT extends BuildFileTest
64  {
65      static protected Class classUnderTest = DbUnitTaskIT.class;
66  
67      private static final String BUILD_FILE_DIR = "xml";
68      private static final String OUTPUT_DIR = "target/xml";
69  
70      private File outputDir;
71  
72      public DbUnitTaskIT(String name)
73      {
74          super(name);
75      }
76  
77      @Override
78      public void setUp() throws Exception
79      {
80          // This line ensure test database is initialized
81          DatabaseEnvironment.getInstance();
82  
83          String filePath = BUILD_FILE_DIR + "/antTestBuildFile.xml";
84          assertTrue("Buildfile not found", TestUtils.getFile(filePath).isFile());
85          configureProject(TestUtils.getFileName(filePath));
86  
87          outputDir = new File(getProjectDir(), OUTPUT_DIR);
88          outputDir.mkdirs();
89      }
90  
91      @Override
92      protected void tearDown() throws Exception
93      {
94          super.tearDown();
95  
96          outputDir = new File(getProjectDir(), OUTPUT_DIR);
97          FileHelper.deleteDirectory(outputDir);
98      }
99  
100     public void testNoDriver()
101     {
102         expectBuildException("no-driver", "Should have required a driver attribute.");
103     }
104 
105     public void testNoDbUrl()
106     {
107         expectBuildException("no-db-url", "Should have required a url attribute.");
108     }
109 
110     public void testNoUserid()
111     {
112         expectBuildException("no-userid", "Should have required a userid attribute.");
113     }
114 
115     public void testNoPassword()
116     {
117         expectBuildException("no-password", "Should have required a password attribute.");
118     }
119 
120     public void testInvalidDatabaseInformation()
121     {
122         Throwable sql = null;
123         try
124         {
125             executeTarget("invalid-db-info");
126         }
127         catch (BuildException e)
128         {
129             sql = e.getException();
130         }
131         finally
132         {
133             assertNotNull("Should have thrown a SQLException.", sql);
134             assertTrue("Should have thrown a SQLException.", (sql instanceof SQLException));
135         }
136     }
137 
138     public void testInvalidOperationType()
139     {
140         Throwable iae = null;
141         try
142         {
143             executeTarget("invalid-type");
144         }
145         catch (BuildException e)
146         {
147             iae = e.getException();
148         }
149         finally
150         {
151             assertNotNull("Should have thrown an IllegalArgumentException.", iae);
152             assertTrue("Should have thrown an IllegalArgumentException.",
153                     (iae instanceof IllegalArgumentException));
154         }
155     }
156 
157     public void testSetFlatFalse()
158     {
159         String targetName = "set-format-xml";
160         Operation operation = (Operation)getFirstStepFromTarget(targetName);
161         assertTrue("Operation attribute format should have been 'xml', but was: "
162                 + operation.getFormat(), operation.getFormat().equalsIgnoreCase("xml"));
163     }
164 
165     public void testResolveOperationTypes()
166     {
167         assertOperationType("Should have been a NONE operation",
168                 "test-type-none", DatabaseOperation.NONE);
169         assertOperationType("Should have been an DELETE_ALL operation",
170                 "test-type-delete-all", DatabaseOperation.DELETE_ALL);
171         assertOperationType("Should have been an INSERT operation",
172                 "test-type-insert", DatabaseOperation.INSERT);
173         assertOperationType("Should have been an UPDATE operation",
174                 "test-type-update", DatabaseOperation.UPDATE);
175         assertOperationType("Should have been an REFRESH operation",
176                 "test-type-refresh", DatabaseOperation.REFRESH);
177         assertOperationType("Should have been an CLEAN_INSERT operation",
178                 "test-type-clean-insert", DatabaseOperation.CLEAN_INSERT);
179         assertOperationType("Should have been an DELETE operation",
180                 "test-type-delete", DatabaseOperation.DELETE);
181         assertOperationType("Should have been an MSSQL_INSERT operation",
182                 "test-type-mssql-insert", InsertIdentityOperation.INSERT);
183         assertOperationType("Should have been an MSSQL_REFRESH operation",
184                 "test-type-mssql-refresh", InsertIdentityOperation.REFRESH);
185         assertOperationType("Should have been an MSSQL_CLEAN_INSERT operation",
186                 "test-type-mssql-clean-insert", InsertIdentityOperation.CLEAN_INSERT);
187     }
188 
189     public void testInvalidCompositeOperationSrc()
190     {
191         expectBuildException("invalid-composite-operation-src",
192                 "Should have objected to nested operation src attribute "
193                         + "being set.");
194     }
195 
196     public void testInvalidCompositeOperationFlat()
197     {
198         expectBuildException("invalid-composite-operation-format-flat",
199                 "Should have objected to nested operation format attribute "
200                         + "being set.");
201     }
202 
203     public void testExportFull()
204     {
205         String targetName = "test-export-full";
206         Export export = (Export)getFirstStepFromTarget(targetName);
207         assertTrue("Should have been a flat format, "
208                 + "but was: " + export.getFormat(),
209                 export.getFormat().equalsIgnoreCase("flat"));
210         List tables = export.getTables();
211         assertTrue("Should have been an empty table list "
212                 + "(indicating a full dataset), but was: "
213                 + tables, tables.size() == 0);
214     }
215 
216     public void testExportPartial()
217     {
218         String targetName = "test-export-partial";
219         Export export = (Export)getFirstStepFromTarget(targetName);
220         List tables = export.getTables();
221         assertEquals("table count", 2, tables.size());
222         Table testTable = (Table)tables.get(0);
223         Table pkTable = (Table)tables.get(1);
224         assertTrue("Should have been been TABLE TEST_TABLE, but was: "
225                 + testTable.getName(), testTable.getName().equals("TEST_TABLE"));
226         assertTrue("Should have been been TABLE PK_TABLE, but was: "
227                 + pkTable.getName(), pkTable.getName().equals("PK_TABLE"));
228     }
229 
230     public void testExportWithForwardOnlyResultSetTable() throws SQLException, DatabaseUnitException
231     {
232         String targetName = "test-export-forward-only-result-set-table-via-config";
233 
234         // Test if the correct result set table factory is set according to dbconfig
235         Export export = (Export)getFirstStepFromTarget(targetName);
236         DbUnitTask task = getFirstTargetTask(targetName);
237         IDatabaseConnection connection = task.createConnection();
238         IDataSet dataSetToBeExported = export.getExportDataSet(connection);
239         assertEquals("org.dbunit.database.ForwardOnlyResultSetTableFactory",
240                 connection.getConfig().getProperty(DatabaseConfig.PROPERTY_RESULTSET_TABLE_FACTORY).getClass().getName());
241     }
242 
243     public void testExportFlat()
244     {
245         String targetName = "test-export-format-flat";
246         Export export = (Export)getFirstStepFromTarget(targetName);
247         assertEquals("format", "flat", export.getFormat());
248     }
249 
250     public void testExportFlatWithDocytpe()
251     {
252         String targetName = "test-export-format-flat-with-doctype";
253         Export export = (Export)getFirstStepFromTarget(targetName);
254         assertEquals("format", "flat", export.getFormat());
255         assertEquals("doctype", "dataset.dtd", export.getDoctype());
256     }
257 
258     public void testExportFlatWithEncoding()
259     {
260         String targetName = "test-export-format-flat-with-encoding";
261         Export export = (Export)getFirstStepFromTarget(targetName);
262         assertEquals("format", "flat", export.getFormat());
263         assertEquals("encoding", "ISO-8859-1", export.getEncoding());
264     }
265 
266     public void testExportXml()
267     {
268         String targetName = "test-export-format-xml";
269         Export export = (Export)getFirstStepFromTarget(targetName);
270         assertTrue("Should have been an xml format, "
271                 + "but was: " + export.getFormat(),
272                 export.getFormat().equalsIgnoreCase("xml"));
273     }
274 
275     public void testExportCsv() {
276         String targetName = "test-export-format-csv";
277         Export export = (Export)getFirstStepFromTarget(targetName);
278         assertTrue("Should have been a csv format, "
279                 + "but was: " + export.getFormat(),
280                 export.getFormat().equalsIgnoreCase("csv"));
281     }
282 
283     public void testExportDtd()
284     {
285         String targetName = "test-export-format-dtd";
286         Export export = (Export)getFirstStepFromTarget(targetName);
287         assertTrue("Should have been a dtd format, "
288                 + "but was: " + export.getFormat(),
289                 export.getFormat().equalsIgnoreCase("dtd"));
290     }
291 
292     public void testInvalidExportFormat()
293     {
294         expectBuildException("invalid-export-format",
295                 "Should have objected to invalid format attribute.");
296     }
297 
298     public void testExportXmlOrdered() throws Exception
299     {
300         String targetName = "test-export-format-xml-ordered";
301         Export export = (Export)getFirstStepFromTarget(targetName);
302         assertEquals("Should be ordered", true, export.isOrdered());
303         assertTrue("Should have been an xml format, "
304                 + "but was: " + export.getFormat(),
305                 export.getFormat().equalsIgnoreCase("xml"));
306 
307         // Test if the correct dataset is created for ordered export
308         DbUnitTask task = getFirstTargetTask(targetName);
309         IDatabaseConnection connection = task.createConnection();
310         IDataSet dataSetToBeExported = export.getExportDataSet(connection);
311         // Ordered export should use the filtered dataset
312         assertEquals(dataSetToBeExported.getClass(), FilteredDataSet.class);
313     }
314 
315     public void testExportQuery()
316     {
317         String targetName = "test-export-query";
318         Export export = (Export)getFirstStepFromTarget(targetName);
319         assertEquals("format", "flat", export.getFormat());
320 
321         List queries = export.getTables();
322         assertEquals("query count", 2, getQueryCount(queries));
323 
324         Query testTable = (Query)queries.get(0);
325         assertEquals("name", "TEST_TABLE", testTable.getName());
326         assertEquals("sql", "SELECT * FROM TEST_TABLE ORDER BY column0 DESC", testTable.getSql());
327 
328         Query pkTable = (Query)queries.get(1);
329         assertEquals("name", "PK_TABLE", pkTable.getName());
330         assertEquals("sql", "SELECT * FROM PK_TABLE", pkTable.getSql());
331     }
332 
333     public void testExportWithQuerySet() {
334         String targetName = "test-export-with-queryset";
335         Export export = (Export)getFirstStepFromTarget(targetName);
336         assertEquals("format", "csv", export.getFormat());
337 
338         List queries = export.getTables();
339 
340         assertEquals("query count", 1, getQueryCount(queries));
341         assertEquals("table count", 1, getTableCount(queries));
342         assertEquals("queryset count", 2, getQuerySetCount(queries));
343 
344         Query secondTable = (Query)queries.get(0);
345         assertEquals("name", "SECOND_TABLE", secondTable.getName());
346         assertEquals("sql", "SELECT * FROM SECOND_TABLE", secondTable.getSql());
347 
348         QuerySet queryset1 = (QuerySet)queries.get(1);
349 
350         Query testTable = (Query)queryset1.getQueries().get(0);
351 
352         assertEquals("name", "TEST_TABLE", testTable.getName());
353 
354         QuerySet queryset2 = (QuerySet)queries.get(2);
355 
356         Query pkTable = (Query)queryset2.getQueries().get(0);
357         Query testTable2 = (Query)queryset2.getQueries().get(1);
358 
359         assertEquals("name", "PK_TABLE", pkTable.getName());
360         assertEquals("name", "TEST_TABLE", testTable2.getName());
361 
362         Table emptyTable = (Table)queries.get(3);
363 
364         assertEquals("name", "EMPTY_TABLE", emptyTable.getName());
365     }
366 
367     public void testWithBadQuerySet() {
368         expectBuildException("invalid-queryset",
369                 "Cannot specify 'id' and 'refid' attributes together in queryset.");
370     }
371 
372     public void testWithReferenceQuerySet() {
373         String targetName = "test-queryset-reference";
374 
375         Export export = (Export)getFirstStepFromTarget(targetName);
376 
377         List tables = export.getTables();
378 
379         assertEquals("total count", 1, tables.size());
380 
381         QuerySet queryset = (QuerySet)tables.get(0);
382         Query testTable = (Query)queryset.getQueries().get(0);
383         Query secondTable = (Query)queryset.getQueries().get(1);
384 
385         assertEquals("name", "TEST_TABLE", testTable.getName());
386         assertEquals("sql", "SELECT * FROM TEST_TABLE WHERE COLUMN0 = 'row0 col0'",
387                 testTable.getSql());
388 
389         assertEquals("name", "SECOND_TABLE", secondTable.getName());
390         assertEquals("sql",
391                 "SELECT B.* FROM TEST_TABLE A, SECOND_TABLE B " +
392                         "WHERE A.COLUMN0 = 'row0 col0' AND B.COLUMN0 = A.COLUMN0",
393                         secondTable.getSql());
394 
395     }
396 
397     public void testExportQueryMixed() {
398         String targetName = "test-export-query-mixed";
399         Export export = (Export)getFirstStepFromTarget(targetName);
400         assertEquals("format", "flat", export.getFormat());
401 
402         List tables = export.getTables();
403         assertEquals("total count", 2, tables.size());
404         assertEquals("table count", 1, getTableCount(tables));
405         assertEquals("query count", 1, getQueryCount(tables));
406 
407         Table testTable = (Table)tables.get(0);
408         assertEquals("name", "TEST_TABLE", testTable.getName());
409 
410         Query pkTable = (Query)tables.get(1);
411         assertEquals("name", "PK_TABLE", pkTable.getName());
412     }
413 
414     /**
415      * Tests the exception that is thrown when the compare fails because
416      * the source format was different from the previous "export" task's write format.
417      */
418     public void testExportAndCompareFormatMismatch() {
419         String targetName = "test-export-and-compare-format-mismatch";
420 
421         try {
422             getFirstTargetTask(targetName);
423             fail("Should not be able to invoke ant task where the expected table was not found because it was tried to read in the wrong format.");
424         }
425         catch(BuildException expected){
426             Throwable cause = expected.getCause();
427             assertTrue(cause instanceof DatabaseUnitException);
428             DatabaseUnitException dbUnitException = (DatabaseUnitException)cause;
429             String filename = new File(outputDir, "antExportDataSet.xml").toString();
430             String expectedMsg = "Did not find table in source file '" + filename + "' using format 'xml'";
431             assertEquals(expectedMsg, dbUnitException.getMessage());
432             assertTrue(dbUnitException.getCause() instanceof NoSuchTableException);
433             NoSuchTableException nstException = (NoSuchTableException)dbUnitException.getCause();
434             assertEquals("TEST_TABLE", nstException.getMessage());
435         }
436     }
437 
438     public void testDataTypeFactory() throws Exception
439     {
440         String targetName = "test-datatypefactory";
441         DbUnitTask task = getFirstTargetTask(targetName);
442 
443         IDatabaseConnection connection = task.createConnection();
444         IDataTypeFactory factory = (IDataTypeFactory)connection.getConfig().getProperty(
445                 DatabaseConfig.PROPERTY_DATATYPE_FACTORY);
446 
447         Class expectedClass = OracleDataTypeFactory.class;
448         assertEquals("factory", expectedClass, factory.getClass());
449     }
450 
451     public void testEscapePattern() throws Exception
452     {
453         String targetName = "test-escapepattern";
454         DbUnitTask task = getFirstTargetTask(targetName);
455 
456         IDatabaseConnection connection = task.createConnection();
457         String actualPattern = (String)connection.getConfig().getProperty(
458                 DatabaseConfig.PROPERTY_ESCAPE_PATTERN);
459 
460         String expectedPattern = "[?]";
461         assertEquals("factory", expectedPattern, actualPattern);
462     }
463 
464     public void testDataTypeFactoryViaGenericConfig() throws Exception
465     {
466         String targetName = "test-datatypefactory-via-generic-config";
467         DbUnitTask task = getFirstTargetTask(targetName);
468 
469         IDatabaseConnection connection = task.createConnection();
470 
471         DatabaseConfig config =connection.getConfig();
472 
473         IDataTypeFactory factory = (IDataTypeFactory)config.getProperty(
474                 DatabaseConfig.PROPERTY_DATATYPE_FACTORY);
475         Class expectedClass = OracleDataTypeFactory.class;
476         assertEquals("factory", expectedClass, factory.getClass());
477 
478         String[] actualTableType = (String[])config.getProperty(DatabaseConfig.PROPERTY_TABLE_TYPE);
479         ArrayAssert.assertEquals("tableType", new String[]{"TABLE", "SYNONYM"}, actualTableType);
480         assertTrue("batched statements feature should be true",
481                 connection.getConfig().getFeature(DatabaseConfig.FEATURE_BATCHED_STATEMENTS));
482         assertTrue("qualified tablenames feature should be true",
483                 connection.getConfig().getFeature(DatabaseConfig.FEATURE_CASE_SENSITIVE_TABLE_NAMES));
484     }
485 
486 
487     public void testClasspath() throws Exception
488     {
489         String targetName = "test-classpath";
490 
491         try
492         {
493             executeTarget(targetName);
494             fail("Should not be able to connect with invalid url!");
495         }
496         catch (BuildException e)
497         {
498             // Verify exception type
499             assertTrue("nested exxception type", e.getException() instanceof SQLException);
500         }
501 
502     }
503 
504     public void testDriverNotInClasspath() throws Exception
505     {
506         String targetName = "test-drivernotinclasspath";
507 
508         try
509         {
510             executeTarget(targetName);
511             fail("Should not have found driver!");
512         }
513         catch (BuildException e)
514         {
515             // Verify exception type
516             assertEquals("nested exception type", ClassNotFoundException.class, e.getException().getClass());
517         }
518     }
519 
520     public void testReplaceOperation() throws Exception {
521         String targetName = "test-replace";
522         final IDatabaseTester dbTest = DatabaseEnvironment.getInstance().getDatabaseTester();
523         executeTarget(targetName);
524         final IDataSet ds = dbTest.getConnection().createDataSet();
525         final ITable table = ds.getTable("PK_TABLE");
526         assertNull(table.getValue(0,"NORMAL0"));
527         assertEquals("row 1",table.getValue(1,"NORMAL0"));
528     }
529 
530     public void testOrderedOperation() throws Exception {
531         String targetName = "test-ordered";
532         final IDatabaseTester dbTest = DatabaseEnvironment.getInstance().getDatabaseTester();
533         executeTarget(targetName);
534         final IDataSet ds = dbTest.getConnection().createDataSet();
535         final ITable table = ds.getTable("PK_TABLE");
536         assertEquals("row 0",table.getValue(0,"NORMAL0"));
537         assertEquals("row 1",table.getValue(1,"NORMAL0"));
538     }
539 
540     public void testReplaceOrderedOperation() throws Exception {
541         String targetName = "test-replace-ordered";
542         final IDatabaseTester dbTest = DatabaseEnvironment.getInstance().getDatabaseTester();
543         executeTarget(targetName);
544         final IDataSet ds = dbTest.getConnection().createDataSet();
545         final ITable table = ds.getTable("PK_TABLE");
546         assertNull(table.getValue(0,"NORMAL0"));
547         assertEquals("row 1",table.getValue(1,"NORMAL0"));
548     }
549 
550     protected void assertOperationType(String failMessage, String targetName, DatabaseOperation expected)
551     {
552         Operation oper = (Operation)getFirstStepFromTarget(targetName);
553         DatabaseOperation dbOper = oper.getDbOperation();
554         assertTrue(failMessage + ", but was: " + dbOper, expected.equals(dbOper));
555     }
556 
557     protected int getQueryCount(List tables)
558     {
559         int count = 0;
560         for (Iterator it = tables.iterator(); it.hasNext();)
561         {
562             if (it.next() instanceof Query)
563             {
564                 count++;
565             }
566         }
567 
568         return count;
569     }
570 
571     protected int getTableCount(List tables)
572     {
573         int count = 0;
574         for (Iterator it = tables.iterator(); it.hasNext();)
575         {
576             if (it.next() instanceof Table)
577             {
578                 count++;
579             }
580         }
581 
582         return count;
583     }
584 
585     protected int getQuerySetCount(List tables) {
586         int count = 0;
587         for (Iterator it = tables.iterator(); it.hasNext();) {
588             if (it.next() instanceof QuerySet) {
589                 count++;
590             }
591         }
592 
593         return count;
594     }
595 
596     protected DbUnitTaskStep getFirstStepFromTarget(String targetName)
597     {
598         return getStepFromTarget(targetName, 0);
599     }
600 
601     protected DbUnitTaskStep getStepFromTarget(String targetName, int index)
602     {
603         DbUnitTask task = getFirstTargetTask(targetName);
604         List steps = task.getSteps();
605         if(steps == null || steps.size() == 0)
606         {
607             fail("Can't get a dbunit <step> from the target: " + targetName + ". No steps available.");
608         }
609         return (DbUnitTaskStep)steps.get(index);
610     }
611 
612     private DbUnitTask getFirstTargetTask(String targetName)
613     {
614         Hashtable targets = project.getTargets();
615         executeTarget(targetName);
616         Target target = (Target)targets.get(targetName);
617 
618         DbUnitTask task = null;
619 
620         Object[] tasks = target.getTasks();
621         for(int i = 0; i < tasks.length; i++) {
622         	if(tasks[i] instanceof DbUnitTask) {
623         		task = (DbUnitTask)tasks[i];
624             }
625         }
626 
627         return task;
628     }
629 
630     public static Test suite()
631     {
632         TestSuite suite = new TestSuite(classUnderTest);
633         return suite;
634     }
635 
636     public static void main(String args[])
637     {
638         if (args.length > 0 && args[0].equals("-gui"))
639         {
640             System.err.println("JUnit Swing-GUI is no longer supported.");
641             System.err.println("Starting textversion.");
642         }
643 
644         junit.textui.TestRunner.run(suite());
645     }
646 
647 }