Milestone 5

This commit is contained in:
Joey Yakimowich-Payne 2026-01-29 21:13:18 -07:00
commit 4e21039222
9 changed files with 877 additions and 22 deletions

View file

@ -653,3 +653,142 @@ TEST_CASE("NodeInfo captures application properties") {
}
FAIL("inserted node not found");
}
TEST_CASE("policy-only mode does not create auto-links") {
warppipe::ConnectionOptions opts = DefaultOptions();
opts.policy_only = true;
auto result = warppipe::Client::Create(opts);
if (!result.ok()) {
SUCCEED("PipeWire unavailable");
return;
}
warppipe::RouteRule rule;
rule.match.application_name = "policy-only-app";
rule.target_node = "policy-sink";
REQUIRE(result.value->AddRouteRule(rule).ok());
warppipe::NodeInfo sink;
sink.id = warppipe::NodeId{900001};
sink.name = "policy-sink";
sink.media_class = "Audio/Sink";
REQUIRE(result.value->Test_InsertNode(sink).ok());
warppipe::PortInfo sink_port;
sink_port.id = warppipe::PortId{900002};
sink_port.node = sink.id;
sink_port.name = "playback_FL";
sink_port.is_input = true;
REQUIRE(result.value->Test_InsertPort(sink_port).ok());
warppipe::NodeInfo source;
source.id = warppipe::NodeId{900003};
source.name = "policy-only-source";
source.media_class = "Stream/Output/Audio";
source.application_name = "policy-only-app";
REQUIRE(result.value->Test_InsertNode(source).ok());
warppipe::PortInfo src_port;
src_port.id = warppipe::PortId{900004};
src_port.node = source.id;
src_port.name = "capture_FL";
src_port.is_input = false;
REQUIRE(result.value->Test_InsertPort(src_port).ok());
REQUIRE(result.value->Test_TriggerPolicyCheck().ok());
REQUIRE(result.value->Test_GetPendingAutoLinkCount() == 0);
auto links = result.value->ListLinks();
REQUIRE(links.ok());
bool found_auto_link = false;
for (const auto& link : links.value) {
if (link.output_port.value == 900004 && link.input_port.value == 900002) {
found_auto_link = true;
}
}
REQUIRE_FALSE(found_auto_link);
}
TEST_CASE("policy engine does not re-create existing links") {
auto result = warppipe::Client::Create(DefaultOptions());
if (!result.ok()) {
SUCCEED("PipeWire unavailable");
return;
}
warppipe::NodeInfo sink;
sink.id = warppipe::NodeId{910001};
sink.name = "relink-sink";
sink.media_class = "Audio/Sink";
REQUIRE(result.value->Test_InsertNode(sink).ok());
warppipe::PortInfo sink_port;
sink_port.id = warppipe::PortId{910002};
sink_port.node = sink.id;
sink_port.name = "playback_FL";
sink_port.is_input = true;
REQUIRE(result.value->Test_InsertPort(sink_port).ok());
warppipe::NodeInfo source;
source.id = warppipe::NodeId{910003};
source.name = "relink-source";
source.media_class = "Stream/Output/Audio";
source.application_name = "relink-app";
REQUIRE(result.value->Test_InsertNode(source).ok());
warppipe::PortInfo src_port;
src_port.id = warppipe::PortId{910004};
src_port.node = source.id;
src_port.name = "capture_FL";
src_port.is_input = false;
REQUIRE(result.value->Test_InsertPort(src_port).ok());
warppipe::Link existing_link;
existing_link.id = warppipe::LinkId{910005};
existing_link.output_port = warppipe::PortId{910004};
existing_link.input_port = warppipe::PortId{910002};
REQUIRE(result.value->Test_InsertLink(existing_link).ok());
warppipe::RouteRule rule;
rule.match.application_name = "relink-app";
rule.target_node = "relink-sink";
REQUIRE(result.value->AddRouteRule(rule).ok());
REQUIRE(result.value->Test_TriggerPolicyCheck().ok());
auto links = result.value->ListLinks();
REQUIRE(links.ok());
int matching_links = 0;
for (const auto& link : links.value) {
if (link.output_port.value == 910004 && link.input_port.value == 910002) {
++matching_links;
}
}
REQUIRE(matching_links == 1);
}
TEST_CASE("policy mode does not override user defaults") {
warppipe::ConnectionOptions opts = DefaultOptions();
opts.policy_only = true;
auto result = warppipe::Client::Create(opts);
if (!result.ok()) {
SUCCEED("PipeWire unavailable");
return;
}
auto defaults = result.value->GetDefaults();
REQUIRE(defaults.ok());
warppipe::RouteRule rule;
rule.match.application_name = "some-app";
rule.target_node = "custom-sink";
REQUIRE(result.value->AddRouteRule(rule).ok());
auto defaults2 = result.value->GetDefaults();
REQUIRE(defaults2.ok());
REQUIRE(defaults2.value.default_sink_name == defaults.value.default_sink_name);
REQUIRE(defaults2.value.default_source_name == defaults.value.default_source_name);
REQUIRE(defaults2.value.configured_sink_name == defaults.value.configured_sink_name);
REQUIRE(defaults2.value.configured_source_name == defaults.value.configured_source_name);
}