Skip to content

Commit 5105484

Browse files
committed
Introduce a simple deterministic reproducer
JAVA-5516
1 parent 3f6bca4 commit 5105484

File tree

2 files changed

+59
-19
lines changed

2 files changed

+59
-19
lines changed

driver-core/src/test/functional/com/mongodb/internal/operation/AsyncCommandBatchCursorFunctionalTest.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
import java.util.ArrayList;
4646
import java.util.List;
4747
import java.util.concurrent.CountDownLatch;
48-
import java.util.concurrent.ForkJoinPool;
4948
import java.util.concurrent.TimeUnit;
5049
import java.util.concurrent.atomic.AtomicInteger;
5150
import java.util.stream.Collectors;
@@ -300,24 +299,6 @@ void testLimitWithGetMore() {
300299
assertTrue(cursor.isClosed());
301300
}
302301

303-
@Test
304-
void attemptJava5516() {
305-
BsonDocument commandResult = executeFindCommand(5, 2);
306-
cursor = new AsyncCommandBatchCursor<>(commandResult, 2, 0, DOCUMENT_DECODER,
307-
null, connectionSource, connection);
308-
assertNotNull(cursorNext());
309-
// Calling `close` twice is the key to reproducing.
310-
// It does not matter whether we call `close` twice from the same thread or not.
311-
ForkJoinPool.commonPool().execute(() -> cursor.close());
312-
ForkJoinPool.commonPool().execute(() -> cursor.close());
313-
try {
314-
assertNotNull(cursorNext());
315-
assertNotNull(cursorNext());
316-
} catch (IllegalStateException e) {
317-
// one of the expected outcomes, because we call `cursorNext` concurrently with `close`
318-
}
319-
}
320-
321302
@Test
322303
@DisplayName("test limit with large documents")
323304
void testLimitWithLargeDocuments() {
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
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.
15+
*/
16+
package com.mongodb.internal.operation;
17+
18+
import com.mongodb.MongoNamespace;
19+
import com.mongodb.ServerCursor;
20+
import com.mongodb.internal.binding.AsyncConnectionSource;
21+
import com.mongodb.internal.binding.ReferenceCounted;
22+
import com.mongodb.internal.connection.Connection;
23+
import com.mongodb.internal.mockito.MongoMockito;
24+
import org.junit.jupiter.api.Test;
25+
26+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
27+
import static org.mockito.Mockito.when;
28+
29+
final class CursorResourceManagerTest {
30+
@Test
31+
void doubleCloseExecutedConcurrentlyWithOperationBeingInProgressShouldNotFail() {
32+
CursorResourceManager<?, ?> cursorResourceManager = new CursorResourceManager<ReferenceCounted, ReferenceCounted>(
33+
new MongoNamespace("db", "coll"),
34+
MongoMockito.mock(AsyncConnectionSource.class, mock -> {
35+
when(mock.retain()).thenReturn(mock);
36+
when(mock.release()).thenReturn(1);
37+
}),
38+
null,
39+
MongoMockito.mock(ServerCursor.class)) {
40+
@Override
41+
void markAsPinned(final ReferenceCounted connectionToPin, final Connection.PinningMode pinningMode) {
42+
}
43+
44+
@Override
45+
void doClose() {
46+
}
47+
};
48+
cursorResourceManager.tryStartOperation();
49+
try {
50+
assertDoesNotThrow(() -> {
51+
cursorResourceManager.close();
52+
cursorResourceManager.close();
53+
cursorResourceManager.setServerCursor(null);
54+
});
55+
} finally {
56+
cursorResourceManager.endOperation();
57+
}
58+
}
59+
}

0 commit comments

Comments
 (0)