Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Functions | Variables
fml::testing Namespace Reference

Classes

struct  LogCapture
 
class  LogInterestListenerFuchsia
 
class  MakeSureFmlLogDoesNotSegfaultWhenStaticallyCalled
 
class  MockLogSink
 
struct  TaskQueueWrapper
 A mock task queue NOT calling MessageLoop->Run() in thread. More...
 
class  TestWakeable
 

Functions

 TEST (BacktraceTest, CanGatherBacktrace)
 
 TEST (CpuAffinity, NonAndroidPlatformDefaults)
 
 TEST (CpuAffinity, NormalSlowMedFastCores)
 
 TEST (CpuAffinity, NoCpuData)
 
 TEST (CpuAffinity, AllSameSpeed)
 
 TEST (CpuAffinity, SingleCore)
 
 TEST (CpuAffinity, FileParsing)
 
 TEST (CpuAffinity, FileParsingWithNonNumber)
 
 TEST (CpuAffinity, MissingFileParsing)
 
 TEST (EndiannessTest, ByteSwap)
 
 TEST (EndiannessTest, BigEndianToArch)
 
 TEST (EndiannessTest, LittleEndianToArch)
 
 TEST (HashCombineTest, CanHash)
 
int UnreachableScopeWithoutReturnDoesNotMakeCompilerMad ()
 
int UnreachableScopeWithMacroWithoutReturnDoesNotMakeCompilerMad ()
 
 TEST (LoggingTest, UnreachableKillProcess)
 
 TEST (LoggingTest, UnreachableKillProcessWithMacro)
 
 TEST (LoggingTest, SanityTests)
 
 TEST (TaskRunnerCheckerTests, RunsOnCurrentTaskRunner)
 
 TEST (TaskRunnerCheckerTests, FailsTheCheckIfOnDifferentTaskRunner)
 
 TEST (TaskRunnerCheckerTests, SameTaskRunnerRunsOnTheSameThread)
 
 TEST (TaskRunnerCheckerTests, RunsOnDifferentThreadsReturnsFalse)
 
 TEST (TaskRunnerCheckerTests, MergedTaskRunnersRunsOnTheSameThread)
 
 TEST (TaskRunnerCheckerTests, PassesRunsOnCreationTaskRunnerIfOnDifferentTaskRunner)
 
static int CountRemainingTasks (fml::MessageLoopTaskQueues *task_queue, const TaskQueueId &queue_id, bool run_invocation=false)
 
 TEST (MessageLoopTaskQueueMergeUnmerge, AfterMergePrimaryTasksServicedOnPrimary)
 
 TEST (MessageLoopTaskQueueMergeUnmerge, AfterMergeSecondaryTasksAlsoServicedOnPrimary)
 
 TEST (MessageLoopTaskQueueMergeUnmerge, MergeUnmergeTasksPreserved)
 
 TEST (MessageLoopTaskQueueMergeUnmerge, OneCanOwnMultipleQueuesAndUnmergeIndependently)
 Multiple standalone engines scene.
 
 TEST (MessageLoopTaskQueueMergeUnmerge, CannotMergeSameQueueToTwoDifferentOwners)
 
 TEST (MessageLoopTaskQueueMergeUnmerge, MergeFailIfAlreadySubsumed)
 
 TEST (MessageLoopTaskQueueMergeUnmerge, MergeFailIfAlreadyOwnsButTryToBeSubsumed)
 
 TEST (MessageLoopTaskQueueMergeUnmerge, UnmergeFailsOnSubsumedOrNeverMerged)
 
 TEST (MessageLoopTaskQueueMergeUnmerge, MergeInvokesBothWakeables)
 
 TEST (MessageLoopTaskQueueMergeUnmerge, MergeUnmergeInvokesBothWakeablesSeparately)
 
 TEST (MessageLoopTaskQueueMergeUnmerge, GetTasksToRunNowBlocksMerge)
 
 TEST (MessageLoopTaskQueueMergeUnmerge, FollowingTasksSwitchQueueIfFirstTaskMergesThreads)
 
 TEST (MessageLoopTaskQueue, StartsWithNoPendingTasks)
 
 TEST (MessageLoopTaskQueue, RegisterOneTask)
 
 TEST (MessageLoopTaskQueue, RegisterTwoTasksAndCount)
 
 TEST (MessageLoopTaskQueue, RegisterTasksOnMergedQueuesAndCount)
 
 TEST (MessageLoopTaskQueue, PreserveTaskOrdering)
 
 TEST (MessageLoopTaskQueue, RegisterTasksOnMergedQueuesPreserveTaskOrdering)
 
 TEST (MessageLoopTaskQueue, UnmergeRespectTheOriginalTaskOrderingInQueues)
 
void TestNotifyObservers (fml::TaskQueueId queue_id)
 
 TEST (MessageLoopTaskQueue, AddRemoveNotifyObservers)
 
 TEST (MessageLoopTaskQueue, WakeUpIndependentOfTime)
 
 TEST (MessageLoopTaskQueue, WokenUpWithNewerTime)
 
 TEST (MessageLoopTaskQueue, NotifyObserversWhileCreatingQueues)
 
 TEST (MessageLoopTaskQueue, QueueDoNotOwnItself)
 
 TEST (MessageLoopTaskQueue, QueueDoNotOwnUnmergedTaskQueueId)
 
 TEST (MessageLoopTaskQueue, QueueOwnsMergedTaskQueueId)
 
 TEST (MessageLoopTaskQueue, ConcurrentQueueAndTaskCreatingCounts)
 
 TEST (MessageLoopTaskQueue, RegisterTaskWakesUpOwnerQueue)
 
 TEST (CFTest, CanCreateRefs)
 
 TEST_F (LogInterestListenerFuchsia, SeverityChanges)
 
 TEST_F (LogInterestListenerFuchsia, AsyncWaitForInterestChange)
 
 TEST (FileWin, OpenDirectoryShare)
 
 TEST (StringConversion, Utf8ToWideStringEmpty)
 
 TEST (StringConversion, Utf8ToWideStringAscii)
 
 TEST (StringConversion, Utf8ToWideStringUnicode)
 
 TEST (StringConversion, WideStringToUtf8Empty)
 
 TEST (StringConversion, WideStringToUtf8Ascii)
 
 TEST (StringConversion, WideStringToUtf8Unicode)
 
 TEST (StringConversion, WideStringToUtf16Empty)
 
 TEST (StringConversion, WideStringToUtf16Ascii)
 
 TEST (StringConversion, WideStringToUtf16Unicode)
 
 TEST (StringConversion, Utf16ToWideStringEmpty)
 
 TEST (StringConversion, Utf16ToWideStringAscii)
 
 TEST (StringConversion, Utf16ToWideStringUtf8Unicode)
 
 TEST (RasterThreadMerger, RemainMergedTillLeaseExpires)
 
 TEST (RasterThreadMerger, IsNotOnRasterizingThread)
 
 TEST (RasterThreadMerger, LeaseExtension)
 
 TEST (RasterThreadMerger, WaitUntilMerged)
 
 TEST (RasterThreadMerger, HandleTaskQueuesAreTheSame)
 
 TEST (RasterThreadMerger, Enable)
 
 TEST (RasterThreadMerger, Disable)
 
 TEST (RasterThreadMerger, IsEnabled)
 
 TEST (RasterThreadMerger, TwoMergersWithSameThreadPairShareEnabledState)
 
 TEST (RasterThreadMerger, RunExpiredTasksWhileFirstTaskMergesThreads)
 
 TEST (RasterThreadMerger, RunExpiredTasksWhileFirstTaskUnMergesThreads)
 
 TEST (RasterThreadMerger, SetMergeUnmergeCallback)
 
 TEST (RasterThreadMerger, MultipleMergersCanMergeSameThreadPair)
 
 TEST (RasterThreadMerger, TheLastCallerOfMultipleMergersCanUnmergeNow)
 
 TEST (RasterThreadMerger, TheLastMergedCallerOfMultipleMergersCanUnmergeNow)
 
 TEST (RasterThreadMerger, TwoIndependentMergersCanMergeTwoDifferentThreadsIntoSamePlatformThread)
 
 TEST (StringConversion, Utf16ToUtf16Empty)
 
 TEST (StringConversion, Utf8ToUtf16Ascii)
 
 TEST (StringConversion, Utf8ToUtf16Unicode)
 
 TEST (StringConversion, Utf16ToUtf8Empty)
 
 TEST (StringConversion, Utf16ToUtf8Ascii)
 
 TEST (StringConversion, Utf16ToUtf8Unicode)
 
 TEST (TaskSourceTests, SimpleInitialization)
 
 TEST (TaskSourceTests, MultipleTaskGrades)
 
 TEST (TaskSourceTests, SimpleOrdering)
 
 TEST (TaskSourceTests, SimpleOrderingMultiTaskHeaps)
 
 TEST (TaskSourceTests, OrderingMultiTaskHeapsSecondaryPaused)
 

Variables

static MakeSureFmlLogDoesNotSegfaultWhenStaticallyCalled fml_log_static_check_
 
static constexpr char kLogSink [] = "log_sink"
 

Function Documentation

◆ CountRemainingTasks()

static int fml::testing::CountRemainingTasks ( fml::MessageLoopTaskQueues task_queue,
const TaskQueueId queue_id,
bool  run_invocation = false 
)
static

Definition at line 31 of file message_loop_task_queues_merge_unmerge_unittests.cc.

33 {
34 const auto now = ChronoTicksSinceEpoch();
35 int count = 0;
36 fml::closure invocation;
37 do {
38 invocation = task_queue->GetNextTaskToRun(queue_id, now);
39 if (!invocation) {
40 break;
41 }
42 count++;
43 if (run_invocation) {
44 invocation();
45 }
46 } while (invocation);
47 return count;
48}
int count
fml::closure GetNextTaskToRun(TaskQueueId queue_id, fml::TimePoint from_time)
fml::TimePoint ChronoTicksSinceEpoch()
std::function< void()> closure
Definition closure.h:14

◆ TEST() [1/91]

fml::testing::TEST ( BacktraceTest  ,
CanGatherBacktrace   
)

Definition at line 13 of file backtrace_unittests.cc.

13 {
15 GTEST_SKIP();
16 return;
17 }
18 {
19 auto trace = BacktraceHere(0);
20 ASSERT_GT(trace.size(), 0u);
21 ASSERT_NE(trace.find("Frame 0"), std::string::npos);
22 }
23
24 {
25 auto trace = BacktraceHere(1);
26 ASSERT_GT(trace.size(), 0u);
27 ASSERT_NE(trace.find("Frame 0"), std::string::npos);
28 }
29
30 {
31 auto trace = BacktraceHere(2);
32 ASSERT_GT(trace.size(), 0u);
33 ASSERT_NE(trace.find("Frame 0"), std::string::npos);
34 }
35}
std::string BacktraceHere(size_t offset)
Definition backtrace.cc:43
bool IsCrashHandlingSupported()
Definition backtrace.cc:140

◆ TEST() [2/91]

fml::testing::TEST ( CFTest  ,
CanCreateRefs   
)

Definition at line 12 of file cf_utils_unittests.mm.

12 {
13 CFRef<CFMutableStringRef> string(CFStringCreateMutable(kCFAllocatorDefault, 100u));
14 // Cast
15 ASSERT_TRUE(static_cast<bool>(string));
16 ASSERT_TRUE(string);
17
18 const auto ref_count = CFGetRetainCount(string);
19
20 // Copy & Reset
21 {
22 CFRef<CFMutableStringRef> string2 = string;
23 ASSERT_TRUE(string2);
24 ASSERT_EQ(ref_count + 1u, CFGetRetainCount(string));
25 ASSERT_EQ(CFGetRetainCount(string2), CFGetRetainCount(string));
26
27 string2.Reset();
28 ASSERT_FALSE(string2);
29 ASSERT_EQ(ref_count, CFGetRetainCount(string));
30 }
31
32 // Release
33 {
34 auto string3 = string;
35 ASSERT_TRUE(string3);
36 ASSERT_EQ(ref_count + 1u, CFGetRetainCount(string));
37 auto raw_string3 = string3.Release();
38 ASSERT_FALSE(string3);
39 ASSERT_EQ(ref_count + 1u, CFGetRetainCount(string));
40 CFRelease(raw_string3);
41 ASSERT_EQ(ref_count, CFGetRetainCount(string));
42 }
43
44 // Move
45 {
46 auto string_source = string;
47 ASSERT_TRUE(string_source);
48 auto string_move = std::move(string_source);
49 ASSERT_FALSE(string_source); // NOLINT(bugprone-use-after-move)
50 ASSERT_EQ(ref_count + 1u, CFGetRetainCount(string));
51 string_move.Reset();
52 ASSERT_EQ(ref_count, CFGetRetainCount(string));
53 }
54
55 // Move assign.
56 {
57 auto string_move_assign = std::move(string);
58 ASSERT_FALSE(string); // NOLINT(bugprone-use-after-move)
59 ASSERT_EQ(ref_count, CFGetRetainCount(string_move_assign));
60 }
61}
void Reset(T instance=nullptr)
Definition cf_utils.h:44

