Phase 7.5 step 2
This commit is contained in:
142
tests/OutputProductionControllerTests.cpp
Normal file
142
tests/OutputProductionControllerTests.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
#include "OutputProductionController.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace
|
||||
{
|
||||
int gFailures = 0;
|
||||
|
||||
void Expect(bool condition, const char* message)
|
||||
{
|
||||
if (condition)
|
||||
return;
|
||||
|
||||
std::cerr << "FAIL: " << message << "\n";
|
||||
++gFailures;
|
||||
}
|
||||
|
||||
void TestLowQueueRequestsProductionToTarget()
|
||||
{
|
||||
VideoPlayoutPolicy policy;
|
||||
policy.targetReadyFrames = 3;
|
||||
policy.maxReadyFrames = 5;
|
||||
OutputProductionController controller(policy);
|
||||
|
||||
OutputProductionPressure pressure;
|
||||
pressure.readyQueueDepth = 1;
|
||||
pressure.readyQueueCapacity = 5;
|
||||
|
||||
const OutputProductionDecision decision = controller.Decide(pressure);
|
||||
Expect(decision.action == OutputProductionAction::Produce, "low ready queue requests production");
|
||||
Expect(decision.requestedFrames == 2, "low ready queue requests enough frames to reach target");
|
||||
Expect(decision.targetReadyFrames == 3, "decision reports effective target");
|
||||
Expect(decision.maxReadyFrames == 5, "decision reports effective max");
|
||||
Expect(decision.reason == "ready-queue-below-target", "low queue decision names reason");
|
||||
}
|
||||
|
||||
void TestFullQueueThrottles()
|
||||
{
|
||||
VideoPlayoutPolicy policy;
|
||||
policy.targetReadyFrames = 2;
|
||||
policy.maxReadyFrames = 4;
|
||||
OutputProductionController controller(policy);
|
||||
|
||||
OutputProductionPressure pressure;
|
||||
pressure.readyQueueDepth = 4;
|
||||
pressure.readyQueueCapacity = 4;
|
||||
|
||||
const OutputProductionDecision decision = controller.Decide(pressure);
|
||||
Expect(decision.action == OutputProductionAction::Throttle, "full ready queue throttles production");
|
||||
Expect(decision.requestedFrames == 0, "full ready queue requests no frames");
|
||||
Expect(decision.reason == "ready-queue-full", "full queue decision names reason");
|
||||
}
|
||||
|
||||
void TestAtTargetWaitsWithoutPressure()
|
||||
{
|
||||
VideoPlayoutPolicy policy;
|
||||
policy.targetReadyFrames = 2;
|
||||
policy.maxReadyFrames = 4;
|
||||
OutputProductionController controller(policy);
|
||||
|
||||
OutputProductionPressure pressure;
|
||||
pressure.readyQueueDepth = 2;
|
||||
pressure.readyQueueCapacity = 4;
|
||||
|
||||
const OutputProductionDecision decision = controller.Decide(pressure);
|
||||
Expect(decision.action == OutputProductionAction::Wait, "ready queue at target waits without pressure");
|
||||
Expect(decision.requestedFrames == 0, "wait decision requests no frames");
|
||||
Expect(decision.reason == "ready-queue-at-target", "wait decision names reason");
|
||||
}
|
||||
|
||||
void TestLateDropPressureRequestsHeadroom()
|
||||
{
|
||||
VideoPlayoutPolicy policy;
|
||||
policy.targetReadyFrames = 2;
|
||||
policy.maxReadyFrames = 4;
|
||||
OutputProductionController controller(policy);
|
||||
|
||||
OutputProductionPressure pressure;
|
||||
pressure.readyQueueDepth = 2;
|
||||
pressure.readyQueueCapacity = 4;
|
||||
pressure.lateStreak = 1;
|
||||
|
||||
OutputProductionDecision decision = controller.Decide(pressure);
|
||||
Expect(decision.action == OutputProductionAction::Produce, "late pressure requests extra headroom");
|
||||
Expect(decision.requestedFrames == 1, "late pressure requests one frame");
|
||||
Expect(decision.reason == "playout-pressure", "late pressure decision names reason");
|
||||
|
||||
pressure.lateStreak = 0;
|
||||
pressure.dropStreak = 2;
|
||||
decision = controller.Decide(pressure);
|
||||
Expect(decision.action == OutputProductionAction::Produce, "drop pressure requests extra headroom");
|
||||
|
||||
pressure.dropStreak = 0;
|
||||
pressure.readyQueueUnderrunCount = 1;
|
||||
decision = controller.Decide(pressure);
|
||||
Expect(decision.action == OutputProductionAction::Produce, "underrun pressure requests extra headroom");
|
||||
}
|
||||
|
||||
void TestPolicyNormalizesAndClampsToCapacity()
|
||||
{
|
||||
VideoPlayoutPolicy policy;
|
||||
policy.targetReadyFrames = 0;
|
||||
policy.maxReadyFrames = 8;
|
||||
OutputProductionController controller(policy);
|
||||
|
||||
OutputProductionPressure pressure;
|
||||
pressure.readyQueueDepth = 1;
|
||||
pressure.readyQueueCapacity = 3;
|
||||
|
||||
const OutputProductionDecision decision = controller.Decide(pressure);
|
||||
Expect(decision.action == OutputProductionAction::Wait, "normalized target at current depth waits");
|
||||
Expect(decision.targetReadyFrames == 1, "target normalizes to at least one frame");
|
||||
Expect(decision.maxReadyFrames == 3, "max ready frames clamps to queue capacity");
|
||||
}
|
||||
|
||||
void TestActionNames()
|
||||
{
|
||||
Expect(OutputProductionActionName(OutputProductionAction::Produce) == std::string("Produce"), "produce action has name");
|
||||
Expect(OutputProductionActionName(OutputProductionAction::Wait) == std::string("Wait"), "wait action has name");
|
||||
Expect(OutputProductionActionName(OutputProductionAction::Throttle) == std::string("Throttle"), "throttle action has name");
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
TestLowQueueRequestsProductionToTarget();
|
||||
TestFullQueueThrottles();
|
||||
TestAtTargetWaitsWithoutPressure();
|
||||
TestLateDropPressureRequestsHeadroom();
|
||||
TestPolicyNormalizesAndClampsToCapacity();
|
||||
TestActionNames();
|
||||
|
||||
if (gFailures != 0)
|
||||
{
|
||||
std::cerr << gFailures << " OutputProductionController test failure(s).\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "OutputProductionController tests passed.\n";
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user