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 static org.assertj.core.api.Assertions.assertThat;
24
25 import java.util.Properties;
26 import java.util.concurrent.atomic.AtomicInteger;
27
28 import javax.sql.DataSource;
29
30 import org.dbunit.database.CachingConnectionProvider;
31 import org.dbunit.database.IDatabaseConnection;
32 import org.dbunit.database.InMemoryJndiContextFactory;
33 import org.h2.jdbcx.JdbcDataSource;
34 import org.junit.jupiter.api.AfterEach;
35 import org.junit.jupiter.api.Test;
36
37
38
39
40
41
42
43
44
45
46 class JndiDatabaseTesterIT
47 {
48 private static final AtomicInteger DB_COUNTER = new AtomicInteger();
49
50 private IDatabaseConnection openedConnection;
51 private String boundName;
52
53 @AfterEach
54 void closeOpenedConnection() throws Exception
55 {
56 if (openedConnection != null)
57 {
58 openedConnection.close();
59 }
60 if (boundName != null)
61 {
62 InMemoryJndiContextFactory.unbind(boundName);
63 }
64 }
65
66 @Test
67 void testGetConnection_withoutProvider_returnsDifferentInstanceOnEachCall() throws Exception
68 {
69 final JndiDatabaseTester tester = tester(null);
70
71 final IDatabaseConnection first = tester.getConnection();
72 final IDatabaseConnection second = tester.getConnection();
73
74 assertThat(second)
75 .as("Without a CachingConnectionProvider, every call must create a fresh "
76 + "connection, matching pre-existing behavior.")
77 .isNotSameAs(first);
78 first.close();
79 second.close();
80 }
81
82 @Test
83 void testGetConnection_withProvider_returnsSameInstanceOnEachCall() throws Exception
84 {
85 final JndiDatabaseTester tester = tester(new CachingConnectionProvider());
86
87 final IDatabaseConnection first = tester.getConnection();
88 final IDatabaseConnection second = tester.getConnection();
89
90 openedConnection = second;
91 assertThat(second)
92 .as("With a CachingConnectionProvider, calls must reuse the cached connection.")
93 .isSameAs(first);
94 }
95
96 @Test
97 void testGetConnection_withProvider_afterUnderlyingConnectionDies_returnsNewWorkingConnection()
98 throws Exception
99 {
100 final JndiDatabaseTester tester = tester(new CachingConnectionProvider());
101
102 final IDatabaseConnection first = tester.getConnection();
103 first.getConnection().close();
104
105 final IDatabaseConnection second = tester.getConnection();
106
107 openedConnection = second;
108 assertThat(second).as("A dead cached connection must be transparently replaced.")
109 .isNotSameAs(first);
110 assertThat(second.getConnection().createStatement().execute("SELECT 1"))
111 .as("The replacement connection must be a real, working JDBC connection.")
112 .isTrue();
113 }
114
115 @Test
116 void testGetConnection_withProvider_looksUpJndiOnlyOnceEvenAcrossConnectionReplacement()
117 throws Exception
118 {
119 final JdbcDataSource dataSource = newDataSource();
120 final String lookupName = InMemoryJndiContextFactory.bind(dataSource);
121 boundName = lookupName;
122 final Properties environment = InMemoryJndiContextFactory.environment();
123 final JndiDatabaseTester tester =
124 new JndiDatabaseTester(environment, lookupName, null, new CachingConnectionProvider());
125
126 tester.getConnection();
127 tester.getConnection().getConnection().close();
128 final IDatabaseConnection third = tester.getConnection();
129
130 openedConnection = third;
131 assertThat(InMemoryJndiContextFactory.lookupCount(lookupName))
132 .as("JndiDatabaseTester's pre-existing initialize()/initialized-flag memoization "
133 + "must still resolve the DataSource via JNDI only once, even across "
134 + "multiple getConnection() calls and a CachingConnectionProvider "
135 + "replacing a dead connection in between.")
136 .isEqualTo(1);
137 }
138
139 private JndiDatabaseTester tester(final CachingConnectionProvider provider)
140 {
141 final String lookupName = InMemoryJndiContextFactory.bind(newDataSource());
142 boundName = lookupName;
143 final Properties environment = InMemoryJndiContextFactory.environment();
144 return new JndiDatabaseTester(environment, lookupName, null, provider);
145 }
146
147 private static JdbcDataSource newDataSource()
148 {
149 final JdbcDataSource dataSource = new JdbcDataSource();
150 dataSource.setUrl(
151 "jdbc:h2:mem:jnditester_" + DB_COUNTER.incrementAndGet() + ";DB_CLOSE_DELAY=-1");
152 return dataSource;
153 }
154 }