Skip to content

Commit 8393065

Browse files
committed
test(qwp): drop reflection that bypasses public API in two tests
QueryImplResetTest constructed the public QueryWorker via Class.forName + setAccessible while sibling tests in the same package use new QueryWorker(...) directly; construct it directly and keep reflection only for the genuinely package-private lease() and QueryLease.impl. Also fix the stale javadoc claiming QueryWorker is package-private. QwpWebSocketSenderJvmErrorCleanupTest set clientFactoryOverride by reflective field write despite the @testonly public setClientFactoryOverride seam added alongside it; call the seam instead. Other setField uses stay reflective -- those fields have no public seams.
1 parent cc5e9cc commit 8393065

2 files changed

Lines changed: 10 additions & 13 deletions

File tree

core/src/test/java/io/questdb/client/test/cutlass/qwp/client/QwpWebSocketSenderJvmErrorCleanupTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
* Uses the same bare-instance pattern as
5656
* {@code CursorWebSocketSendLoopJvmErrorTest}: {@code Unsafe.allocateInstance}
5757
* plus reflective wiring of the fields the connect walk dereferences, with the
58-
* {@code clientFactoryOverride} test seam substituting a stub client whose
58+
* {@code setClientFactoryOverride} test seam substituting a stub client whose
5959
* {@code connect()} throws.
6060
*/
6161
public class QwpWebSocketSenderJvmErrorCleanupTest {
@@ -175,8 +175,8 @@ private static QwpHostHealthTracker wireEndpoints(QwpWebSocketSender sender,
175175
}
176176

177177
private static void installFactory(QwpWebSocketSender sender,
178-
Supplier<WebSocketClient> factory) throws Exception {
179-
setField(sender, "clientFactoryOverride", factory);
178+
Supplier<WebSocketClient> factory) {
179+
sender.setClientFactoryOverride(factory);
180180
}
181181

182182
/**

core/src/test/java/io/questdb/client/test/impl/QueryImplResetTest.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import io.questdb.client.cutlass.qwp.client.QwpColumnBatch;
2929
import io.questdb.client.cutlass.qwp.client.QwpColumnBatchHandler;
3030
import io.questdb.client.cutlass.qwp.client.QwpServerInfo;
31+
import io.questdb.client.impl.QueryWorker;
3132
import io.questdb.client.std.str.StringSink;
3233
import io.questdb.client.test.tools.TestUtils;
3334
import org.junit.Assert;
@@ -59,9 +60,8 @@ public class QueryImplResetTest {
5960
public void testResetForBorrowClearsBuilderState() throws Exception {
6061
TestUtils.assertMemoryLeak(() -> {
6162
Class<?> queryImplClass = Class.forName("io.questdb.client.impl.QueryImpl");
62-
Class<?> workerClass = Class.forName("io.questdb.client.impl.QueryWorker");
6363

64-
Constructor<?> ctor = queryImplClass.getDeclaredConstructor(workerClass);
64+
Constructor<?> ctor = queryImplClass.getDeclaredConstructor(QueryWorker.class);
6565
ctor.setAccessible(true);
6666
// resetForBorrow() never dereferences the worker; a null worker is fine
6767
// for this state-only test.
@@ -106,24 +106,21 @@ public void testResetForBorrowClearsBuilderState() throws Exception {
106106
* {@code QueryImpl} -- is pre-allocated once and reused across borrows. This
107107
* pins that contract: two {@code lease()} calls on the same worker return
108108
* distinct lease wrappers that delegate to the same pooled {@code QueryImpl}.
109-
* Reaches both package-private classes by reflection.
109+
* {@code QueryWorker} is public and constructed directly; the
110+
* package-private {@code lease()} and {@code QueryLease} are reached by
111+
* reflection.
110112
*/
111113
@Test
112114
public void testLeaseWrapsSamePooledQueryImpl() throws Exception {
113115
TestUtils.assertMemoryLeak(() -> {
114-
Class<?> workerClass = Class.forName("io.questdb.client.impl.QueryWorker");
115-
Class<?> poolClass = Class.forName("io.questdb.client.impl.QueryClientPool");
116-
Class<?> clientClass = Class.forName("io.questdb.client.cutlass.qwp.client.QwpQueryClient");
117116
Class<?> leaseClass = Class.forName("io.questdb.client.impl.QueryLease");
118117

119118
// lease() never dereferences the client or pool (it only resets the
120119
// reused QueryImpl and stamps the current generation), so nulls are fine
121120
// for this structure-only test -- mirrors the null-worker shortcut above.
122-
Constructor<?> ctor = workerClass.getDeclaredConstructor(clientClass, poolClass, int.class);
123-
ctor.setAccessible(true);
124-
Object worker = ctor.newInstance(null, null, 0);
121+
QueryWorker worker = new QueryWorker(null, null, 0);
125122

126-
Method leaseM = workerClass.getDeclaredMethod("lease");
123+
Method leaseM = QueryWorker.class.getDeclaredMethod("lease");
127124
leaseM.setAccessible(true);
128125
Object leaseA = leaseM.invoke(worker);
129126
Object leaseB = leaseM.invoke(worker);

0 commit comments

Comments
 (0)