Skip to content

Commit

Permalink
Unify the showing of simulator seeds so we don't forget any cases
Browse files Browse the repository at this point in the history
  • Loading branch information
bugarela committed Oct 3, 2024
1 parent dcd506f commit 1ad8760
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 13 deletions.
19 changes: 11 additions & 8 deletions quint/io-cli-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,8 @@ An example execution:
[State 4] { n: 12 }
[violation] Found an issue (duration).
Use --seed=0x308623f2a48e7 to reproduce.
Use --verbosity=3 to show executions.
Use --seed=0x308623f2a48e7 to reproduce.
error: Invariant violated
```

Expand Down Expand Up @@ -477,8 +477,8 @@ An example execution:
[State 4] { action_taken: "OnDivByThree", n: 12, nondet_picks: { } }
[violation] Found an issue (duration).
Use --seed=0x308623f2a48e7 to reproduce.
Use --verbosity=3 to show executions.
Use --seed=0x308623f2a48e7 to reproduce.
error: Invariant violated
```

Expand Down Expand Up @@ -508,9 +508,9 @@ An example execution:
[State 4] { n: 12 }
[ok] No violation found (duration).
Use --seed=0x11 to reproduce.
You may increase --max-samples and --max-steps.
Use --verbosity to produce more (or less) output.
Use --seed=0x11 to reproduce.
```

### Repl evaluates coin
Expand Down Expand Up @@ -589,8 +589,8 @@ An example execution:
}
[violation] Found an issue (duration).
Use --seed=0x1e352e160ffbb3 to reproduce.
Use --verbosity=3 to show executions.
Use --seed=0x1e352e160ffbb3 to reproduce.
error: Invariant violated
```

