5#define FML_USED_ON_EMBEDDER
10#include "flutter/fml/message_loop_task_queues.h"
11#include "flutter/fml/synchronization/count_down_latch.h"
12#include "flutter/fml/synchronization/waitable_event.h"
13#include "flutter/fml/time/chrono_timestamp_provider.h"
14#include "gtest/gtest.h"
33 bool run_invocation =
false) {
50TEST(MessageLoopTaskQueueMergeUnmerge,
51 AfterMergePrimaryTasksServicedOnPrimary) {
54 auto queue_id_1 = task_queue->CreateTaskQueue();
55 auto queue_id_2 = task_queue->CreateTaskQueue();
58 ASSERT_EQ(1u, task_queue->GetNumPendingTasks(queue_id_1));
60 task_queue->Merge(queue_id_1, queue_id_2);
63 ASSERT_EQ(2u, task_queue->GetNumPendingTasks(queue_id_1));
64 ASSERT_EQ(0u, task_queue->GetNumPendingTasks(queue_id_2));
67TEST(MessageLoopTaskQueueMergeUnmerge,
68 AfterMergeSecondaryTasksAlsoServicedOnPrimary) {
71 auto queue_id_1 = task_queue->CreateTaskQueue();
72 auto queue_id_2 = task_queue->CreateTaskQueue();
75 ASSERT_EQ(1u, task_queue->GetNumPendingTasks(queue_id_2));
77 task_queue->Merge(queue_id_1, queue_id_2);
78 ASSERT_EQ(1u, task_queue->GetNumPendingTasks(queue_id_1));
79 ASSERT_EQ(0u, task_queue->GetNumPendingTasks(queue_id_2));
82TEST(MessageLoopTaskQueueMergeUnmerge, MergeUnmergeTasksPreserved) {
85 auto queue_id_1 = task_queue->CreateTaskQueue();
86 auto queue_id_2 = task_queue->CreateTaskQueue();
91 ASSERT_EQ(1u, task_queue->GetNumPendingTasks(queue_id_1));
92 ASSERT_EQ(1u, task_queue->GetNumPendingTasks(queue_id_2));
94 task_queue->Merge(queue_id_1, queue_id_2);
96 ASSERT_EQ(2u, task_queue->GetNumPendingTasks(queue_id_1));
97 ASSERT_EQ(0u, task_queue->GetNumPendingTasks(queue_id_2));
99 task_queue->Unmerge(queue_id_1, queue_id_2);
101 ASSERT_EQ(1u, task_queue->GetNumPendingTasks(queue_id_1));
102 ASSERT_EQ(1u, task_queue->GetNumPendingTasks(queue_id_2));
106TEST(MessageLoopTaskQueueMergeUnmerge,
107 OneCanOwnMultipleQueuesAndUnmergeIndependently) {
109 auto queue_id_1 = task_queue->CreateTaskQueue();
110 auto queue_id_2 = task_queue->CreateTaskQueue();
111 auto queue_id_3 = task_queue->CreateTaskQueue();
114 ASSERT_TRUE(task_queue->Merge(queue_id_1, queue_id_2));
115 ASSERT_TRUE(task_queue->Owns(queue_id_1, queue_id_2));
116 ASSERT_FALSE(task_queue->Owns(queue_id_1, queue_id_3));
118 ASSERT_TRUE(task_queue->Merge(queue_id_1, queue_id_3));
119 ASSERT_TRUE(task_queue->Owns(queue_id_1, queue_id_2));
120 ASSERT_TRUE(task_queue->Owns(queue_id_1, queue_id_3));
123 ASSERT_TRUE(task_queue->Unmerge(queue_id_1, queue_id_2));
124 ASSERT_FALSE(task_queue->Owns(queue_id_1, queue_id_2));
125 ASSERT_TRUE(task_queue->Owns(queue_id_1, queue_id_3));
127 ASSERT_TRUE(task_queue->Unmerge(queue_id_1, queue_id_3));
128 ASSERT_FALSE(task_queue->Owns(queue_id_1, queue_id_2));
129 ASSERT_FALSE(task_queue->Owns(queue_id_1, queue_id_3));
132TEST(MessageLoopTaskQueueMergeUnmerge,
133 CannotMergeSameQueueToTwoDifferentOwners) {
135 auto queue = task_queue->CreateTaskQueue();
136 auto owner_1 = task_queue->CreateTaskQueue();
137 auto owner_2 = task_queue->CreateTaskQueue();
139 ASSERT_TRUE(task_queue->Merge(owner_1,
queue));
140 ASSERT_FALSE(task_queue->Merge(owner_2,
queue));
143TEST(MessageLoopTaskQueueMergeUnmerge, MergeFailIfAlreadySubsumed) {
146 auto queue_id_1 = task_queue->CreateTaskQueue();
147 auto queue_id_2 = task_queue->CreateTaskQueue();
148 auto queue_id_3 = task_queue->CreateTaskQueue();
150 ASSERT_TRUE(task_queue->Merge(queue_id_1, queue_id_2));
151 ASSERT_FALSE(task_queue->Merge(queue_id_2, queue_id_3));
152 ASSERT_FALSE(task_queue->Merge(queue_id_2, queue_id_1));
155TEST(MessageLoopTaskQueueMergeUnmerge,
156 MergeFailIfAlreadyOwnsButTryToBeSubsumed) {
159 auto queue_id_1 = task_queue->CreateTaskQueue();
160 auto queue_id_2 = task_queue->CreateTaskQueue();
161 auto queue_id_3 = task_queue->CreateTaskQueue();
163 task_queue->Merge(queue_id_1, queue_id_2);
165 ASSERT_FALSE(task_queue->Merge(queue_id_3, queue_id_1));
168TEST(MessageLoopTaskQueueMergeUnmerge, UnmergeFailsOnSubsumedOrNeverMerged) {
171 auto queue_id_1 = task_queue->CreateTaskQueue();
172 auto queue_id_2 = task_queue->CreateTaskQueue();
173 auto queue_id_3 = task_queue->CreateTaskQueue();
175 task_queue->Merge(queue_id_1, queue_id_2);
176 ASSERT_FALSE(task_queue->Unmerge(queue_id_2, queue_id_3));
177 ASSERT_FALSE(task_queue->Unmerge(queue_id_1, queue_id_3));
178 ASSERT_FALSE(task_queue->Unmerge(queue_id_3, queue_id_1));
179 ASSERT_FALSE(task_queue->Unmerge(queue_id_2, queue_id_1));
182TEST(MessageLoopTaskQueueMergeUnmerge, MergeInvokesBothWakeables) {
185 auto queue_id_1 = task_queue->CreateTaskQueue();
186 auto queue_id_2 = task_queue->CreateTaskQueue();
190 auto wakeable1 = std::make_unique<TestWakeable>(
192 auto wakeable2 = std::make_unique<TestWakeable>(
195 task_queue->SetWakeable(queue_id_1, wakeable1.get());
196 task_queue->SetWakeable(queue_id_2, wakeable2.get());
200 task_queue->Merge(queue_id_1, queue_id_2);
207TEST(MessageLoopTaskQueueMergeUnmerge,
208 MergeUnmergeInvokesBothWakeablesSeparately) {
211 auto queue_id_1 = task_queue->CreateTaskQueue();
212 auto queue_id_2 = task_queue->CreateTaskQueue();
216 auto wakeable1 = std::make_unique<TestWakeable>(
218 auto wakeable2 = std::make_unique<TestWakeable>(
221 task_queue->SetWakeable(queue_id_1, wakeable1.get());
222 task_queue->SetWakeable(queue_id_2, wakeable2.get());
227 task_queue->Merge(queue_id_1, queue_id_2);
228 task_queue->Unmerge(queue_id_1, queue_id_2);
239TEST(MessageLoopTaskQueueMergeUnmerge, GetTasksToRunNowBlocksMerge) {
242 auto queue_id_1 = task_queue->CreateTaskQueue();
243 auto queue_id_2 = task_queue->CreateTaskQueue();
248 auto wakeable = std::make_unique<TestWakeable>([&](
fml::TimePoint wake_time) {
254 task_queue->SetWakeable(queue_id_1, wakeable.get());
256 std::thread tasks_to_run_now_thread(
259 wake_up_start.
Wait();
260 bool merge_done =
false;
262 std::thread merge_thread([&]() {
264 task_queue->Merge(queue_id_1, queue_id_2);
270 ASSERT_FALSE(merge_done);
274 ASSERT_TRUE(merge_done);
276 tasks_to_run_now_thread.join();
280TEST(MessageLoopTaskQueueMergeUnmerge,
281 FollowingTasksSwitchQueueIfFirstTaskMergesThreads) {
284 auto queue_id_1 = task_queue->CreateTaskQueue();
285 auto queue_id_2 = task_queue->CreateTaskQueue();
289 auto wakeable1 = std::make_unique<TestWakeable>(
291 auto wakeable2 = std::make_unique<TestWakeable>(
294 task_queue->SetWakeable(queue_id_1, wakeable1.get());
295 task_queue->SetWakeable(queue_id_2, wakeable2.get());
297 task_queue->RegisterTask(
298 queue_id_2, [&]() { task_queue->Merge(queue_id_1, queue_id_2); },
fml::closure GetNextTaskToRun(TaskQueueId queue_id, fml::TimePoint from_time)
static MessageLoopTaskQueues * GetInstance()
void WakeUp(fml::TimePoint time_point) override
std::function< void(const fml::TimePoint)> WakeUpCall
TestWakeable(WakeUpCall call)
Dart_NativeFunction function
static int CountRemainingTasks(fml::MessageLoopTaskQueues *task_queue, const TaskQueueId &queue_id, bool run_invocation=false)
TEST(BacktraceTest, CanGatherBacktrace)
fml::TimePoint ChronoTicksSinceEpoch()
std::function< void()> closure