32
32
#include <boost/accumulators/statistics/stats.hpp>
33
33
#include <boost/accumulators/statistics/variance.hpp>
35
#include "mcs/mediamanagerfactory.h"
36
#include "mcs/networkutils.h"
37
#include "mcs/utils.h"
38
#include "mcs/logger.h"
35
#include "ac/mediamanagerfactory.h"
36
#include "ac/networkutils.h"
38
#include "ac/logger.h"
40
#include "mcs/systemcontroller.h"
40
#include "ac/systemcontroller.h"
42
42
#include "tests/common/benchmark.h"
43
43
#include "tests/common/statistics.h"
45
#include "tests/mcs/integration_tests/config.h"
45
#include "tests/ac/integration_tests/config.h"
47
47
namespace ba = boost::accumulators;
52
52
static constexpr unsigned int kStreamMaxUnitSize = 1472;
53
53
static constexpr const char *kNullIpAddress{"0.0.0.0"};
55
class MockStream : public mcs::network::Stream {
55
class MockStream : public ac::network::Stream {
57
MOCK_METHOD2(Connect, bool(const std::string &address, const mcs::network::Port &port));
57
MOCK_METHOD2(Connect, bool(const std::string &address, const ac::network::Port &port));
58
58
MOCK_METHOD0(WaitUntilReady, bool());
59
MOCK_METHOD3(Write, mcs::network::Stream::Error(const uint8_t*, unsigned int, const mcs::TimestampUs&));
60
MOCK_CONST_METHOD0(LocalPort, mcs::network::Port());
59
MOCK_METHOD3(Write, ac::network::Stream::Error(const uint8_t*, unsigned int, const ac::TimestampUs&));
60
MOCK_CONST_METHOD0(LocalPort, ac::network::Port());
61
61
MOCK_CONST_METHOD0(MaxUnitSize, std::uint32_t());
64
64
typedef std::chrono::high_resolution_clock Clock;
65
typedef mcs::testing::Benchmark::Result::Timing::Seconds Resolution;
65
typedef ac::testing::Benchmark::Result::Timing::Seconds Resolution;
67
67
typedef ba::accumulator_set<
69
69
ba::stats<ba::tag::count, ba::tag::min, ba::tag::max, ba::tag::mean, ba::tag::variance>
72
void FillResultsFromStatistics(mcs::testing::Benchmark::Result& result,
72
void FillResultsFromStatistics(ac::testing::Benchmark::Result& result,
73
73
const Statistics& stats)
75
75
result.sample_size = ba::count(stats);
80
80
result.timing.std_dev = Resolution{static_cast<Resolution::rep>(std::sqrt(ba::variance(stats)))};
83
class StreamBenchmark : public mcs::testing::Benchmark {
83
class StreamBenchmark : public ac::testing::Benchmark {
85
85
struct PlaybackConfiguration {
86
86
std::chrono::seconds duration{10};
87
87
StatisticsConfiguration statistics_configuration{};
90
mcs::testing::Benchmark::Result ForPlayback(const PlaybackConfiguration &config) {
90
ac::testing::Benchmark::Result ForPlayback(const PlaybackConfiguration &config) {
92
mcs::testing::Benchmark::Result benchmark_result;
92
ac::testing::Benchmark::Result benchmark_result;
94
auto system_controller = mcs::SystemController::CreatePlatformDefault();
94
auto system_controller = ac::SystemController::CreatePlatformDefault();
96
96
// Make sure the screen is turned on to get the fully boosted
97
97
// system which compares best to a running service.
98
system_controller->DisplayStateLock()->Acquire(mcs::DisplayState::On);
98
system_controller->DisplayStateLock()->Acquire(ac::DisplayState::On);
100
100
const auto output_stream = std::make_shared<MockStream>();
112
112
.WillRepeatedly(Return(true));
114
114
EXPECT_CALL(*output_stream, Write(_, _, _))
115
.WillRepeatedly(Invoke([&](const uint8_t *data, unsigned int size, const mcs::TimestampUs ×tamp) {
115
.WillRepeatedly(Invoke([&](const uint8_t *data, unsigned int size, const ac::TimestampUs ×tamp) {
116
116
boost::ignore_unused_variable_warning(data);
117
117
boost::ignore_unused_variable_warning(size);
119
const mcs::TimestampUs now = mcs::Utils::GetNowUs();
119
const ac::TimestampUs now = ac::Utils::GetNowUs();
121
121
// FIXME there is atleast one buffer which doesn't have a timestamp
122
122
// set. Most propably its the one carrying the CSD data.
123
123
if (timestamp <= 0ll)
124
return mcs::network::Stream::Error::kNone;
124
return ac::network::Stream::Error::kNone;
126
const mcs::TimestampUs diff = now - timestamp;
126
const ac::TimestampUs diff = now - timestamp;
128
128
double seconds = diff;
129
129
// Converting from microseconds to seconds as that is what the
131
131
seconds /= 1000000.0;
134
benchmark_result.timing.sample.push_back(mcs::testing::Benchmark::Result::Timing::Seconds{seconds});
134
benchmark_result.timing.sample.push_back(ac::testing::Benchmark::Result::Timing::Seconds{seconds});
136
return mcs::network::Stream::Error::kNone;
136
return ac::network::Stream::Error::kNone;
139
const auto media_manager = mcs::MediaManagerFactory::CreateSource(kNullIpAddress, output_stream);
140
const auto port = mcs::NetworkUtils::PickRandomPort();
139
const auto media_manager = ac::MediaManagerFactory::CreateSource(kNullIpAddress, output_stream);
140
const auto port = ac::NetworkUtils::PickRandomPort();
142
142
std::vector<wds::H264VideoCodec> sink_codecs;
143
143
wds::NativeVideoFormat sink_native_format;
166
166
media_manager->Teardown();
168
system_controller->DisplayStateLock()->Acquire(mcs::DisplayState::Off);
168
system_controller->DisplayStateLock()->Acquire(ac::DisplayState::Off);
170
170
FillResultsFromStatistics(benchmark_result, stats);
171
171
return benchmark_result;
176
176
TEST(StreamPerformance, EndToEndIsAcceptable) {
177
mcs::testing::Benchmark::Result reference_result;
177
ac::testing::Benchmark::Result reference_result;
179
std::ifstream in{mcs::testing::stream_performance::kReferenceResultFile};
179
std::ifstream in{ac::testing::stream_performance::kReferenceResultFile};
180
180
reference_result.load_from_xml(in);
182
182
StreamBenchmark benchmark;
188
188
std::ofstream out{"ref-new.xml"};
189
189
result.save_to_xml(out);
191
MCS_DEBUG("current sample size %d mean %f var %f std dev %f",
191
AC_DEBUG("current sample size %d mean %f var %f std dev %f",
192
192
result.timing.get_size(), result.timing.get_mean(),
193
193
result.timing.get_variance(), result.timing.get_stddev());
194
MCS_DEBUG("reference sample size %d mean %f var %f std dev %f",
194
AC_DEBUG("reference sample size %d mean %f var %f std dev %f",
195
195
reference_result.timing.get_size(), reference_result.timing.get_mean(),
196
196
reference_result.timing.get_variance(), reference_result.timing.get_stddev());
203
203
ASSERT_FALSE(result.timing.is_significantly_slower_than_reference(reference_result.timing));
205
205
if (result.timing.is_significantly_faster_than_reference(reference_result.timing))
206
MCS_WARNING("Benchmark shows significantly better performance than reference sample");
206
AC_WARNING("Benchmark shows significantly better performance than reference sample");