Skip to content

Commit 4120e6b

Browse files
authored
Fix timing-related test failure in SessionsProseTest (#1325)
There are two tests in AbstractSessionsProseTest that rely on a running mongocryptd process. Each test starts and destroys the process, and it appears that occasionally the destruction in the first test interferes with the starting in the second test, and the second test fails to connect to the mongocryptd process. This commit attempts to work around this by starting a single mongocryptd process and use it for both tests. Note that AbstractSessionsProseTest has two subclasses and therefore the mongocryptd process is still actually started and destroyed twice, it doesn't seem to be a problem in practice because the two subclasses are in different modules and there is enough time between their execution that there is interference. JAVA-4998
1 parent 3f5f18e commit 4120e6b

File tree

1 file changed

+73
-63
lines changed

1 file changed

+73
-63
lines changed

driver-sync/src/test/functional/com/mongodb/client/AbstractSessionsProseTest.java

Lines changed: 73 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import com.mongodb.event.CommandStartedEvent;
2828
import org.bson.BsonDocument;
2929
import org.bson.Document;
30+
import org.junit.jupiter.api.AfterAll;
31+
import org.junit.jupiter.api.BeforeAll;
3032
import org.junit.jupiter.api.Test;
3133

3234
import java.io.File;
@@ -55,9 +57,25 @@
5557
public abstract class AbstractSessionsProseTest {
5658

5759
private static final int MONGOCRYPTD_PORT = 47017;
60+
private static Process mongocryptdProcess;
5861

5962
protected abstract MongoClient getMongoClient(MongoClientSettings settings);
6063

64+
@BeforeAll
65+
public static void beforeAll() throws IOException {
66+
if (serverVersionAtLeast(4, 2)) {
67+
mongocryptdProcess = startMongocryptdProcess();
68+
}
69+
}
70+
71+
@AfterAll
72+
public static void afterAll() {
73+
if (mongocryptdProcess != null) {
74+
mongocryptdProcess.destroy();
75+
mongocryptdProcess = null;
76+
}
77+
}
78+
6179
// Test 13 from #13-existing-sessions-are-not-checked-into-a-cleared-pool-after-forking
6280
@Test
6381
public void shouldCreateServerSessionOnlyAfterConnectionCheckout() throws InterruptedException {
@@ -119,78 +137,69 @@ public void commandStarted(final CommandStartedEvent event) {
119137
@Test
120138
public void shouldIgnoreImplicitSessionIfConnectionDoesNotSupportSessions() throws IOException {
121139
assumeTrue(serverVersionAtLeast(4, 2));
122-
Process mongocryptdProcess = startMongocryptdProcess("1");
123-
try {
124-
// initialize to true in case the command listener is never actually called, in which case the assertFalse will fire
125-
AtomicBoolean containsLsid = new AtomicBoolean(true);
126-
try (MongoClient client = getMongoClient(
127-
getMongocryptdMongoClientSettingsBuilder()
128-
.addCommandListener(new CommandListener() {
129-
@Override
130-
public void commandStarted(final CommandStartedEvent event) {
131-
containsLsid.set(event.getCommand().containsKey("lsid"));
132-
}
133-
})
134-
.build())) {
135-
136-
Document helloResponse = client.getDatabase("admin").runCommand(new Document("hello", 1));
137-
assertFalse((helloResponse.containsKey("logicalSessionTimeoutMinutes")));
138-
139-
MongoCollection<Document> collection = client.getDatabase(getDefaultDatabaseName()).getCollection(getClass().getName());
140-
try {
141-
collection.find().first();
142-
} catch (MongoCommandException e) {
143-
// ignore command errors from mongocryptd
144-
}
145-
assertFalse(containsLsid.get());
146140

147-
// reset
148-
containsLsid.set(true);
141+
// initialize to true in case the command listener is never actually called, in which case the assertFalse will fire
142+
AtomicBoolean containsLsid = new AtomicBoolean(true);
143+
try (MongoClient client = getMongoClient(
144+
getMongocryptdMongoClientSettingsBuilder()
145+
.addCommandListener(new CommandListener() {
146+
@Override
147+
public void commandStarted(final CommandStartedEvent event) {
148+
containsLsid.set(event.getCommand().containsKey("lsid"));
149+
}
150+
})
151+
.build())) {
152+
153+
Document helloResponse = client.getDatabase("admin").runCommand(new Document("hello", 1));
154+
assertFalse((helloResponse.containsKey("logicalSessionTimeoutMinutes")));
149155

150-
try {
151-
collection.insertOne(new Document());
152-
} catch (MongoCommandException e) {
153-
// ignore command errors from mongocryptd
154-
}
155-
assertFalse(containsLsid.get());
156+
MongoCollection<Document> collection = client.getDatabase(getDefaultDatabaseName()).getCollection(getClass().getName());
157+
try {
158+
collection.find().first();
159+
} catch (MongoCommandException e) {
160+
// ignore command errors from mongocryptd
156161
}
157-
} finally {
158-
mongocryptdProcess.destroy();
162+
assertFalse(containsLsid.get());
163+
164+
// reset
165+
containsLsid.set(true);
166+
167+
try {
168+
collection.insertOne(new Document());
169+
} catch (MongoCommandException e) {
170+
// ignore command errors from mongocryptd
171+
}
172+
assertFalse(containsLsid.get());
159173
}
160174
}
161175

162176
// Test 19 from #19-explicit-session-raises-an-error-if-connection-does-not-support-sessions
163177
@Test
164178
public void shouldThrowOnExplicitSessionIfConnectionDoesNotSupportSessions() throws IOException {
165179
assumeTrue(serverVersionAtLeast(4, 2));
166-
Process mongocryptdProcess = startMongocryptdProcess("2");
167-
try {
168-
try (MongoClient client = getMongoClient(getMongocryptdMongoClientSettingsBuilder().build())) {
169-
MongoCollection<Document> collection = client.getDatabase(getDefaultDatabaseName()).getCollection(getClass().getName());
170-
171-
Document helloResponse = client.getDatabase("admin").runCommand(new Document("hello", 1));
172-
assertFalse((helloResponse.containsKey("logicalSessionTimeoutMinutes")));
173-
174-
try (ClientSession session = client.startSession()) {
175-
String expectedClientExceptionMessage =
176-
"Attempting to use a ClientSession while connected to a server that doesn't support sessions";
177-
try {
178-
collection.find(session).first();
179-
fail("Expected MongoClientException");
180-
} catch (MongoClientException e) {
181-
assertEquals(expectedClientExceptionMessage, e.getMessage());
182-
}
183-
184-
try {
185-
collection.insertOne(session, new Document());
186-
fail("Expected MongoClientException");
187-
} catch (MongoClientException e) {
188-
assertEquals(expectedClientExceptionMessage, e.getMessage());
189-
}
180+
try (MongoClient client = getMongoClient(getMongocryptdMongoClientSettingsBuilder().build())) {
181+
MongoCollection<Document> collection = client.getDatabase(getDefaultDatabaseName()).getCollection(getClass().getName());
182+
183+
Document helloResponse = client.getDatabase("admin").runCommand(new Document("hello", 1));
184+
assertFalse((helloResponse.containsKey("logicalSessionTimeoutMinutes")));
185+
186+
try (ClientSession session = client.startSession()) {
187+
String expectedClientExceptionMessage =
188+
"Attempting to use a ClientSession while connected to a server that doesn't support sessions";
189+
try {
190+
collection.find(session).first();
191+
fail("Expected MongoClientException");
192+
} catch (MongoClientException e) {
193+
assertEquals(expectedClientExceptionMessage, e.getMessage());
194+
}
195+
196+
try {
197+
collection.insertOne(session, new Document());
198+
fail("Expected MongoClientException");
199+
} catch (MongoClientException e) {
200+
assertEquals(expectedClientExceptionMessage, e.getMessage());
190201
}
191202
}
192-
} finally {
193-
mongocryptdProcess.destroy();
194203
}
195204
}
196205

@@ -200,10 +209,11 @@ private static MongoClientSettings.Builder getMongocryptdMongoClientSettingsBuil
200209
builder.hosts(singletonList(new ServerAddress("localhost", MONGOCRYPTD_PORT))));
201210
}
202211

203-
private static Process startMongocryptdProcess(final String pidSuffix) throws IOException {
212+
private static Process startMongocryptdProcess() throws IOException {
213+
String port = Integer.toString(MONGOCRYPTD_PORT);
204214
ProcessBuilder processBuilder = new ProcessBuilder(asList("mongocryptd",
205-
"--port", Integer.toString(MONGOCRYPTD_PORT),
206-
"--pidfilepath", "mongocryptd-" + pidSuffix + ".pid"));
215+
"--port", port,
216+
"--pidfilepath", "mongocryptd-" + port + ".pid"));
207217
processBuilder.redirectErrorStream(true);
208218
processBuilder.redirectOutput(new File("/tmp/mongocryptd.log"));
209219
return processBuilder.start();

0 commit comments

Comments
 (0)