M5UnitUnified 0.4.4 git rev:306ddd5
Loading...
Searching...
No Matches
test_helper.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
11#ifndef M5_UNIT_COMPONENT_GOOGLETEST_HELPER_HPP
12#define M5_UNIT_COMPONENT_GOOGLETEST_HELPER_HPP
13
14#include <M5Utility.hpp>
15#include <algorithm>
16#include <cstdint>
17#include <numeric>
18#include <vector>
19
20namespace m5 {
21namespace unit {
22namespace googletest {
23
29 std::vector<uint32_t> intervals;
30 uint32_t update_count{};
31 uint32_t expected_interval{};
32 bool timed_out{};
33
35 uint32_t average() const
36 {
37 if (intervals.empty()) {
38 return 0;
39 }
40 uint64_t sum = std::accumulate(intervals.begin(), intervals.end(), uint64_t{0});
41 return static_cast<uint32_t>(sum / intervals.size());
42 }
43
45 uint32_t median() const
46 {
47 if (intervals.empty()) {
48 return 0;
49 }
50 auto sorted = intervals;
51 std::sort(sorted.begin(), sorted.end());
52 auto n = sorted.size();
53 return (n % 2) ? sorted[n / 2] : (sorted[n / 2 - 1] + sorted[n / 2]) / 2;
54 }
55
57 uint32_t min_interval() const
58 {
59 if (intervals.empty()) {
60 return 0;
61 }
62 return *std::min_element(intervals.begin(), intervals.end());
63 }
64
66 uint32_t max_interval() const
67 {
68 if (intervals.empty()) {
69 return 0;
70 }
71 return *std::max_element(intervals.begin(), intervals.end());
72 }
73};
74
84template <class U>
86 const uint32_t timeout_duration = 0,
87 void (*callback)(U*) = nullptr)
88{
89 static_assert(std::is_base_of<m5::unit::Component, U>::value, "U must be derived from Component");
90
92 result.expected_interval = unit->interval();
93 if (times > 1) {
94 result.intervals.reserve(times - 1);
95 }
96
97 auto actual_timeout = timeout_duration ? timeout_duration : result.expected_interval * (times + 1);
98 auto timeout_at = m5::utility::millis() + actual_timeout;
99 uint32_t remaining = times;
100 decltype(unit->updatedMillis()) prev{};
101 bool first_update = true;
102
103 while (remaining && m5::utility::millis() <= timeout_at) {
104 unit->update();
105 if (unit->updated()) {
106 ++result.update_count;
107 --remaining;
108 auto um = unit->updatedMillis();
109 if (!first_update) {
110 result.intervals.push_back(um - prev);
111 }
112 first_update = false;
113 prev = um;
114 if (callback) {
115 callback(unit);
116 }
117 }
118 }
119
120 result.timed_out = (remaining > 0);
121 return result;
122}
123
124} // namespace googletest
125} // namespace unit
126} // namespace m5
127#endif
For GoogleTest.
Top level namespace of M5stack.
Definition test_helper.hpp:20
Unit-related namespace.
Result of periodic measurement data collection with statistical analysis.
Definition test_helper.hpp:28
uint32_t median() const
Median of intervals (ms), robust to outliers.
Definition test_helper.hpp:45
uint32_t update_count
Number of successful updates.
Definition test_helper.hpp:30
uint32_t max_interval() const
Maximum interval (ms)
Definition test_helper.hpp:66
uint32_t expected_interval
Expected interval from unit->interval()
Definition test_helper.hpp:31
bool timed_out
True if timeout before collecting all samples.
Definition test_helper.hpp:32
uint32_t average() const
Average of intervals (ms)
Definition test_helper.hpp:35
uint32_t min_interval() const
Minimum interval (ms)
Definition test_helper.hpp:57
std::vector< uint32_t > intervals
All inter-update intervals (ms)
Definition test_helper.hpp:29
PeriodicMeasurementResult collect_periodic_measurements(U *unit, const uint32_t times=8, const uint32_t timeout_duration=0, void(*callback)(U *)=nullptr)
Collect periodic measurement data from a unit.
Definition test_helper.hpp:85