◆ TEST() [3/91]

fml::testing::TEST ( CpuAffinity  ,
AllSameSpeed   
)

Definition at line 40 of file cpu_affinity_unittests.cc.

40 {
41 auto speeds = {CpuIndexAndSpeed{.index = 0, .speed = 1},
42 CpuIndexAndSpeed{.index = 1, .speed = 1},
43 CpuIndexAndSpeed{.index = 2, .speed = 1}};
44 auto tracker = CPUSpeedTracker(speeds);
45
46 ASSERT_FALSE(tracker.IsValid());
47}

◆ TEST() [4/91]

fml::testing::TEST ( CpuAffinity  ,
FileParsing   
)

Definition at line 56 of file cpu_affinity_unittests.cc.

56 {
58 ASSERT_TRUE(base_dir.fd().is_valid());
59
60 // Generate a fake CPU speed file
61 fml::DataMapping test_data(std::string("12345"));
62 ASSERT_TRUE(fml::WriteAtomically(base_dir.fd(), "test_file", test_data));
63
64 auto file = fml::OpenFileReadOnly(base_dir.fd(), "test_file");
65 ASSERT_TRUE(file.is_valid());
66
67 // Open file and parse speed.
68 auto result = ReadIntFromFile(base_dir.path() + "/test_file");
69 ASSERT_TRUE(result.has_value());
70 ASSERT_EQ(result.value_or(0), 12345);
71}
const UniqueFD & fd()
Definition file.h:147
const std::string & path() const
Definition file.h:146
bool is_valid() const
GAsyncResult * result
fml::UniqueFD OpenFileReadOnly(const fml::UniqueFD &base_directory, const char *path)
Definition file.cc:92
bool WriteAtomically(const fml::UniqueFD &base_directory, const char *file_name, const Mapping &mapping)
std::optional< int64_t > ReadIntFromFile(const std::string &path)

◆ TEST() [5/91]

fml::testing::TEST ( CpuAffinity  ,
FileParsingWithNonNumber   
)

Definition at line 73 of file cpu_affinity_unittests.cc.

73 {
75 ASSERT_TRUE(base_dir.fd().is_valid());
76
77 // Generate a fake CPU speed file
78 fml::DataMapping test_data(std::string("whoa this isnt a number"));
79 ASSERT_TRUE(fml::WriteAtomically(base_dir.fd(), "test_file", test_data));
80
81 auto file = fml::OpenFileReadOnly(base_dir.fd(), "test_file");
82 ASSERT_TRUE(file.is_valid());
83
84 // Open file and parse speed.
85 auto result = ReadIntFromFile(base_dir.path() + "/test_file");
86 ASSERT_FALSE(result.has_value());
87}

◆ TEST() [6/91]

fml::testing::TEST ( CpuAffinity  ,
MissingFileParsing   
)

Definition at line 89 of file cpu_affinity_unittests.cc.

89 {
90 auto result = ReadIntFromFile("/does_not_exist");
91 ASSERT_FALSE(result.has_value());
92}

◆ TEST() [7/91]

fml::testing::TEST ( CpuAffinity  ,
NoCpuData   
)

Definition at line 34 of file cpu_affinity_unittests.cc.

34 {
35 auto tracker = CPUSpeedTracker({});
36
37 ASSERT_FALSE(tracker.IsValid());
38}
A class that computes the correct CPU indices for a requested CPU affinity.

◆ TEST() [8/91]

fml::testing::TEST ( CpuAffinity  ,
NonAndroidPlatformDefaults   
)

Definition at line 15 of file cpu_affinity_unittests.cc.

15 {
16 ASSERT_FALSE(fml::EfficiencyCoreCount().has_value());
18}
@ kEfficiency
Request CPU affinity for the efficiency cores.
bool RequestAffinity(CpuAffinity affinity)
Request the given affinity for the current thread.
std::optional< size_t > EfficiencyCoreCount()
Request count of efficiency cores.

◆ TEST() [9/91]

fml::testing::TEST ( CpuAffinity  ,
NormalSlowMedFastCores   
)

Definition at line 20 of file cpu_affinity_unittests.cc.

20 {
21 auto speeds = {CpuIndexAndSpeed{.index = 0, .speed = 1},
22 CpuIndexAndSpeed{.index = 1, .speed = 2},
23 CpuIndexAndSpeed{.index = 2, .speed = 3}};
24 auto tracker = CPUSpeedTracker(speeds);
25
26 ASSERT_TRUE(tracker.IsValid());
27 ASSERT_EQ(tracker.GetIndices(CpuAffinity::kEfficiency)[0], 0u);
28 ASSERT_EQ(tracker.GetIndices(CpuAffinity::kPerformance)[0], 2u);
29 ASSERT_EQ(tracker.GetIndices(CpuAffinity::kNotPerformance).size(), 2u);
30 ASSERT_EQ(tracker.GetIndices(CpuAffinity::kNotPerformance)[0], 0u);
31 ASSERT_EQ(tracker.GetIndices(CpuAffinity::kNotPerformance)[1], 1u);
32}

◆ TEST() [10/91]

fml::testing::TEST ( CpuAffinity  ,
SingleCore   
)

Definition at line 49 of file cpu_affinity_unittests.cc.

49 {
50 auto speeds = {CpuIndexAndSpeed{.index = 0, .speed = 1}};
51 auto tracker = CPUSpeedTracker(speeds);
52
53 ASSERT_FALSE(tracker.IsValid());
54}

◆ TEST() [11/91]

fml::testing::TEST ( EndiannessTest  ,
BigEndianToArch   
)

Definition at line 18 of file endianness_unittests.cc.

18 {
19#if FML_ARCH_CPU_LITTLE_ENDIAN
20 uint32_t expected = 0x44332211;
21#else
22 uint32_t expected = 0x11223344;
23#endif
24 ASSERT_EQ(BigEndianToArch(0x11223344u), expected);
25}
constexpr T BigEndianToArch(T n)
Convert a known big endian value to match the endianness of the current architecture....
Definition endianness.h:59

◆ TEST() [12/91]

fml::testing::TEST ( EndiannessTest  ,
ByteSwap   
)

Definition at line 12 of file endianness_unittests.cc.

12 {
13 ASSERT_EQ(ByteSwap<int16_t>(0x1122), 0x2211);
14 ASSERT_EQ(ByteSwap<int32_t>(0x11223344), 0x44332211);
15 ASSERT_EQ(ByteSwap<uint64_t>(0x1122334455667788), 0x8877665544332211);
16}

◆ TEST() [13/91]

fml::testing::TEST ( EndiannessTest  ,
LittleEndianToArch   
)

Definition at line 27 of file endianness_unittests.cc.

27 {
28#if FML_ARCH_CPU_LITTLE_ENDIAN
29 uint32_t expected = 0x11223344;
30#else
31 uint32_t expected = 0x44332211;
32#endif
33 ASSERT_EQ(LittleEndianToArch(0x11223344u), expected);
34}
constexpr T LittleEndianToArch(T n)
Convert a known little endian value to match the endianness of the current architecture....
Definition endianness.h:71

◆ TEST() [14/91]

fml::testing::TEST ( FileWin  ,
OpenDirectoryShare   
)

Definition at line 15 of file file_win_unittests.cc.

