Spec #164: A sixth outcome word: not_found splits out of errors
This commit is contained in:
@@ -1947,9 +1947,9 @@ func TestRunLanePassCarryForwardOnlyWhenGapZero(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
// The pass row's five outcome counts are the classification the Series read
|
||||
// The pass row's six outcome counts are the classification the Series read
|
||||
// already makes — never a second taxonomy (issue #141). Success is derived,
|
||||
// never stored: checked minus the four named counts, unreachable excluded
|
||||
// never stored: checked minus the five named failures, unreachable excluded
|
||||
// because its exit returns before the checked counter increments.
|
||||
func TestRunLanePassCountsOutcomes(t *testing.T) {
|
||||
s, _ := newTestStore(t)
|
||||
@@ -1986,7 +1986,7 @@ func TestRunLanePassCountsOutcomes(t *testing.T) {
|
||||
t.Fatalf("outcome counts = refused %d unreachable %d no_chapter %d unfetchable %d errors %d, want 1 0 1 1 1",
|
||||
pass.Refused, pass.Unreachable, pass.NoChapter, pass.Unfetchable, pass.Errors)
|
||||
}
|
||||
if success := pass.Checked - (pass.Refused + pass.NoChapter + pass.Unfetchable + pass.Errors); success != 1 {
|
||||
if success := pass.Checked - (pass.Refused + pass.NoChapter + pass.Unfetchable + pass.NotFound + pass.Errors); success != 1 {
|
||||
t.Fatalf("derived success = %d, want 1", success)
|
||||
}
|
||||
// The one genuine read went through: the success Series carries the
|
||||
@@ -2009,6 +2009,36 @@ func TestRunLanePassCountsOutcomes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// A 4xx other than the 403 refusal means the page is gone — a sixth outcome
|
||||
// word (issue #164) — while a 5xx stays errors. Both land in the durable row,
|
||||
// so the owner can tell "correct the address" from "the Site is unwell"
|
||||
// without opening a log.
|
||||
func TestRunLanePassSplitsNotFoundFromErrors(t *testing.T) {
|
||||
s, _ := newTestStore(t)
|
||||
now := time.UnixMilli(5_000_000)
|
||||
seeds := map[string]string{
|
||||
"asura:gone": "https://asurascans.com/series/gone",
|
||||
"asura:unwell": "https://asurascans.com/series/unwell",
|
||||
}
|
||||
for key, url := range seeds {
|
||||
seedForCheck(t, s, key, url, 0)
|
||||
}
|
||||
|
||||
f := &fakeFetcher{perURL: map[string]fakeResponse{
|
||||
seeds["asura:gone"]: {status: 404},
|
||||
seeds["asura:unwell"]: {status: 503},
|
||||
}}
|
||||
newTestPoller(t, s, f, now).runLanePass(context.Background(), "asura", false)
|
||||
|
||||
pass := latestPassFor(t, s, "asura")
|
||||
if pass.NotFound != 1 || pass.Errors != 1 {
|
||||
t.Fatalf("not_found=%d errors=%d, want 1 1", pass.NotFound, pass.Errors)
|
||||
}
|
||||
if success := pass.Checked - (pass.Refused + pass.NoChapter + pass.Unfetchable + pass.NotFound + pass.Errors); success != 0 {
|
||||
t.Fatalf("derived success = %d, want 0 (both reads failed)", success)
|
||||
}
|
||||
}
|
||||
|
||||
// A refusal is the Site's mood and outlives our process: the durable stamp a
|
||||
// pass writes is honoured by a freshly constructed poller, which must not
|
||||
// re-probe the Site inside its backoff (issue #141).
|
||||
|
||||
Reference in New Issue
Block a user