Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,11 @@ internal fun runCampaignFile(
)

val json = PropertyManifestJson.json.encodeToUtf8SafeString(artifact)
output.appendLine(json)
Files.writeString(Path.of(args[1]), json)
try {
Files.writeString(Path.of(args[1]), json)
} finally {
output.appendLine(json)
}

campaignExitCode(artifact.result)
} catch (error: IllegalArgumentException) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.usvm.ts.pbt.cli

import kotlinx.serialization.decodeFromString
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
import org.usvm.ts.pbt.backend.PropertyRunConfiguration
Expand All @@ -13,6 +14,8 @@ import org.usvm.ts.pbt.model.PropertyInput
import org.usvm.ts.pbt.model.TypeScriptEntryPoint
import org.usvm.ts.pbt.model.encodeToUtf8SafeString
import org.usvm.ts.pbt.testResourcesRoot
import java.io.IOException
import java.io.Writer
import java.nio.file.Files
import java.nio.file.Path
import kotlin.test.assertEquals
Expand Down Expand Up @@ -61,6 +64,57 @@ class CampaignFileCliTest {
assertFalse(Files.exists(destination))
}

@Test
fun `file artifact is readable before failing stdout publication`() {
val request = request(mode = PropertyCampaignMode.PBT_ONLY)
val path = directory.resolve("request.json")
val destination = directory.resolve("artifact.json")
Files.writeString(path, PropertyManifestJson.json.encodeToUtf8SafeString(request))
val errors = StringBuilder()
var stdoutAttempted = false
val output = object : Writer() {
override fun write(buffer: CharArray, offset: Int, length: Int) {
stdoutAttempted = true
val artifact = PropertyCampaignArtifact.read(destination)
assertEquals(PropertyCampaignMode.PBT_ONLY, artifact.result.mode)

throw IOException("stdout closed")
}

override fun flush() = Unit

override fun close() = Unit
}

val exit = runCampaignFile(arrayOf(path.toString(), destination.toString()), output, errors)
val artifact = PropertyCampaignArtifact.read(destination)

assertEquals(2, exit)
assertTrue(stdoutAttempted)
assertTrue(errors.contains("stdout closed"))
assertEquals(1, artifact.result.concrete?.numRuns)
assertEquals(37, artifact.configuration.seed)
}

@Test
fun `file write failure retains the full stdout artifact and original error`() {
val request = request(mode = PropertyCampaignMode.PBT_ONLY)
val path = directory.resolve("request.json")
val destination = directory.resolve("missing-parent").resolve("artifact.json")
Files.writeString(path, PropertyManifestJson.json.encodeToUtf8SafeString(request))
val output = StringBuilder()
val errors = StringBuilder()

val exit = runCampaignFile(arrayOf(path.toString(), destination.toString()), output, errors)
val artifact = PropertyManifestJson.json.decodeFromString<PropertyCampaignArtifact>(output.toString())

assertEquals(2, exit)
assertEquals(destination.toString(), errors.toString().trim())
assertFalse(Files.exists(destination))
assertEquals(1, artifact.result.concrete?.numRuns)
assertEquals(37, artifact.configuration.seed)
}

private fun request(mode: PropertyCampaignMode) = CampaignFileRequest(
sourceRoot = testResourcesRoot().resolve("properties/campaign").toString(),
property = PropertyDefinition(
Expand Down
Loading