15 {
17 auto temp_path = Utf8ToWideString({temp_dir.path()});
18 fml::UniqueFD handle(
19 CreateFile(temp_path.c_str(), GENERIC_WRITE,
20 FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING,
21 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, nullptr));
22 ASSERT_TRUE(handle.is_valid());
23
24 // Check that fml::OpenDirectory(FilePermission::kRead) works with a
25 // directory that has also been opened for writing.
26 auto dir = fml::OpenDirectory(temp_dir.path().c_str(), false,
28 ASSERT_TRUE(dir.is_valid());
29}
std::wstring Utf8ToWideString(const std::string_view str)
fml::UniqueFD OpenDirectory(const char *path, bool create_if_necessary, FilePermission permission)
Definition file_posix.cc:97
#define CreateFile

◆ TEST() [15/91]

fml::testing::TEST ( HashCombineTest  ,
CanHash   
)

Definition at line 12 of file hash_combine_unittests.cc.

12 {
13 ASSERT_EQ(HashCombine(), HashCombine());
14 ASSERT_EQ(HashCombine("Hello"), HashCombine("Hello"));
15 ASSERT_NE(HashCombine("Hello"), HashCombine("World"));
16 ASSERT_EQ(HashCombine("Hello", "World"), HashCombine("Hello", "World"));
17 ASSERT_NE(HashCombine("World", "Hello"), HashCombine("Hello", "World"));
18 ASSERT_EQ(HashCombine(12u), HashCombine(12u));
19 ASSERT_NE(HashCombine(12u), HashCombine(12.0f));
20 ASSERT_EQ(HashCombine('a'), HashCombine('a'));
21}
constexpr std::size_t HashCombine()

◆ TEST() [16/91]

fml::testing::TEST ( LoggingTest  ,
SanityTests   
)

Definition at line 76 of file logging_unittests.cc.

76 {
77 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
78 std::vector<std::string> severities = {"INFO", "WARNING", "ERROR",
79 "IMPORTANT"};
80
81 for (size_t i = 0; i < severities.size(); i++) {
82 LogCapture capture;
83 {
84 LogMessage log(i, "path/to/file.cc", 4, nullptr);
85 log.stream() << "Hello!";
86 }
87 EXPECT_EQ(capture.str(), std::string("[" + severities[i] +
88 ":path/to/file.cc(4)] Hello!\n"));
89 }
90
91 ASSERT_DEATH(
92 {
93 LogMessage log(kLogFatal, "path/to/file.cc", 5, nullptr);
94 log.stream() << "Goodbye";
95 },
96 R"(\[FATAL:path/to/file.cc\‍(5\)\] Goodbye)");
97}

◆ TEST() [17/91]

fml::testing::TEST ( LoggingTest  ,
UnreachableKillProcess   
)

Definition at line 65 of file logging_unittests.cc.

65 {
66 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
67 ASSERT_DEATH(KillProcess(), "");
68}
void KillProcess()
Definition logging.cc:220

◆ TEST() [18/91]

fml::testing::TEST ( LoggingTest  ,
UnreachableKillProcessWithMacro   
)

Definition at line 70 of file logging_unittests.cc.

70 {
71 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
72 ASSERT_DEATH({ FML_UNREACHABLE(); }, "");
73}
#define FML_UNREACHABLE()
Definition logging.h:109

◆ TEST() [19/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
AddRemoveNotifyObservers   
)

Definition at line 242 of file message_loop_task_queues_unittests.cc.

242 {
243 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
244 auto queue_id = task_queue->CreateTaskQueue();
245
246 int test_val = 0;
247 intptr_t key = 123;
248
249 task_queue->AddTaskObserver(queue_id, key, [&test_val]() { test_val = 1; });
250 TestNotifyObservers(queue_id);
251 ASSERT_TRUE(test_val == 1);
252
253 test_val = 0;
254 task_queue->RemoveTaskObserver(queue_id, key);
255 TestNotifyObservers(queue_id);
256 ASSERT_TRUE(test_val == 0);
257}
static MessageLoopTaskQueues * GetInstance()

◆ TEST() [20/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
ConcurrentQueueAndTaskCreatingCounts   
)

Verifies that tasks can be added to task queues concurrently.

Definition at line 351 of file message_loop_task_queues_unittests.cc.

351 {
352 auto task_queues = fml::MessageLoopTaskQueues::GetInstance();
353
354 // kThreadCount threads post kThreadTaskCount tasks each to kTaskQueuesCount
355 // task queues. Each thread picks a task queue randomly for each task.
356 constexpr size_t kThreadCount = 4;
357 constexpr size_t kTaskQueuesCount = 2;
358 constexpr size_t kThreadTaskCount = 500;
359
360 std::vector<TaskQueueId> task_queue_ids;
361 for (size_t i = 0; i < kTaskQueuesCount; ++i) {
362 task_queue_ids.emplace_back(task_queues->CreateTaskQueue());
363 }
364
365 ASSERT_EQ(task_queue_ids.size(), kTaskQueuesCount);
366
367 fml::CountDownLatch tasks_posted_latch(kThreadCount);
368
369 auto thread_main = [&]() {
370 for (size_t i = 0; i < kThreadTaskCount; i++) {
371 const auto current_task_queue_id =
372 task_queue_ids[std::rand() % kTaskQueuesCount];
373 const auto empty_task = []() {};
374 // The timepoint doesn't matter as the queue is never going to be drained.
375 const auto task_timepoint = ChronoTicksSinceEpoch();
376
377 task_queues->RegisterTask(current_task_queue_id, empty_task,
378 task_timepoint);
379 }
380
381 tasks_posted_latch.CountDown();
382 };
383
384 std::vector<std::thread> threads;
385
386 for (size_t i = 0; i < kThreadCount; i++) {
387 threads.emplace_back(std::thread{thread_main});
388 }
389
390 ASSERT_EQ(threads.size(), kThreadCount);
391
392 for (size_t i = 0; i < kThreadCount; i++) {
393 threads[i].join();
394 }
395
396 // All tasks have been posted by now. Check that they are all pending.
397
398 size_t pending_tasks = 0u;
399 std::for_each(task_queue_ids.begin(), task_queue_ids.end(),
400 [&](const auto& queue) {
401 pending_tasks += task_queues->GetNumPendingTasks(queue);
402 });
403
404 ASSERT_EQ(pending_tasks, kThreadCount * kThreadTaskCount);
405}
static constexpr uint64_t kThreadCount

◆ TEST() [21/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
NotifyObserversWhileCreatingQueues   
)

Definition at line 298 of file message_loop_task_queues_unittests.cc.

298 {
299 auto task_queues = fml::MessageLoopTaskQueues::GetInstance();
300 fml::TaskQueueId queue_id = task_queues->CreateTaskQueue();
301 fml::AutoResetWaitableEvent first_observer_executing, before_second_observer;
302
303 task_queues->AddTaskObserver(queue_id, queue_id + 1, [&]() {
304 first_observer_executing.Signal();
305 before_second_observer.Wait();
306 });
307
308 for (int i = 0; i < 100; i++) {
309 task_queues->AddTaskObserver(queue_id, queue_id + i + 2, [] {});
310 }
311
312 std::thread notify_observers([&]() { TestNotifyObservers(queue_id); });
313
314 first_observer_executing.Wait();
315
316 for (int i = 0; i < 100; i++) {
317 task_queues->CreateTaskQueue();
318 }
319
320 before_second_observer.Signal();
321 notify_observers.join();
322}
void TestNotifyObservers(fml::TaskQueueId queue_id)

◆ TEST() [22/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
PreserveTaskOrdering   
)

Definition at line 90 of file message_loop_task_queues_unittests.cc.

90 {
92 auto queue_id = task_queue->CreateTaskQueue();
93 int test_val = 0;
94
95 // order: 0
96 task_queue->RegisterTask(
97 queue_id, [&test_val]() { test_val = 1; }, ChronoTicksSinceEpoch());
98
99 // order: 1
100 task_queue->RegisterTask(
101 queue_id, [&test_val]() { test_val = 2; }, ChronoTicksSinceEpoch());
102
103 const auto now = ChronoTicksSinceEpoch();
104 int expected_value = 1;
105 while (true) {
106 fml::closure invocation = task_queue->GetNextTaskToRun(queue_id, now);
107 if (!invocation) {
108 break;
109 }
110 invocation();
111 ASSERT_TRUE(test_val == expected_value);
113 }
114}
static const char * expected_value

◆ TEST() [23/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
QueueDoNotOwnItself   
)

Definition at line 324 of file message_loop_task_queues_unittests.cc.

324 {
325 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
326 auto queue_id = task_queue->CreateTaskQueue();
327 ASSERT_FALSE(task_queue->Owns(queue_id, queue_id));
328}

◆ TEST() [24/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
QueueDoNotOwnUnmergedTaskQueueId   
)

Definition at line 330 of file message_loop_task_queues_unittests.cc.

330 {
331 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
332 ASSERT_FALSE(task_queue->Owns(task_queue->CreateTaskQueue(), kUnmerged));
333 ASSERT_FALSE(task_queue->Owns(kUnmerged, task_queue->CreateTaskQueue()));
334 ASSERT_FALSE(task_queue->Owns(kUnmerged, kUnmerged));
335}

◆ TEST() [25/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
QueueOwnsMergedTaskQueueId   
)

Definition at line 337 of file message_loop_task_queues_unittests.cc.

337 {
338 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
339 auto platform_queue = task_queue->CreateTaskQueue();
340 auto raster_queue = task_queue->CreateTaskQueue();
341 ASSERT_FALSE(task_queue->Owns(platform_queue, raster_queue));
342 ASSERT_FALSE(task_queue->Owns(raster_queue, platform_queue));
343 task_queue->Merge(platform_queue, raster_queue);
344 ASSERT_TRUE(task_queue->Owns(platform_queue, raster_queue));
345 ASSERT_FALSE(task_queue->Owns(raster_queue, platform_queue));
346}

◆ TEST() [26/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
RegisterOneTask   
)

Definition at line 40 of file message_loop_task_queues_unittests.cc.

40 {
41 const auto time = fml::TimePoint::Max();
42
44 auto queue_id = task_queue->CreateTaskQueue();
45 auto wakeable = std::make_unique<TestWakeable>(
46 [&time](fml::TimePoint wake_time) { ASSERT_TRUE(wake_time == time); });
47 task_queue->SetWakeable(queue_id, wakeable.get());
48
49 task_queue->RegisterTask(queue_id, [] {}, time);
50 ASSERT_TRUE(task_queue->HasPendingTasks(queue_id));
51 ASSERT_TRUE(task_queue->GetNumPendingTasks(queue_id) == 1);
52}
static constexpr TimePoint Max()
Definition time_point.h:39

◆ TEST() [27/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
RegisterTasksOnMergedQueuesAndCount   
)

Definition at line 63 of file message_loop_task_queues_unittests.cc.

63 {
65 auto platform_queue = task_queue->CreateTaskQueue();
66 auto raster_queue = task_queue->CreateTaskQueue();
67 // A task in platform_queue
68 task_queue->RegisterTask(platform_queue, []() {}, fml::TimePoint::Now());
69 // A task in raster_queue
70 task_queue->RegisterTask(raster_queue, []() {}, fml::TimePoint::Now());
71 ASSERT_TRUE(task_queue->GetNumPendingTasks(platform_queue) == 1);
72 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 1);
73
74 ASSERT_FALSE(task_queue->Owns(platform_queue, raster_queue));
75 task_queue->Merge(platform_queue, raster_queue);
76 ASSERT_TRUE(task_queue->Owns(platform_queue, raster_queue));
77
78 ASSERT_TRUE(task_queue->HasPendingTasks(platform_queue));
79 ASSERT_TRUE(task_queue->GetNumPendingTasks(platform_queue) == 2);
80 // The task count of subsumed queue is 0
81 ASSERT_FALSE(task_queue->HasPendingTasks(raster_queue));
82 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 0);
83
84 task_queue->Unmerge(platform_queue, raster_queue);
85 ASSERT_FALSE(task_queue->Owns(platform_queue, raster_queue));
86 ASSERT_TRUE(task_queue->GetNumPendingTasks(platform_queue) == 1);
87 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 1);
88}
static TimePoint Now()
Definition time_point.cc:49

◆ TEST() [28/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
RegisterTasksOnMergedQueuesPreserveTaskOrdering   
)

Definition at line 116 of file message_loop_task_queues_unittests.cc.

116 {
117 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
118 auto platform_queue = task_queue->CreateTaskQueue();
119 auto raster1_queue = task_queue->CreateTaskQueue();
120 auto raster2_queue = task_queue->CreateTaskQueue();
121 int test_val = 0;
122
123 // order 0 in raster1_queue
124 task_queue->RegisterTask(
125 raster1_queue, [&test_val]() { test_val = 0; }, fml::TimePoint::Now());
126
127 // order 1 in platform_queue
128 task_queue->RegisterTask(
129 platform_queue, [&test_val]() { test_val = 1; }, fml::TimePoint::Now());
130
131 // order 2 in raster2_queue
132 task_queue->RegisterTask(
133 raster2_queue, [&test_val]() { test_val = 2; }, fml::TimePoint::Now());
134
135 task_queue->Merge(platform_queue, raster1_queue);
136 ASSERT_TRUE(task_queue->Owns(platform_queue, raster1_queue));
137 task_queue->Merge(platform_queue, raster2_queue);
138 ASSERT_TRUE(task_queue->Owns(platform_queue, raster2_queue));
139 const auto now = fml::TimePoint::Now();
140 int expected_value = 0;
141 // Right order:
142 // "test_val = 0" in raster1_queue
143 // "test_val = 1" in platform_queue
144 // "test_val = 2" in raster2_queue
145 while (true) {
146 fml::closure invocation = task_queue->GetNextTaskToRun(platform_queue, now);
147 if (!invocation) {
148 break;
149 }
150 invocation();
151 ASSERT_TRUE(test_val == expected_value);
153 }
154}

◆ TEST() [29/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
RegisterTaskWakesUpOwnerQueue   
)

Definition at line 407 of file message_loop_task_queues_unittests.cc.

407 {
408 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
409 auto platform_queue = task_queue->CreateTaskQueue();
410 auto raster_queue = task_queue->CreateTaskQueue();
411
412 std::vector<fml::TimePoint> wakes;
413
414 auto wakeable1 = std::make_unique<TestWakeable>(
415 [&wakes](fml::TimePoint wake_time) { wakes.push_back(wake_time); });
416 auto wakeable2 = std::make_unique<TestWakeable>([](fml::TimePoint wake_time) {
417 // The raster queue is owned by the platform queue.
418 ASSERT_FALSE(true);
419 });
420
421 task_queue->SetWakeable(platform_queue, wakeable1.get());
422 task_queue->SetWakeable(raster_queue, wakeable2.get());
423
424 auto time1 = ChronoTicksSinceEpoch() + fml::TimeDelta::FromMilliseconds(1);
425 auto time2 = ChronoTicksSinceEpoch() + fml::TimeDelta::FromMilliseconds(2);
426
427 ASSERT_EQ(0UL, wakes.size());
428
429 task_queue->RegisterTask(platform_queue, []() {}, time1);
430
431 ASSERT_EQ(1UL, wakes.size());
432 ASSERT_EQ(time1, wakes[0]);
433
434 task_queue->Merge(platform_queue, raster_queue);
435
436 task_queue->RegisterTask(raster_queue, []() {}, time2);
437
438 ASSERT_EQ(3UL, wakes.size());
439 ASSERT_EQ(time1, wakes[1]);
440 ASSERT_EQ(time1, wakes[2]);
441}
static constexpr TimeDelta FromMilliseconds(int64_t millis)
Definition time_delta.h:46

◆ TEST() [30/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
RegisterTwoTasksAndCount   
)

Definition at line 54 of file message_loop_task_queues_unittests.cc.

54 {
56 auto queue_id = task_queue->CreateTaskQueue();
57 task_queue->RegisterTask(queue_id, [] {}, ChronoTicksSinceEpoch());
58 task_queue->RegisterTask(queue_id, [] {}, fml::TimePoint::Max());
59 ASSERT_TRUE(task_queue->HasPendingTasks(queue_id));
60 ASSERT_TRUE(task_queue->GetNumPendingTasks(queue_id) == 2);
61}

◆ TEST() [31/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
StartsWithNoPendingTasks   
)

Definition at line 34 of file message_loop_task_queues_unittests.cc.

34 {
36 auto queue_id = task_queue->CreateTaskQueue();
37 ASSERT_FALSE(task_queue->HasPendingTasks(queue_id));
38}

◆ TEST() [32/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
UnmergeRespectTheOriginalTaskOrderingInQueues   
)

Definition at line 156 of file message_loop_task_queues_unittests.cc.

