1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.dbunit;
22
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.dbunit.assertion.comparer.value.ValueComparer;
29 import org.dbunit.assertion.comparer.value.verifier.DefaultValueComparerAndVerifyTableDefinitionVerifier;
30 import org.dbunit.assertion.comparer.value.verifier.ValueComparerAndVerifyTableDefinitionVerifier;
31 import org.dbunit.database.DatabaseConfig;
32 import org.dbunit.database.IDatabaseConnection;
33 import org.dbunit.dataset.Column;
34 import org.dbunit.dataset.CompositeDataSet;
35 import org.dbunit.dataset.DataSetException;
36 import org.dbunit.dataset.DefaultDataSet;
37 import org.dbunit.dataset.IDataSet;
38 import org.dbunit.dataset.ITable;
39 import org.dbunit.dataset.SortedTable;
40 import org.dbunit.dataset.filter.DefaultColumnFilter;
41 import org.dbunit.operation.DatabaseOperation;
42 import org.dbunit.util.fileloader.DataFileLoader;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public class DefaultPrepAndExpectedTestCase extends DBTestCase
60 implements PrepAndExpectedTestCase
61 {
62 private final Logger log =
63 LoggerFactory.getLogger(DefaultPrepAndExpectedTestCase.class);
64
65 private static final String DATABASE_TESTER_IS_NULL_MSG =
66 "databaseTester is null; must configure or set it first";
67
68 public static final String TEST_ERROR_MSG = "DbUnit test error.";
69
70 private IDatabaseTester databaseTester;
71 private DataFileLoader dataFileLoader;
72
73
74 private IDataSet prepDataSet = new DefaultDataSet();
75 private IDataSet expectedDataSet = new DefaultDataSet();
76 private VerifyTableDefinition[] verifyTableDefs = {};
77
78 private ExpectedDataSetAndVerifyTableDefinitionVerifier expectedDataSetAndVerifyTableDefinitionVerifier =
79 new DefaultExpectedDataSetAndVerifyTableDefinitionVerifier();
80
81 private ValueComparer defaultValueComparer;
82 private Map<String, Map<String, ValueComparer>> tableColumnValueComparers;
83
84 private ValueComparerAndVerifyTableDefinitionVerifier valueComparerAndVerifyTableDefinitionVerifier =
85 new DefaultValueComparerAndVerifyTableDefinitionVerifier();
86
87
88 public DefaultPrepAndExpectedTestCase()
89 {
90 }
91
92
93
94
95
96
97
98
99
100 public DefaultPrepAndExpectedTestCase(final DataFileLoader dataFileLoader,
101 final IDatabaseTester databaseTester)
102 {
103 this.dataFileLoader = dataFileLoader;
104 this.databaseTester = databaseTester;
105 }
106
107
108
109
110
111
112
113 public DefaultPrepAndExpectedTestCase(final String name)
114 {
115 super(name);
116 }
117
118
119
120
121
122 @Override
123 public IDatabaseTester newDatabaseTester() throws Exception
124 {
125
126 return databaseTester;
127 }
128
129
130
131
132 @Override
133 public IDataSet getDataSet() throws Exception
134 {
135 return prepDataSet;
136 }
137
138
139
140
141 public void configureTest(
142 final VerifyTableDefinition[] verifyTableDefinitions,
143 final String[] prepDataFiles, final String[] expectedDataFiles)
144 throws Exception
145 {
146 log.info("configureTest: saving instance variables");
147 this.prepDataSet = makeCompositeDataSet(prepDataFiles, "prep");
148 this.expectedDataSet =
149 makeCompositeDataSet(expectedDataFiles, "expected");
150 this.verifyTableDefs = verifyTableDefinitions;
151 }
152
153
154
155
156 public void configureTest(
157 final VerifyTableDefinition[] verifyTableDefinitions,
158 final String[] prepDataFiles, final String[] expectedDataFiles,
159 final ValueComparer defaultValueComparer,
160 final Map<String, Map<String, ValueComparer>> tableColumnValueComparers)
161 throws Exception
162 {
163 configureTest(verifyTableDefinitions, prepDataFiles, expectedDataFiles);
164 this.defaultValueComparer = defaultValueComparer;
165 this.tableColumnValueComparers = tableColumnValueComparers;
166 }
167
168
169
170
171 public void preTest() throws Exception
172 {
173 setupData();
174 }
175
176
177
178
179 public void preTest(final VerifyTableDefinition[] tables,
180 final String[] prepDataFiles, final String[] expectedDataFiles)
181 throws Exception
182 {
183 configureTest(tables, prepDataFiles, expectedDataFiles);
184 preTest();
185 }
186
187
188
189
190 public void preTest(final VerifyTableDefinition[] tables,
191 final String[] prepDataFiles, final String[] expectedDataFiles,
192 final ValueComparer defaultValueComparer,
193 final Map<String, Map<String, ValueComparer>> tableColumnValueComparers)
194 throws Exception
195 {
196 configureTest(tables, prepDataFiles, expectedDataFiles,
197 defaultValueComparer, tableColumnValueComparers);
198 preTest();
199 }
200
201
202
203
204 public Object runTest(final VerifyTableDefinition[] verifyTables,
205 final String[] prepDataFiles, final String[] expectedDataFiles,
206 final PrepAndExpectedTestCaseSteps testSteps) throws Exception
207 {
208 return runTest(verifyTables, prepDataFiles, expectedDataFiles, null,
209 null, testSteps);
210 }
211
212
213
214
215 public Object runTest(final VerifyTableDefinition[] verifyTables,
216 final String[] prepDataFiles, final String[] expectedDataFiles,
217 final ValueComparer defaultValueComparer,
218 final Map<String, Map<String, ValueComparer>> tableColumnValueComparers,
219 final PrepAndExpectedTestCaseSteps testSteps) throws Exception
220 {
221 final Object result;
222
223 try
224 {
225 preTest(verifyTables, prepDataFiles, expectedDataFiles,
226 defaultValueComparer, tableColumnValueComparers);
227 log.info("runTest: running test steps");
228 result = testSteps.run();
229 } catch (final Exception e)
230 {
231 log.error(TEST_ERROR_MSG, e);
232
233
234
235 postTest(false);
236 throw e;
237 }
238
239 postTest();
240
241 return result;
242 }
243
244
245
246
247 public void postTest() throws Exception
248 {
249 postTest(true);
250 }
251
252
253
254
255 public void postTest(final boolean verifyData) throws Exception
256 {
257 try
258 {
259 if (verifyData)
260 {
261 verifyData();
262 }
263 } finally
264 {
265
266
267
268
269 cleanupData();
270 }
271 }
272
273
274
275
276 public void cleanupData() throws Exception
277 {
278 try
279 {
280 final IDataSet dataset =
281 new CompositeDataSet(prepDataSet, expectedDataSet);
282 final String[] tableNames = dataset.getTableNames();
283 final int count = tableNames.length;
284 log.info("cleanupData: about to clean up {} tables={}", count,
285 tableNames);
286
287 if (databaseTester == null)
288 {
289 throw new IllegalStateException(DATABASE_TESTER_IS_NULL_MSG);
290 }
291
292 databaseTester.setTearDownOperation(getTearDownOperation());
293 databaseTester.setDataSet(dataset);
294 databaseTester.setOperationListener(getOperationListener());
295 databaseTester.onTearDown();
296 log.debug("cleanupData: Clean up done");
297 } catch (final Exception e)
298 {
299 log.error("cleanupData: Exception:", e);
300 throw e;
301 }
302 }
303
304 @Override
305 protected void tearDown() throws Exception
306 {
307
308 cleanupData();
309 super.tearDown();
310 }
311
312
313
314
315
316
317
318 public void setupData() throws Exception
319 {
320 log.info("setupData: setting prep dataset and inserting rows");
321 if (databaseTester == null)
322 {
323 throw new IllegalStateException(DATABASE_TESTER_IS_NULL_MSG);
324 }
325
326 try
327 {
328 super.setUp();
329 } catch (final Exception e)
330 {
331 log.error("setupData: Exception with setting up data:", e);
332 throw e;
333 }
334 }
335
336 @Override
337 protected DatabaseOperation getSetUpOperation() throws Exception
338 {
339 assertNotNull(DATABASE_TESTER_IS_NULL_MSG, databaseTester);
340 return databaseTester.getSetUpOperation();
341 }
342
343 @Override
344 protected DatabaseOperation getTearDownOperation() throws Exception
345 {
346 assertNotNull(DATABASE_TESTER_IS_NULL_MSG, databaseTester);
347 return databaseTester.getTearDownOperation();
348 }
349
350
351
352
353 public void verifyData() throws Exception
354 {
355 if (databaseTester == null)
356 {
357 throw new IllegalStateException(DATABASE_TESTER_IS_NULL_MSG);
358 }
359
360 valueComparerAndVerifyTableDefinitionVerifier
361 .verify(tableColumnValueComparers, verifyTableDefs);
362
363 final IDatabaseConnection connection = getConnection();
364
365 final DatabaseConfig config = connection.getConfig();
366 expectedDataSetAndVerifyTableDefinitionVerifier.verify(verifyTableDefs,
367 expectedDataSet, config);
368
369 try
370 {
371 final int tableDefsCount = verifyTableDefs.length;
372 log.info(
373 "verifyData: about to verify {} tables"
374 + " using verifyTableDefinitions={}",
375 tableDefsCount, verifyTableDefs);
376 if (tableDefsCount == 0)
377 {
378 log.warn("verifyData: No tables to verify as"
379 + " no VerifyTableDefinitions specified");
380 }
381
382 for (int i = 0; i < tableDefsCount; i++)
383 {
384 final VerifyTableDefinition td = verifyTableDefs[i];
385 verifyData(connection, td);
386 }
387 } catch (final Exception e)
388 {
389 log.error("verifyData: Exception:", e);
390 throw e;
391 } finally
392 {
393 log.debug("verifyData: Verification done, closing connection");
394 connection.close();
395 }
396 }
397
398 protected void verifyData(final IDatabaseConnection connection,
399 final VerifyTableDefinition verifyTableDefinition) throws Exception
400 {
401 final String tableName = verifyTableDefinition.getTableName();
402 log.info("verifyData: Verifying table '{}'", tableName);
403
404 final String[] excludeColumns =
405 verifyTableDefinition.getColumnExclusionFilters();
406 final String[] includeColumns =
407 verifyTableDefinition.getColumnInclusionFilters();
408
409 final ITable expectedTable = loadTableDataFromDataSet(tableName);
410 final ITable actualTable =
411 loadTableDataFromDatabase(tableName, connection);
412
413 final Map<String, ValueComparer> columnValueComparers =
414 findColumnValueComparer(tableName);
415
416 verifyData(expectedTable, actualTable, excludeColumns, includeColumns,
417 columnValueComparers);
418 }
419
420 protected Map<String, ValueComparer> findColumnValueComparer(
421 final String tableName)
422 {
423 final Map<String, ValueComparer> columnValueComparers;
424
425 if (tableColumnValueComparers == null)
426 {
427 columnValueComparers = null;
428 } else
429 {
430 columnValueComparers = tableColumnValueComparers.get(tableName);
431 }
432
433 return columnValueComparers;
434 }
435
436 public ITable loadTableDataFromDataSet(final String tableName)
437 throws DataSetException
438 {
439 ITable table = null;
440
441 final String methodName = "loadTableDataFromDataSet";
442
443 log.debug("{}: Loading table {} from expected dataset", methodName,
444 tableName);
445 try
446 {
447 table = expectedDataSet.getTable(tableName);
448 } catch (final Exception e)
449 {
450 final String msg = methodName + ": Problem obtaining table '"
451 + tableName + "' from expected dataset";
452 log.error(msg, e);
453 throw new DataSetException(msg, e);
454 }
455 return table;
456 }
457
458 public ITable loadTableDataFromDatabase(final String tableName,
459 final IDatabaseConnection connection) throws Exception
460 {
461 ITable table = null;
462
463 final String methodName = "loadTableDataFromDatabase";
464
465 log.debug("{}: Loading table {} from database", methodName, tableName);
466 try
467 {
468 table = connection.createTable(tableName);
469 } catch (final Exception e)
470 {
471 final String msg = methodName + ": Problem obtaining table '"
472 + tableName + "' from database";
473 log.error(msg, e);
474 throw new DataSetException(msg, e);
475 }
476 return table;
477 }
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499 protected void verifyData(final ITable expectedTable,
500 final ITable actualTable, final String[] excludeColumns,
501 final String[] includeColumns,
502 final Map<String, ValueComparer> columnValueComparers)
503 throws DatabaseUnitException
504 {
505 final String methodName = "verifyData";
506
507 log.debug("{}: Applying filters to expected table", methodName);
508 final ITable expectedFilteredTable = applyColumnFilters(expectedTable,
509 excludeColumns, includeColumns);
510 log.debug("{}: Applying filters to actual table", methodName);
511 final ITable actualFilteredTable =
512 applyColumnFilters(actualTable, excludeColumns, includeColumns);
513
514 log.debug("{}: Sorting expected table", methodName);
515 final SortedTable expectedSortedTable =
516 new SortedTable(expectedFilteredTable);
517 log.debug("{}: Sorted expected table={}", methodName,
518 expectedSortedTable);
519
520 log.debug("{}: Sorting actual table", methodName);
521 final SortedTable actualSortedTable = new SortedTable(
522 actualFilteredTable, expectedFilteredTable.getTableMetaData());
523 log.debug("{}: Sorted actual table={}", methodName, actualSortedTable);
524
525 log.debug("{}: Creating additionalColumnInfo", methodName);
526 final Column[] additionalColumnInfo =
527 makeAdditionalColumnInfo(expectedTable, excludeColumns);
528 log.debug("{}: additionalColumnInfo={}", methodName,
529 additionalColumnInfo);
530
531 log.debug("{}: Comparing expected table to actual table", methodName);
532 compareData(expectedSortedTable, actualSortedTable,
533 additionalColumnInfo, defaultValueComparer,
534 columnValueComparers);
535 }
536
537
538 protected void compareData(final SortedTable expectedSortedTable,
539 final SortedTable actualSortedTable,
540 final Column[] additionalColumnInfo,
541 final ValueComparer defaultValueComparer,
542 final Map<String, ValueComparer> columnValueComparers)
543 throws DatabaseUnitException
544 {
545 if (defaultValueComparer == null)
546 {
547
548 Assertion.assertEquals(expectedSortedTable, actualSortedTable,
549 additionalColumnInfo);
550 } else
551 {
552 Assertion.assertWithValueComparer(expectedSortedTable,
553 actualSortedTable, additionalColumnInfo,
554 defaultValueComparer, columnValueComparers);
555 }
556 }
557
558
559
560
561
562 protected Column[] makeAdditionalColumnInfo(final ITable expectedTable,
563 final String[] excludeColumns) throws DataSetException
564 {
565 final List<Column> keepColumnsList = new ArrayList<Column>();
566 final List<String> excludeColumnsList = Arrays.asList(excludeColumns);
567
568 final Column[] allColumns =
569 expectedTable.getTableMetaData().getColumns();
570 for (final Column column : allColumns)
571 {
572 final String columnName = column.getColumnName();
573 if (!excludeColumnsList.contains(columnName))
574 {
575 keepColumnsList.add(column);
576 }
577 }
578
579 return keepColumnsList.toArray(new Column[keepColumnsList.size()]);
580 }
581
582
583
584
585
586
587
588
589
590
591 public IDataSet makeCompositeDataSet(final String[] dataFiles,
592 final String dataFilesName) throws DataSetException
593 {
594 if (dataFileLoader == null)
595 {
596 throw new IllegalStateException(
597 "dataFileLoader is null; must configure or set it first");
598 }
599
600 final int count = dataFiles.length;
601 log.debug("makeCompositeDataSet: {} dataFiles count={}", dataFilesName,
602 count);
603 if (count == 0)
604 {
605 log.info("makeCompositeDataSet: Specified zero {} data files",
606 dataFilesName);
607 }
608
609 final List list = new ArrayList();
610 for (int i = 0; i < count; i++)
611 {
612 final IDataSet ds = dataFileLoader.load(dataFiles[i]);
613 list.add(ds);
614 }
615
616 final IDataSet[] dataSet = (IDataSet[]) list.toArray(new IDataSet[] {});
617 final IDataSet compositeDS = new CompositeDataSet(dataSet);
618 return compositeDS;
619 }
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635 public ITable applyColumnFilters(final ITable table,
636 final String[] excludeColumns, final String[] includeColumns)
637 throws DataSetException
638 {
639 ITable filteredTable = table;
640
641 if (table == null)
642 {
643 throw new IllegalArgumentException("table is null");
644 }
645
646
647
648 if (includeColumns == null)
649 {
650 log.debug("applyColumnFilters: including columns=(all)");
651 } else
652 {
653 log.debug("applyColumnFilters: including columns='{}'",
654 new Object[] {includeColumns});
655 filteredTable = DefaultColumnFilter
656 .includedColumnsTable(filteredTable, includeColumns);
657 }
658
659 if (excludeColumns == null || excludeColumns.length == 0)
660 {
661 log.debug("applyColumnFilters: excluding columns=(none)");
662 } else
663 {
664 log.debug("applyColumnFilters: excluding columns='{}'",
665 new Object[] {excludeColumns});
666 filteredTable = DefaultColumnFilter
667 .excludedColumnsTable(filteredTable, excludeColumns);
668 }
669
670 return filteredTable;
671 }
672
673
674
675
676 public IDataSet getPrepDataset()
677 {
678 return prepDataSet;
679 }
680
681
682
683
684 public IDataSet getExpectedDataset()
685 {
686 return expectedDataSet;
687 }
688
689
690
691
692
693
694
695
696 @Override
697 public IDatabaseTester getDatabaseTester()
698 {
699 return databaseTester;
700 }
701
702
703
704
705
706
707
708
709
710 public void setDatabaseTester(final IDatabaseTester databaseTester)
711 {
712 this.databaseTester = databaseTester;
713 }
714
715
716
717
718
719
720
721
722 public DataFileLoader getDataFileLoader()
723 {
724 return dataFileLoader;
725 }
726
727
728
729
730
731
732
733
734
735 public void setDataFileLoader(final DataFileLoader dataFileLoader)
736 {
737 this.dataFileLoader = dataFileLoader;
738 }
739
740
741
742
743
744
745
746
747
748 public void setPrepDs(final IDataSet prepDataSet)
749 {
750 this.prepDataSet = prepDataSet;
751 }
752
753
754
755
756
757
758
759
760
761 public void setExpectedDs(final IDataSet expectedDataSet)
762 {
763 this.expectedDataSet = expectedDataSet;
764 }
765
766
767
768
769
770
771
772
773 public VerifyTableDefinition[] getVerifyTableDefs()
774 {
775 return verifyTableDefs;
776 }
777
778
779
780
781
782
783
784
785
786 public void setVerifyTableDefs(
787 final VerifyTableDefinition[] verifyTableDefs)
788 {
789 this.verifyTableDefs = verifyTableDefs;
790 }
791
792 public ExpectedDataSetAndVerifyTableDefinitionVerifier getExpectedDataSetAndVerifyTableDefinitionVerifier()
793 {
794 return expectedDataSetAndVerifyTableDefinitionVerifier;
795 }
796
797 public void setExpectedDataSetAndVerifyTableDefinitionVerifier(
798 final ExpectedDataSetAndVerifyTableDefinitionVerifier expectedDataSetAndVerifyTableDefinitionVerifier)
799 {
800 this.expectedDataSetAndVerifyTableDefinitionVerifier =
801 expectedDataSetAndVerifyTableDefinitionVerifier;
802 }
803
804 public ValueComparerAndVerifyTableDefinitionVerifier getValueComparerAndVerifyTableDefinitionVerifier()
805 {
806 return valueComparerAndVerifyTableDefinitionVerifier;
807 }
808
809 public void setValueComparerAndVerifyTableDefinitionVerifier(
810 final ValueComparerAndVerifyTableDefinitionVerifier valueComparerAndVerifyTableDefinitionVerifier)
811 {
812 this.valueComparerAndVerifyTableDefinitionVerifier =
813 valueComparerAndVerifyTableDefinitionVerifier;
814 }
815 }