fix: replace retained report sessions when re-adding queue items

This commit is contained in:
2026-10-22 17:20:19 +02:00
parent b132bab393
commit 3ff498720b
6 changed files with 96 additions and 16 deletions
+39 -5
View File
@@ -348,6 +348,33 @@ int main(int argc, char **argv) {
expect(firstRows[0], @"progress", firstURL, 12, true);
expect(firstRows[2], @"progress", firstURL, 24, true);
expect(secondRows[0], @"ended", secondURL, 100, true);
const auto retired = root + "/retired.jsonl", replacement = root + "/replacement.jsonl";
{
playback::ProgressReports reports;
reports.registerFile(firstURL, retired);
reports.begin(firstURL);
reports.observe(sample(PLAYER_PAUSED, 12));
bool accepted = true;
try { reports.registerFile(firstURL, replacement); } catch (...) { accepted = false; }
require(accepted, "a removed identity can register a fresh reporting session");
auto retiredRows = records(retired);
require(retiredRows.count == 2, "replacement drains the retired writer");
expect(retiredRows[1], @"closed", firstURL, 12, true);
NSData *retiredBytes = [NSData dataWithContentsOfFile:nativePath(retired)];
reports.observe(sample(PLAYER_PAUSED, 50));
reports.begin(firstURL);
reports.observe(sample(PLAYER_PAUSED, 24));
reports.finish();
require([[NSData dataWithContentsOfFile:nativePath(retired)] isEqual:retiredBytes],
"replacement never appends to or overwrites the retired report");
auto replacementRows = records(replacement);
require(replacementRows.count == 2, "fresh session starts only when its media begins");
expect(replacementRows[0], @"progress", firstURL, 24, true);
expect(replacementRows[1], @"closed", firstURL, 24, true);
bool refused = false;
try { reports.registerFile(secondURL, retired); } catch (...) { refused = true; }
require(refused, "retired report paths remain reserved");
}
const auto liveSingle = root + "/live-single.jsonl", liveNext = root + "/live-next.jsonl";
const auto rollbackPath = root + "/rollback.jsonl";
{
@@ -357,9 +384,9 @@ int main(int argc, char **argv) {
const char *identities[] = {secondURL.c_str()}, *destinations[] = {liveNext.c_str()};
reports.registerFiles(identities, destinations, 1);
reports.observe(sample(PLAYER_PAUSED, 8));
const char *conflictingIDs[] = {"miruro:new:1", secondURL.c_str()};
const char *conflictingIDs[] = {firstURL.c_str(), secondURL.c_str()};
const auto unused = root + "/unused.jsonl";
const char *conflictingPaths[] = {rollbackPath.c_str(), unused.c_str()};
const char *conflictingPaths[] = {rollbackPath.c_str(), liveNext.c_str()};
bool refused = false;
try { reports.registerFiles(conflictingIDs, conflictingPaths, 2); } catch (...) { refused = true; }
require(refused, "conflicting later entry rejects the complete registration batch");
@@ -370,10 +397,17 @@ int main(int argc, char **argv) {
reports.observe(sample(PLAYER_PAUSED, 9));
reports.begin("miruro:unregistered:1");
reports.observe(sample(PLAYER_PAUSED, 55));
refused = false;
try { reports.registerFile(firstURL, unused); } catch (...) { refused = true; }
require(refused, "enqueue cannot rebind the original single identity after its queue row is removed");
NSData *singleBytes = [NSData dataWithContentsOfFile:nativePath(liveSingle)];
reports.registerFile(firstURL, unused);
reports.begin(firstURL);
reports.observe(sample(PLAYER_PAUSED, 11));
reports.finish();
require([[NSData dataWithContentsOfFile:nativePath(liveSingle)] isEqual:singleBytes],
"re-adding the original standalone identity leaves its old report unchanged");
auto reboundRows = records(unused);
require(reboundRows.count == 2, "standalone identity can start a fresh queue report");
expect(reboundRows[0], @"progress", firstURL, 11, true);
expect(reboundRows[1], @"closed", firstURL, 11, true);
require(reports.error().empty(), "enqueue preserves single reporting and supports owned report revisits");
}
auto singleRows = records(liveSingle), nextRows = records(liveNext);