156 {
157 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
158 auto platform_queue = task_queue->CreateTaskQueue();
159 auto raster_queue = task_queue->CreateTaskQueue();
160 int test_val = 0;
161
162 // order 0 in platform_queue
163 task_queue->RegisterTask(
164 platform_queue, [&test_val]() { test_val = 0; }, fml::TimePoint::Now());
165 // order 1 in platform_queue
166 task_queue->RegisterTask(
167 platform_queue, [&test_val]() { test_val = 1; }, fml::TimePoint::Now());
168 // order 2 in raster_queue
169 task_queue->RegisterTask(
170 raster_queue, [&test_val]() { test_val = 2; }, fml::TimePoint::Now());
171 // order 3 in raster_queue
172 task_queue->RegisterTask(
173 raster_queue, [&test_val]() { test_val = 3; }, fml::TimePoint::Now());
174 // order 4 in platform_queue
175 task_queue->RegisterTask(
176 platform_queue, [&test_val]() { test_val = 4; }, fml::TimePoint::Now());
177 // order 5 in raster_queue
178 task_queue->RegisterTask(
179 raster_queue, [&test_val]() { test_val = 5; }, fml::TimePoint::Now());
180
181 ASSERT_TRUE(task_queue->Merge(platform_queue, raster_queue));
182 ASSERT_TRUE(task_queue->Owns(platform_queue, raster_queue));
183 const auto now = fml::TimePoint::Now();
184 // The right order after merged and consumed 3 tasks:
185 // "test_val = 0" in platform_queue
186 // "test_val = 1" in platform_queue
187 // "test_val = 2" in raster_queue (running on platform)
188 for (int i = 0; i < 3; i++) {
189 fml::closure invocation = task_queue->GetNextTaskToRun(platform_queue, now);
190 ASSERT_FALSE(!invocation);
191 invocation();
192 ASSERT_TRUE(test_val == i);
193 }
194 ASSERT_TRUE(task_queue->GetNumPendingTasks(platform_queue) == 3);
195 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 0);
196
197 ASSERT_TRUE(task_queue->Unmerge(platform_queue, raster_queue));
198 ASSERT_FALSE(task_queue->Owns(platform_queue, raster_queue));
199
200 // The right order after unmerged and left 3 tasks:
201 // "test_val = 3" in raster_queue
202 // "test_val = 4" in platform_queue
203 // "test_val = 5" in raster_queue
204
205 // platform_queue has 1 task left: "test_val = 4"
206 {
207 ASSERT_TRUE(task_queue->GetNumPendingTasks(platform_queue) == 1);
208 fml::closure invocation = task_queue->GetNextTaskToRun(platform_queue, now);
209 ASSERT_FALSE(!invocation);
210 invocation();
211 ASSERT_TRUE(test_val == 4);
212 ASSERT_TRUE(task_queue->GetNumPendingTasks(platform_queue) == 0);
213 }
214
215 // raster_queue has 2 tasks left: "test_val = 3" and "test_val = 5"
216 {
217 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 2);
218 fml::closure invocation = task_queue->GetNextTaskToRun(raster_queue, now);
219 ASSERT_FALSE(!invocation);
220 invocation();
221 ASSERT_TRUE(test_val == 3);
222 }
223 {
224 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 1);
225 fml::closure invocation = task_queue->GetNextTaskToRun(raster_queue, now);
226 ASSERT_FALSE(!invocation);
227 invocation();
228 ASSERT_TRUE(test_val == 5);
229 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 0);
230 }
231}

◆ TEST() [33/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
WakeUpIndependentOfTime   
)

Definition at line 259 of file message_loop_task_queues_unittests.cc.

259 {
260 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
261 auto queue_id = task_queue->CreateTaskQueue();
262
263 int num_wakes = 0;
264 auto wakeable = std::make_unique<TestWakeable>(
265 [&num_wakes](fml::TimePoint wake_time) { ++num_wakes; });
266 task_queue->SetWakeable(queue_id, wakeable.get());
267
268 task_queue->RegisterTask(queue_id, []() {}, ChronoTicksSinceEpoch());
269 task_queue->RegisterTask(queue_id, []() {}, fml::TimePoint::Max());
270
271 ASSERT_TRUE(num_wakes == 2);
272}

◆ TEST() [34/91]

fml::testing::TEST ( MessageLoopTaskQueue  ,
WokenUpWithNewerTime   
)

Definition at line 274 of file message_loop_task_queues_unittests.cc.

274 {
275 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
276 auto queue_id = task_queue->CreateTaskQueue();
277 fml::CountDownLatch latch(2);
278
280
281 auto wakeable = std::make_unique<TestWakeable>(
282 [&latch, &expected](fml::TimePoint wake_time) {
283 ASSERT_TRUE(wake_time == expected);
284 latch.CountDown();
285 });
286
287 task_queue->SetWakeable(queue_id, wakeable.get());
288
289 task_queue->RegisterTask(queue_id, []() {}, fml::TimePoint::Max());
290
291 const auto now = ChronoTicksSinceEpoch();
292 expected = now;
293 task_queue->RegisterTask(queue_id, []() {}, now);
294
295 latch.Wait();
296}

◆ TEST() [35/91]

fml::testing::TEST ( MessageLoopTaskQueueMergeUnmerge  ,
AfterMergePrimaryTasksServicedOnPrimary   
)

Definition at line 50 of file message_loop_task_queues_merge_unmerge_unittests.cc.

51 {
53
54 auto queue_id_1 = task_queue->CreateTaskQueue();
55 auto queue_id_2 = task_queue->CreateTaskQueue();
56
57 task_queue->RegisterTask(queue_id_1, []() {}, ChronoTicksSinceEpoch());
58 ASSERT_EQ(1u, task_queue->GetNumPendingTasks(queue_id_1));
59
60 task_queue->Merge(queue_id_1, queue_id_2);
61 task_queue->RegisterTask(queue_id_1, []() {}, ChronoTicksSinceEpoch());
62
63 ASSERT_EQ(2u, task_queue->GetNumPendingTasks(queue_id_1));
64 ASSERT_EQ(0u, task_queue->GetNumPendingTasks(queue_id_2));
65}

◆ TEST() [36/91]

fml::testing::TEST ( MessageLoopTaskQueueMergeUnmerge  ,
AfterMergeSecondaryTasksAlsoServicedOnPrimary   
)

Definition at line 67 of file message_loop_task_queues_merge_unmerge_unittests.cc.

68 {
70
71 auto queue_id_1 = task_queue->CreateTaskQueue();
72 auto queue_id_2 = task_queue->CreateTaskQueue();
73
74 task_queue->RegisterTask(queue_id_2, []() {}, ChronoTicksSinceEpoch());
75 ASSERT_EQ(1u, task_queue->GetNumPendingTasks(queue_id_2));
76
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));
80}

◆ TEST() [37/91]

fml::testing::TEST ( MessageLoopTaskQueueMergeUnmerge  ,
CannotMergeSameQueueToTwoDifferentOwners   
)

Definition at line 132 of file message_loop_task_queues_merge_unmerge_unittests.cc.

133 {
134 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
135 auto queue = task_queue->CreateTaskQueue();
136 auto owner_1 = task_queue->CreateTaskQueue();
137 auto owner_2 = task_queue->CreateTaskQueue();
138
139 ASSERT_TRUE(task_queue->Merge(owner_1, queue));
140 ASSERT_FALSE(task_queue->Merge(owner_2, queue));
141}
VkQueue queue
Definition main.cc:55

◆ TEST() [38/91]

fml::testing::TEST ( MessageLoopTaskQueueMergeUnmerge  ,
FollowingTasksSwitchQueueIfFirstTaskMergesThreads   
)

Definition at line 280 of file message_loop_task_queues_merge_unmerge_unittests.cc.

281 {
282 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
283
284 auto queue_id_1 = task_queue->CreateTaskQueue();
285 auto queue_id_2 = task_queue->CreateTaskQueue();
286
287 fml::CountDownLatch latch(2);
288
289 auto wakeable1 = std::make_unique<TestWakeable>(
290 [&](fml::TimePoint wake_time) { latch.CountDown(); });
291 auto wakeable2 = std::make_unique<TestWakeable>(
292 [&](fml::TimePoint wake_time) { latch.CountDown(); });
293
294 task_queue->SetWakeable(queue_id_1, wakeable1.get());
295 task_queue->SetWakeable(queue_id_2, wakeable2.get());
296
297 task_queue->RegisterTask(
298 queue_id_2, [&]() { task_queue->Merge(queue_id_1, queue_id_2); },
300
301 task_queue->RegisterTask(queue_id_2, []() {}, ChronoTicksSinceEpoch());
302
303 ASSERT_EQ(CountRemainingTasks(task_queue, queue_id_2, true), 1);
304 ASSERT_EQ(CountRemainingTasks(task_queue, queue_id_1, true), 1);
305
306 latch.Wait();
307}
static int CountRemainingTasks(fml::MessageLoopTaskQueues *task_queue, const TaskQueueId &queue_id, bool run_invocation=false)

◆ TEST() [39/91]

fml::testing::TEST ( MessageLoopTaskQueueMergeUnmerge  ,
GetTasksToRunNowBlocksMerge   
)

Definition at line 239 of file message_loop_task_queues_merge_unmerge_unittests.cc.

239 {
240 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
241
242 auto queue_id_1 = task_queue->CreateTaskQueue();
243 auto queue_id_2 = task_queue->CreateTaskQueue();
244
245 fml::AutoResetWaitableEvent wake_up_start, wake_up_end, merge_start,
246 merge_end;
247
248 auto wakeable = std::make_unique<TestWakeable>([&](fml::TimePoint wake_time) {
249 wake_up_start.Signal();
250 wake_up_end.Wait();
251 });
252
253 task_queue->RegisterTask(queue_id_1, []() {}, ChronoTicksSinceEpoch());
254 task_queue->SetWakeable(queue_id_1, wakeable.get());
255
256 std::thread tasks_to_run_now_thread(
257 [&]() { CountRemainingTasks(task_queue, queue_id_1); });
258
259 wake_up_start.Wait();
260 bool merge_done = false;
261
262 std::thread merge_thread([&]() {
263 merge_start.Signal();
264 task_queue->Merge(queue_id_1, queue_id_2);
265 merge_done = true;
266 merge_end.Signal();
267 });
268
269 merge_start.Wait();
270 ASSERT_FALSE(merge_done);
271 wake_up_end.Signal();
272
273 merge_end.Wait();
274 ASSERT_TRUE(merge_done);
275
276 tasks_to_run_now_thread.join();
277 merge_thread.join();
278}

◆ TEST() [40/91]

fml::testing::TEST ( MessageLoopTaskQueueMergeUnmerge  ,
MergeFailIfAlreadyOwnsButTryToBeSubsumed   
)

Definition at line 155 of file message_loop_task_queues_merge_unmerge_unittests.cc.

156 {
157 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
158
159 auto queue_id_1 = task_queue->CreateTaskQueue();
160 auto queue_id_2 = task_queue->CreateTaskQueue();
161 auto queue_id_3 = task_queue->CreateTaskQueue();
162
163 task_queue->Merge(queue_id_1, queue_id_2);
164 // A recursively linked merging will fail
165 ASSERT_FALSE(task_queue->Merge(queue_id_3, queue_id_1));
166}

◆ TEST() [41/91]

fml::testing::TEST ( MessageLoopTaskQueueMergeUnmerge  ,
MergeFailIfAlreadySubsumed   
)

Definition at line 143 of file message_loop_task_queues_merge_unmerge_unittests.cc.

143 {
144 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
145
146 auto queue_id_1 = task_queue->CreateTaskQueue();
147 auto queue_id_2 = task_queue->CreateTaskQueue();
148 auto queue_id_3 = task_queue->CreateTaskQueue();
149
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));
153}

◆ TEST() [42/91]

fml::testing::TEST ( MessageLoopTaskQueueMergeUnmerge  ,
MergeInvokesBothWakeables   
)

Definition at line 182 of file message_loop_task_queues_merge_unmerge_unittests.cc.

182 {
183 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
184
185 auto queue_id_1 = task_queue->CreateTaskQueue();
186 auto queue_id_2 = task_queue->CreateTaskQueue();
187
188 fml::CountDownLatch latch(2);
189
190 auto wakeable1 = std::make_unique<TestWakeable>(
191 [&](fml::TimePoint wake_time) { latch.CountDown(); });
192 auto wakeable2 = std::make_unique<TestWakeable>(
193 [&](fml::TimePoint wake_time) { latch.CountDown(); });
194
195 task_queue->SetWakeable(queue_id_1, wakeable1.get());
196 task_queue->SetWakeable(queue_id_2, wakeable2.get());
197
198 task_queue->RegisterTask(queue_id_1, []() {}, ChronoTicksSinceEpoch());
199
200 task_queue->Merge(queue_id_1, queue_id_2);
201
202 CountRemainingTasks(task_queue, queue_id_1);
203
204 latch.Wait();
205}

◆ TEST() [43/91]

fml::testing::TEST ( MessageLoopTaskQueueMergeUnmerge  ,
MergeUnmergeInvokesBothWakeablesSeparately   
)

Definition at line 207 of file message_loop_task_queues_merge_unmerge_unittests.cc.

