Add renderer and package readiness validation gates
This commit is contained in:
88
tests/app_core/app_thread_stress_tests.cpp
Normal file
88
tests/app_core/app_thread_stress_tests.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include "app_core/app_thread.h"
|
||||
#include "test_harness.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace {
|
||||
|
||||
void dispatch_plan_is_consistent_under_stress(pp::tests::Harness& harness)
|
||||
{
|
||||
constexpr std::size_t queued_sizes[] = { 0U, 1U, 4U, 8U, 16U };
|
||||
|
||||
for (const auto queued_task_count : queued_sizes) {
|
||||
const auto plan = pp::app::plan_app_task_dispatch(
|
||||
false,
|
||||
true,
|
||||
queued_task_count,
|
||||
true,
|
||||
true,
|
||||
true);
|
||||
|
||||
PP_EXPECT(harness, !plan.execute_immediately);
|
||||
PP_EXPECT(harness, plan.queue_task);
|
||||
PP_EXPECT(harness, plan.remove_matching_unique_task == (queued_task_count > 0U));
|
||||
PP_EXPECT(harness, plan.notify_worker);
|
||||
PP_EXPECT(harness, plan.wait_for_completion);
|
||||
PP_EXPECT(harness, plan.request_redraw);
|
||||
PP_EXPECT(harness, !plan.reject_unsafe_cross_thread_dispatch);
|
||||
}
|
||||
}
|
||||
|
||||
void dispatch_plan_handles_target_thread_with_rejection_flag(pp::tests::Harness& harness)
|
||||
{
|
||||
constexpr std::size_t queued_sizes[] = { 0U, 5U };
|
||||
for (const auto queued_task_count : queued_sizes) {
|
||||
const auto plan = pp::app::plan_app_task_dispatch(
|
||||
true,
|
||||
true,
|
||||
queued_task_count,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true);
|
||||
|
||||
PP_EXPECT(harness, plan.execute_immediately);
|
||||
PP_EXPECT(harness, !plan.queue_task);
|
||||
PP_EXPECT(harness, !plan.remove_matching_unique_task);
|
||||
PP_EXPECT(harness, !plan.notify_worker);
|
||||
PP_EXPECT(harness, !plan.wait_for_completion);
|
||||
PP_EXPECT(harness, !plan.request_redraw);
|
||||
PP_EXPECT(harness, !plan.reject_unsafe_cross_thread_dispatch);
|
||||
}
|
||||
}
|
||||
|
||||
void dispatch_plan_rejects_cross_thread_mutations_under_pressure(pp::tests::Harness& harness)
|
||||
{
|
||||
constexpr std::size_t queued_sizes[] = { 0U, 4U, 8U };
|
||||
|
||||
for (const auto queued_task_count : queued_sizes) {
|
||||
const auto plan = pp::app::plan_app_task_dispatch(
|
||||
false,
|
||||
true,
|
||||
queued_task_count,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true);
|
||||
|
||||
PP_EXPECT(harness, !plan.execute_immediately);
|
||||
PP_EXPECT(harness, !plan.queue_task);
|
||||
PP_EXPECT(harness, !plan.remove_matching_unique_task);
|
||||
PP_EXPECT(harness, !plan.notify_worker);
|
||||
PP_EXPECT(harness, !plan.wait_for_completion);
|
||||
PP_EXPECT(harness, !plan.request_redraw);
|
||||
PP_EXPECT(harness, plan.reject_unsafe_cross_thread_dispatch);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
pp::tests::Harness harness;
|
||||
harness.run("dispatch plan is consistent across queue sizes", dispatch_plan_is_consistent_under_stress);
|
||||
harness.run("dispatch plan ignores reject flag when already on target thread", dispatch_plan_handles_target_thread_with_rejection_flag);
|
||||
harness.run("dispatch plan rejects unsafe cross-thread work under load", dispatch_plan_rejects_cross_thread_mutations_under_pressure);
|
||||
return harness.finish();
|
||||
}
|
||||
|
||||
@@ -38,6 +38,19 @@ void task_dispatch_does_not_wait_for_stopped_worker(pp::tests::Harness& harness)
|
||||
PP_EXPECT(harness, !plan.wait_for_completion);
|
||||
}
|
||||
|
||||
void task_dispatch_rejects_unsafe_cross_thread_mutations(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto plan = pp::app::plan_app_task_dispatch(false, true, 2, true, true, false, true);
|
||||
|
||||
PP_EXPECT(harness, !plan.execute_immediately);
|
||||
PP_EXPECT(harness, !plan.queue_task);
|
||||
PP_EXPECT(harness, !plan.remove_matching_unique_task);
|
||||
PP_EXPECT(harness, !plan.notify_worker);
|
||||
PP_EXPECT(harness, !plan.wait_for_completion);
|
||||
PP_EXPECT(harness, !plan.request_redraw);
|
||||
PP_EXPECT(harness, plan.reject_unsafe_cross_thread_dispatch);
|
||||
}
|
||||
|
||||
void render_queue_drain_wraps_non_empty_work_in_context(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto empty = pp::app::plan_app_render_queue_drain(0);
|
||||
@@ -124,6 +137,7 @@ int main()
|
||||
harness.run("task dispatch executes immediately on target thread", task_dispatch_executes_immediately_on_target_thread);
|
||||
harness.run("task dispatch queues unique work and waits for running worker", task_dispatch_queues_unique_work_and_waits_for_running_worker);
|
||||
harness.run("task dispatch does not wait for stopped worker", task_dispatch_does_not_wait_for_stopped_worker);
|
||||
harness.run("task dispatch can reject unsafe cross-thread mutations", task_dispatch_rejects_unsafe_cross_thread_mutations);
|
||||
harness.run("render queue drain wraps non empty work in context", render_queue_drain_wraps_non_empty_work_in_context);
|
||||
harness.run("ui thread tick runs tasks and schedules redraw", ui_thread_tick_runs_tasks_and_schedules_redraw);
|
||||
harness.run("ui loop timers report fps and reload on threshold", ui_loop_timers_report_fps_and_reload_on_threshold);
|
||||
|
||||
Reference in New Issue
Block a user