1 /*
2 * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10 #include <memory>
11
12 #include "api/sequence_checker.h"
13 #include "api/task_queue/pending_task_safety_flag.h"
14 #include "api/task_queue/task_queue_factory.h"
15 #include "api/units/time_delta.h"
16 #include "modules/utility/maybe_worker_thread.h"
17 #include "rtc_base/event.h"
18 #include "test/explicit_key_value_config.h"
19 #include "test/gtest.h"
20 #include "test/time_controller/real_time_controller.h"
21
22 namespace webrtc {
23
24 namespace {
25
26 constexpr char kFieldTrialString[] =
27 "WebRTC-SendPacketsOnWorkerThread/Enabled/";
28
TEST(MaybeWorkerThreadTest,RunOrPostRunOnWorkerThreadInExperiment)29 TEST(MaybeWorkerThreadTest, RunOrPostRunOnWorkerThreadInExperiment) {
30 test::ExplicitKeyValueConfig field_trial(kFieldTrialString);
31 RealTimeController controller;
32 MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory());
33
34 SequenceChecker checker;
35 bool run = false;
36 m.RunOrPost([&] {
37 EXPECT_TRUE(checker.IsCurrent());
38 run = true;
39 });
40 EXPECT_TRUE(run);
41 }
42
TEST(MaybeWorkerThreadTest,RunOrPostPostsOnTqPerDefault)43 TEST(MaybeWorkerThreadTest, RunOrPostPostsOnTqPerDefault) {
44 test::ExplicitKeyValueConfig field_trial("");
45 RealTimeController controller;
46 MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory());
47
48 SequenceChecker checker;
49 rtc::Event event;
50 m.RunOrPost([&] {
51 EXPECT_FALSE(checker.IsCurrent());
52 event.Set();
53 });
54 EXPECT_TRUE(event.Wait(TimeDelta::Seconds(10)));
55 }
56
TEST(MaybeWorkerThreadTest,RunSynchronousRunOnWorkerThreadInExperiment)57 TEST(MaybeWorkerThreadTest, RunSynchronousRunOnWorkerThreadInExperiment) {
58 test::ExplicitKeyValueConfig field_trial(kFieldTrialString);
59 RealTimeController controller;
60 MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory());
61
62 SequenceChecker checker;
63 bool run = false;
64 m.RunSynchronous([&] {
65 EXPECT_TRUE(checker.IsCurrent());
66 run = true;
67 });
68 EXPECT_TRUE(run);
69 }
70
TEST(MaybeWorkerThreadTest,RunSynchronousRunOnTqPerDefault)71 TEST(MaybeWorkerThreadTest, RunSynchronousRunOnTqPerDefault) {
72 test::ExplicitKeyValueConfig field_trial("");
73 RealTimeController controller;
74 MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory());
75
76 SequenceChecker checker;
77 bool run = false;
78 m.RunSynchronous([&] {
79 EXPECT_FALSE(checker.IsCurrent());
80 run = true;
81 });
82 EXPECT_TRUE(run);
83 }
84
TEST(MaybeWorkerThreadTest,MaybeSafeTaskDoesNotReturnSafeTaskPerDefault)85 TEST(MaybeWorkerThreadTest, MaybeSafeTaskDoesNotReturnSafeTaskPerDefault) {
86 // We cant really test that the return value from MaybeSafeTask is a SafeTask.
87 // But we can test that the safety flag does not have more references after a
88 // call.
89 test::ExplicitKeyValueConfig field_trial("");
90 RealTimeController controller;
91 MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory());
92
93 rtc::scoped_refptr<PendingTaskSafetyFlag> flag =
94 PendingTaskSafetyFlag::Create();
95 auto closure = m.MaybeSafeTask(flag, [] {});
96 EXPECT_EQ(flag->Release(), rtc::RefCountReleaseStatus::kDroppedLastRef);
97 flag.release();
98 }
99
TEST(MaybeWorkerThreadTest,MaybeSafeTaskDoesNotReturnSafeTaskInExperiment)100 TEST(MaybeWorkerThreadTest, MaybeSafeTaskDoesNotReturnSafeTaskInExperiment) {
101 // We cant really test that the return value from MaybeSafeTask is a SafeTask.
102 // But we can test that the safety flag does have one more references after a
103 // call.
104 test::ExplicitKeyValueConfig field_trial(kFieldTrialString);
105 RealTimeController controller;
106 MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory());
107
108 rtc::scoped_refptr<PendingTaskSafetyFlag> flag =
109 PendingTaskSafetyFlag::Create();
110 auto closure = m.MaybeSafeTask(flag, [] {});
111 EXPECT_EQ(flag->Release(), rtc::RefCountReleaseStatus::kOtherRefsRemained);
112 flag.release();
113 }
114
TEST(MaybeWorkerThreadTest,IsCurrentBehavesCorrectPerDefault)115 TEST(MaybeWorkerThreadTest, IsCurrentBehavesCorrectPerDefault) {
116 test::ExplicitKeyValueConfig field_trial("");
117 RealTimeController controller;
118 MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory());
119
120 EXPECT_FALSE(m.IsCurrent());
121 m.RunSynchronous([&] { EXPECT_TRUE(m.IsCurrent()); });
122 }
123
TEST(MaybeWorkerThreadTest,IsCurrentBehavesCorrectInExperiment)124 TEST(MaybeWorkerThreadTest, IsCurrentBehavesCorrectInExperiment) {
125 test::ExplicitKeyValueConfig field_trial(kFieldTrialString);
126 RealTimeController controller;
127 MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory());
128
129 EXPECT_TRUE(m.IsCurrent());
130 auto tq = controller.GetTaskQueueFactory()->CreateTaskQueue(
131 "tq", TaskQueueFactory::Priority::NORMAL);
132 rtc::Event event;
133 tq->PostTask([&] {
134 EXPECT_FALSE(m.IsCurrent());
135 event.Set();
136 });
137 ASSERT_TRUE(event.Wait(TimeDelta::Seconds(10)));
138 }
139
TEST(MaybeWorkerThreadTest,IsCurrentCanBeCalledInDestructorPerDefault)140 TEST(MaybeWorkerThreadTest, IsCurrentCanBeCalledInDestructorPerDefault) {
141 test::ExplicitKeyValueConfig field_trial("");
142 RealTimeController controller;
143 {
144 MaybeWorkerThread m(field_trial, "test_tq",
145 controller.GetTaskQueueFactory());
146 m.RunOrPost([&] { EXPECT_TRUE(m.IsCurrent()); });
147 }
148 }
149
TEST(MaybeWorkerThreadTest,IsCurrentCanBeCalledInDestructorInExperiment)150 TEST(MaybeWorkerThreadTest, IsCurrentCanBeCalledInDestructorInExperiment) {
151 test::ExplicitKeyValueConfig field_trial(kFieldTrialString);
152 RealTimeController controller;
153 {
154 MaybeWorkerThread m(field_trial, "test_tq",
155 controller.GetTaskQueueFactory());
156 m.RunOrPost([&] { EXPECT_TRUE(m.IsCurrent()); });
157 }
158 }
159
160 } // namespace
161 } // namespace webrtc
162