or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

event-handling.mdframework-integration.mdindex.mdjs-platform.mdjvm-platform.mdnative-platform.mdtest-discovery.md

native-platform.mddocs/

0

# Native Platform Support

1

2

Scala Native test runner optimized for native compilation with efficient memory usage and native-specific execution patterns. Provides cross-platform compatibility for native executables.

3

4

## Capabilities

5

6

### ZTestRunnerNative Base Class

7

8

Abstract base class for Scala Native test runners that provides common functionality optimized for native compilation and execution.

9

10

```scala { .api }

11

/**

12

* Base Scala Native test runner with master/slave architecture support

13

* Optimized for native compilation with efficient memory usage

14

*/

15

sealed abstract class ZTestRunnerNative(

16

val args: Array[String],

17

remoteArgs0: Array[String],

18

testClassLoader: ClassLoader,

19

runnerType: String

20

) extends Runner {

21

/** Get remote execution arguments */

22

def remoteArgs(): Array[String]

23

24

/** Abstract method for summary handling strategy */

25

def sendSummary: SendSummary

26

27

/** Thread-safe queue for collecting test summaries */

28

val summaries: ConcurrentLinkedQueue[Summary]

29

30

/**

31

* Create test tasks from discovered test definitions

32

* @param defs Array of SBT task definitions

33

* @return Array of executable native test tasks

34

*/

35

def tasks(defs: Array[TaskDef]): Array[Task]

36

37

/**

38

* Complete test execution and return formatted results

39

* Efficiently processes summaries with minimal memory allocation

40

* @return Formatted test results or "No tests executed" message

41

*/

42

def done(): String

43

44

/**

45

* Receive serialized summaries from distributed execution

46

* @param summary Serialized summary string from SummaryProtocol

47

* @return Optional response message (always None for Native)

48

*/

49

override def receiveMessage(summary: String): Option[String]

50

51

/**

52

* Serialize task for distributed execution

53

* @param task Task to serialize

54

* @param serializer SBT-provided serialization function

55

* @return Serialized task string

56

*/

57

override def serializeTask(task: Task, serializer: TaskDef => String): String

58

59

/**

60

* Deserialize task from distributed execution

61

* @param task Serialized task string

62

* @param deserializer SBT-provided deserialization function

63

* @return Reconstructed test task

64

*/

65

override def deserializeTask(task: String, deserializer: String => TaskDef): Task

66

}

67

```

68

69

### ZMasterTestRunner

70

71

Master runner for single-process Scala Native execution, optimized for native executable environments.

72

73

```scala { .api }

74

/**

75

* Master Scala Native test runner for single-process execution

76

* Provides efficient local summary collection for native executables

77

*/

78

final class ZMasterTestRunner(

79

args: Array[String],

80

remoteArgs: Array[String],

81

testClassLoader: ClassLoader

82

) extends ZTestRunnerNative(args, remoteArgs, testClassLoader, "master") {

83

/**

84

* Summary sender that collects results locally using thread-safe queue

85

* Optimized for native execution with minimal overhead

86

*/

87

override val sendSummary: SendSummary

88

}

89

```

90

91

### ZSlaveTestRunner

92

93

Slave runner for distributed Scala Native execution, used when tests are executed across multiple native processes.

94

95

```scala { .api }

96

/**

97

* Slave Scala Native test runner for distributed execution

98

* Sends summaries to master process via serialization protocol

99

*/

100

final class ZSlaveTestRunner(

101

args: Array[String],

102

remoteArgs: Array[String],

103

testClassLoader: ClassLoader,

104

val sendSummary: SendSummary

105

) extends ZTestRunnerNative(args, remoteArgs, testClassLoader, "slave")

106

```

107

108

### ZTestTask (Native)

109

110

Scala Native-specific test task implementation with blocking execution optimized for native environments.

111

112

```scala { .api }

113

/**

114

* Scala Native-specific test task with blocking execution

115

* Optimized for native compilation and minimal memory usage

116

*/

117

sealed class ZTestTask(

118

taskDef: TaskDef,

119

testClassLoader: ClassLoader,

120

runnerType: String,

121

sendSummary: SendSummary,

122

testArgs: TestArgs,

123

spec: ZIOSpecAbstract

124

) extends BaseTestTask(

125

taskDef, testClassLoader, sendSummary, testArgs, spec,

126

zio.Runtime.default, zio.Console.ConsoleLive

127

) {

128

/**

129

* Execute test with blocking semantics suitable for native execution

130

* Uses Await.result for synchronous execution model

131

* @param eventHandler SBT event handler for reporting

132

* @param loggers Array of SBT loggers

133

* @return Empty array (no sub-tasks created)

134

*/

135

override def execute(eventHandler: EventHandler, loggers: Array[Logger]): Array[sbt.testing.Task]

136

}

137

```

138

139

### ZTestTask Companion Object (Native)

140

141

Factory methods for creating Scala Native test tasks.

142

143

```scala { .api }

144

object ZTestTask {

145

/**

146

* Create a Scala Native test task instance

147

* @param taskDef SBT task definition

148

* @param testClassLoader ClassLoader for loading test classes

149

* @param runnerType Runner type identifier ("master" or "slave")

150

* @param sendSummary Summary collection effect

151

* @param args Parsed test arguments

152

* @return Configured native ZTestTask instance

153

*/

154

def apply(

155

taskDef: TaskDef,

156

testClassLoader: ClassLoader,

157

runnerType: String,

158

sendSummary: SendSummary,

159

args: TestArgs

160

): ZTestTask

161

}

162

```

