11/*
2- * Copyright (C) 2023-2024 DiffPlug
2+ * Copyright (C) 2023-2025 DiffPlug
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
@@ -177,9 +177,9 @@ internal class SnapshotFileProgress(val system: SnapshotSystemJUnit5, val classN
177177 require(tests.get() != = TERMINATED ) { " Cannot call methods on a terminated ClassProgress" }
178178 }
179179
180- private var file: SnapshotFile ? = null
180+ private var file = atomic< SnapshotFile ?>( null )
181181 private val tests = atomic(ArrayMap .empty<String , WithinTestGC >())
182- private var diskWriteTracker: DiskWriteTracker ? = DiskWriteTracker ( )
182+ private var diskWriteTracker = atomic< DiskWriteTracker ?>( DiskWriteTracker () )
183183 private val timesStarted = AtomicInteger (0 )
184184 private val hasFailed = AtomicBoolean (false )
185185
@@ -209,23 +209,24 @@ internal class SnapshotFileProgress(val system: SnapshotSystemJUnit5, val classN
209209 }
210210 private fun finishedClassWithSuccess (success : Boolean ) {
211211 assertNotTerminated()
212- diskWriteTracker = null // don't need this anymore
212+ diskWriteTracker.updateAndGet { null } // don't need this anymore
213213 val tests = tests.getAndUpdate { TERMINATED }
214214 require(tests != = TERMINATED ) { " Snapshot $className already terminated!" }
215+ val file = file.getAndUpdate { null }
215216 if (file != null ) {
216217 val staleSnapshotIndices =
217218 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)
221222 val snapshotPath = system.layout.snapshotPathForClass(className)
222- if (file!! .snapshots.isEmpty()) {
223+ if (file.snapshots.isEmpty()) {
223224 deleteFileAndParentDirIfEmpty(snapshotPath)
224225 } else {
225226 system.markPathAsWritten(system.layout.snapshotPathForClass(className))
226227 Files .createDirectories(snapshotPath.toPath().parent)
227228 Files .newBufferedWriter(snapshotPath.toPath(), StandardCharsets .UTF_8 ).use { writer ->
228- file!! .serialize(writer)
229+ file.serialize(writer)
229230 }
230231 }
231232 }
@@ -239,8 +240,6 @@ internal class SnapshotFileProgress(val system: SnapshotSystemJUnit5, val classN
239240 deleteFileAndParentDirIfEmpty(snapshotFile)
240241 }
241242 }
242- // now that we are done, allow our contents to be GC'ed
243- file = null
244243 }
245244 // the methods below are called from the test thread for I/O on snapshots
246245 fun keep (test : String , suffixOrAll : String? ) {
@@ -260,7 +259,7 @@ internal class SnapshotFileProgress(val system: SnapshotSystemJUnit5, val classN
260259 ) {
261260 assertNotTerminated()
262261 val key = " $test$suffix "
263- diskWriteTracker!! .record(key, snapshot, callStack, layout)
262+ diskWriteTracker.get() !! .record(key, snapshot, callStack, layout)
264263 tests.get()[test]!! .keepSuffix(suffix)
265264 read().setAtTestTime(key, snapshot)
266265 }
@@ -273,17 +272,22 @@ internal class SnapshotFileProgress(val system: SnapshotSystemJUnit5, val classN
273272 return snapshot
274273 }
275274 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+ }!!
287291 }
288292 fun incrementContainers () {
289293 assertNotTerminated()
0 commit comments