Skip to content

Commit f245c27

Browse files
committed
Fix PreparedStatementTestBase#XXXX42P18 intermittent failures (#1654)
Changed implementation for the in-transaction case. There was a racy behavior between the closing of the connection close and the invocation of the assertion. Changed the implementation to close the connection after verifying expectations. Repeating test to make it more likely to fail on CI if there's still a problem. Signed-off-by: Thomas Segismont <tsegismont@gmail.com>
1 parent 863b36d commit f245c27

File tree

1 file changed

+51
-38
lines changed

1 file changed

+51
-38
lines changed

vertx-pg-client/src/test/java/io/vertx/pgclient/PreparedStatementTestBase.java

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
/*
2-
* Copyright (C) 2017 Julien Viet
2+
* Copyright (c) 2011-2026 Contributors to the Eclipse Foundation
33
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
158
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
1610
*/
1711

1812
package io.vertx.pgclient;
@@ -24,30 +18,17 @@
2418
import io.vertx.core.json.JsonObject;
2519
import io.vertx.ext.unit.Async;
2620
import io.vertx.ext.unit.TestContext;
27-
import io.vertx.pgclient.data.Box;
28-
import io.vertx.pgclient.data.Circle;
29-
import io.vertx.pgclient.data.Interval;
30-
import io.vertx.pgclient.data.Line;
31-
import io.vertx.pgclient.data.LineSegment;
32-
import io.vertx.pgclient.data.Path;
33-
import io.vertx.pgclient.data.Point;
34-
import io.vertx.pgclient.data.Polygon;
35-
import io.vertx.sqlclient.Cursor;
36-
import io.vertx.sqlclient.Row;
37-
import io.vertx.sqlclient.RowIterator;
38-
import io.vertx.sqlclient.RowSet;
39-
import io.vertx.sqlclient.RowStream;
40-
import io.vertx.sqlclient.Tuple;
21+
import io.vertx.ext.unit.junit.Repeat;
22+
import io.vertx.ext.unit.junit.RepeatRule;
23+
import io.vertx.pgclient.data.*;
24+
import io.vertx.sqlclient.*;
4125
import org.junit.After;
4226
import org.junit.Before;
27+
import org.junit.Rule;
4328
import org.junit.Test;
4429

