step 6
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include "PersistenceWriter.h"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
@@ -123,6 +125,70 @@ void TestWriteFailureReportsStructuredResult()
|
||||
Expect(!results.empty() && !results[0].newerRequestPending, "writer result reports no newer pending request");
|
||||
Expect(writer.GetMetrics().failedCount == 1, "writer metrics count failed writes");
|
||||
}
|
||||
|
||||
void TestShutdownFlushDrainsPendingSnapshotAndRejectsNewRequests()
|
||||
{
|
||||
std::mutex mutex;
|
||||
std::vector<PersistenceSnapshot> writtenSnapshots;
|
||||
PersistenceWriter writer(
|
||||
std::chrono::milliseconds(1000),
|
||||
[&](const PersistenceSnapshot& snapshot, std::string&) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
writtenSnapshots.push_back(snapshot);
|
||||
return true;
|
||||
});
|
||||
|
||||
std::string error;
|
||||
Expect(writer.EnqueueSnapshot(MakeRuntimeSnapshot("pending"), error), "pending snapshot enqueues before shutdown");
|
||||
Expect(writer.StopAndFlush(std::chrono::seconds(1), error), "bounded shutdown flush completes");
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
Expect(writtenSnapshots.size() == 1, "shutdown flush writes pending debounced snapshot");
|
||||
Expect(!writtenSnapshots.empty() && writtenSnapshots[0].contents == "pending", "shutdown flush preserves pending snapshot contents");
|
||||
}
|
||||
|
||||
Expect(!writer.EnqueueSnapshot(MakeRuntimeSnapshot("late"), error), "writer rejects requests after shutdown flush");
|
||||
}
|
||||
|
||||
void TestShutdownFlushTimeoutCanBeRetried()
|
||||
{
|
||||
std::mutex mutex;
|
||||
std::condition_variable condition;
|
||||
bool sinkStarted = false;
|
||||
bool releaseSink = false;
|
||||
PersistenceWriter writer(
|
||||
std::chrono::milliseconds(1),
|
||||
[&](const PersistenceSnapshot&, std::string&) {
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
sinkStarted = true;
|
||||
condition.notify_all();
|
||||
condition.wait(lock, [&]() { return releaseSink; });
|
||||
return true;
|
||||
});
|
||||
|
||||
PersistenceSnapshot snapshot = MakeRuntimeSnapshot("slow");
|
||||
snapshot.debounceAllowed = false;
|
||||
|
||||
std::string error;
|
||||
Expect(writer.EnqueueSnapshot(snapshot, error), "slow snapshot enqueues");
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
Expect(condition.wait_for(lock, std::chrono::seconds(1), [&]() { return sinkStarted; }),
|
||||
"slow sink starts before timeout test");
|
||||
}
|
||||
|
||||
Expect(!writer.StopAndFlush(std::chrono::milliseconds(10), error), "bounded shutdown flush reports timeout");
|
||||
Expect(error.find("Timed out") != std::string::npos, "shutdown timeout returns a useful error");
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
releaseSink = true;
|
||||
}
|
||||
condition.notify_all();
|
||||
error.clear();
|
||||
Expect(writer.StopAndFlush(std::chrono::seconds(1), error), "shutdown flush can complete after earlier timeout");
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
@@ -130,6 +196,8 @@ int main()
|
||||
TestDebouncedRequestsCoalesceToNewestSnapshot();
|
||||
TestImmediateRequestsAreNotCoalesced();
|
||||
TestWriteFailureReportsStructuredResult();
|
||||
TestShutdownFlushDrainsPendingSnapshotAndRejectsNewRequests();
|
||||
TestShutdownFlushTimeoutCanBeRetried();
|
||||
|
||||
if (gFailures != 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user