5151import java .sql .ResultSet ;
5252import java .sql .SQLException ;
5353import java .sql .Statement ;
54+ import java .util .ArrayList ;
55+ import java .util .List ;
5456import java .util .Properties ;
5557import java .util .UUID ;
58+ import java .util .concurrent .Callable ;
59+ import java .util .concurrent .ExecutorService ;
60+ import java .util .concurrent .Executors ;
61+ import java .util .concurrent .Future ;
5662import java .util .concurrent .ThreadLocalRandom ;
5763import java .util .concurrent .TimeUnit ;
64+ import java .util .function .Supplier ;
5865import org .junit .AfterClass ;
5966import org .junit .Before ;
6067import org .junit .BeforeClass ;
@@ -125,21 +132,22 @@ public void setup() {
125132 }
126133
127134 @ Test
128- public void testGlobalOpenTelemetry () throws SQLException , IOException , InterruptedException {
135+ public void testGlobalOpenTelemetry () throws Exception {
129136 GlobalOpenTelemetry .resetForTest ();
130137 GlobalOpenTelemetry .set (openTelemetry );
131138 Properties info = new Properties ();
132139 info .put ("enableExtendedTracing" , "true" );
133140 try (Connection connection = createConnection (env , database , info )) {
134141 testOpenTelemetry (connection );
142+ testOpenTelemetryConcurrency (() -> createConnection (env , database , info ));
135143 } finally {
136144 GlobalOpenTelemetry .resetForTest ();
137145 }
138146 }
139147
140148 @ Test
141149 public void testOpenTelemetryInProperties ()
142- throws SQLException , IOException , InterruptedException {
150+ throws Exception {
143151 // Make sure there is no Global OpenTelemetry.
144152 GlobalOpenTelemetry .resetForTest ();
145153 Properties info = new Properties ();
@@ -148,6 +156,7 @@ public void testOpenTelemetryInProperties()
148156 try (Connection connection = createConnection (env , database , info )) {
149157 testOpenTelemetry (connection );
150158 }
159+ testOpenTelemetryConcurrency (() -> createConnection (env , database , info ));
151160 }
152161
153162 private void testOpenTelemetry (Connection connection )
@@ -159,14 +168,14 @@ private void testOpenTelemetry(Connection connection)
159168
160169 // Test executeQuery(String)
161170 try (ResultSet resultSet = statement .executeQuery (sql )) {
162- assertQueryResult (resultSet , sql , uuid );
171+ assertQueryResult (resultSet , sql , uuid , true );
163172 }
164173
165174 // Test execute(String)
166175 uuid = UUID .randomUUID ();
167176 sql = "select '" + uuid + "'" ;
168177 assertTrue (statement .execute (sql ));
169- assertQueryResult (statement .getResultSet (), sql , uuid );
178+ assertQueryResult (statement .getResultSet (), sql , uuid , true );
170179
171180 // Test executeUpdate(String)
172181 uuid = UUID .randomUUID ();
@@ -189,15 +198,15 @@ private void testOpenTelemetry(Connection connection)
189198 String sql = "select '" + uuid + "'" ;
190199 try (PreparedStatement statement = connection .prepareStatement (sql )) {
191200 try (ResultSet resultSet = statement .executeQuery ()) {
192- assertQueryResult (resultSet , sql , uuid );
201+ assertQueryResult (resultSet , sql , uuid , true );
193202 }
194203 }
195204
196205 uuid = UUID .randomUUID ();
197206 sql = "select '" + uuid + "'" ;
198207 try (PreparedStatement statement = connection .prepareStatement (sql )) {
199208 assertTrue (statement .execute ());
200- assertQueryResult (statement .getResultSet (), sql , uuid );
209+ assertQueryResult (statement .getResultSet (), sql , uuid , true );
201210 }
202211
203212 uuid = UUID .randomUUID ();
@@ -216,15 +225,49 @@ private void testOpenTelemetry(Connection connection)
216225 assertUpdateResult (statement .executeLargeUpdate (), spannerSql );
217226 }
218227 }
228+
229+ private interface ConnectionProducer {
230+ Connection createConnection () throws SQLException ;
231+ }
232+
233+ private void testOpenTelemetryConcurrency (ConnectionProducer connectionProducer ) throws Exception {
234+ int numThreads = 16 ;
235+ int numIterations = 1000 ;
236+ ExecutorService executor = Executors .newFixedThreadPool (16 );
237+ List <Future <?>> futures = new ArrayList <>(numThreads );
238+ for (int n =0 ; n <numThreads ; n ++) {
239+ futures .add (executor .submit ((Callable <Void >) () -> {
240+ try (Connection connection = connectionProducer .createConnection (); Statement statement = connection .createStatement ()) {
241+ for (int i = 0 ; i < numIterations ; i ++) {
242+ UUID uuid = UUID .randomUUID ();
243+ String sql = "select '" + uuid + "'" ;
219244
220- private void assertQueryResult (ResultSet resultSet , String sql , UUID uuid )
245+ try (ResultSet resultSet = statement .executeQuery (sql )) {
246+ assertQueryResult (resultSet , sql , uuid , false );
247+ }
248+ }
249+ }
250+ return null ;
251+ }));
252+ }
253+ executor .shutdown ();
254+ assertTrue (executor .awaitTermination (600L , TimeUnit .SECONDS ));
255+ for (Future <?> future : futures ) {
256+ // Just verify that we did not get an exception.
257+ future .get ();
258+ }
259+ }
260+
261+ private void assertQueryResult (ResultSet resultSet , String sql , UUID uuid , boolean assertTrace )
221262 throws SQLException , IOException , InterruptedException {
222263 assertTrue (resultSet .next ());
223264 assertEquals (uuid .toString (), resultSet .getString (1 ));
224265 assertFalse (resultSet .next ());
225266
226267 flushOpenTelemetry ();
227- assertTrace (sql );
268+ if (assertTrace ) {
269+ assertTrace (sql );
270+ }
228271 }
229272
230273 private void assertUpdateResult (long updateCount , String sql )
0 commit comments