208 {
209 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
210
211 auto queue_id_1 = task_queue->CreateTaskQueue();
212 auto queue_id_2 = task_queue->CreateTaskQueue();
213
214 fml::AutoResetWaitableEvent latch_1, latch_2;
215
216 auto wakeable1 = std::make_unique<TestWakeable>(
217 [&](fml::TimePoint wake_time) { latch_1.Signal(); });
218 auto wakeable2 = std::make_unique<TestWakeable>(
219 [&](fml::TimePoint wake_time) { latch_2.Signal(); });
220
221 task_queue->SetWakeable(queue_id_1, wakeable1.get());
222 task_queue->SetWakeable(queue_id_2, wakeable2.get());
223
224 task_queue->RegisterTask(queue_id_1, []() {}, ChronoTicksSinceEpoch());
225 task_queue->RegisterTask(queue_id_2, []() {}, ChronoTicksSinceEpoch());
226
227 task_queue->Merge(queue_id_1, queue_id_2);
228 task_queue->Unmerge(queue_id_1, queue_id_2);
229
230 CountRemainingTasks(task_queue, queue_id_1);
231
232 latch_1.Wait();
233
234 CountRemainingTasks(task_queue, queue_id_2);
235
236 latch_2.Wait();
237}

◆ TEST() [44/91]

fml::testing::TEST ( MessageLoopTaskQueueMergeUnmerge  ,
MergeUnmergeTasksPreserved   
)

Definition at line 82 of file message_loop_task_queues_merge_unmerge_unittests.cc.

82 {
84
85 auto queue_id_1 = task_queue->CreateTaskQueue();
86 auto queue_id_2 = task_queue->CreateTaskQueue();
87
88 task_queue->RegisterTask(queue_id_1, []() {}, ChronoTicksSinceEpoch());
89 task_queue->RegisterTask(queue_id_2, []() {}, ChronoTicksSinceEpoch());
90
91 ASSERT_EQ(1u, task_queue->GetNumPendingTasks(queue_id_1));
92 ASSERT_EQ(1u, task_queue->GetNumPendingTasks(queue_id_2));
93
94 task_queue->Merge(queue_id_1, queue_id_2);
95
96 ASSERT_EQ(2u, task_queue->GetNumPendingTasks(queue_id_1));
97 ASSERT_EQ(0u, task_queue->GetNumPendingTasks(queue_id_2));
98
99 task_queue->Unmerge(queue_id_1, queue_id_2);
100
101 ASSERT_EQ(1u, task_queue->GetNumPendingTasks(queue_id_1));
102 ASSERT_EQ(1u, task_queue->GetNumPendingTasks(queue_id_2));
103}

◆ TEST() [45/91]

fml::testing::TEST ( MessageLoopTaskQueueMergeUnmerge  ,
OneCanOwnMultipleQueuesAndUnmergeIndependently   
)

Multiple standalone engines scene.

Definition at line 106 of file message_loop_task_queues_merge_unmerge_unittests.cc.

107 {
108 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
109 auto queue_id_1 = task_queue->CreateTaskQueue();
110 auto queue_id_2 = task_queue->CreateTaskQueue();
111 auto queue_id_3 = task_queue->CreateTaskQueue();
112
113 // merge
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));
117
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));
121
122 // unmerge
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));
126
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));
130}

◆ TEST() [46/91]

fml::testing::TEST ( MessageLoopTaskQueueMergeUnmerge  ,
UnmergeFailsOnSubsumedOrNeverMerged   
)

Definition at line 168 of file message_loop_task_queues_merge_unmerge_unittests.cc.

168 {
169 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
170
171 auto queue_id_1 = task_queue->CreateTaskQueue();
172 auto queue_id_2 = task_queue->CreateTaskQueue();
173 auto queue_id_3 = task_queue->CreateTaskQueue();
174
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));
180}

◆ TEST() [47/91]

fml::testing::TEST ( RasterThreadMerger  ,
Disable   
)

Definition at line 303 of file raster_thread_merger_unittests.cc.

303 {
304 TaskQueueWrapper queue1;
305 TaskQueueWrapper queue2;
306 fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
307 fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
308 const auto raster_thread_merger =
309 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
310
311 raster_thread_merger->Disable();
312 ASSERT_FALSE(raster_thread_merger->IsMerged());
313
314 raster_thread_merger->MergeWithLease(1);
315 ASSERT_FALSE(raster_thread_merger->IsMerged());
316
317 raster_thread_merger->Enable();
318 raster_thread_merger->MergeWithLease(1);
319 ASSERT_TRUE(raster_thread_merger->IsMerged());
320
321 raster_thread_merger->Disable();
322 raster_thread_merger->UnMergeNowIfLastOne();
323 ASSERT_TRUE(raster_thread_merger->IsMerged());
324
325 {
326 auto decrement_result = raster_thread_merger->DecrementLease();
327 ASSERT_EQ(fml::RasterThreadStatus::kRemainsMerged, decrement_result);
328 }
329
330 ASSERT_TRUE(raster_thread_merger->IsMerged());
331
332 raster_thread_merger->Enable();
333 raster_thread_merger->UnMergeNowIfLastOne();
334 ASSERT_FALSE(raster_thread_merger->IsMerged());
335
336 raster_thread_merger->MergeWithLease(1);
337
338 ASSERT_TRUE(raster_thread_merger->IsMerged());
339
340 {
341 auto decrement_result = raster_thread_merger->DecrementLease();
342 ASSERT_EQ(fml::RasterThreadStatus::kUnmergedNow, decrement_result);
343 }
344
345 ASSERT_FALSE(raster_thread_merger->IsMerged());
346}
A mock task queue NOT calling MessageLoop->Run() in thread.

◆ TEST() [48/91]

fml::testing::TEST ( RasterThreadMerger  ,
Enable   
)

Definition at line 281 of file raster_thread_merger_unittests.cc.

281 {
282 TaskQueueWrapper queue1;
283 TaskQueueWrapper queue2;
284 fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
285 fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
286 const auto raster_thread_merger =
287 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
288
289 raster_thread_merger->Disable();
290 raster_thread_merger->MergeWithLease(1);
291 ASSERT_FALSE(raster_thread_merger->IsMerged());
292
293 raster_thread_merger->Enable();
294 ASSERT_FALSE(raster_thread_merger->IsMerged());
295
296 raster_thread_merger->MergeWithLease(1);
297 ASSERT_TRUE(raster_thread_merger->IsMerged());
298
299 raster_thread_merger->DecrementLease();
300 ASSERT_FALSE(raster_thread_merger->IsMerged());
301}

◆ TEST() [49/91]

fml::testing::TEST ( RasterThreadMerger  ,
HandleTaskQueuesAreTheSame   
)

Definition at line 255 of file raster_thread_merger_unittests.cc.

255 {
257 fml::TaskQueueId qid1 = queue.GetTaskQueueId();
258 fml::TaskQueueId qid2 = qid1;
259 const auto raster_thread_merger =
260 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
261 // Statically merged.
262 ASSERT_TRUE(raster_thread_merger->IsMerged());
263
264 // Test decrement lease and unmerge are both no-ops.
265 // The task queues should be always merged.
266 const size_t kNumFramesMerged = 5;
267 raster_thread_merger->MergeWithLease(kNumFramesMerged);
268
269 for (size_t i = 0; i < kNumFramesMerged; i++) {
270 ASSERT_TRUE(raster_thread_merger->IsMerged());
271 raster_thread_merger->DecrementLease();
272 }
273
274 ASSERT_TRUE(raster_thread_merger->IsMerged());
275
276 // Wait until merged should also return immediately.
277 raster_thread_merger->WaitUntilMerged();
278 ASSERT_TRUE(raster_thread_merger->IsMerged());
279}

◆ TEST() [50/91]

fml::testing::TEST ( RasterThreadMerger  ,
IsEnabled   
)

Definition at line 348 of file raster_thread_merger_unittests.cc.

348 {
349 TaskQueueWrapper queue1;
350 TaskQueueWrapper queue2;
351 fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
352 fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
353 const auto raster_thread_merger =
354 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
355 ASSERT_TRUE(raster_thread_merger->IsEnabled());
356
357 raster_thread_merger->Disable();
358 ASSERT_FALSE(raster_thread_merger->IsEnabled());
359
360 raster_thread_merger->Enable();
361 ASSERT_TRUE(raster_thread_merger->IsEnabled());
362}

◆ TEST() [51/91]

fml::testing::TEST ( RasterThreadMerger  ,
IsNotOnRasterizingThread   
)

Definition at line 79 of file raster_thread_merger_unittests.cc.

79 {
80 fml::MessageLoop* loop1 = nullptr;
82 std::thread thread1([&loop1, &latch1]() {
85 loop1->GetTaskRunner()->PostTask([&]() { latch1.Signal(); });
86 loop1->Run();
87 });
88
89 fml::MessageLoop* loop2 = nullptr;
91 std::thread thread2([&loop2, &latch2]() {
94 loop2->GetTaskRunner()->PostTask([&]() { latch2.Signal(); });
95 loop2->Run();
96 });
97
98 latch1.Wait();
99 latch2.Wait();
100
101 fml::TaskQueueId qid1 = loop1->GetTaskRunner()->GetTaskQueueId();
102 fml::TaskQueueId qid2 = loop2->GetTaskRunner()->GetTaskQueueId();
103 const auto raster_thread_merger =
104 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
105
106 fml::CountDownLatch pre_merge(2), post_merge(2), post_unmerge(2);
107
108 loop1->GetTaskRunner()->PostTask([&]() {
109 ASSERT_FALSE(raster_thread_merger->IsOnRasterizingThread());
110 ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
112 pre_merge.CountDown();
113 });
114
115 loop2->GetTaskRunner()->PostTask([&]() {
116 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
117 ASSERT_FALSE(raster_thread_merger->IsOnPlatformThread());
119 pre_merge.CountDown();
120 });
121
122 pre_merge.Wait();
123
124 raster_thread_merger->MergeWithLease(1);
125
126 loop1->GetTaskRunner()->PostTask([&]() {
127 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
128 ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
130 post_merge.CountDown();
131 });
132
133 loop2->GetTaskRunner()->PostTask([&]() {
134 // this will be false since this is going to be run
135 // on loop1 really.
136 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
137 ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
139 post_merge.CountDown();
140 });
141
142 post_merge.Wait();
143
144 raster_thread_merger->DecrementLease();
145
146 loop1->GetTaskRunner()->PostTask([&]() {
147 ASSERT_FALSE(raster_thread_merger->IsOnRasterizingThread());
148 ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
150 post_unmerge.CountDown();
151 });
152
153 loop2->GetTaskRunner()->PostTask([&]() {
154 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
155 ASSERT_FALSE(raster_thread_merger->IsOnPlatformThread());
157 post_unmerge.CountDown();
158 });
159
160 post_unmerge.Wait();
161
162 loop1->GetTaskRunner()->PostTask([&]() { loop1->Terminate(); });
163
164 loop2->GetTaskRunner()->PostTask([&]() { loop2->Terminate(); });
165
166 thread1.join();
167 thread2.join();
168}
static void loop1(skiatest::Reporter *reporter, const char *filename)
static void loop2(skiatest::Reporter *reporter, const char *filename)
static void EnsureInitializedForCurrentThread()
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
static TaskQueueId GetCurrentTaskQueueId()

◆ TEST() [52/91]

fml::testing::TEST ( RasterThreadMerger  ,
LeaseExtension   
)

Definition at line 170 of file raster_thread_merger_unittests.cc.

170 {
171 TaskQueueWrapper queue1;
172 TaskQueueWrapper queue2;
173
174 fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
175 fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
176 const auto raster_thread_merger =
177 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
178 const size_t kNumFramesMerged = 5;
179
180 ASSERT_FALSE(raster_thread_merger->IsMerged());
181
182 raster_thread_merger->MergeWithLease(kNumFramesMerged);
183
184 // let there be one more turn till the leases expire.
185 for (size_t i = 0; i < kNumFramesMerged - 1; i++) {
186 ASSERT_TRUE(raster_thread_merger->IsMerged());
187 raster_thread_merger->DecrementLease();
188 }
189
190 // extend the lease once.
191 raster_thread_merger->ExtendLeaseTo(kNumFramesMerged);
192
193 // we will NOT last for 1 extra turn, we just set it.
194 for (size_t i = 0; i < kNumFramesMerged; i++) {
195 ASSERT_TRUE(raster_thread_merger->IsMerged());
196 raster_thread_merger->DecrementLease();
197 }
198
199 ASSERT_FALSE(raster_thread_merger->IsMerged());
200}

◆ TEST() [53/91]

fml::testing::TEST ( RasterThreadMerger  ,
MultipleMergersCanMergeSameThreadPair   
)

Definition at line 513 of file raster_thread_merger_unittests.cc.

