更完
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include "../app/Gallery_Plot_Session.h"
|
||||
#include "../app/Gallery_Observer_Adminive.h"
|
||||
#include "../app/Gallery_Protocol.h"
|
||||
#include "../app/Gallery_Renderables.h"
|
||||
#include "../app/Pixel_Frame.h"
|
||||
@@ -268,6 +269,30 @@ TEST(RenderiveWebGallery, CatalogOwnsDashboardFieldsAndDynamicBehavior) {
|
||||
EXPECT_TRUE(action->at("request_frame"));
|
||||
}
|
||||
|
||||
TEST(RenderiveWebGallery, ObserverTelemetryAndDashboardUseAdminiveDescriptors) {
|
||||
const auto catalog = parse_json(Gallery_Protocol::catalog_json());
|
||||
const auto& observer_contract = catalog.at("dashboard").at("observer");
|
||||
const auto& observer_descriptor = observer_contract.at("descriptor");
|
||||
const auto& feedback_descriptor =
|
||||
observer_contract.at("consumer_feedback_descriptor");
|
||||
|
||||
Gallery_Plot_Session session;
|
||||
const auto opened = response_json(session.handle(gallery_request(
|
||||
Gallery_Request_Kind::Open, open_message("spectrum", "manual"))));
|
||||
const auto& telemetry = opened.at("telemetry");
|
||||
const auto& observer = telemetry.at("kernel_observer");
|
||||
const auto& feedback = telemetry.at("consumer_feedback");
|
||||
|
||||
EXPECT_EQ(observer.size(), observer_descriptor.at("fields").size());
|
||||
for (const auto& field : observer_descriptor.at("fields"))
|
||||
EXPECT_TRUE(observer.contains(field.at("name").get<std::string>()));
|
||||
EXPECT_EQ(feedback.size(), feedback_descriptor.at("fields").size());
|
||||
for (const auto& field : feedback_descriptor.at("fields"))
|
||||
EXPECT_TRUE(feedback.contains(field.at("name").get<std::string>()));
|
||||
EXPECT_EQ(observer.at("mode"), "manual");
|
||||
EXPECT_FALSE(telemetry.contains("low_latency_limit"));
|
||||
}
|
||||
|
||||
TEST(RenderiveWebGallery, ActionsComeFromStructiveTypeMetadata) {
|
||||
using Spectrum_Schema = structive::type_descriptor_schema_t<Gallery_Spectrum>;
|
||||
using Time_Axis_Schema = structive::type_descriptor_schema_t<Gallery_Time_Axis>;
|
||||
@@ -719,20 +744,21 @@ TEST(RenderiveWebGallery, ThreeFrameStrategiesExposeTheirRealActionsAndObservers
|
||||
ASSERT_TRUE(low_latency.handle(Frame_Request{}));
|
||||
const auto low_telemetry = observe(low_latency);
|
||||
EXPECT_EQ(low_telemetry.at("frame_mode"), "low_latency");
|
||||
EXPECT_GT(low_telemetry.at("kernel_observer").at("observation_count").get<std::uint64_t>(), 0U);
|
||||
EXPECT_TRUE(low_telemetry.contains("render_fps"));
|
||||
ASSERT_TRUE(low_telemetry.contains("low_latency_limit"));
|
||||
const auto& limit = low_telemetry.at("low_latency_limit");
|
||||
EXPECT_FALSE(limit.at("consumer_limited").get<bool>());
|
||||
EXPECT_FALSE(limit.at("frequency_limited").get<bool>());
|
||||
EXPECT_TRUE(limit.at("paint_limited").get<bool>() || limit.at("render_limited").get<bool>());
|
||||
EXPECT_EQ(limit.at("target_interval_ns"), 1);
|
||||
EXPECT_EQ(limit.at("consumer_interval_ns"), 0);
|
||||
EXPECT_GT(limit.at("bottleneck_duration_ns").get<std::uint64_t>(), 1U);
|
||||
EXPECT_TRUE(low_telemetry.at("kernel_observer").contains("paint_lease_wait_ns"));
|
||||
EXPECT_TRUE(low_telemetry.at("kernel_observer").contains("render_finish_state_wait_ns"));
|
||||
const auto& low_observer = low_telemetry.at("kernel_observer");
|
||||
EXPECT_GT(low_observer.at("observation_count").get<std::uint64_t>(), 0U);
|
||||
EXPECT_FALSE(low_telemetry.contains("render_fps"));
|
||||
EXPECT_FALSE(low_telemetry.contains("low_latency_limit"));
|
||||
EXPECT_NE(low_observer.at("limit_state"), "consumer_limited");
|
||||
EXPECT_NE(low_observer.at("limit_state"), "frequency_limited");
|
||||
EXPECT_TRUE(low_observer.at("limit_state") == "paint_limited" ||
|
||||
low_observer.at("limit_state") == "render_limited");
|
||||
EXPECT_EQ(low_observer.at("target_interval_ns"), 1);
|
||||
EXPECT_EQ(low_observer.at("consumer_interval_ns"), 0);
|
||||
EXPECT_GT(low_observer.at("bottleneck_duration_ns").get<std::uint64_t>(), 1U);
|
||||
EXPECT_TRUE(low_observer.contains("paint_lease_wait_ns"));
|
||||
EXPECT_TRUE(low_observer.contains("render_finish_state_wait_ns"));
|
||||
constexpr std::array<std::string_view, 33> observer_fields{
|
||||
"mode", "last_event", "limit_state", "configured_frequency_hz", "observation_count",
|
||||
"mode", "last_event", "limit_state", "frequency_hz", "observation_count",
|
||||
"produced_frame_count", "consumed_frame_count", "dropped_frame_count",
|
||||
"failed_operation_count", "pending_frame_count", "latest_sequence",
|
||||
"paint_duration_ns", "render_duration_ns", "target_interval_ns", "frequency_limit_enabled",
|
||||
@@ -744,7 +770,7 @@ TEST(RenderiveWebGallery, ThreeFrameStrategiesExposeTheirRealActionsAndObservers
|
||||
"render_finish_state_wait_ns", "queue_wait_ns", "end_to_end_ns"
|
||||
};
|
||||
for (const auto field : observer_fields)
|
||||
EXPECT_TRUE(low_telemetry.at("kernel_observer").contains(field)) << field;
|
||||
EXPECT_TRUE(low_observer.contains(field)) << field;
|
||||
|
||||
Gallery_Plot_Session playback;
|
||||
ASSERT_TRUE(playback.handle(gallery_request(
|
||||
@@ -838,7 +864,7 @@ TEST(RenderiveWebGallery, LowLatencyStrategyKeepsForegroundResponsiveUnderAggres
|
||||
const auto telemetry = observe_telemetry(session);
|
||||
EXPECT_LT(std::chrono::steady_clock::now() - started,
|
||||
std::chrono::milliseconds(250)) << iteration;
|
||||
EXPECT_EQ(telemetry.at("kernel_observer").at("configured_frequency_hz"), 1000.0);
|
||||
EXPECT_EQ(telemetry.at("kernel_observer").at("frequency_hz"), 1000.0);
|
||||
if (iteration == 0)
|
||||
first_pixels = frame->payload;
|
||||
last_pixels = frame->payload;
|
||||
@@ -949,7 +975,7 @@ TEST(RenderiveWebGallery, WebRuntimeMetricsPublishKernelSmoothedConsumerFeedback
|
||||
Gallery_Request_Kind::Observe,
|
||||
R"({"category":"event","type":"gallery_observe","client_metrics":{"transport_fps":50,"presentation_fps":50,"websocket_buffered_bytes":0,"changed_pixel_frames":10,"duplicate_pixel_frames":0,"frame_request_timeout_count":0,"frame_round_trip_ms":80,"display_interval_ms":20,"overwritten_pixel_frames":0,"last_pixel_receive_age_ms":1,"last_pixel_change_age_ms":1}})")));
|
||||
auto observer = observed.at("telemetry").at("kernel_observer");
|
||||
auto limit = observed.at("telemetry").at("low_latency_limit");
|
||||
auto feedback = observed.at("telemetry").at("consumer_feedback");
|
||||
EXPECT_TRUE(observer.at("frequency_limit_enabled").get<bool>());
|
||||
EXPECT_TRUE(observer.at("consumer_feedback_enabled").get<bool>());
|
||||
EXPECT_EQ(observer.at("consumer_sample_interval_ns"), 20'000'000);
|
||||
@@ -958,7 +984,7 @@ TEST(RenderiveWebGallery, WebRuntimeMetricsPublishKernelSmoothedConsumerFeedback
|
||||
EXPECT_EQ(observer.at("consumer_safety_interval_ns"), 20'000'000);
|
||||
EXPECT_EQ(observer.at("consumer_interval_ns"), 20'000'000);
|
||||
EXPECT_EQ(observer.at("limit_state"), "consumer_limited");
|
||||
EXPECT_EQ(limit.at("consumer_feedback_source"), "presentation");
|
||||
EXPECT_EQ(feedback.at("source"), "presentation");
|
||||
observed = response_json(session.handle(gallery_request(
|
||||
Gallery_Request_Kind::Observe,
|
||||
R"({"category":"event","type":"gallery_observe","client_metrics":{"transport_fps":45,"presentation_fps":45,"websocket_buffered_bytes":0,"changed_pixel_frames":20,"duplicate_pixel_frames":0,"frame_request_timeout_count":0,"frame_round_trip_ms":4,"display_interval_ms":22,"overwritten_pixel_frames":0,"last_pixel_receive_age_ms":1,"last_pixel_change_age_ms":1}})")));
|
||||
@@ -999,31 +1025,35 @@ TEST(RenderiveWebGallery, ConsumerFeedbackSourcesCanBeSelectedIndependentlyAndMa
|
||||
Gallery_Request_Kind::Observe,
|
||||
R"({"category":"event","type":"gallery_observe","client_metrics":{"transport_fps":25,"presentation_fps":60,"websocket_buffered_bytes":0,"changed_pixel_frames":1,"duplicate_pixel_frames":0,"frame_request_timeout_count":0,"frame_round_trip_ms":5,"display_interval_ms":16,"display_interval_latest_ms":16,"display_interval_p95_ms":17,"display_jitter_ms":1,"overwritten_pixel_frames":0,"last_pixel_receive_age_ms":1,"last_pixel_change_age_ms":1}})")));
|
||||
auto observer = observed.at("telemetry").at("kernel_observer");
|
||||
EXPECT_EQ(observer.at("consumer_feedback_source"), "pixel");
|
||||
EXPECT_EQ(observer.at("consumer_pixel_interval_ns"), 40'000'000);
|
||||
EXPECT_EQ(observer.at("consumer_presentation_interval_ns"), 16'000'000);
|
||||
auto feedback = observed.at("telemetry").at("consumer_feedback");
|
||||
EXPECT_EQ(feedback.at("source"), "pixel");
|
||||
EXPECT_EQ(feedback.at("pixel_interval_ns"), 40'000'000);
|
||||
EXPECT_EQ(feedback.at("presentation_interval_ns"), 16'000'000);
|
||||
EXPECT_EQ(observer.at("consumer_sample_interval_ns"), 40'000'000);
|
||||
observed = patch_controls(session, {
|
||||
{"feedback", {{"pixel", false}, {"presentation", true}}}
|
||||
});
|
||||
observer = observed.at("telemetry").at("kernel_observer");
|
||||
EXPECT_EQ(observer.at("consumer_feedback_source"), "presentation");
|
||||
feedback = observed.at("telemetry").at("consumer_feedback");
|
||||
EXPECT_EQ(feedback.at("source"), "presentation");
|
||||
EXPECT_EQ(observer.at("consumer_sample_interval_ns"), 16'000'000);
|
||||
observed = patch_controls(session, {
|
||||
{"feedback", {{"presentation", false}, {"manual", true},
|
||||
{"manual_fps", 20.0}}}
|
||||
});
|
||||
observer = observed.at("telemetry").at("kernel_observer");
|
||||
EXPECT_EQ(observer.at("consumer_feedback_source"), "manual");
|
||||
EXPECT_EQ(observer.at("consumer_manual_interval_ns"), 50'000'000);
|
||||
feedback = observed.at("telemetry").at("consumer_feedback");
|
||||
EXPECT_EQ(feedback.at("source"), "manual");
|
||||
EXPECT_EQ(feedback.at("manual_interval_ns"), 50'000'000);
|
||||
EXPECT_EQ(observer.at("consumer_sample_interval_ns"), 50'000'000);
|
||||
observed = patch_controls(session, {
|
||||
{"feedback", {{"manual", false}}}
|
||||
});
|
||||
observer = observed.at("telemetry").at("kernel_observer");
|
||||
EXPECT_EQ(observer.at("consumer_feedback_source"), "none");
|
||||
feedback = observed.at("telemetry").at("consumer_feedback");
|
||||
EXPECT_EQ(feedback.at("source"), "none");
|
||||
EXPECT_FALSE(observer.at("consumer_feedback_enabled").get<bool>());
|
||||
EXPECT_TRUE(observer.at("consumer_feedback_master_enabled").get<bool>());
|
||||
EXPECT_TRUE(feedback.at("master_enabled").get<bool>());
|
||||
EXPECT_EQ(observer.at("consumer_interval_ns"), 0);
|
||||
}
|
||||
|
||||
@@ -1119,7 +1149,7 @@ TEST(RenderiveWebGallery, ProductionLowLatencySessionRendersWithoutPixelPulls) {
|
||||
EXPECT_TRUE(performance.at("automatic_low_latency_scheduler").get<bool>());
|
||||
EXPECT_GE(performance.at("successful_render_count").get<std::uint64_t>(), 4U);
|
||||
EXPECT_GT(performance.at("measured_fps").get<double>(), 0.0);
|
||||
EXPECT_DOUBLE_EQ(telemetry.at("kernel_observer").at("configured_frequency_hz"), 120.0);
|
||||
EXPECT_DOUBLE_EQ(telemetry.at("kernel_observer").at("frequency_hz"), 120.0);
|
||||
EXPECT_EQ(telemetry.at("kernel_observer").at("target_interval_ns"), 8'333'333);
|
||||
EXPECT_TRUE(telemetry.at("kernel_observer").at("limit_state") == "frequency_limited" ||
|
||||
telemetry.at("kernel_observer").at("limit_state") == "paint_limited" ||
|
||||
@@ -1273,11 +1303,11 @@ TEST(RenderiveWebGallery, DirectPropertyChangesAndAllImageModesRender) {
|
||||
open_message("constellation", "low_latency"))));
|
||||
const auto patched = constellation.handle(gallery_request(
|
||||
Gallery_Request_Kind::Patch,
|
||||
R"({"category":"event","type":"gallery_patch","target":"constellation","patch":{"type":"PSK16","phase_offset_radians":0.75}})"));
|
||||
R"({"category":"event","type":"gallery_patch","target":"constellation","patch":{"type":"Psk16","phase_offset_radians":0.75}})"));
|
||||
ASSERT_TRUE(patched.has_value());
|
||||
const auto patched_json = parse_json(patched->payload);
|
||||
EXPECT_EQ(patched_json.at("controls").at("resources").at(3).at("data").at("type"),
|
||||
"PSK16");
|
||||
"Psk16");
|
||||
ASSERT_TRUE(constellation.handle(Frame_Request{}).has_value());
|
||||
|
||||
Gallery_Plot_Session waterfall;
|
||||
|
||||
Reference in New Issue
Block a user