mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-12 21:30:45 +01:00

BlockingCall doesn't take rtc::Location parameter and thus most of the dependencies on location can be removed Bug: webrtc:11318 Change-Id: I91a17e342dd9a9e3e2c8f7fbe267474c98a8d0e5 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/274620 Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38045}
181 lines
6.7 KiB
C++
181 lines
6.7 KiB
C++
/*
|
|
* Copyright 2020 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
#include "api/test/time_controller.h"
|
|
#include "api/units/time_delta.h"
|
|
#include "rtc_base/event.h"
|
|
#include "rtc_base/synchronization/mutex.h"
|
|
#include "rtc_base/thread.h"
|
|
#include "rtc_base/thread_annotations.h"
|
|
#include "test/gmock.h"
|
|
#include "test/gtest.h"
|
|
#include "test/time_controller/real_time_controller.h"
|
|
#include "test/time_controller/simulated_time_controller.h"
|
|
|
|
namespace webrtc {
|
|
namespace {
|
|
|
|
using ::testing::ElementsAreArray;
|
|
using ::testing::TestParamInfo;
|
|
using ::testing::TestWithParam;
|
|
using ::testing::Values;
|
|
|
|
enum class TimeMode { kRealTime, kSimulated };
|
|
|
|
std::unique_ptr<TimeController> CreateTimeController(TimeMode mode) {
|
|
switch (mode) {
|
|
case TimeMode::kRealTime:
|
|
return std::make_unique<RealTimeController>();
|
|
case TimeMode::kSimulated:
|
|
// Using an offset of 100000 to get nice fixed width and readable
|
|
// timestamps in typical test scenarios.
|
|
constexpr Timestamp kSimulatedStartTime = Timestamp::Seconds(100000);
|
|
return std::make_unique<GlobalSimulatedTimeController>(
|
|
kSimulatedStartTime);
|
|
}
|
|
}
|
|
|
|
std::string ParamsToString(const TestParamInfo<webrtc::TimeMode>& param) {
|
|
switch (param.param) {
|
|
case webrtc::TimeMode::kRealTime:
|
|
return "RealTime";
|
|
case webrtc::TimeMode::kSimulated:
|
|
return "SimulatedTime";
|
|
default:
|
|
RTC_DCHECK_NOTREACHED() << "Time mode not supported";
|
|
}
|
|
}
|
|
|
|
// Keeps order of executions. May be called from different threads.
|
|
class ExecutionOrderKeeper {
|
|
public:
|
|
void Executed(int execution_id) {
|
|
MutexLock lock(&mutex_);
|
|
order_.push_back(execution_id);
|
|
}
|
|
|
|
std::vector<int> order() const {
|
|
MutexLock lock(&mutex_);
|
|
return order_;
|
|
}
|
|
|
|
private:
|
|
mutable Mutex mutex_;
|
|
std::vector<int> order_ RTC_GUARDED_BY(mutex_);
|
|
};
|
|
|
|
// Tests conformance between real time and simulated time time controller.
|
|
class SimulatedRealTimeControllerConformanceTest
|
|
: public TestWithParam<webrtc::TimeMode> {};
|
|
|
|
TEST_P(SimulatedRealTimeControllerConformanceTest, ThreadPostOrderTest) {
|
|
std::unique_ptr<TimeController> time_controller =
|
|
CreateTimeController(GetParam());
|
|
std::unique_ptr<rtc::Thread> thread = time_controller->CreateThread("thread");
|
|
|
|
// Tasks on thread have to be executed in order in which they were
|
|
// posted.
|
|
ExecutionOrderKeeper execution_order;
|
|
thread->PostTask([&]() { execution_order.Executed(1); });
|
|
thread->PostTask([&]() { execution_order.Executed(2); });
|
|
time_controller->AdvanceTime(TimeDelta::Millis(100));
|
|
EXPECT_THAT(execution_order.order(), ElementsAreArray({1, 2}));
|
|
// Destroy `thread` before `execution_order` to be sure `execution_order`
|
|
// is not accessed on the posted task after it is destroyed.
|
|
thread = nullptr;
|
|
}
|
|
|
|
TEST_P(SimulatedRealTimeControllerConformanceTest, ThreadPostDelayedOrderTest) {
|
|
std::unique_ptr<TimeController> time_controller =
|
|
CreateTimeController(GetParam());
|
|
std::unique_ptr<rtc::Thread> thread = time_controller->CreateThread("thread");
|
|
|
|
ExecutionOrderKeeper execution_order;
|
|
thread->PostDelayedTask([&]() { execution_order.Executed(2); },
|
|
TimeDelta::Millis(500));
|
|
thread->PostTask([&]() { execution_order.Executed(1); });
|
|
time_controller->AdvanceTime(TimeDelta::Millis(600));
|
|
EXPECT_THAT(execution_order.order(), ElementsAreArray({1, 2}));
|
|
// Destroy `thread` before `execution_order` to be sure `execution_order`
|
|
// is not accessed on the posted task after it is destroyed.
|
|
thread = nullptr;
|
|
}
|
|
|
|
TEST_P(SimulatedRealTimeControllerConformanceTest, ThreadPostInvokeOrderTest) {
|
|
std::unique_ptr<TimeController> time_controller =
|
|
CreateTimeController(GetParam());
|
|
std::unique_ptr<rtc::Thread> thread = time_controller->CreateThread("thread");
|
|
|
|
// Tasks on thread have to be executed in order in which they were
|
|
// posted/invoked.
|
|
ExecutionOrderKeeper execution_order;
|
|
thread->PostTask([&]() { execution_order.Executed(1); });
|
|
thread->BlockingCall([&]() { execution_order.Executed(2); });
|
|
time_controller->AdvanceTime(TimeDelta::Millis(100));
|
|
EXPECT_THAT(execution_order.order(), ElementsAreArray({1, 2}));
|
|
// Destroy `thread` before `execution_order` to be sure `execution_order`
|
|
// is not accessed on the posted task after it is destroyed.
|
|
thread = nullptr;
|
|
}
|
|
|
|
TEST_P(SimulatedRealTimeControllerConformanceTest,
|
|
ThreadPostInvokeFromThreadOrderTest) {
|
|
std::unique_ptr<TimeController> time_controller =
|
|
CreateTimeController(GetParam());
|
|
std::unique_ptr<rtc::Thread> thread = time_controller->CreateThread("thread");
|
|
|
|
// If task is invoked from thread X on thread X it has to be executed
|
|
// immediately.
|
|
ExecutionOrderKeeper execution_order;
|
|
thread->PostTask([&]() {
|
|
thread->PostTask([&]() { execution_order.Executed(2); });
|
|
thread->BlockingCall([&]() { execution_order.Executed(1); });
|
|
});
|
|
time_controller->AdvanceTime(TimeDelta::Millis(100));
|
|
EXPECT_THAT(execution_order.order(), ElementsAreArray({1, 2}));
|
|
// Destroy `thread` before `execution_order` to be sure `execution_order`
|
|
// is not accessed on the posted task after it is destroyed.
|
|
thread = nullptr;
|
|
}
|
|
|
|
TEST_P(SimulatedRealTimeControllerConformanceTest,
|
|
TaskQueuePostEventWaitOrderTest) {
|
|
std::unique_ptr<TimeController> time_controller =
|
|
CreateTimeController(GetParam());
|
|
auto task_queue = time_controller->GetTaskQueueFactory()->CreateTaskQueue(
|
|
"task_queue", webrtc::TaskQueueFactory::Priority::NORMAL);
|
|
|
|
// Tasks on thread have to be executed in order in which they were
|
|
// posted/invoked.
|
|
ExecutionOrderKeeper execution_order;
|
|
rtc::Event event;
|
|
task_queue->PostTask([&]() { execution_order.Executed(1); });
|
|
task_queue->PostTask([&]() {
|
|
execution_order.Executed(2);
|
|
event.Set();
|
|
});
|
|
EXPECT_TRUE(event.Wait(/*give_up_after=*/TimeDelta::Millis(100)));
|
|
time_controller->AdvanceTime(TimeDelta::Millis(100));
|
|
EXPECT_THAT(execution_order.order(), ElementsAreArray({1, 2}));
|
|
// Destroy `task_queue` before `execution_order` to be sure `execution_order`
|
|
// is not accessed on the posted task after it is destroyed.
|
|
task_queue = nullptr;
|
|
}
|
|
|
|
INSTANTIATE_TEST_SUITE_P(ConformanceTest,
|
|
SimulatedRealTimeControllerConformanceTest,
|
|
Values(TimeMode::kRealTime, TimeMode::kSimulated),
|
|
ParamsToString);
|
|
|
|
} // namespace
|
|
} // namespace webrtc
|