513 {
514 TaskQueueWrapper queue1;
515 TaskQueueWrapper queue2;
516 fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
517 fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
518 // Two mergers will share one same inner merger
519 const auto raster_thread_merger1 =
521 const auto raster_thread_merger2 =
523 qid1, qid2);
524 const size_t kNumFramesMerged = 5;
525 ASSERT_FALSE(raster_thread_merger1->IsMerged());
526 ASSERT_FALSE(raster_thread_merger2->IsMerged());
527
528 // Merge using the first merger
529 raster_thread_merger1->MergeWithLease(kNumFramesMerged);
530
531 ASSERT_TRUE(raster_thread_merger1->IsMerged());
532 ASSERT_TRUE(raster_thread_merger2->IsMerged());
533
534 // let there be one more turn till the leases expire.
535 for (size_t i = 0; i < kNumFramesMerged - 1; i++) {
536 // Check merge state using the two merger
537 ASSERT_TRUE(raster_thread_merger1->IsMerged());
538 ASSERT_TRUE(raster_thread_merger2->IsMerged());
539 raster_thread_merger1->DecrementLease();
540 }
541
542 ASSERT_TRUE(raster_thread_merger1->IsMerged());
543 ASSERT_TRUE(raster_thread_merger2->IsMerged());
544
545 // extend the lease once with the first merger
546 raster_thread_merger1->ExtendLeaseTo(kNumFramesMerged);
547
548 // we will NOT last for 1 extra turn, we just set it.
549 for (size_t i = 0; i < kNumFramesMerged; i++) {
550 // Check merge state using the two merger
551 ASSERT_TRUE(raster_thread_merger1->IsMerged());
552 ASSERT_TRUE(raster_thread_merger2->IsMerged());
553 raster_thread_merger1->DecrementLease();
554 }
555
556 ASSERT_FALSE(raster_thread_merger1->IsMerged());
557 ASSERT_FALSE(raster_thread_merger2->IsMerged());
558}
static fml::RefPtr< fml::RasterThreadMerger > CreateOrShareThreadMerger(const fml::RefPtr< fml::RasterThreadMerger > &parent_merger, TaskQueueId platform_id, TaskQueueId raster_id)

◆ TEST() [54/91]

fml::testing::TEST ( RasterThreadMerger  ,
RemainMergedTillLeaseExpires   
)

Definition at line 58 of file raster_thread_merger_unittests.cc.

58 {
59 TaskQueueWrapper queue1;
60 TaskQueueWrapper queue2;
61 fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
62 fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
63 const auto raster_thread_merger =
64 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
65 const size_t kNumFramesMerged = 5;
66
67 ASSERT_FALSE(raster_thread_merger->IsMerged());
68
69 raster_thread_merger->MergeWithLease(kNumFramesMerged);
70
71 for (size_t i = 0; i < kNumFramesMerged; i++) {
72 ASSERT_TRUE(raster_thread_merger->IsMerged());
73 raster_thread_merger->DecrementLease();
74 }
75
76 ASSERT_FALSE(raster_thread_merger->IsMerged());
77}

◆ TEST() [55/91]

fml::testing::TEST ( RasterThreadMerger  ,
RunExpiredTasksWhileFirstTaskMergesThreads   
)

Definition at line 385 of file raster_thread_merger_unittests.cc.

385 {
386 fml::MessageLoop* loop_platform = nullptr;
388 std::thread thread_platform([&loop_platform, &latch1]() {
390 loop_platform = &fml::MessageLoop::GetCurrent();
391 loop_platform->GetTaskRunner()->PostTask([&]() { latch1.Signal(); });
392 loop_platform->Run();
393 });
394
395 fml::MessageLoop* loop_raster = nullptr;
397 std::thread thread_raster([&loop_raster, &loop_platform, &latch1, &latch2]() {
398 latch1.Wait();
399
401 loop_raster = &fml::MessageLoop::GetCurrent();
402 fml::TaskQueueId qid_platform =
403 loop_platform->GetTaskRunner()->GetTaskQueueId();
404 fml::TaskQueueId qid_raster =
405 loop_raster->GetTaskRunner()->GetTaskQueueId();
406 fml::CountDownLatch post_merge(2);
407 const auto raster_thread_merger =
408 fml::MakeRefCounted<fml::RasterThreadMerger>(qid_platform, qid_raster);
409 loop_raster->GetTaskRunner()->PostTask([&]() {
410 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
411 ASSERT_FALSE(raster_thread_merger->IsOnPlatformThread());
412 ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid_raster);
413 raster_thread_merger->MergeWithLease(1);
414 post_merge.CountDown();
415 });
416
417 loop_raster->GetTaskRunner()->PostTask([&]() {
418 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
419 ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
420 ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid_platform);
421 raster_thread_merger->DecrementLease();
422 post_merge.CountDown();
423 });
424
425 loop_raster->RunExpiredTasksNow();
426 post_merge.Wait();
427 latch2.Signal();
428 });
429
430 latch2.Wait();
431 loop_platform->GetTaskRunner()->PostTask(
432 [&]() { loop_platform->Terminate(); });
433
434 thread_platform.join();
435 thread_raster.join();
436}
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
virtual void PostTask(const fml::closure &task) override
virtual TaskQueueId GetTaskQueueId()

◆ TEST() [56/91]

fml::testing::TEST ( RasterThreadMerger  ,
RunExpiredTasksWhileFirstTaskUnMergesThreads   
)

Definition at line 438 of file raster_thread_merger_unittests.cc.

438 {
439 fml::Thread platform_thread("test_platform_thread");
440
441 fml::AutoResetWaitableEvent raster_latch;
442 std::thread thread_raster([&]() {
445
446 fml::TaskQueueId qid_platform =
447 platform_thread.GetTaskRunner()->GetTaskQueueId();
448 fml::TaskQueueId qid_raster =
449 loop_raster->GetTaskRunner()->GetTaskQueueId();
450
451 fml::AutoResetWaitableEvent merge_latch;
452 const auto raster_thread_merger =
453 fml::MakeRefCounted<fml::RasterThreadMerger>(qid_platform, qid_raster);
454 loop_raster->GetTaskRunner()->PostTask([&]() {
455 raster_thread_merger->MergeWithLease(1);
456 merge_latch.Signal();
457 });
458
459 loop_raster->RunExpiredTasksNow();
460 merge_latch.Wait();
461
462 // threads should be merged at this point.
463 fml::AutoResetWaitableEvent unmerge_latch;
464 loop_raster->GetTaskRunner()->PostTask([&]() {
465 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
466 ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
467 ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid_platform);
468 raster_thread_merger->DecrementLease();
469 unmerge_latch.Signal();
470 });
471
472 fml::AutoResetWaitableEvent post_unmerge_latch;
473 loop_raster->GetTaskRunner()->PostTask([&]() {
474 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
475 ASSERT_FALSE(raster_thread_merger->IsOnPlatformThread());
476 ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid_raster);
477 post_unmerge_latch.Signal();
478 });
479
480 unmerge_latch.Wait();
481 loop_raster->RunExpiredTasksNow();
482
483 post_unmerge_latch.Wait();
484 raster_latch.Signal();
485 });
486
487 raster_latch.Wait();
488 thread_raster.join();
489}
void RunExpiredTasksNow()

◆ TEST() [57/91]

fml::testing::TEST ( RasterThreadMerger  ,
SetMergeUnmergeCallback   
)

Definition at line 491 of file raster_thread_merger_unittests.cc.

491 {
492 TaskQueueWrapper queue1;
493 TaskQueueWrapper queue2;
494 fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
495 fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
496
497 const auto raster_thread_merger =
498 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
499
500 int callbacks = 0;
501 raster_thread_merger->SetMergeUnmergeCallback(
502 [&callbacks]() { callbacks++; });
503
504 ASSERT_EQ(0, callbacks);
505
506 raster_thread_merger->MergeWithLease(1);
507 ASSERT_EQ(1, callbacks);
508
509 raster_thread_merger->DecrementLease();
510 ASSERT_EQ(2, callbacks);
511}

◆ TEST() [58/91]

fml::testing::TEST ( RasterThreadMerger  ,
TheLastCallerOfMultipleMergersCanUnmergeNow   
)

Definition at line 560 of file raster_thread_merger_unittests.cc.

560 {
561 TaskQueueWrapper queue1;
562 TaskQueueWrapper queue2;
563 fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
564 fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
565 // Two mergers will share one same inner merger
566 const auto raster_thread_merger1 =
568 const auto raster_thread_merger2 =
570 qid1, qid2);
571 const size_t kNumFramesMerged = 5;
572 ASSERT_FALSE(raster_thread_merger1->IsMerged());
573 ASSERT_FALSE(raster_thread_merger2->IsMerged());
574
575 // Merge using the mergers
576 raster_thread_merger1->MergeWithLease(kNumFramesMerged);
577 ASSERT_TRUE(raster_thread_merger1->IsMerged());
578 ASSERT_TRUE(raster_thread_merger2->IsMerged());
579 // Extend the second merger's lease
580 raster_thread_merger2->ExtendLeaseTo(kNumFramesMerged);
581 ASSERT_TRUE(raster_thread_merger1->IsMerged());
582 ASSERT_TRUE(raster_thread_merger2->IsMerged());
583
584 // Two callers state becomes one caller left.
585 raster_thread_merger1->UnMergeNowIfLastOne();
586 // Check if still merged
587 ASSERT_TRUE(raster_thread_merger1->IsMerged());
588 ASSERT_TRUE(raster_thread_merger2->IsMerged());
589
590 // One caller state becomes no callers left.
591 raster_thread_merger2->UnMergeNowIfLastOne();
592 // Check if unmerged
593 ASSERT_FALSE(raster_thread_merger1->IsMerged());
594 ASSERT_FALSE(raster_thread_merger2->IsMerged());
595}

◆ TEST() [59/91]

fml::testing::TEST ( RasterThreadMerger  ,
TheLastMergedCallerOfMultipleMergersCanUnmergeNow   
)

Definition at line 597 of file raster_thread_merger_unittests.cc.

597 {
598 TaskQueueWrapper queue1;
599 TaskQueueWrapper queue2;
600 fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
601 fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
602 // Two mergers will share one same inner merger
603 const auto raster_thread_merger1 =
605
606 const size_t kNumFramesMerged = 1;
607 ASSERT_FALSE(raster_thread_merger1->IsMerged());
608
609 // Merge using the mergers
610 raster_thread_merger1->MergeWithLease(kNumFramesMerged);
611 ASSERT_TRUE(raster_thread_merger1->IsMerged());
612
613 for (size_t i = 0; i < kNumFramesMerged; i++) {
614 // Un-merge thread merger 1.
615 raster_thread_merger1->DecrementLease();
616 }
617 ASSERT_FALSE(raster_thread_merger1->IsMerged());
618
619 const auto raster_thread_merger2 =
621 qid1, qid2);
622 ASSERT_FALSE(raster_thread_merger2->IsMerged());
623 raster_thread_merger2->MergeWithLease(kNumFramesMerged);
624 ASSERT_TRUE(raster_thread_merger2->IsMerged());
625
626 // One caller state becomes no callers left.
627 raster_thread_merger2->UnMergeNowIfLastOne();
628 // Check if unmerged
629 ASSERT_FALSE(raster_thread_merger1->IsMerged());
630 ASSERT_FALSE(raster_thread_merger2->IsMerged());
631}

◆ TEST() [60/91]

fml::testing::TEST ( RasterThreadMerger  ,
TwoIndependentMergersCanMergeTwoDifferentThreadsIntoSamePlatformThread   
)

This case tests multiple standalone engines using independent merger to merge two different raster threads into the same platform thread.

Definition at line 635 of file raster_thread_merger_unittests.cc.

