or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration-initialization.mdconnection-access.mdcontainer-management.mdindex.mdwait-strategies-delegation.md

wait-strategies-delegation.mddocs/

0

# Wait Strategies and Database Delegation

1

2

Advanced wait strategies and database operation delegation for ensuring container readiness and executing database operations.

3

4

## Capabilities

5

6

### Cassandra Query Wait Strategy

7

8

Custom wait strategy that ensures Cassandra is ready to accept CQL queries before considering the container ready for use.

9

10

```java { .api }

11

/**

12

* Waits until Cassandra returns its version by executing a query.

13

* This strategy ensures the database is not only running but ready to process CQL queries.

14

*/

15

public class CassandraQueryWaitStrategy extends AbstractWaitStrategy {

16

/**

17

* Wait until Cassandra is ready by executing version query.

18

* Executes "SELECT release_version FROM system.local" until success or timeout.

19

*/

20

protected void waitUntilReady();

21

}

22

```

23

24

**Usage Examples:**

25

26

```java

27

import org.testcontainers.cassandra.CassandraContainer;

28

import org.testcontainers.cassandra.wait.CassandraQueryWaitStrategy;

29

30

// The CassandraContainer uses CassandraQueryWaitStrategy by default

31

CassandraContainer cassandra = new CassandraContainer("cassandra:3.11.2");

32

// No need to explicitly set wait strategy - it's automatic

33

34

// Manual wait strategy configuration (if needed for customization)

35

CassandraContainer cassandra = new CassandraContainer("cassandra:3.11.2")

36

.waitingFor(new CassandraQueryWaitStrategy());

37

```

38

39

**Wait Strategy Process:**

40

41

1. Container starts and basic Docker health checks pass

42

2. Wait strategy begins executing test queries

43

3. Retries "SELECT release_version FROM system.local" query

44

4. Continues until query succeeds or timeout is reached

45

5. Container is marked ready only after successful query execution

46

47

**Timeout Configuration:**

48

49

```java

50

// Custom timeout (inherits from AbstractWaitStrategy)

51

CassandraContainer cassandra = new CassandraContainer("cassandra:3.11.2")

52

.waitingFor(new CassandraQueryWaitStrategy()

53

.withStartupTimeout(Duration.ofMinutes(5)));

54

```

55

56

### Database Delegate for Script Execution

57

58

Database delegate that handles CQL script and statement execution via the cqlsh command inside the container.

59

60

```java { .api }

61

/**

62

* Cassandra database delegate for executing CQL statements and scripts.

63

* Uses cqlsh command directly inside the container for maximum compatibility.

64

*/

65

public class CassandraDatabaseDelegate extends AbstractDatabaseDelegate<Void> {

66

/**

67

* Create database delegate for the given container

68

* @param container Container state for accessing the running container

69

*/

70

public CassandraDatabaseDelegate(ContainerState container);

71

72

/**

73

* Execute CQL statement or script file

74

* @param statement CQL statement to execute (if not null/empty)

75

* @param scriptPath Path to script file inside container (if statement is null/empty)

76

* @param lineNumber Line number for error reporting

77

* @param continueOnError Whether to continue execution on error

78

* @param ignoreFailedDrops Whether to ignore failed DROP statements

79

*/

80

public void execute(

81

String statement,

82

String scriptPath,

83

int lineNumber,

84

boolean continueOnError,

85

boolean ignoreFailedDrops

86

);

87

}

88

```

89

90

**Internal Usage:**

91

92

The database delegate is primarily used internally by the container for:

93

- Executing initialization scripts via `withInitScript()`

94

- Wait strategy query execution

95

- Internal database operations

96

97

**Execution Methods:**

98

99

```java

100

// Statement execution (used internally)

101

delegate.execute("CREATE KEYSPACE test WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}",

102

null, 1, false, false);

103

104

// Script file execution (used internally)

105

delegate.execute(null, "/tmp/init.cql", -1, false, false);

106

```

107

108

**Command Generation:**

109

110

The delegate constructs cqlsh commands based on container configuration:

111

112

```bash

113

# Basic command

114

cqlsh -e "SELECT release_version FROM system.local"

115

116

# With authentication (when container has auth enabled)

117

cqlsh -u cassandra -p cassandra -e "SELECT release_version FROM system.local"

118

119

# Script file execution

120

cqlsh -f /tmp/init.cql

121

122

# With authentication for script

123

cqlsh -u cassandra -p cassandra -f /tmp/init.cql

124

```

125

126

### Error Handling and Exceptions

127

128

Both wait strategies and database delegates handle various error conditions:

129

130

**Wait Strategy Errors:**

131

132

```java

133

import org.testcontainers.containers.ContainerLaunchException;

134

135

try {

136

cassandra.start();

137

} catch (ContainerLaunchException e) {

138

// Wait strategy timeout or query execution failure

139

if (e.getMessage().contains("Timed out waiting for Cassandra")) {

140

logger.error("Cassandra failed to become ready within timeout", e);

141

}

142

}

143

```

144

145

**Database Delegate Errors:**

146

147

```java

148

import org.testcontainers.ext.ScriptUtils.ScriptStatementFailedException;

149

150

// These exceptions are thrown internally and propagated through container methods

151

try {

152

cassandra.withInitScript("invalid-script.cql").start();

153

} catch (ScriptStatementFailedException e) {

154

logger.error("CQL script execution failed at line " + e.getLineNumber(), e);

155

}

156

```

157

158

### Custom Wait Strategy Implementation

159

160

For advanced use cases, you can extend the wait strategy:

161

162

```java

163

import org.testcontainers.cassandra.wait.CassandraQueryWaitStrategy;

164

165

public class CustomCassandraWaitStrategy extends CassandraQueryWaitStrategy {

166

@Override

167

protected void waitUntilReady() {

168

// Custom readiness logic

169

super.waitUntilReady(); // Execute standard version query

170

171

// Additional custom checks

172

DatabaseDelegate delegate = new CassandraDatabaseDelegate(waitStrategyTarget);

173

delegate.execute("SELECT COUNT(*) FROM system.peers", "", 1, false, false);

174

}

175

}

176

177

// Usage

178

CassandraContainer cassandra = new CassandraContainer("cassandra:3.11.2")

179

.waitingFor(new CustomCassandraWaitStrategy());

180

```

181

182

## Deprecated Wait Strategy and Delegate

183

184

Legacy implementations in the `org.testcontainers.containers` package are deprecated:

185

186

```java { .api }

187

/**

188

* @deprecated use org.testcontainers.cassandra.wait.CassandraQueryWaitStrategy instead

189

*/

190

@Deprecated

191

public class CassandraQueryWaitStrategy extends AbstractWaitStrategy {

192

protected void waitUntilReady();

193

}

194

195

/**

196

* @deprecated use org.testcontainers.cassandra.delegate.CassandraDatabaseDelegate instead

197

*/

198

@Deprecated

199

public class CassandraDatabaseDelegate extends AbstractDatabaseDelegate<Session> {

200

public CassandraDatabaseDelegate(ContainerState container);

201

public void execute(String statement, String scriptPath, int lineNumber,

202

boolean continueOnError, boolean ignoreFailedDrops);

203

}

204

```

205

206

**Key Differences:**

207

208

- **Current implementation**: Uses cqlsh command execution, returns `Void` connection type

209

- **Deprecated implementation**: Uses DataStax driver Session objects, requires driver 3.x dependency

210

211

The current implementation is more robust and doesn't require specific driver versions, making it more suitable for diverse testing environments.