Skip to content

Commit 75edbb2

Browse files
committed
Pin what any-failure counts as a row that did not pass
The gate reads unpassed as total minus passed, so a row that errored or was skipped breaches -- which is the point of a gate. Nothing tested it: replacing that with the Failed count alone left every test green, and a run whose rows all errored would have reported success to a pipeline. The pass-rate half of the same concern was already covered, so the gap was one gate, not the idea. Found by mutating the two guards rather than reading the test names, which read as though both were covered. Also worth recording: the first attempt at that mutation silently failed to match and reported the tests as toothless. A mutation you do not verify landed is worse than none, because it accuses the tests instead of the code.
1 parent 5c09c85 commit 75edbb2

1 file changed

Lines changed: 18 additions & 0 deletions

File tree

cli/azd/extensions/azure.ai.evaluations/internal/cmd/gating_conformance_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,24 @@ func TestPassRateCountsErroredAndSkippedAgainstTheThreshold(t *testing.T) {
6565
assert.Empty(t, g.breach(&eval_api.EvalRunResultCounts{Total: 3, Passed: 3}))
6666
}
6767

68+
// any-failure is the same concern as the rate above asked as a yes or no, and
69+
// it was the untested half: the gate counts everything that is not a pass, so
70+
// replacing that with the Failed count alone let a run whose rows errored
71+
// report success, and no test noticed.
72+
func TestAnyFailureCountsErroredAndSkippedAsUnpassed(t *testing.T) {
73+
g, err := parseGate("any-failure")
74+
require.NoError(t, err)
75+
76+
assert.NotEmpty(t, g.breach(&eval_api.EvalRunResultCounts{Total: 3, Passed: 2, Errored: 1}),
77+
"a row that errored did not pass")
78+
assert.NotEmpty(t, g.breach(&eval_api.EvalRunResultCounts{Total: 3, Passed: 2, Skipped: 1}),
79+
"a row that was skipped did not pass either")
80+
assert.NotEmpty(t, g.breach(&eval_api.EvalRunResultCounts{Total: 3, Passed: 2, Failed: 1}))
81+
82+
assert.Empty(t, g.breach(&eval_api.EvalRunResultCounts{Total: 3, Passed: 3}),
83+
"every row passed, so there is nothing to report")
84+
}
85+
6886
// A run that scored nothing breaches every threshold rather than dividing by
6987
// zero. "No rows passed" is the honest reading of an empty result.
7088
func TestEmptyRunBreachesEveryThreshold(t *testing.T) {

0 commit comments

Comments
 (0)