or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdmulti-node-spec.mdsystem-properties.mdtest-conductor.mdtest-configuration.md

test-configuration.mddocs/

0

# Test Configuration

1

2

The MultiNodeConfig class provides the foundation for configuring multi-node tests, including participant roles, Akka settings, and deployment configurations.

3

4

## MultiNodeConfig Class

5

6

```scala { .api }

7

abstract class MultiNodeConfig {

8

def commonConfig(config: Config): Unit

9

def nodeConfig(roles: RoleName*)(configs: Config*): Unit

10

def role(name: String): RoleName

11

def debugConfig(on: Boolean): Config

12

def deployOn(role: RoleName, deployment: String): Unit

13

def deployOnAll(deployment: String): Unit

14

def testTransport(on: Boolean): Unit

15

}

16

```

17

18

### Configuration Methods

19

20

#### Common Configuration

21

22

```scala { .api }

23

def commonConfig(config: Config): Unit

24

```

25

26

Registers a common base configuration that applies to all test participants. This is typically used for shared Akka settings.

27

28

**Usage Example:**

29

30

```scala

31

object MyMultiNodeConfig extends MultiNodeConfig {

32

commonConfig(ConfigFactory.parseString("""

33

akka {

34

actor.provider = remote

35

loglevel = "INFO"

36

remote.artery.canonical.port = 0

37

}

38

"""))

39

}

40

```

41

42

#### Node-Specific Configuration

43

44

```scala { .api }

45

def nodeConfig(roles: RoleName*)(configs: Config*): Unit

46

```

47

48

Registers configuration overrides for specific participants. Multiple roles can share the same configuration, and multiple configs are merged with fallback behavior.

49

50

**Usage Example:**

51

52

```scala

53

val first = role("first")

54

val second = role("second")

55

val third = role("third")

56

57

// Configure first node with specific settings

58

nodeConfig(first)(ConfigFactory.parseString("""

59

akka.cluster.roles = ["seed"]

60

"""))

61

62

// Configure second and third nodes with shared settings

63

nodeConfig(second, third)(ConfigFactory.parseString("""

64

akka.cluster.roles = ["worker"]

65

"""))

66

```

67

68

#### Role Creation

69

70

```scala { .api }

71

def role(name: String): RoleName

72

```

73

74

Creates and registers a new role name for test participants. Each role name must be unique within the test configuration.

75

76

**Usage Example:**

77

78

```scala

79

object ClusterTestConfig extends MultiNodeConfig {

80

val controller = role("controller")

81

val worker1 = role("worker1")

82

val worker2 = role("worker2")

83

val observer = role("observer")

84

}

85

```

86

87

**Parameters:**

88

- `name: String` - Unique name for the role

89

90

**Returns:** `RoleName` - Role identifier for use in test execution

91

92

**Throws:** `IllegalArgumentException` if role name is not unique

93

94

#### Debug Configuration

95

96

```scala { .api }

97

def debugConfig(on: Boolean): Config

98

```

99

100

Generates debug configuration for verbose logging of actor and remoting operations.

101

102

**Usage Example:**

103

104

```scala

105

commonConfig(debugConfig(on = true).withFallback(baseConfig))

106

```

107

108

**Parameters:**

109

- `on: Boolean` - When true, enables debug logging for actors and remoting

110

111

**Returns:** `Config` - Configuration with debug settings or empty config

112

113

### Deployment Configuration

114

115

#### Role-Specific Deployment

116

117

```scala { .api }

118

def deployOn(role: RoleName, deployment: String): Unit

119

```

120

121

Configures actor deployment for a specific role. Deployment strings use HOCON format and support address replacement tokens.

122

123

**Usage Example:**

124

125

```scala

126

deployOn(worker1, """

127

/myActor {

128

remote = "@worker2@/user/service"

129

router = round-robin-pool

130

nr-of-instances = 3

131

}

132

""")

133

```

134

135

#### Global Deployment

136

137

```scala { .api }

138

def deployOnAll(deployment: String): Unit

139

```

140

141

