1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.dbunit.junit.jupiter;
22
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
25
26 import java.sql.Connection;
27 import java.sql.DriverManager;
28 import java.sql.ResultSet;
29 import java.sql.Statement;
30
31 import org.dbunit.DatabaseEnvironment;
32 import org.dbunit.DatabaseProfile;
33 import org.dbunit.DefaultDatabaseTester;
34 import org.dbunit.IDatabaseTester;
35 import org.dbunit.IOperationListener;
36 import org.dbunit.annotation.DbUnitExpected;
37 import org.dbunit.annotation.DbUnitPrep;
38 import org.dbunit.annotation.DbUnitRowCountCheck;
39 import org.dbunit.annotation.DbUnitTearDown;
40 import org.dbunit.annotation.DbUnitTester;
41 import org.dbunit.annotation.DbUnitVerifyTable;
42 import org.dbunit.database.DatabaseConnection;
43 import org.dbunit.database.IDatabaseConnection;
44 import org.dbunit.database.rowcount.ClearRowCountCheckSystemProperties;
45 import org.dbunit.operation.DbUnitOperation;
46 import org.junit.jupiter.api.Test;
47 import org.junit.jupiter.api.extension.ExtendWith;
48 import org.junit.platform.testkit.engine.EngineTestKit;
49 import org.slf4j.LoggerFactory;
50
51 import ch.qos.logback.classic.Level;
52 import ch.qos.logback.classic.Logger;
53 import ch.qos.logback.classic.spi.ILoggingEvent;
54 import ch.qos.logback.core.read.ListAppender;
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 @ClearRowCountCheckSystemProperties
71 class DbUnitExtensionAutoCommitOffIT
72 {
73 private static final String TEST_TABLE = "TEST_TABLE";
74
75 @Test
76 void testAfterTestExecution_prepExpectedRowCountCheckOnANonAutocommitConnection_warnsRunsCleanAndPersistsNothing()
77 throws Exception
78 {
79 final DatabaseEnvironment environment = DatabaseEnvironment.getInstance();
80 final DatabaseProfile profile = environment.getProfile();
81 deleteAllRowsQuietly(environment);
82
83 final Connection nonAutocommit = DriverManager.getConnection(
84 profile.getConnectionUrl(), profile.getUser(), profile.getPassword());
85 nonAutocommit.setAutoCommit(false);
86 AutoCommitOffSample.databaseTester = new DefaultDatabaseTester(
87 new DatabaseConnection(nonAutocommit, profile.getSchema()));
88 AutoCommitOffSample.databaseTester
89 .setOperationListener(IOperationListener.NO_OP_OPERATION_LISTENER);
90
91 final Logger warningLogger = (Logger) LoggerFactory
92 .getLogger("org.dbunit.database.connection.AutoCommitOffWarning");
93 final ListAppender<ILoggingEvent> appender = new ListAppender<>();
94 appender.start();
95 warningLogger.addAppender(appender);
96 try
97 {
98 EngineTestKit.engine("junit-jupiter")
99 .selectors(selectClass(AutoCommitOffSample.class)).execute().testEvents()
100 .assertStatistics(stats -> stats.started(1).succeeded(1));
101
102 assertThat(appender.list)
103 .filteredOn(event -> event.getLevel() == Level.WARN
104 && event.getFormattedMessage().contains("autocommit disabled"))
105 .as("A non-autocommit connection on the prep/expected path must be warned"
106 + " about (#965).")
107 .hasSize(1);
108
109 final IDatabaseConnection verifyConnection = environment.getConnection();
110 assertThat(rowCount(verifyConnection, TEST_TABLE))
111 .as("With autocommit disabled the setup/teardown operations never commit"
112 + " (#965), so a separate connection must see TEST_TABLE unchanged"
113 + " from before the run - the @DbUnitPrep seed and the test's own"
114 + " UPDATE both invisible outside the never-committed transaction.")
115 .isZero();
116 } finally
117 {
118 warningLogger.detachAppender(appender);
119 appender.stop();
120 closeQuietly(nonAutocommit);
121 deleteAllRowsQuietly(environment);
122 environment.closeConnection();
123 }
124 }
125
126 @Test
127 void testBeforeTestExecution_setupTeardownPrepOnANonAutocommitConnection_warnsAndPersistsNothing()
128 throws Exception
129 {
130 final DatabaseEnvironment environment = DatabaseEnvironment.getInstance();
131 final DatabaseProfile profile = environment.getProfile();
132 deleteAllRowsQuietly(environment);
133
134 final Connection nonAutocommit = DriverManager.getConnection(
135 profile.getConnectionUrl(), profile.getUser(), profile.getPassword());
136 nonAutocommit.setAutoCommit(false);
137 AutoCommitOffSetupTeardownSample.databaseTester = new DefaultDatabaseTester(
138 new DatabaseConnection(nonAutocommit, profile.getSchema()));
139
140 final Logger warningLogger = (Logger) LoggerFactory
141 .getLogger("org.dbunit.database.connection.AutoCommitOffWarning");
142 final ListAppender<ILoggingEvent> appender = new ListAppender<>();
143 appender.start();
144 warningLogger.addAppender(appender);
145 try
146 {
147 EngineTestKit.engine("junit-jupiter")
148 .selectors(selectClass(AutoCommitOffSetupTeardownSample.class)).execute()
149 .testEvents().assertStatistics(stats -> stats.started(1).succeeded(1));
150
151 assertThat(appender.list)
152 .filteredOn(event -> event.getLevel() == Level.WARN
153 && event.getFormattedMessage().contains("autocommit disabled"))
154 .as("The setup/teardown path must warn about a non-autocommit connection"
155 + " too - its @DbUnitPrep runs through the tester with no"
156 + " transaction, exactly the #965 shape the prep/expected path"
157 + " already warns about.")
158 .hasSize(1);
159
160
161
162
163 final IDatabaseConnection verifyConnection = environment.getConnection();
164 assertThat(rowCount(verifyConnection, TEST_TABLE))
165 .as("The @DbUnitPrep CLEAN_INSERT ran on the never-committed transaction, so"
166 + " a separate connection sees no rows.")
167 .isZero();
168 } finally
169 {
170 warningLogger.detachAppender(appender);
171 appender.stop();
172 closeQuietly(nonAutocommit);
173 deleteAllRowsQuietly(environment);
174 environment.closeConnection();
175 }
176 }
177
178 private static int rowCount(final IDatabaseConnection connection, final String tableName)
179 throws Exception
180 {
181 try (Statement statement = connection.getConnection().createStatement();
182 ResultSet resultSet =
183 statement.executeQuery("SELECT COUNT(*) FROM " + tableName))
184 {
185 resultSet.next();
186 return resultSet.getInt(1);
187 }
188 }
189
190 private static void closeQuietly(final Connection connection)
191 {
192 try
193 {
194 if (!connection.isClosed())
195 {
196 connection.rollback();
197 connection.close();
198 }
199 } catch (final Exception e)
200 {
201
202 }
203 }
204
205 private static void deleteAllRowsQuietly(final DatabaseEnvironment environment)
206 {
207 try (Statement statement =
208 environment.getConnection().getConnection().createStatement())
209 {
210 statement.execute("DELETE FROM " + TEST_TABLE);
211 } catch (final Exception e)
212 {
213
214 }
215 }
216
217 @ExtendWith(DbUnitExtension.class)
218 @ClearRowCountCheckSystemProperties
219 @DbUnitRowCountCheck
220 static class AutoCommitOffSample
221 {
222 @DbUnitTester
223 static IDatabaseTester databaseTester;
224
225 @Test
226 @DbUnitPrep("annotation-it-prep.xml")
227 @DbUnitExpected(value = "annotation-it-expected.xml",
228 verify = @DbUnitVerifyTable(value = TEST_TABLE,
229 include = {"COLUMN0", "COLUMN1"}))
230 @DbUnitTearDown(operation = DbUnitOperation.DELETE_ALL)
231 void mutateTheSeededRow(final Connection connection) throws Exception
232 {
233 try (Statement statement = connection.createStatement())
234 {
235 statement.execute("UPDATE " + TEST_TABLE
236 + " SET COLUMN1 = 'after' WHERE COLUMN0 = 'row0'");
237 }
238 }
239 }
240
241 @ExtendWith(DbUnitExtension.class)
242 @ClearRowCountCheckSystemProperties
243 static class AutoCommitOffSetupTeardownSample
244 {
245 @DbUnitTester
246 static IDatabaseTester databaseTester;
247
248 @Test
249 @DbUnitPrep("annotation-it-prep.xml")
250 @DbUnitTearDown(operation = DbUnitOperation.DELETE_ALL)
251 void seedsThePrepDataset()
252 {
253
254 }
255 }
256 }