mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
fix(testrun): a recorded violation outranks the dead-run refusal
A campaign never passes --exit-on-violation, so the refusal was discarding runs that had found something: exit_code 1 in the record and the analysis drops them as missing data. A run that recorded a violation holds a verdict, which is the whole reason the refusal exists.
This commit is contained in:
1 parent
f631415cb6
commit
aa49c3bc34
2 files changed
+29
-5
No files matched your search
@@ -280,10 +280,12 @@ func Execute(ctx context.Context, options Options, stdout io.Writer) error {
|
|||||||
// run drove nothing. The count is the generator's alone because a spec's setup
|
// run drove nothing. The count is the generator's alone because a spec's setup
|
||||||
// drives the app before the generator is consulted, so a login that ran leaves
|
// drives the app before the generator is consulted, so a login that ran leaves
|
||||||
// dispatched actions behind whatever the generator then did.
|
// dispatched actions behind whatever the generator then did.
|
||||||
// --exit-on-violation keeps precedence over it so a run that found something
|
//
|
||||||
// still exits on its evidence, and the property-free opt-out exempts the sweeps,
|
// A recorded violation carries such a run through whether or not
|
||||||
// whose measurement is where a generator reaches and for which "nowhere on this
|
// --exit-on-violation was passed: the refusal exists because a run with no
|
||||||
// build" is a result rather than a broken run.
|
// verdict must not read as a clean one, and a run that recorded a violation
|
||||||
|
// holds a verdict. Campaigns pass no flags, so refusing them there would write
|
||||||
|
// exit_code 1 and lose a real detection to the analysis as missing data.
|
||||||
func runOutcome(options Options, summary runner.Summary) error {
|
func runOutcome(options Options, summary runner.Summary) error {
|
||||||
if summary.Steps > 0 && summary.SkippedVerification == summary.Steps {
|
if summary.Steps > 0 && summary.SkippedVerification == summary.Steps {
|
||||||
return VacuousRunError{Steps: summary.Steps}
|
return VacuousRunError{Steps: summary.Steps}
|
||||||
@@ -291,7 +293,8 @@ func runOutcome(options Options, summary runner.Summary) error {
|
|||||||
if options.ExitOnViolation && len(summary.Violations) > 0 {
|
if options.ExitOnViolation && len(summary.Violations) > 0 {
|
||||||
return ViolationsError{Count: len(summary.Violations)}
|
return ViolationsError{Count: len(summary.Violations)}
|
||||||
}
|
}
|
||||||
if !options.AllowNoProperties && summary.Steps > 0 && summary.GeneratorActions == 0 {
|
if !options.AllowNoProperties && len(summary.Violations) == 0 &&
|
||||||
|
summary.Steps > 0 && summary.GeneratorActions == 0 {
|
||||||
return NoGeneratorActionsError{
|
return NoGeneratorActionsError{
|
||||||
Steps: summary.Steps,
|
Steps: summary.Steps,
|
||||||
SkippedActions: summary.SkippedActions,
|
SkippedActions: summary.SkippedActions,
|
||||||
|
|||||||
@@ -473,6 +473,27 @@ func TestRunOutcome_SetupActionsDoNotCarryARunWhoseGeneratorDroveNothing(t *test
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A recorded violation is a verdict, and a run that reached one is not a dead
|
||||||
|
// run whatever drove the app to it. Campaigns are where this bites: they never
|
||||||
|
// pass --exit-on-violation, so refusing such a run writes exit_code 1 into the
|
||||||
|
// record and the analysis drops a real detection as missing data.
|
||||||
|
func TestRunOutcome_ARecordedViolationCarriesARunWhoseGeneratorDroveNothing(t *testing.T) {
|
||||||
|
setupReachedTheBug := runner.Summary{
|
||||||
|
Steps: 40,
|
||||||
|
DispatchedActions: 3,
|
||||||
|
GeneratorActions: 0,
|
||||||
|
SkippedActions: map[string]int{"no_action_produced": 40},
|
||||||
|
Violations: []runner.ViolationRecord{
|
||||||
|
{StepIndex: 3, Properties: []string{"noUncaughtExceptions"}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := runOutcome(Options{}, setupReachedTheBug); err != nil {
|
||||||
|
t.Fatalf("a run that recorded a violation came back %v, want the run to succeed "+
|
||||||
|
"so the campaign records exit_code 0 and the detection survives", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// wedgedLaunchDriver never returns from Launch, standing in for a driver whose
|
// wedgedLaunchDriver never returns from Launch, standing in for a driver whose
|
||||||
// device-side session is stuck.
|
// device-side session is stuck.
|
||||||
type wedgedLaunchDriver struct {
|
type wedgedLaunchDriver struct {
|
||||||
|
|||||||
Reference in new issue
Block a user