Skip to content

Commit a588557

Browse files
committed
test: wait in startTarantool() / stopTarantool()
It fixes race conditions in testLongParallelCloseReconnects: an attempt to start jdk-testing instance against already started one could be performed because stopTarantool() did not wait until an instance will really stop. Use these functions in setupEnv() / cleanupEnv() to avoid possible race conditions.
1 parent 292671e commit a588557

File tree

2 files changed

+93
-6
lines changed

2 files changed

+93
-6
lines changed

src/test/java/org/tarantool/AbstractTarantoolConnectorIT.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public abstract class AbstractTarantoolConnectorIT {
8282
@BeforeAll
8383
public static void setupEnv() {
8484
control = new TarantoolControl();
85-
control.start("jdk-testing");
85+
startTarantool("jdk-testing");
8686

8787
console = openConsole();
8888

@@ -104,7 +104,7 @@ public static void cleanupEnv() {
104104

105105
console.close();
106106
} finally {
107-
control.stop("jdk-testing");
107+
stopTarantool("jdk-testing");
108108
}
109109
}
110110

@@ -189,12 +189,14 @@ protected List<?> consoleSelect(String spaceName, Object key) {
189189
return console.eval(sb.toString());
190190
}
191191

192-
protected void stopTarantool(String instance) {
192+
protected static void stopTarantool(String instance) {
193193
control.stop(instance);
194+
control.waitStopped("jdk-testing");
194195
}
195196

196-
protected void startTarantool(String instance) {
197+
protected static void startTarantool(String instance) {
197198
control.start(instance);
199+
control.waitStarted("jdk-testing");
198200
}
199201

200202
/**

src/test/java/org/tarantool/TarantoolControl.java

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,20 @@
1616
* Wrapper around tarantoolctl utility.
1717
*/
1818
public class TarantoolControl {
19+
public class TarantoolControlException extends RuntimeException {
20+
int code;
21+
String stdout;
22+
String stderr;
23+
24+
TarantoolControlException(int code, String stdout, String stderr) {
25+
super("returned exitcode " + code + "\n" +
26+
"[stdout]\n" + stdout + "\n[stderr]\n" + stderr);
27+
this.code = code;
28+
this.stdout = stdout;
29+
this.stderr = stderr;
30+
}
31+
}
32+
1933
protected static final String tntCtlWorkDir = System.getProperty("tntCtlWorkDir",
2034
new File("testroot").getAbsolutePath());
2135
protected static final String instanceDir = new File("src/test").getAbsolutePath();
@@ -163,16 +177,87 @@ public void run() {
163177
} catch (IOException e) {
164178
/* No-op. */
165179
}
166-
throw new RuntimeException("returned exitcode " + code + "\n" +
167-
"[stdout]\n" + stdout + "\n[stderr]\n" + stderr);
180+
throw new TarantoolControlException(code, stdout, stderr);
181+
}
182+
}
183+
184+
/**
185+
* Wait until the instance will be started.
186+
*
187+
* Use tarantoolctl status instanceName.
188+
*
189+
* Then test the instance with TarantoolTcpConsole (ADMIN environment
190+
* variable is set) or TarantoolLocalConsole.
191+
*
192+
* XXX: Now TarantoolLocalConsole is used unconditionally, see
193+
* openConsole().
194+
*/
195+
public void waitStarted(String instanceName) {
196+
while (status(instanceName) != 0)
197+
sleep();
198+
199+
while (true) {
200+
try {
201+
openConsole(instanceName).close();
202+
break;
203+
} catch (Exception ignored) {
204+
/* No-op. */
205+
}
206+
sleep();
168207
}
169208
}
170209

210+
/**
211+
* Wait until the instance will be stopped.
212+
*
213+
* Use tarantoolctl status instanceName.
214+
*/
215+
public void waitStopped(String instanceName) {
216+
while (status(instanceName) != 1)
217+
sleep();
218+
}
219+
171220
public void start(String instanceName) {
172221
executeCommand("start", instanceName);
173222
}
174223

175224
public void stop(String instanceName) {
176225
executeCommand("stop", instanceName);
177226
}
227+
228+
/**
229+
* Wrapper for `tarantoolctl status instanceName`.
230+
*
231+
* Return exit code of the command:
232+
*
233+
* * 0 -- started;
234+
* * 1 -- stopped;
235+
* * 2 -- pid file exists, control socket inaccessible.
236+
*/
237+
public int status(String instanceName) {
238+
try {
239+
executeCommand("status", instanceName);
240+
} catch (TarantoolControlException e) {
241+
return e.code;
242+
}
243+
244+
return 0;
245+
}
246+
247+
/*
248+
* XXX: This function is planned to use text console (from ADMIN
249+
* environment variable) when it is available for the instance and
250+
* fallback to TarantoolLocalConsole.
251+
*/
252+
public TarantoolConsole openConsole(String instanceName) {
253+
return TarantoolConsole.open(tntCtlWorkDir, instanceName);
254+
}
255+
256+
public static void sleep() {
257+
try {
258+
Thread.sleep(100);
259+
} catch (InterruptedException e) {
260+
throw new RuntimeException(e);
261+
}
262+
}
178263
}

0 commit comments

Comments
 (0)