1
1
/*
2
- * Copyright (C) 2023-2024 DiffPlug
2
+ * Copyright (C) 2023-2025 DiffPlug
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
@@ -177,9 +177,9 @@ internal class SnapshotFileProgress(val system: SnapshotSystemJUnit5, val classN
177
177
require(tests.get() != = TERMINATED ) { " Cannot call methods on a terminated ClassProgress" }
178
178
}
179
179
180
- private var file: SnapshotFile ? = null
180
+ private var file = atomic< SnapshotFile ?>( null )
181
181
private val tests = atomic(ArrayMap .empty<String , WithinTestGC >())
182
- private var diskWriteTracker: DiskWriteTracker ? = DiskWriteTracker ( )
182
+ private var diskWriteTracker = atomic< DiskWriteTracker ?>( DiskWriteTracker () )
183
183
private val timesStarted = AtomicInteger (0 )
184
184
private val hasFailed = AtomicBoolean (false )
185
185
@@ -209,23 +209,24 @@ internal class SnapshotFileProgress(val system: SnapshotSystemJUnit5, val classN
209
209
}
210
210
private fun finishedClassWithSuccess (success : Boolean ) {
211
211
assertNotTerminated()
212
- diskWriteTracker = null // don't need this anymore
212
+ diskWriteTracker.updateAndGet { null } // don't need this anymore
213
213
val tests = tests.getAndUpdate { TERMINATED }
214
214
require(tests != = TERMINATED ) { " Snapshot $className already terminated!" }
215
+ val file = file.getAndUpdate { null }
215
216
if (file != null ) {
216
217
val staleSnapshotIndices =
217
218
WithinTestGC .findStaleSnapshotsWithin(
218
- file!! .snapshots, tests, findTestMethodsThatDidntRun(className, tests))
219
- if (staleSnapshotIndices.isNotEmpty() || file!! .wasSetAtTestTime) {
220
- file!! .removeAllIndices(staleSnapshotIndices)
219
+ file.snapshots, tests, findTestMethodsThatDidntRun(className, tests))
220
+ if (staleSnapshotIndices.isNotEmpty() || file.wasSetAtTestTime) {
221
+ file.removeAllIndices(staleSnapshotIndices)
221
222
val snapshotPath = system.layout.snapshotPathForClass(className)
222
- if (file!! .snapshots.isEmpty()) {
223
+ if (file.snapshots.isEmpty()) {
223
224
deleteFileAndParentDirIfEmpty(snapshotPath)
224
225
} else {
225
226
system.markPathAsWritten(system.layout.snapshotPathForClass(className))
226
227
Files .createDirectories(snapshotPath.toPath().parent)
227
228
Files .newBufferedWriter(snapshotPath.toPath(), StandardCharsets .UTF_8 ).use { writer ->
228
- file!! .serialize(writer)
229
+ file.serialize(writer)
229
230
}
230
231
}
231
232
}
@@ -239,8 +240,6 @@ internal class SnapshotFileProgress(val system: SnapshotSystemJUnit5, val classN
239
240
deleteFileAndParentDirIfEmpty(snapshotFile)
240
241
}
241
242
}
242
- // now that we are done, allow our contents to be GC'ed
243
- file = null
244
243
}
245
244
// the methods below are called from the test thread for I/O on snapshots
246
245
fun keep (test : String , suffixOrAll : String? ) {
@@ -260,7 +259,7 @@ internal class SnapshotFileProgress(val system: SnapshotSystemJUnit5, val classN
260
259
) {
261
260
assertNotTerminated()
262
261
val key = " $test$suffix "
263
- diskWriteTracker!! .record(key, snapshot, callStack, layout)
262
+ diskWriteTracker.get() !! .record(key, snapshot, callStack, layout)
264
263
tests.get()[test]!! .keepSuffix(suffix)
265
264
read().setAtTestTime(key, snapshot)
266
265
}
@@ -273,17 +272,22 @@ internal class SnapshotFileProgress(val system: SnapshotSystemJUnit5, val classN
273
272
return snapshot
274
273
}
275
274
private fun read (): SnapshotFile {
276
- if (file == null ) {
277
- val snapshotPath = system.layout.snapshotPathForClass(className).toPath()
278
- file =
279
- if (Files .exists(snapshotPath) && Files .isRegularFile(snapshotPath)) {
280
- val content = Files .readAllBytes(snapshotPath)
281
- SnapshotFile .parse(SnapshotValueReader .of(content))
282
- } else {
283
- SnapshotFile .createEmptyWithUnixNewlines(system.layout.unixNewlines)
284
- }
285
- }
286
- return file!!
275
+ val file = this .file.get()
276
+ if (file != null ) return file
277
+
278
+ return this .file.updateAndGet { file ->
279
+ if (file != null ) {
280
+ file
281
+ } else {
282
+ val snapshotPath = system.layout.snapshotPathForClass(className).toPath()
283
+ if (Files .exists(snapshotPath) && Files .isRegularFile(snapshotPath)) {
284
+ val content = Files .readAllBytes(snapshotPath)
285
+ SnapshotFile .parse(SnapshotValueReader .of(content))
286
+ } else {
287
+ SnapshotFile .createEmptyWithUnixNewlines(system.layout.unixNewlines)
288
+ }
289
+ }
290
+ }!!
287
291
}
288
292
fun incrementContainers () {
289
293
assertNotTerminated()
0 commit comments