ci: make both workflows able to run at all #1
@@ -192,6 +192,13 @@ TEST_CASE("a track within the extinction window is still a candidate",
|
||||
|
||||
Embedding person = at_sim(0, 1, 0.99f);
|
||||
int id_pre = r.track_of(frame(0.0, 10, 10, person));
|
||||
|
||||
// Identify it while it is still on screen. Since 1477c53 a DORMANT track is
|
||||
// only associable if it was owned -- an anonymous one has no actor to
|
||||
// re-attach to, so it is dropped from the pool a line before the horizon is
|
||||
// ever consulted. Without this the test cannot reach what it is about.
|
||||
r.reg->observe(id_pre, /*actor=*/0, /*posterior=*/0.99f, person);
|
||||
|
||||
r.track_of(frame(1.0, 300, 300, axis(7), /*is_cut=*/true));
|
||||
|
||||
// Back inside the window: the same person continues the same track, so the
|
||||
|
||||
@@ -415,15 +415,21 @@ TEST_CASE("a track is not reaped until the evidence clock passes it",
|
||||
}
|
||||
|
||||
/// TRACES: UT-001 | AR-008, AR-013 | SR-002
|
||||
TEST_CASE("a track retired from association is still open to evidence",
|
||||
TEST_CASE("association and reaping retire a track on the same clock",
|
||||
"[registry][AR-008]") {
|
||||
// The two clocks answer different questions and must not share an answer.
|
||||
// Association asks "may this detection link to that track?" on the tracker's
|
||||
// clock; reaping asks "is that track finished?" and cannot answer until the
|
||||
// votes are in. Deferring both to the evidence clock was the second half of
|
||||
// this bug: retired tracks lingered in the candidate pool for as long as the
|
||||
// matcher lagged, so a new face re-associated onto a long-dead track and two
|
||||
// people merged into one window.
|
||||
// Renamed and rewritten for the unified clock. This test used to assert the
|
||||
// opposite arrangement -- association answered on the tracker's clock while
|
||||
// reaping answered on the evidence watermark -- and it was written when that
|
||||
// was true. It is not true now: candidates() and reap_locked() take the SAME
|
||||
// clock and the SAME threshold, so "retired from association" and "reaped"
|
||||
// are one event, and the interval the old name described does not exist.
|
||||
//
|
||||
// Both halves of the AR-013 bug are visible here. Offering on a LOOSER
|
||||
// horizon than the reap left retired tracks in the candidate pool for as
|
||||
// long as the matcher lagged, so a new face re-associated onto a long-dead
|
||||
// track and two people merged into one window. Reaping on a looser horizon
|
||||
// than the offer killed tracks whose votes were still in flight. One clock
|
||||
// makes both unrepresentable.
|
||||
TrackRegistry reg(cfg(/*extinction=*/5.0), disc());
|
||||
Sink sink; sink.attach(reg);
|
||||
reg.expect_evidence();
|
||||
@@ -432,21 +438,37 @@ TEST_CASE("a track retired from association is still open to evidence",
|
||||
{
|
||||
auto s = reg.begin_frame(0.0);
|
||||
id = s.create(0.0, axis(1));
|
||||
}
|
||||
// Owned before it goes dormant, for the reason above: an unidentified
|
||||
// dormant track is not a candidate at any horizon (1477c53).
|
||||
reg.observe(id, 7, 0.99f, axis(1));
|
||||
{
|
||||
auto s = reg.begin_frame(0.0);
|
||||
s.mark_lost(id, 0.0);
|
||||
}
|
||||
|
||||
{
|
||||
auto s = reg.begin_frame(3.0); // inside the window
|
||||
auto s = reg.begin_frame(3.0); // watermark inside the window
|
||||
CHECK(s.candidates().size() == 1); // still associable
|
||||
}
|
||||
// The tracker races far past the horizon while the matcher lags. This
|
||||
// retires nothing, and that is the point of the watermark: the clock that
|
||||
// decides has not moved, so the track is still offered.
|
||||
{
|
||||
auto s = reg.begin_frame(50.0); // far outside it
|
||||
CHECK(s.candidates().empty()); // retired from association...
|
||||
auto s = reg.begin_frame(50.0);
|
||||
CHECK(s.candidates().size() == 1);
|
||||
}
|
||||
// ...but not gone, and still able to receive the votes in flight for it.
|
||||
// Which is what keeps it able to receive the votes still in flight for it.
|
||||
reg.observe(id, 7, 0.99f, axis(1));
|
||||
CHECK(reg.dropped_votes() == 0);
|
||||
|
||||
// Only the watermark passing last_seen + extinction retires it -- and the
|
||||
// same call reaps and emits it, so there is no interval in between.
|
||||
reg.advance_evidence(50.0);
|
||||
{
|
||||
auto s = reg.begin_frame(50.0);
|
||||
CHECK(s.candidates().empty());
|
||||
}
|
||||
REQUIRE(sink.claims.size() == 1);
|
||||
CHECK(sink.claims[0].actor_idx == 7);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user