636 {
637 TaskQueueWrapper queue1;
638 TaskQueueWrapper queue2;
639 TaskQueueWrapper queue3;
640 fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
641 fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
642 fml::TaskQueueId qid3 = queue3.GetTaskQueueId();
643
644 // Two mergers will NOT share same inner merger
645 const auto merger_from_2_to_1 =
647 const auto merger_from_3_to_1 =
649 qid1, qid3);
650 const size_t kNumFramesMerged = 5;
651 ASSERT_FALSE(merger_from_2_to_1->IsMerged());
652 ASSERT_FALSE(merger_from_3_to_1->IsMerged());
653
654 // Merge thread2 into thread1
655 merger_from_2_to_1->MergeWithLease(kNumFramesMerged);
656 // Merge thread3 into thread1
657 merger_from_3_to_1->MergeWithLease(kNumFramesMerged);
658
659 ASSERT_TRUE(merger_from_2_to_1->IsMerged());
660 ASSERT_TRUE(merger_from_3_to_1->IsMerged());
661
662 for (size_t i = 0; i < kNumFramesMerged; i++) {
663 ASSERT_TRUE(merger_from_2_to_1->IsMerged());
664 merger_from_2_to_1->DecrementLease();
665 }
666
667 ASSERT_FALSE(merger_from_2_to_1->IsMerged());
668 ASSERT_TRUE(merger_from_3_to_1->IsMerged());
669
670 for (size_t i = 0; i < kNumFramesMerged; i++) {
671 ASSERT_TRUE(merger_from_3_to_1->IsMerged());
672 merger_from_3_to_1->DecrementLease();
673 }
674
675 ASSERT_FALSE(merger_from_2_to_1->IsMerged());
676 ASSERT_FALSE(merger_from_3_to_1->IsMerged());
677
678 merger_from_2_to_1->MergeWithLease(kNumFramesMerged);
679 ASSERT_TRUE(merger_from_2_to_1->IsMerged());
680 ASSERT_FALSE(merger_from_3_to_1->IsMerged());
681 merger_from_3_to_1->MergeWithLease(kNumFramesMerged);
682 ASSERT_TRUE(merger_from_2_to_1->IsMerged());
683 ASSERT_TRUE(merger_from_3_to_1->IsMerged());
684
685 // Can unmerge independently
686 merger_from_2_to_1->UnMergeNowIfLastOne();
687 ASSERT_FALSE(merger_from_2_to_1->IsMerged());
688 ASSERT_TRUE(merger_from_3_to_1->IsMerged());
689
690 // Can unmerge independently
691 merger_from_3_to_1->UnMergeNowIfLastOne();
692 ASSERT_FALSE(merger_from_2_to_1->IsMerged());
693 ASSERT_FALSE(merger_from_3_to_1->IsMerged());
694}

◆ TEST() [61/91]

fml::testing::TEST ( RasterThreadMerger  ,
TwoMergersWithSameThreadPairShareEnabledState   
)

Definition at line 364 of file raster_thread_merger_unittests.cc.

364 {
365 TaskQueueWrapper queue1;
366 TaskQueueWrapper queue2;
367 fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
368 fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
369 const auto merger1 =
370 RasterThreadMerger::CreateOrShareThreadMerger(nullptr, qid1, qid2);
371 const auto merger2 =
372 RasterThreadMerger::CreateOrShareThreadMerger(merger1, qid1, qid2);
373 ASSERT_TRUE(merger1->IsEnabled());
374 ASSERT_TRUE(merger2->IsEnabled());
375
376 merger1->Disable();
377 ASSERT_FALSE(merger1->IsEnabled());
378 ASSERT_FALSE(merger2->IsEnabled());
379
380 merger2->Enable();
381 ASSERT_TRUE(merger1->IsEnabled());
382 ASSERT_TRUE(merger2->IsEnabled());
383}

◆ TEST() [62/91]

fml::testing::TEST ( RasterThreadMerger  ,
WaitUntilMerged   
)

Definition at line 202 of file raster_thread_merger_unittests.cc.

202 {
203 fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger;
204
205 fml::AutoResetWaitableEvent create_thread_merger_latch;
206 fml::MessageLoop* loop_platform = nullptr;
207 fml::AutoResetWaitableEvent latch_platform;
208 fml::AutoResetWaitableEvent term_platform;
209 fml::AutoResetWaitableEvent latch_merged;
210 std::thread thread_platform([&]() {
212 loop_platform = &fml::MessageLoop::GetCurrent();
213 latch_platform.Signal();
214 create_thread_merger_latch.Wait();
215 raster_thread_merger->WaitUntilMerged();
216 latch_merged.Signal();
217 term_platform.Wait();
218 });
219
220 const size_t kNumFramesMerged = 5;
221 fml::MessageLoop* loop_raster = nullptr;
222 fml::AutoResetWaitableEvent term_raster;
223 std::thread thread_raster([&]() {
225 loop_raster = &fml::MessageLoop::GetCurrent();
226 latch_platform.Wait();
227 fml::TaskQueueId qid_platform =
228 loop_platform->GetTaskRunner()->GetTaskQueueId();
229 fml::TaskQueueId qid_raster =
230 loop_raster->GetTaskRunner()->GetTaskQueueId();
231 raster_thread_merger =
232 fml::MakeRefCounted<fml::RasterThreadMerger>(qid_platform, qid_raster);
233 ASSERT_FALSE(raster_thread_merger->IsMerged());
234 create_thread_merger_latch.Signal();
235 raster_thread_merger->MergeWithLease(kNumFramesMerged);
236 term_raster.Wait();
237 });
238
239 latch_merged.Wait();
240 ASSERT_TRUE(raster_thread_merger->IsMerged());
241
242 for (size_t i = 0; i < kNumFramesMerged; i++) {
243 ASSERT_TRUE(raster_thread_merger->IsMerged());
244 raster_thread_merger->DecrementLease();
245 }
246
247 ASSERT_FALSE(raster_thread_merger->IsMerged());
248
249 term_platform.Signal();
250 term_raster.Signal();
251 thread_platform.join();
252 thread_raster.join();
253}

◆ TEST() [63/91]

fml::testing::TEST ( StringConversion  ,
Utf16ToUtf16Empty   
)

Definition at line 12 of file string_conversion_unittests.cc.

12 {
13 EXPECT_EQ(Utf8ToUtf16(""), u"");
14}
std::u16string Utf8ToUtf16(const std::string_view string)

◆ TEST() [64/91]

fml::testing::TEST ( StringConversion  ,
Utf16ToUtf8Ascii   
)

Definition at line 28 of file string_conversion_unittests.cc.

28 {
29 EXPECT_EQ(Utf16ToUtf8(u"abc123"), "abc123");
30}
std::string Utf16ToUtf8(const std::u16string_view string)

◆ TEST() [65/91]

fml::testing::TEST ( StringConversion  ,
Utf16ToUtf8Empty   
)

Definition at line 24 of file string_conversion_unittests.cc.

24 {
25 EXPECT_EQ(Utf16ToUtf8(u""), "");
26}

◆ TEST() [66/91]

fml::testing::TEST ( StringConversion  ,
Utf16ToUtf8Unicode   
)

Definition at line 32 of file string_conversion_unittests.cc.

32 {
33 EXPECT_EQ(Utf16ToUtf8(u"\x2603"), "\xe2\x98\x83");
34}

◆ TEST() [67/91]

fml::testing::TEST ( StringConversion  ,
Utf16ToWideStringAscii   
)

Definition at line 52 of file wstring_conversion_unittests.cc.

52 {
53 EXPECT_EQ(Utf16ToWideString(u"abc123"), L"abc123");
54}
std::wstring Utf16ToWideString(const std::u16string_view str)

◆ TEST() [68/91]

fml::testing::TEST ( StringConversion  ,
Utf16ToWideStringEmpty   
)

Definition at line 48 of file wstring_conversion_unittests.cc.

48 {
49 EXPECT_EQ(Utf16ToWideString(u""), L"");
50}

◆ TEST() [69/91]

fml::testing::TEST ( StringConversion  ,
Utf16ToWideStringUtf8Unicode   
)

Definition at line 56 of file wstring_conversion_unittests.cc.

56 {
57 EXPECT_EQ(Utf16ToWideString(u"\xe2\x98\x83"), L"\xe2\x98\x83");
58}

◆ TEST() [70/91]

fml::testing::TEST ( StringConversion  ,
Utf8ToUtf16Ascii   
)

Definition at line 16 of file string_conversion_unittests.cc.

16 {
17 EXPECT_EQ(Utf8ToUtf16("abc123"), u"abc123");
18}

◆ TEST() [71/91]

fml::testing::TEST ( StringConversion  ,
Utf8ToUtf16Unicode   
)

Definition at line 20 of file string_conversion_unittests.cc.

20 {
21 EXPECT_EQ(Utf8ToUtf16("\xe2\x98\x83"), u"\x2603");
22}

◆ TEST() [72/91]

fml::testing::TEST ( StringConversion  ,
Utf8ToWideStringAscii   
)

Definition at line 16 of file wstring_conversion_unittests.cc.

16 {
17 EXPECT_EQ(Utf8ToWideString("abc123"), L"abc123");
18}

◆ TEST() [73/91]

fml::testing::TEST ( StringConversion  ,
Utf8ToWideStringEmpty   
)

Definition at line 12 of file wstring_conversion_unittests.cc.

12 {
13 EXPECT_EQ(Utf8ToWideString(""), L"");
14}

◆ TEST() [74/91]

fml::testing::TEST ( StringConversion  ,
Utf8ToWideStringUnicode   
)

Definition at line 20 of file wstring_conversion_unittests.cc.

20 {
21 EXPECT_EQ(Utf8ToWideString("\xe2\x98\x83"), L"\x2603");
22}

◆ TEST() [75/91]

fml::testing::TEST ( StringConversion  ,
WideStringToUtf16Ascii   
)

Definition at line 40 of file wstring_conversion_unittests.cc.

40 {
41 EXPECT_EQ(WideStringToUtf16(L"abc123"), u"abc123");
42}
std::u16string WideStringToUtf16(const std::wstring_view str)

◆ TEST() [76/91]

fml::testing::TEST ( StringConversion  ,
WideStringToUtf16Empty   
)

Definition at line 36 of file wstring_conversion_unittests.cc.

36 {
37 EXPECT_EQ(WideStringToUtf16(L""), u"");
38}

◆ TEST() [77/91]

fml::testing::TEST ( StringConversion  ,
WideStringToUtf16Unicode   
)

Definition at line 44 of file wstring_conversion_unittests.cc.

44 {
45 EXPECT_EQ(WideStringToUtf16(L"\xe2\x98\x83"), u"\xe2\x98\x83");
46}

◆ TEST() [78/91]

fml::testing::TEST ( StringConversion  ,
WideStringToUtf8Ascii   
)

Definition at line 28 of file wstring_conversion_unittests.cc.

28 {
29 EXPECT_EQ(WideStringToUtf8(L"abc123"), "abc123");
30}
std::string WideStringToUtf8(const std::wstring_view str)

◆ TEST() [79/91]

fml::testing::TEST ( StringConversion  ,
WideStringToUtf8Empty   
)

Definition at line 24 of file wstring_conversion_unittests.cc.

24 {
25 EXPECT_EQ(WideStringToUtf8(L""), "");
26}

◆ TEST() [80/91]

fml::testing::TEST ( StringConversion  ,
WideStringToUtf8Unicode   
)

Definition at line 32 of file wstring_conversion_unittests.cc.

32 {
33 EXPECT_EQ(WideStringToUtf8(L"\x2603"), "\xe2\x98\x83");
34}

◆ TEST() [81/91]

fml::testing::TEST ( TaskRunnerCheckerTests  ,
FailsTheCheckIfOnDifferentTaskRunner   
)

Definition at line 25 of file task_runner_checker_unittest.cc.

25 {
26 TaskRunnerChecker checker;
27 EXPECT_EQ(checker.RunsOnCreationTaskRunner(), true);
28 fml::MessageLoop* loop = nullptr;
30 std::thread another_thread([&]() {
33 loop->GetTaskRunner()->PostTask([&]() {
34 EXPECT_EQ(checker.RunsOnCreationTaskRunner(), false);
35 latch.Signal();
36 });
37 loop->Run();
38 });
39 latch.Wait();
40 loop->Terminate();
41 another_thread.join();
42 EXPECT_EQ(checker.RunsOnCreationTaskRunner(), true);
43}

◆ TEST() [82/91]

fml::testing::TEST ( TaskRunnerCheckerTests  ,
MergedTaskRunnersRunsOnTheSameThread   
)

Definition at line 70 of file task_runner_checker_unittest.cc.

70 {
71 fml::MessageLoop* loop1 = nullptr;
74 std::thread thread1([&loop1, &latch1, &term1]() {
77 latch1.Signal();
78 term1.Wait();
79 });
80
81 fml::MessageLoop* loop2 = nullptr;
84 std::thread thread2([&loop2, &latch2, &term2]() {
87 latch2.Signal();
88 term2.Wait();
89 });
90
91 latch1.Wait();
92 latch2.Wait();
93 fml::TaskQueueId qid1 = loop1->GetTaskRunner()->GetTaskQueueId();
94 fml::TaskQueueId qid2 = loop2->GetTaskRunner()->GetTaskQueueId();
95 const auto raster_thread_merger =
96 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
97 const size_t kNumFramesMerged = 5;
98
99 raster_thread_merger->MergeWithLease(kNumFramesMerged);
100
101 // merged, running on the same thread
102 EXPECT_EQ(TaskRunnerChecker::RunsOnTheSameThread(qid1, qid2), true);
103
104 for (size_t i = 0; i < kNumFramesMerged; i++) {
105 ASSERT_TRUE(raster_thread_merger->IsMerged());
106 raster_thread_merger->DecrementLease();
107 }
108
109 ASSERT_FALSE(raster_thread_merger->IsMerged());
110
111 // un-merged, not running on the same thread
112 EXPECT_EQ(TaskRunnerChecker::RunsOnTheSameThread(qid1, qid2), false);
113
114 term1.Signal();
115 term2.Signal();
116 thread1.join();
117 thread2.join();
118}