163

164

### Efficient Summary Processing

165

166

The native platform uses optimized summary processing for minimal memory allocation:

167

168

```scala { .api }

169

def done(): String = {

170

val log = new StringBuilder

171

var summary = summaries.poll()

172

var total = 0

173

var ignore = 0

174

val isEmpty = summary eq null

175

176

// Process summaries without creating intermediate collections

177

while (summary ne null) {

178

total += summary.total

179

ignore += summary.ignore

180

val details = summary.failureDetails

181

if (!details.isBlank) {

182

log append colored(details)

183

log append '\n'

184

}

185

summary = summaries.poll()

186

}

187

188

if (isEmpty || total == ignore)

189

s"${Console.YELLOW}No tests were executed${Console.RESET}"

190

else

191

log.append("Done").result()

192

}

193

```

194

195

### Blocking Execution Model

196

197

Native test tasks use blocking execution for simplicity and efficiency:

198

199

```scala { .api }

200

override def execute(eventHandler: EventHandler, loggers: Array[Logger]): Array[sbt.testing.Task] = {

201

var resOutter: CancelableFuture[Unit] = null

202

try {

203

resOutter = Runtime.default.unsafe.runToFuture {

204

ZIO.consoleWith { console =>

205

(for {

206

summary <- spec.runSpecAsApp(FilteredSpec(spec.spec, args), args, console)

207

_ <- sendSummary.provideSomeEnvironment[Any](_.add(summary))

208

_ <- ZIO.when(summary.status == Summary.Failure) {

209

ZIO.attempt(eventHandler.handle(ZTestEvent(/* failure event */)))

210

}

211

} yield ()).provideLayer(

212

sharedFilledTestLayer +!+ (Scope.default >>> spec.bootstrap)

213

)

214

}.mapError {

215

case t: Throwable => t

216

case other => new RuntimeException(s"Unknown error during tests: $other")

217

}

218

}

219

220

// Block until completion for native execution model

221

Await.result(resOutter, SDuration.Inf)

222

Array()

223

} catch {

224

case t: Throwable =>

225

if (resOutter != null) resOutter.cancel()

226

throw t

227

}

228

}

229

```

230

231

### SummaryProtocol (Native)

232

233

The native platform uses the same serialization protocol as JavaScript for inter-process communication:

234

235

```scala { .api }

236

/**

237

* Serialization protocol for test summaries in native environments

238

* Identical to JavaScript implementation for consistency

239

*/

240

object SummaryProtocol {

241

/**

242

* Serialize test summary to string for transmission

243

* @param summary Test execution summary to serialize

244

* @return Tab-separated string representation

245

*/

246

def serialize(summary: Summary): String

247

248

/**

249

* Deserialize string back to test summary

250

* @param s Serialized summary string

251

* @return Optional Summary if deserialization succeeds

252

*/

253

def deserialize(s: String): Option[Summary]

254

255

/**

256

* Escape tab characters for serialization

257

* @param token String token to escape

258

* @return Escaped string

259

*/

260

def escape(token: String): String

261

262

/**

263

* Unescape tab characters from serialized tokens

264

* @param token Escaped string token

265

* @return Unescaped original string

266

*/

267

def unescape(token: String): String

268

}

269

```

270

271

### Native Platform Optimizations

272

273

Scala Native provides several optimizations:

274

275

- **Memory Efficiency**: Uses `ConcurrentLinkedQueue` and `StringBuilder` for minimal allocations

276

- **Blocking Execution**: Simplifies execution model with `Await.result` for native environments

277

- **Native Compilation**: Optimized for ahead-of-time compilation to native executables

278

- **Cross-Platform**: Works on Linux, macOS, and Windows native targets

279

- **Fast Startup**: Native executables have faster startup compared to JVM

280

- **Small Binary Size**: Compiled to compact native executables

281

282

### Error Handling

283

284

Native execution includes comprehensive error handling:

285

286

```scala { .api }

287

// Explicit error mapping for native environments

288

.mapError {

289

case t: Throwable => t

290

case other => new RuntimeException(s"Unknown error during tests: $other")

291

}

292

293

// Proper resource cleanup on cancellation

294

catch {

295

case t: Throwable =>

296

if (resOutter != null) resOutter.cancel()

297

throw t

298

}

299

```

300

301

### Platform Considerations

302

303

The native platform has specific considerations:

304

305

- **Reflection Limitations**: Uses portable reflection for class loading

306

- **Threading Model**: Compatible with native threading constraints

307

- **Memory Management**: Optimized for native garbage collection

308

- **IO Operations**: Works with native file system and console access

309

- **Signal Handling**: Limited compared to JVM but functional for basic needs

310

311

### Usage Example

312

313

```scala

314

// Native framework usage is identical to other platforms

315

val framework = new ZTestFramework()

316

val runner = framework.runner(args, remoteArgs, classLoader)

317

318

// Native compilation produces fast-starting executable

319

// $ scala-native:nativeLink

320

// $ ./target/scala-native/my-tests

321

```