pebble/tests/fw/kernel/test_interval_timer.c
2025-01-27 11:38:16 -08:00

238 lines
6.5 KiB
C

/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "kernel/util/interval_timer.h"
#include "fakes/fake_rtc.h"
#include "clar.h"
void passert_failed_no_message(const char* filename, int line_number) {
}
void vPortEnterCritical(void) {
}
void vPortExitCritical(void) {
}
void test_interval_timer__initialize(void) {
fake_rtc_init(0, 0);
}
void test_interval_timer__simple(void) {
IntervalTimer timer;
interval_timer_init(&timer, 0, UINT32_MAX, 2);
uint32_t num_intervals;
uint32_t average_ms;
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 0);
cl_assert_equal_i(average_ms, 0);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 0);
cl_assert_equal_i(average_ms, 0);
fake_rtc_increment_time_ms(1000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 1);
cl_assert_equal_i(average_ms, 1000);
fake_rtc_increment_time_ms(1000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 2);
cl_assert_equal_i(average_ms, 1000);
fake_rtc_increment_time_ms(1030);
interval_timer_take_sample(&timer);
// = 1000 + (0.5 * (1030 - 1000))
// = 1000 + (0.5 * 30)
// = 1015
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 3);
cl_assert_equal_i(average_ms, 1015);
}
void test_interval_timer__invalid_samples(void) {
IntervalTimer timer;
interval_timer_init(&timer, 800, 1200, 2);
uint32_t num_intervals;
uint32_t average_ms;
interval_timer_take_sample(&timer);
fake_rtc_increment_time_ms(1000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 1);
cl_assert_equal_i(average_ms, 1000);
// valid interval
fake_rtc_increment_time_ms(1020);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 2);
cl_assert_equal_i(average_ms, 1010);
// invalid interval, too high
fake_rtc_increment_time_ms(1220);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 2);
cl_assert_equal_i(average_ms, 1010);
// invalid interval, too low
fake_rtc_increment_time_ms(780);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 2);
cl_assert_equal_i(average_ms, 1010);
// valid interval
fake_rtc_increment_time_ms(1010);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 3);
cl_assert_equal_i(average_ms, 1010);
}
// Make sure we don't run into any issues when our internals are close to UINT32_MAX
void test_interval_timer__big_interval(void) {
IntervalTimer timer;
interval_timer_init(&timer, 0, UINT32_MAX, 2);
uint32_t num_intervals;
uint32_t average_ms;
interval_timer_take_sample(&timer);
fake_rtc_increment_time_ms(3000000000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 1);
cl_assert_equal_i(average_ms, 3000000000);
fake_rtc_increment_time_ms(3000000000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 2);
cl_assert_equal_i(average_ms, 3000000000);
fake_rtc_increment_time_ms(3000000000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 3);
cl_assert_equal_i(average_ms, 3000000000);
}
void test_interval_timer__moving_average(void) {
IntervalTimer timer;
interval_timer_init(&timer, 0, UINT32_MAX, 4);
uint32_t num_intervals;
uint32_t average_ms;
interval_timer_take_sample(&timer);
fake_rtc_increment_time_ms(1000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 1);
cl_assert_equal_i(average_ms, 1000);
fake_rtc_increment_time_ms(1020);
interval_timer_take_sample(&timer);
// = 1000 + (0.25 * (1020 - 1000))
// = 1000 + (0.25 * 20)
// = 1005
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 2);
cl_assert_equal_i(average_ms, 1005);
fake_rtc_increment_time_ms(1010);
interval_timer_take_sample(&timer);
// = 1005 + (0.25 * (1010 - 1005))
// = 1005 + (0.25 * 5)
// = 1006
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 3);
cl_assert_equal_i(average_ms, 1006);
fake_rtc_increment_time_ms(1010);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 4);
cl_assert_equal_i(average_ms, 1007);
fake_rtc_increment_time_ms(1030);
interval_timer_take_sample(&timer);
// = 1007 + (0.25 * (1030 - 1007))
// = 1007 + (0.25 * 23)
// = 1007 + 5
// = 1012
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 5);
cl_assert_equal_i(average_ms, 1012);
fake_rtc_increment_time_ms(1030);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 6);
cl_assert_equal_i(average_ms, 1016);
// Take a bunch of samples to make sure the moving average moves up to the new interval
for (int i = 0; i < 10; ++i) {
fake_rtc_increment_time_ms(1030);
interval_timer_take_sample(&timer);
}
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 16);
// Close enough, rounding issues will prevent us from every actually hitting 1030
// = 1027 + (0.25 * (1030 - 1027))
// = 1027 + (0.25 * 3)
// = 1027
cl_assert_equal_i(average_ms, 1027);
}