◆ TEST() [83/91]

fml::testing::TEST ( TaskRunnerCheckerTests  ,
PassesRunsOnCreationTaskRunnerIfOnDifferentTaskRunner   
)

Definition at line 120 of file task_runner_checker_unittest.cc.

121 {
122 fml::MessageLoop* loop1 = nullptr;
124 std::thread thread1([&]() {
127 latch1.Signal();
128 loop1->Run();
129 });
130
131 fml::MessageLoop* loop2 = nullptr;
133 std::thread thread2([&]() {
136 latch2.Signal();
137 loop2->Run();
138 });
139
140 latch1.Wait();
141 latch2.Wait();
142
143 fml::TaskQueueId qid1 = loop1->GetTaskRunner()->GetTaskQueueId();
144 fml::TaskQueueId qid2 = loop2->GetTaskRunner()->GetTaskQueueId();
146
147 std::unique_ptr<TaskRunnerChecker> checker;
148
150 loop2->GetTaskRunner()->PostTask([&]() {
151 checker = std::make_unique<TaskRunnerChecker>();
152 EXPECT_EQ(checker->RunsOnCreationTaskRunner(), true);
153 latch3.Signal();
154 });
155 latch3.Wait();
156
158
160 loop2->GetTaskRunner()->PostTask([&]() {
161 EXPECT_EQ(checker->RunsOnCreationTaskRunner(), true);
162 latch4.Signal();
163 });
164 latch4.Wait();
165
166 loop1->Terminate();
167 loop2->Terminate();
168 thread1.join();
169 thread2.join();
170}
bool Merge(TaskQueueId owner, TaskQueueId subsumed)
bool Unmerge(TaskQueueId owner, TaskQueueId subsumed)

◆ TEST() [84/91]

fml::testing::TEST ( TaskRunnerCheckerTests  ,
RunsOnCurrentTaskRunner   
)

Definition at line 20 of file task_runner_checker_unittest.cc.

20 {
21 TaskRunnerChecker checker;
22 EXPECT_EQ(checker.RunsOnCreationTaskRunner(), true);
23}

◆ TEST() [85/91]

fml::testing::TEST ( TaskRunnerCheckerTests  ,
RunsOnDifferentThreadsReturnsFalse   
)

Definition at line 54 of file task_runner_checker_unittest.cc.

54 {
57 TaskQueueId a = loop1.GetTaskRunner()->GetTaskQueueId();
59 std::thread another_thread([&]() {
62 TaskQueueId b = loop2.GetTaskRunner()->GetTaskQueueId();
63 EXPECT_EQ(TaskRunnerChecker::RunsOnTheSameThread(a, b), false);
64 latch.Signal();
65 });
66 latch.Wait();
67 another_thread.join();
68}
static bool b
struct MyStruct a[10]

◆ TEST() [86/91]

fml::testing::TEST ( TaskRunnerCheckerTests  ,
SameTaskRunnerRunsOnTheSameThread   
)

Definition at line 45 of file task_runner_checker_unittest.cc.

45 {
49 TaskQueueId a = loop1.GetTaskRunner()->GetTaskQueueId();
50 TaskQueueId b = loop2.GetTaskRunner()->GetTaskQueueId();
51 EXPECT_EQ(TaskRunnerChecker::RunsOnTheSameThread(a, b), true);
52}

◆ TEST() [87/91]

fml::testing::TEST ( TaskSourceTests  ,
MultipleTaskGrades   
)

Definition at line 25 of file task_source_unittests.cc.

25 {
26 TaskSource task_source = TaskSource(TaskQueueId(1));
27 task_source.RegisterTask(
28 {1, [] {}, ChronoTicksSinceEpoch(), TaskSourceGrade::kUnspecified});
29 task_source.RegisterTask(
30 {2, [] {}, ChronoTicksSinceEpoch(), TaskSourceGrade::kUserInteraction});
31 task_source.RegisterTask(
32 {3, [] {}, ChronoTicksSinceEpoch(), TaskSourceGrade::kDartEventLoop});
33 ASSERT_EQ(task_source.GetNumPendingTasks(), 3u);
34}
void RegisterTask(const DelayedTask &task)
size_t GetNumPendingTasks() const

◆ TEST() [88/91]

fml::testing::TEST ( TaskSourceTests  ,
OrderingMultiTaskHeapsSecondaryPaused   
)

Definition at line 73 of file task_source_unittests.cc.

73 {
74 TaskSource task_source = TaskSource(TaskQueueId(1));
75 auto time_stamp = ChronoTicksSinceEpoch();
76 int value = 0;
77 task_source.RegisterTask(
78 {1, [&] { value = 1; }, time_stamp, TaskSourceGrade::kDartEventLoop});
79 task_source.RegisterTask({2, [&] { value = 7; },
81 TaskSourceGrade::kUserInteraction});
82
83 task_source.PauseSecondary();
84
85 auto top_task = task_source.Top();
86 top_task.task.GetTask()();
87 task_source.PopTask(top_task.task.GetTaskSourceGrade());
88 ASSERT_EQ(value, 7);
89
90 ASSERT_TRUE(task_source.IsEmpty());
91
92 task_source.ResumeSecondary();
93
94 auto second_task = task_source.Top();
95 second_task.task.GetTask()();
96 task_source.PopTask(second_task.task.GetTaskSourceGrade());
97 ASSERT_EQ(value, 1);
98}
const fml::closure & GetTask() const
bool IsEmpty() const
Returns true if GetNumPendingTasks is zero.
void ResumeSecondary()
Resume providing tasks from secondary task heap.
void PauseSecondary()
Pause providing tasks from secondary task heap.
void PopTask(TaskSourceGrade grade)
Pops the task heap corresponding to the TaskSourceGrade.
TopTask Top() const
uint8_t value
const DelayedTask & task
Definition task_source.h:39

◆ TEST() [89/91]

fml::testing::TEST ( TaskSourceTests  ,
SimpleInitialization   
)

Definition at line 18 of file task_source_unittests.cc.

18 {
19 TaskSource task_source = TaskSource(TaskQueueId(1));
20 task_source.RegisterTask(
21 {1, [] {}, ChronoTicksSinceEpoch(), TaskSourceGrade::kUnspecified});
22 ASSERT_EQ(task_source.GetNumPendingTasks(), 1u);
23}

◆ TEST() [90/91]

fml::testing::TEST ( TaskSourceTests  ,
SimpleOrdering   
)

Definition at line 36 of file task_source_unittests.cc.

36 {
37 TaskSource task_source = TaskSource(TaskQueueId(1));
38 auto time_stamp = ChronoTicksSinceEpoch();
39 int value = 0;
40 task_source.RegisterTask(
41 {1, [&] { value = 1; }, time_stamp, TaskSourceGrade::kUnspecified});
42 task_source.RegisterTask({2, [&] { value = 7; },
44 TaskSourceGrade::kUnspecified});
45 task_source.Top().task.GetTask()();
46 task_source.PopTask(TaskSourceGrade::kUnspecified);
47 ASSERT_EQ(value, 1);
48 task_source.Top().task.GetTask()();
49 task_source.PopTask(TaskSourceGrade::kUnspecified);
50 ASSERT_EQ(value, 7);
51}

◆ TEST() [91/91]

fml::testing::TEST ( TaskSourceTests  ,
SimpleOrderingMultiTaskHeaps   
)

Definition at line 53 of file task_source_unittests.cc.

53 {
54 TaskSource task_source = TaskSource(TaskQueueId(1));
55 auto time_stamp = ChronoTicksSinceEpoch();
56 int value = 0;
57 task_source.RegisterTask(
58 {1, [&] { value = 1; }, time_stamp, TaskSourceGrade::kDartEventLoop});
59 task_source.RegisterTask({2, [&] { value = 7; },
61 TaskSourceGrade::kUserInteraction});
62 auto top_task = task_source.Top();
63 top_task.task.GetTask()();
64 task_source.PopTask(top_task.task.GetTaskSourceGrade());
65 ASSERT_EQ(value, 1);
66
67 auto second_task = task_source.Top();
68 second_task.task.GetTask()();
69 task_source.PopTask(second_task.task.GetTaskSourceGrade());
70 ASSERT_EQ(value, 7);
71}

◆ TEST_F() [1/2]

fml::testing::TEST_F ( LogInterestListenerFuchsia  ,
AsyncWaitForInterestChange   
)

Definition at line 99 of file log_interest_listener_unittests.cc.

99 {
100 ScopedSetLogSettings backup({.min_log_level = kLogInfo});
101 auto realm_builder = component_testing::RealmBuilder::Create();
102 realm_builder.AddLocalChild(kLogSink, [&]() {
103 return std::make_unique<MockLogSink>(QuitLoopClosure(), dispatcher());
104 });
105 realm_builder.AddRoute(component_testing::Route{
106 .capabilities = {component_testing::Protocol{
107 fidl::DiscoverableProtocolName<fuchsia_logger::LogSink>}},
108 .source = component_testing::ChildRef{kLogSink},
109 .targets = {component_testing::ParentRef()}});
110
111 auto realm = realm_builder.Build(dispatcher());
112 auto cleanup = fit::defer([&]() {
113 bool complete = false;
114 realm.Teardown([&](auto result) { complete = true; });
115 RunLoopUntil([&]() { return complete; });
116 });
117 auto client_end = realm.component().Connect<fuchsia_logger::LogSink>();
118 ASSERT_TRUE(client_end.is_ok());
119 LogInterestListener listener(std::move(client_end.value()), dispatcher());
120 listener.AsyncWaitForInterestChanged();
121 RunLoop();
122
123 EXPECT_EQ(GetMinLogLevel(), kLogWarning);
124}
static constexpr char kLogSink[]
int GetMinLogLevel()
constexpr LogSeverity kLogInfo
Definition log_level.h:13

◆ TEST_F() [2/2]

fml::testing::TEST_F ( LogInterestListenerFuchsia  ,
SeverityChanges   
)

Definition at line 33 of file log_interest_listener_unittests.cc.

33 {
34 ScopedSetLogSettings backup({.min_log_level = kLogInfo});
35 {
36 ::fuchsia_diagnostics::Interest interest;
37 interest.min_severity(::fuchsia_diagnostics::Severity::kTrace);
38 LogInterestListener::HandleInterestChange(interest);
39 EXPECT_EQ(GetMinLogLevel(), -1); // VERBOSE
40 }
41 {
42 ::fuchsia_diagnostics::Interest interest;
43 interest.min_severity(::fuchsia_diagnostics::Severity::kInfo);
44 LogInterestListener::HandleInterestChange(interest);
45 EXPECT_EQ(GetMinLogLevel(), kLogInfo);
46 }
47 {
48 ::fuchsia_diagnostics::Interest interest;
49 interest.min_severity(::fuchsia_diagnostics::Severity::kError);
50 LogInterestListener::HandleInterestChange(interest);
51 EXPECT_EQ(GetMinLogLevel(), kLogError);
52 }
53}

◆ TestNotifyObservers()

void fml::testing::TestNotifyObservers ( fml::TaskQueueId  queue_id)

Definition at line 233 of file message_loop_task_queues_unittests.cc.

233 {
234 auto task_queue = fml::MessageLoopTaskQueues::GetInstance();
235 std::vector<fml::closure> observers =
236 task_queue->GetObserversToNotify(queue_id);
237 for (const auto& observer : observers) {
238 observer();
239 }
240}

◆ UnreachableScopeWithMacroWithoutReturnDoesNotMakeCompilerMad()

int fml::testing::UnreachableScopeWithMacroWithoutReturnDoesNotMakeCompilerMad ( )

Definition at line 60 of file logging_unittests.cc.

60 {
62 // return 0; <--- Missing but compiler is fine.
63}

◆ UnreachableScopeWithoutReturnDoesNotMakeCompilerMad()

int fml::testing::UnreachableScopeWithoutReturnDoesNotMakeCompilerMad ( )

Definition at line 55 of file logging_unittests.cc.

55 {
57 // return 0; <--- Missing but compiler is fine.
58}

Variable Documentation

◆ fml_log_static_check_

MakeSureFmlLogDoesNotSegfaultWhenStaticallyCalled fml::testing::fml_log_static_check_
static

Definition at line 52 of file logging_unittests.cc.

◆ kLogSink

constexpr char fml::testing::kLogSink[] = "log_sink"
staticconstexpr

Definition at line 28 of file log_interest_listener_unittests.cc.