Expand Down Expand Up @@ -721,8 +721,8 @@ q::stepAndInvariant => false
}
[violation] Found an issue (duration).
Use --seed=0x1786e678d460fe to reproduce.
Use --verbosity=3 to show executions.
Use --seed=0x1786e678d460fe to reproduce.
error: Invariant violated
```

Expand Down Expand Up @@ -823,7 +823,7 @@ rm out-itf-mbt-example.itf.json

<!-- !test in successful run itf -->
```
quint run --out-itf=out-itf-example.itf.json --max-steps=5 --seed=123 ../examples/tutorials/coin.qnt
quint run --out-itf=out-itf-example.itf.json --max-steps=5 --seed=123 ../examples/tutorials/coin.qnt >/dev/null
cat out-itf-example.itf.json | jq '.states[0]."balances"."#map"[0]'
rm out-itf-example.itf.json
```
Expand All @@ -842,7 +842,7 @@ rm out-itf-example.itf.json

<!-- !test in run with n-traces itf -->
```
quint run --out-itf=out-itf-example.itf.json --n-traces=3 --max-steps=5 --seed=123 ../examples/tutorials/coin.qnt
quint run --out-itf=out-itf-example.itf.json --n-traces=3 --max-steps=5 --seed=123 ../examples/tutorials/coin.qnt >/dev/null
cat out-itf-example0.itf.json | jq '.["#meta"].status'
rm out-itf-example*.itf.json
```
Expand Down Expand Up @@ -1164,9 +1164,11 @@ error: Tests failed

### Fail on run with uninitialized constants

FIXME: this should not be a runtime error

<!-- !test in run uninitialized -->
```
output=$(quint run testFixture/_1041compileConst.qnt 2>&1)
output=$(quint run testFixture/_1041compileConst.qnt --seed=1 2>&1)
exit_code=$?
echo "$output" | sed -e 's/([0-9]*ms)/(duration)/g' \
-e 's#^.*_1041compileConst.qnt#HOME/_1041compileConst.qnt#g'
Expand All @@ -1180,6 +1182,7 @@ HOME/_1041compileConst.qnt:5:24 - error: [QNT500] Uninitialized const N. Use: im
5: action init = { x' = N }
^
Use --seed=0x1 to reproduce.
error: Runtime error
```

Expand Down
20 changes: 15 additions & 5 deletions quint/src/cliCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ interface OutputStage {
// Possible results from 'run'
status?: 'ok' | 'violation' | 'failure' | 'error'
trace?: QuintEx[]
seed?: bigint
/* Docstrings by definition name by module name */
documentation?: Map<string, Map<string, DocumentationEntry>>
errors?: ErrorMessage[]
Expand All @@ -104,6 +105,7 @@ const pickOutputStage = ({
ignored,
status,
trace,
seed,
}: ProcedureStage) => {
return {
stage,
Expand All @@ -119,6 +121,7 @@ const pickOutputStage = ({
ignored,
status,
trace,
seed,
}
}

Expand Down Expand Up @@ -567,6 +570,10 @@ export async function runSimulator(prev: TypecheckedStage): Promise<CLIProcedure
? { status: (evalResult.value as QuintBool).value ? 'ok' : 'violation' }
: { status: 'error', errors: [evalResult.value] }

const states = recorder.bestTraces[0]?.frame?.args?.map(e => e.toQuintEx(zerog))
const frames = recorder.bestTraces[0]?.frame?.subframes
simulator.seed = recorder.bestTraces[0]?.seed

recorder.bestTraces.forEach((trace, index) => {
const maybeEvalResult = trace.frame.result
if (maybeEvalResult.isLeft()) {
Expand All @@ -584,9 +591,6 @@ export async function runSimulator(prev: TypecheckedStage): Promise<CLIProcedure
options.onTrace(index, status, evaluator.varNames(), states)
})

const states = recorder.bestTraces[0]?.frame?.args?.map(e => e.toQuintEx(zerog))
const frames = recorder.bestTraces[0]?.frame?.subframes
const seed = recorder.bestTraces[0]?.seed
switch (outcome.status) {
case 'error':
return cliErr('Runtime error', {
Expand All @@ -600,7 +604,6 @@ export async function runSimulator(prev: TypecheckedStage): Promise<CLIProcedure
maybePrintCounterExample(verbosityLevel, states, frames)
if (verbosity.hasResults(verbosityLevel)) {
console.log(chalk.green('[ok]') + ' No violation found ' + chalk.gray(`(${elapsedMs}ms).`))
console.log(chalk.gray(`Use --seed=0x${seed.toString(16)} to reproduce.`))
if (verbosity.hasHints(verbosityLevel)) {
console.log(chalk.gray('You may increase --max-samples and --max-steps.'))
console.log(chalk.gray('Use --verbosity to produce more (or less) output.'))
Expand All @@ -617,7 +620,6 @@ export async function runSimulator(prev: TypecheckedStage): Promise<CLIProcedure
maybePrintCounterExample(verbosityLevel, states, frames)
if (verbosity.hasResults(verbosityLevel)) {
console.log(chalk.red(`[violation]`) + ' Found an issue ' + chalk.gray(`(${elapsedMs}ms).`))
console.log(chalk.gray(`Use --seed=0x${seed.toString(16)} to reproduce.`))

if (verbosity.hasHints(verbosityLevel)) {
console.log(chalk.gray('Use --verbosity=3 to show executions.'))
Expand Down Expand Up @@ -866,21 +868,29 @@ export async function docs(loaded: LoadedStage): Promise<CLIProcedure<Documentat
export function outputResult(result: CLIProcedure<ProcedureStage>) {
result
.map(stage => {
const verbosityLevel = deriveVerbosity(stage.args)
const outputData = pickOutputStage(stage)
if (stage.args.out) {
writeToJson(stage.args.out, outputData)
}
if (outputData.seed && verbosity.hasResults(verbosityLevel)) {
console.log(chalk.gray(`Use --seed=0x${outputData.seed.toString(16)} to reproduce.`))
}

process.exit(0)
})
.mapLeft(({ msg, stage }) => {
const { args, errors, sourceCode } = stage
const verbosityLevel = deriveVerbosity(args)
const outputData = pickOutputStage(stage)
if (args.out) {
writeToJson(args.out, outputData)
} else {
const finders = createFinders(sourceCode!)
uniqWith(errors, isEqual).forEach(err => console.error(formatError(sourceCode, finders, err)))
if (outputData.seed && verbosity.hasResults(verbosityLevel)) {
console.log(chalk.gray(`Use --seed=0x${outputData.seed.toString(16)} to reproduce.`))
}
console.error(`error: ${msg}`)
}
process.exit(1)
Expand Down

0 comments on commit 1ad8760

Please sign in to comment.