4530
import java.lang.reflect.Array;
46-
import java.time.LocalDate;
47-
import java.time.LocalDateTime;
48-
import java.time.LocalTime;
49-
import java.time.OffsetDateTime;
50-
import java.time.ZoneOffset;
31+
import java.time.*;
5132
import java.time.format.DateTimeFormatter;
5233
import java.util.Collections;
5334
import java.util.List;
@@ -62,6 +43,9 @@
6243
*/
6344
public abstract class PreparedStatementTestBase extends PgTestBase {
6445

46+
@Rule
47+
public RepeatRule rule = new RepeatRule();
48+
6549
Vertx vertx;
6650

6751
protected abstract PgConnectOptions options();
@@ -359,126 +343,148 @@ public void testCloseStatement(TestContext ctx) {
359343
}
360344

361345
@Test
346+
@Repeat(10)
362347
public void testInferDataTypeString42P18(TestContext ctx) {
363348
testInferDataType42P18(ctx, String.class, "WORLD", "WORLD");
364349
}
365350

366351
@Test
352+
@Repeat(10)
367353
public void testInferDataTypeBoolean42P18(TestContext ctx) {
368354
testInferDataType42P18(ctx, Boolean.class, true, "t");
369355
}
370356

371357
@Test
358+
@Repeat(10)
372359
public void testInferDataTypeShort42P18(TestContext ctx) {
373360
testInferDataType42P18(ctx, Short.class, (short)2, "2");
374361
}
375362

376363
@Test
364+
@Repeat(10)
377365
public void testInferDataTypeInteger42P18(TestContext ctx) {
378366
testInferDataType42P18(ctx, Integer.class, Integer.MAX_VALUE, "" + Integer.MAX_VALUE);
379367
}
380368

381369
@Test
370+
@Repeat(10)
382371
public void testInferDataTypeLong42P18(TestContext ctx) {
383372
testInferDataType42P18(ctx, Long.class, Long.MAX_VALUE, "" + Long.MAX_VALUE);
384373
}
385374

386375
@Test
376+
@Repeat(10)
387377
public void testInferDataTypeFloat42P18(TestContext ctx) {
388378
testInferDataType42P18(ctx, Float.class, 0F, "0");
389379
}
390380

391381
@Test
382+
@Repeat(10)
392383
public void testInferDataTypeDouble42P18(TestContext ctx) {
393384
testInferDataType42P18(ctx, Double.class, 0D, "0");
394385
}
395386

396387
@Test
388+
@Repeat(10)
397389
public void testInferDataTypeLocalDate42P18(TestContext ctx) {
398390
LocalDate value = LocalDate.now();
399391
testInferDataType42P18(ctx, LocalDate.class, value, value.toString());
400392
}
401393

402394
@Test
395+
@Repeat(10)
403396
public void testInferDataTypeLocalDateTime42P18(TestContext ctx) {
404397
LocalDateTime value = LocalDateTime.of(LocalDate.now(), LocalTime.NOON);
405398
String suffix = value.toLocalDate() + " " + value.toLocalTime().format(DateTimeFormatter.ISO_LOCAL_TIME);
406399
testInferDataType42P18(ctx, LocalDateTime.class, value, suffix, "{\"" + suffix + "\"}");
407400
}
408401

409402
@Test
403+
@Repeat(10)
410404
public void testInferDataTypeOffsetDateTime42P18(TestContext ctx) {
411405
OffsetDateTime value = OffsetDateTime.of(LocalDateTime.of(LocalDate.now(), LocalTime.NOON), ZoneOffset.UTC);
412406
String suffix = value.toLocalDate() + " " + value.toLocalTime().format(DateTimeFormatter.ISO_LOCAL_TIME) + "+00";
413407
testInferDataType42P18(ctx, OffsetDateTime.class, value, suffix, "{\"" + suffix + "\"}");
414408
}
415409

416410
@Test
411+
@Repeat(10)
417412
public void testInferDataTypeOffsetInterval42P18(TestContext ctx) {
418413
Interval value = Interval.of(1);
419414
testInferDataType42P18(ctx, Interval.class, value, "1 year", "{\"1 year\"}");
420415
}
421416

422417
@Test
418+
@Repeat(10)
423419
public void testInferDataTypeBuffer42P18(TestContext ctx) {
424420
testInferDataType42P18(ctx, Buffer.class, Buffer.buffer("WORLD"), "\\x574f524c44", "{\"\\\\x574f524c44\"}");
425421
}
426422

427423
@Test
424+
@Repeat(10)
428425
public void testInferDataTypeUUID42P18(TestContext ctx) {
429426
UUID value = UUID.randomUUID();
430427
testInferDataType42P18(ctx, UUID.class, value, "" + value);
431428
}
432429

433430
@Test
431+
@Repeat(10)
434432
public void testInferDataTypeJsonObject42P18(TestContext ctx) {
435433
JsonObject value = new JsonObject().put("foo", "bar");
436434
testInferDataType42P18(ctx, JsonObject.class, value, "" + value, "{\"{\\\"foo\\\":\\\"bar\\\"}\"}");
437435
}
438436

439437
@Test
438+
@Repeat(10)
440439
public void testInferDataTypeJsonArray42P18(TestContext ctx) {
441440
JsonArray value = new JsonArray().add(1).add("foo").add(true);
442441
testInferDataType42P18(ctx, JsonArray.class, value, "" + value, "{\"[1,\\\"foo\\\",true]\"}");
443442
}
444443

445444
@Test
445+
@Repeat(10)
446446
public void testInferDataTypePoint42P18(TestContext ctx) {
447447
Point value = new Point();
448448
testInferDataType42P18(ctx, Point.class, value, "(0,0)", "{\"(0,0)\"}");
449449
}
450450

451451
@Test
452+
@Repeat(10)
452453
public void testInferDataTypeLine42P18(TestContext ctx) {
453454
Line value = new Line(1.0, 0.0, 0.0);
454455
testInferDataType42P18(ctx, Line.class, value, "{1,0,0}", "{\"{1,0,0}\"}");
455456
}
456457

457458
@Test
459+
@Repeat(10)
458460
public void testInferDataTypeLineSegment42P18(TestContext ctx) {
459461
LineSegment value = new LineSegment();
460462
testInferDataType42P18(ctx, LineSegment.class, value, "[(0,0),(0,0)]", "{\"[(0,0),(0,0)]\"}");
461463
}
462464

463465
@Test
466+
@Repeat(10)
464467
public void testInferDataTypeBox42P18(TestContext ctx) {
465468
Box value = new Box();
466469
testInferDataType42P18(ctx, Box.class, value, "(0,0),(0,0)");
467470
}
468471

469472
@Test
473+
@Repeat(10)
470474
public void testInferDataTypePath42P18(TestContext ctx) {
471475
Path value = new Path().addPoint(new Point());
472476
testInferDataType42P18(ctx, Path.class, value, "((0,0))", "{\"((0,0))\"}");
473477
}
474478

475479
@Test
480+
@Repeat(10)
476481
public void testInferDataTypePolygon42P18(TestContext ctx) {
477482
Polygon value = new Polygon().addPoint(new Point()).addPoint(new Point()).addPoint(new Point());
478483
testInferDataType42P18(ctx, Polygon.class, value, "((0,0),(0,0),(0,0))", "{\"((0,0),(0,0),(0,0))\"}");
479484
}
480485

481486
@Test
487+
@Repeat(10)
482488
public void testInferDataTypeCircle42P18(TestContext ctx) {
483489
Circle value = new Circle();
484490
testInferDataType42P18(ctx, Circle.class, value, "<(0,0),0>", "{\"<(0,0),0>\"}");
@@ -510,14 +516,21 @@ private <T> void testInferDataType42P18(TestContext ctx, Class<T> type, T value,
510516
}));
511517
}));
512518
PgConnection.connect(vertx, options()).onComplete(ctx.asyncAssertSuccess(conn -> {
519+
Async async = ctx.async();
513520
conn.begin()
514-
.flatMap(tx -> conn.preparedQuery("SELECT CONCAT('HELLO ', $1)").execute(Tuple.of(value))
515-
.eventually(() -> conn.close())
516-
.onComplete(ctx.asyncAssertFailure(failure -> {
517-
if (!hasSqlstateCode(failure, "42P18")) {
518-
ctx.fail(failure);
519-
}
520-
})));
521+
.compose(tx -> conn.preparedQuery("SELECT CONCAT('HELLO ', $1)").execute(Tuple.of(value)))
522+
.onComplete(ar -> {
523+
if (ar.succeeded()) {
524+
conn.close().onComplete(v -> ctx.fail("Expected failure with SQLSTATE 42P18"));
525+
return;
526+
}
527+
Throwable failure = ar.cause();
528+
if (!hasSqlstateCode(failure, "42P18")) {
529+
conn.close().onComplete(ctx.asyncAssertSuccess(v -> ctx.fail(failure)));
530+
return;
531+
}
532+
conn.close().onComplete(v -> async.complete());
533+
});
521534
}));
522535
}
523536

0 commit comments

Comments
 (0)