Configures actor deployment that applies to all roles.

142

143

**Usage Example:**

144

145

```scala

146

deployOnAll("""

147

/globalService {

148

router = consistent-hashing-pool

149

nr-of-instances = 5

150

}

151

""")

152

```

153

154

### Network Testing Configuration

155

156

#### Test Transport

157

158

```scala { .api }

159

def testTransport(on: Boolean): Unit

160

```

161

162

Enables or disables the test transport mode required for network failure injection features like blackhole, passThrough, and throttle.

163

164

**Usage Example:**

165

166

```scala

167

object NetworkTestConfig extends MultiNodeConfig {

168

testTransport(on = true) // Required for failure injection

169

170

val node1 = role("node1")

171

val node2 = role("node2")

172

}

173

174

class NetworkFailureTest extends MultiNodeSpec(NetworkTestConfig) {

175

"network test" must {

176

"simulate network partition" in {

177

testConductor.blackhole(node1, node2, Direction.Both).await

178

// Test behavior during network partition

179

}

180

}

181

}

182

```

183

184

**Parameters:**

185

- `on: Boolean` - Enable test transport adapters when true

186

187

**Note:** Must be enabled before using blackhole, passThrough, or throttle methods in TestConductor.

188

189

## Configuration Properties

190

191

The MultiNodeConfig provides several read-only properties for accessing configuration state:

192

193

```scala { .api }

194

// Internal properties (read-only)

195

private[testkit] def myself: RoleName // Current node's role

196

private[akka] def config: Config // Computed final configuration

197

private[testkit] def deployments(node: RoleName): immutable.Seq[String] // Node deployments

198

private[testkit] def roles: immutable.Seq[RoleName] // All registered roles

199

```

200

201

## Address Replacement Tokens

202

203

Deployment configurations support address replacement tokens that are resolved at runtime:

204

205

```scala

206

deployOn(serviceNode, """

207

/client {

208

remote = "@dataNode@/user/database"

209

}

210

""")

211

```

212

213

**Available Tokens:**

214

- `@roleName@` - Replaced with the actual network address of the specified role

215

216

## Configuration Inheritance

217

218

Configuration follows a layered approach with fallback behavior:

219

220

1. **Node-specific config** (highest priority)

221

2. **Common config**

222

3. **Test transport config** (if enabled)

223

4. **Base MultiNodeSpec config**

224

5. **Default Akka config** (lowest priority)

225

226

## Complete Configuration Example

227

228

```scala

229

object ComplexMultiNodeConfig extends MultiNodeConfig {

230

// Define roles

231

val seed = role("seed")

232

val worker1 = role("worker1")

233

val worker2 = role("worker2")

234

val client = role("client")

235

236

// Common configuration for all nodes

237

commonConfig(ConfigFactory.parseString("""

238

akka {

239

actor.provider = remote

240

cluster {

241

seed-nodes = []

242

auto-down-unreachable-after = 10s

243

}

244

remote.artery.canonical.port = 0

245

}

246

"""))

247

248

// Seed node specific configuration

249

nodeConfig(seed)(ConfigFactory.parseString("""

250

akka.cluster.roles = ["seed"]

251

"""))

252

253

// Worker nodes configuration

254

nodeConfig(worker1, worker2)(ConfigFactory.parseString("""

255

akka.cluster.roles = ["worker"]

256

"""))

257

258

// Client node configuration

259

nodeConfig(client)(ConfigFactory.parseString("""

260

akka.cluster.roles = ["client"]

261

"""))

262

263

// Enable network failure injection

264

testTransport(on = true)

265

266

// Deploy services on specific nodes

267

deployOn(worker1, """

268

/workerService {

269

router = round-robin-pool

270

nr-of-instances = 2

271

}

272

""")

273

274

deployOn(client, """

275

/clientService {

276

remote = "@worker1@/user/workerService"

277

}

278

""")

279

280

// Global deployment

281

deployOnAll("""

282

/monitor {

283

dispatcher = "akka.actor.default-dispatcher"

284

}

285

""")

286

}

287

```