/* Copyright 2022 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * * Simple test to validate the benchmark library. */ #include "benchmark.h" extern "C" { #include "test_util.h" } /* Sample function for the benchmark */ static void float_mult() { float a = 1.1; float b = 1.1; int i; for (i = 0; i < 1000; ++i) a *= b; } test_static int test_valid_benchmark() { Benchmark benchmark; auto result = benchmark.run("float_mult", float_mult); TEST_ASSERT(result.has_value()); benchmark.print_results(); return EC_SUCCESS; } test_static int test_num_iterations() { Benchmark benchmark({ .num_iterations = 5 }); int num_calls = 0; auto result = benchmark.run("call_counter", [&] { ++num_calls; }); TEST_ASSERT(result.has_value()); TEST_EQ(num_calls, 5, "%d"); benchmark.print_results(); return EC_SUCCESS; } test_static int test_multiple_benchmarks() { // Use two separate instances with different settings Benchmark benchmark1({ .num_iterations = 5 }); Benchmark benchmark2({ .num_iterations = 3 }); int num_calls = 0; auto result1 = benchmark1.run("call_counter1", [&] { ++num_calls; }); TEST_ASSERT(result1.has_value()); TEST_EQ(num_calls, 5, "%d"); num_calls = 0; auto result2 = benchmark2.run("call_counter2", [&] { ++num_calls; }); TEST_ASSERT(result2.has_value()); TEST_EQ(num_calls, 3, "%d"); benchmark1.print_results(); benchmark2.print_results(); return EC_SUCCESS; } test_static int test_long_benchmark() { Benchmark benchmark({ .num_iterations = 100 }); int num_calls = 0; auto result = benchmark.run("call_counter", [&] { ++num_calls; udelay(10000); }); TEST_ASSERT(result.has_value()); TEST_EQ(num_calls, 100, "%d"); benchmark.print_results(); return EC_SUCCESS; } test_static int test_result_comparison() { constexpr auto result1 = BenchmarkResult{ .name = "implementation1", .elapsed_time = 10000, .average_time = 100, .min_time = 10, .max_time = 200, }; constexpr auto result2 = BenchmarkResult{ .name = "implementation2", .elapsed_time = 8000, .average_time = 80, .min_time = 13, .max_time = 150, }; BenchmarkResult::compare(result1, result2); return EC_SUCCESS; } test_static int test_empty_benchmark_name() { Benchmark benchmark; TEST_ASSERT(!benchmark.run("", [] {}).has_value()); return EC_SUCCESS; } test_static int test_too_many_runs() { auto benchmark = Benchmark<3>(); TEST_ASSERT(benchmark.run("call_1", [] {}).has_value()); TEST_ASSERT(benchmark.run("call_2", [] {}).has_value()); TEST_ASSERT(benchmark.run("call_3", [] {}).has_value()); TEST_ASSERT(!benchmark.run("call_4", [] {}).has_value()); return EC_SUCCESS; } test_static int test_min_max_time() { // Run test 3 times with increasing delay of 1ms, 2ms, and 4ms Benchmark benchmark({ .num_iterations = 3 }); int delay_us = 1000; auto result = benchmark.run("delay", [&delay_us] { udelay(delay_us); delay_us *= 2; }); TEST_ASSERT(result.has_value()); auto min_time = result.value().min_time; auto max_time = result.value().max_time; TEST_GE(min_time, 995U, "%u"); TEST_LE(min_time, 1005U, "%u"); TEST_GE(max_time, 3995U, "%u"); TEST_LE(max_time, 4005U, "%u"); benchmark.print_results(); return EC_SUCCESS; } void run_test(int argc, const char **argv) { test_reset(); RUN_TEST(test_valid_benchmark); RUN_TEST(test_num_iterations); RUN_TEST(test_multiple_benchmarks); RUN_TEST(test_long_benchmark); RUN_TEST(test_result_comparison); RUN_TEST(test_too_many_runs); RUN_TEST(test_empty_benchmark_name); RUN_TEST(test_min_max_time); test_print_result(); }