The Fossil Mark Framework provides a unified, lightweight, and highly flexible benchmarking layer designed for developers who want precise and reproducible performance metrics inside Fossil Test environments. It offers a consistent API for measuring execution time across a wide range of granularities—from minutes down to yoctoseconds—making it suitable both for coarse system-level profiling and extremely fine-grained microbenchmarks. Using standard C timing primitives, the framework tracks total duration, minimum and maximum samples, averages, and the number of recorded iterations, ensuring that performance data remains accurate and easy to interpret.
In addition to manual start/stop benchmarks, the framework introduces scoped benchmarking, a safer and more ergonomic pattern that automatically starts and stops timing based on object lifetime. This ensures that even complex code paths or early returns are included in the measurement, removing the risk of mismatched start/stop calls. The scoped design mirrors RAII-style patterns found in modern C++ but is implemented here in plain C, making it portable and suitable for embedded systems, testing tools, and high-performance environments.
To support test automation pipelines, Fossil Mark also provides specialized macros for test-focused benchmarks, enabling developers to report timing in whichever unit is most meaningful for their test domain—seconds, microseconds, nanoseconds, or more exotic attosecond-level detail. These reporting utilities integrate seamlessly with Fossil’s test output, making it trivial to verify timing expectations, detect regressions, or enforce performance budgets. Whether used for profiling internal systems, validating high-precision algorithms, or comparing implementations, Fossil Mark offers a clean, extensible foundation for all benchmark-driven workflows.
PUBLIC INTERFACE #
/**
* @brief Structure to hold the benchmark statistics.
*
* This structure contains various fields to manage the statistics for a benchmark,
* including the name of the benchmark, the start and end times, the number of samples,
* the total duration, the minimum and maximum durations, and a flag to indicate if the
* benchmark is currently running.
*/
typedef struct {
const char* name;
uint64_t start_time;
uint64_t end_time;
uint64_t* iteration_times;
size_t num_iterations;
size_t num_warmup;
size_t capacity;
double total_duration;
double min_duration;
double max_duration;
double mean_duration;
double median_duration;
double std_dev;
int running;
uint32_t num_samples;
} fossil_mark_t;
/**
* @brief Initializes a fossil_mark_t object with the given name.
* @param benchmark The fossil_mark_t object to initialize.
* @param name The name of the benchmark.
*/
FOSSIL_MAIP_API void fossil_benchmark_init(fossil_mark_t* benchmark, const char* name);
/**
* @brief Starts the benchmark timer.
* @param benchmark The fossil_mark_t object to start.
*/
FOSSIL_MAIP_API void fossil_benchmark_start(fossil_mark_t* benchmark);
/**
* @brief Stops the benchmark timer.
* @param benchmark The fossil_mark_t object to stop.
*/
FOSSIL_MAIP_API void fossil_benchmark_stop(fossil_mark_t* benchmark);
/**
* @brief Returns the total elapsed time in seconds.
* @param benchmark The fossil_mark_t object to get the elapsed time from.
* @return The total elapsed time in seconds.
*/
FOSSIL_MAIP_API double fossil_benchmark_elapsed_seconds(const fossil_mark_t* benchmark);
/**
* @brief Returns the minimum elapsed time in seconds.
* @param benchmark The fossil_mark_t object to get the minimum time from.
* @return The minimum elapsed time in seconds.
*/
FOSSIL_MAIP_API double fossil_benchmark_min_time(const fossil_mark_t* benchmark);
/**
* @brief Returns the maximum elapsed time in seconds.
* @param benchmark The fossil_mark_t object to get the maximum time from.
* @return The maximum elapsed time in seconds.
*/
FOSSIL_MAIP_API double fossil_benchmark_max_time(const fossil_mark_t* benchmark);
/**
* @brief Returns the average elapsed time in seconds.
* @param benchmark The fossil_mark_t object to get the average time from.
* @return The average elapsed time in seconds.
*/
FOSSIL_MAIP_API double fossil_benchmark_avg_time(const fossil_mark_t* benchmark);
/**
* @brief Resets the benchmark statistics.
* @param benchmark The fossil_mark_t object to reset.
*/
FOSSIL_MAIP_API void fossil_benchmark_reset(fossil_mark_t* benchmark);
/**
* @brief Prints a report of the benchmark statistics.
* @param benchmark The fossil_mark_t object to report.
*/
FOSSIL_MAIP_API void fossil_benchmark_report(const fossil_mark_t* benchmark);
typedef struct {
fossil_mark_t* benchmark;
} fossil_scoped_mark_t;
/**
* @brief Initializes a fossil_scoped_mark_t object with the given benchmark.
* @param scoped_benchmark The fossil_scoped_mark_t object to initialize.
* @param benchmark The benchmark to be scoped.
*/
FOSSIL_MAIP_API void fossil_scoped_benchmark_init(fossil_scoped_mark_t* scoped_benchmark, fossil_mark_t* benchmark);
/**
* @brief Destroys a fossil_scoped_mark_t object.
* @param scoped_benchmark The fossil_scoped_mark_t object to destroy.
*/
FOSSIL_MAIP_API void fossil_scoped_benchmark_destroy(fossil_scoped_mark_t* scoped_benchmark);
/**
* Function to test benchmark with specified duration type, expected value, and actual value.
*
* @param duration_type The duration type to test.
* @param expected The expected value.
* @param actual The actual value.
*/
FOSSIL_MAIP_API void fossil_test_benchmark(char* duration_type, double expected, double actual);
/**
* Function to start the benchmark.
*/
FOSSIL_MAIP_API void fossil_test_start_benchmark(void);
/**
* Function to stop the benchmark and return the elapsed time in nanoseconds.
*
* @return The elapsed time in nanoseconds.
*/
FOSSIL_MAIP_API uint64_t fossil_test_stop_benchmark(void);
// *****************************************************************************
// Macro definitions
// *****************************************************************************
/**
* @brief Define macro for marking a benchmark.
*
* This macro is used to mark a benchmark with a given name. It initializes
* the benchmark structure and sets the name of the benchmark.
*
* @param name The name of the benchmark.
*/
#define _MARK_BENCHMARK(name) \
fossil_mark_t benchmark_##name; \
fossil_benchmark_init(&benchmark_##name, #name)
/**
* @brief Define macro for starting a benchmark.
*
* This macro is used to start a benchmark with a given name. It starts the
* timer for the benchmark.
*
* @param name The name of the benchmark.
*/
#define _MARK_START(name) \
fossil_benchmark_start(&benchmark_##name)
/**
* @brief Define macro for stopping a benchmark.
*
* This macro is used to stop a benchmark with a given name. It stops the
* timer for the benchmark.
*
* @param name The name of the benchmark.
*/
#define _MARK_STOP(name) \
fossil_benchmark_stop(&benchmark_##name)
/**
* @brief Define macro for reporting a benchmark.
*
* This macro is used to report the results of a benchmark with a given name.
* It prints the benchmark name and the elapsed time.
*
* @param name The name of the benchmark.
*/
#define _MARK_REPORT(name) \
fossil_benchmark_report(&benchmark_##name)
/**
* @brief Define macro for scoped benchmarking.
*
* This macro is used to create a scoped benchmark with a given name. It
* initializes the scoped benchmark structure and sets the benchmark to be
* used.
*
* @param name The name of the benchmark.
*/
#define _MARK_SCOPED(name) \
fossil_scoped_mark_t scoped_benchmark_##name; \
fossil_scoped_benchmark_init(&scoped_benchmark_##name, &benchmark_##name)
// =================================================================
// Bench specific commands
// =================================================================
/**
* @brief Define macro for starting a benchmark.
*
* This macro is used to mark the start of a benchmark. It typically initializes
* any necessary resources or variables required for benchmarking.
*/
#define _TEST_BENCHMARK() fossil_test_start_benchmark()
/**
* @brief Define macro for getting the current time.
*
* This macro is used to retrieve the current time, which is typically used
* in conjunction with TEST_BENCHMARK to calculate the elapsed time for a benchmark.
*/
#define _TEST_CURRENT_TIME() fossil_test_stop_benchmark()
/**
* @brief Define macro for reporting test duration with a given timeout.
*
* This macro is used to report the duration of a test with a given timeout.
* It takes the timeout duration, elapsed time, and actual duration as arguments
* and reports the results, typically in the form of logs or console output.
*
* @param duration The duration unit (e.g., "minutes", "seconds").
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define _TEST_DURATION(duration, elapsed, actual) fossil_test_benchmark((char*)duration, elapsed, actual)
/**
* @brief Define macro for reporting test duration in minutes.
*
* This macro is a shorthand for reporting test duration in minutes using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in minutes.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define _TEST_DURATION_MIN(elapsed, actual) _TEST_DURATION((char*)"minutes", elapsed, actual)
/**
* @brief Define macro for reporting test duration in seconds.
*
* This macro is a shorthand for reporting test duration in seconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in seconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define _TEST_DURATION_SEC(elapsed, actual) _TEST_DURATION((char*)"seconds", elapsed, actual)
/**
* @brief Define macro for reporting test duration in milliseconds.
*
* This macro is a shorthand for reporting test duration in milliseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in milliseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define _TEST_DURATION_MIL(elapsed, actual) _TEST_DURATION((char*)"milliseconds", elapsed, actual)
/**
* @brief Define macro for reporting test duration in microseconds.
*
* This macro is a shorthand for reporting test duration in microseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in microseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define _TEST_DURATION_MIC(elapsed, actual) _TEST_DURATION((char*)"microseconds", elapsed, actual)
/**
* @brief Define macro for reporting test duration in nanoseconds.
*
* This macro is a shorthand for reporting test duration in nanoseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in nanoseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define _TEST_DURATION_NAN(elapsed, actual) _TEST_DURATION((char*)"nanoseconds", elapsed, actual)
/**
* @brief Define macro for reporting test duration in picoseconds.
*
* This macro is a shorthand for reporting test duration in picoseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in picoseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define _TEST_DURATION_PIC(elapsed, actual) _TEST_DURATION((char*)"picoseconds", elapsed, actual)
/**
* @brief Define macro for reporting test duration in femtoseconds.
*
* This macro is a shorthand for reporting test duration in femtoseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in femtoseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define _TEST_DURATION_FEM(elapsed, actual) _TEST_DURATION((char*)"femtoseconds", elapsed, actual)
/**
* @brief Define macro for reporting test duration in attoseconds.
*
* This macro is a shorthand for reporting test duration in attoseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in attoseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define _TEST_DURATION_ATT(elapsed, actual) _TEST_DURATION((char*)"attoseconds", elapsed, actual)
/**
* @brief Define macro for reporting test duration in zeptoseconds.
*
* This macro is a shorthand for reporting test duration in zeptoseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in zeptoseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define _TEST_DURATION_ZEP(elapsed, actual) _TEST_DURATION((char*)"zeptoseconds", elapsed, actual)
/**
* @brief Define macro for reporting test duration in yoctoseconds.
*
* This macro is a shorthand for reporting test duration in yoctoseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in yoctoseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define _TEST_DURATION_YOC(elapsed, actual) _TEST_DURATION((char*)"yoctoseconds", elapsed, actual)
// *****************************************************************************
// Public API Macros
// *****************************************************************************
/**
* @brief Define macro for marking a benchmark.
*
* This macro is used to mark a benchmark with a given name. It initializes
* the benchmark structure and sets the name of the benchmark.
*
* @param name The name of the benchmark.
*/
#define MARK_BENCHMARK(name) \
_MARK_BENCHMARK(name)
/**
* @brief Define macro for starting a benchmark.
*
* This macro is used to start a benchmark with a given name. It starts the
* timer for the benchmark.
*
* @param name The name of the benchmark.
*/
#define MARK_START(name) \
_MARK_START(name)
/**
* @brief Define macro for stopping a benchmark.
*
* This macro is used to stop a benchmark with a given name. It stops the
* timer for the benchmark.
*
* @param name The name of the benchmark.
*/
#define MARK_STOP(name) \
_MARK_STOP(name)
/**
* @brief Define macro for reporting a benchmark.
*
* This macro is used to report the results of a benchmark with a given name.
* It prints the benchmark name and the elapsed time.
*
* @param name The name of the benchmark.
*/
#define MARK_REPORT(name) \
_MARK_REPORT(name)
/**
* @brief Define macro for scoped benchmarking.
*
* This macro is used to create a scoped benchmark with a given name. It
* initializes the scoped benchmark structure and sets the benchmark to be
* used.
*
* @param name The name of the benchmark.
*/
#define MARK_SCOPED(name) \
_MARK_SCOPED(name)
// =================================================================
// Bench specific commands
// =================================================================
/**
* @brief Define macro for starting a benchmark.
*
* This macro is used to mark the start of a benchmark. It typically initializes
* any necessary resources or variables required for benchmarking.
*/
#define TEST_BENCHMARK() \
_TEST_BENCHMARK()
/**
* @brief Define macro for getting the current time.
*
* This macro is used to retrieve the current time, which is typically used
* in conjunction with TEST_BENCHMARK to calculate the elapsed time for a benchmark.
*/
#define TEST_CURRENT_TIME() \
_TEST_CURRENT_TIME()
/**
* @brief Define macro for reporting test duration with a given timeout.
*
* This macro is used to report the duration of a test with a given timeout.
* It takes the timeout duration, elapsed time, and actual duration as arguments
* and reports the results, typically in the form of logs or console output.
*
* @param duration The duration unit (e.g., "minutes", "seconds").
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define TEST_DURATION(duration, elapsed, actual) \
_TEST_DURATION(duration, elapsed, actual)
/**
* @brief Define macro for reporting test duration in minutes.
*
* This macro is a shorthand for reporting test duration in minutes using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in minutes.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define TEST_DURATION_MIN(elapsed, actual) \
_TEST_DURATION_MIN(elapsed, actual)
/**
* @brief Define macro for reporting test duration in seconds.
*
* This macro is a shorthand for reporting test duration in seconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in seconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define TEST_DURATION_SEC(elapsed, actual) \
_TEST_DURATION_SEC(elapsed, actual)
/**
* @brief Define macro for reporting test duration in milliseconds.
*
* This macro is a shorthand for reporting test duration in milliseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in milliseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define TEST_DURATION_MIL(elapsed, actual) \
_TEST_DURATION_MIL(elapsed, actual)
/**
* @brief Define macro for reporting test duration in microseconds.
*
* This macro is a shorthand for reporting test duration in microseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in microseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define TEST_DURATION_MIC(elapsed, actual) \
_TEST_DURATION_MIC(elapsed, actual)
/**
* @brief Define macro for reporting test duration in nanoseconds.
*
* This macro is a shorthand for reporting test duration in nanoseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in nanoseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define TEST_DURATION_NAN(elapsed, actual) \
_TEST_DURATION_NAN(elapsed, actual)
/**
* @brief Define macro for reporting test duration in picoseconds.
*
* This macro is a shorthand for reporting test duration in picoseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in picoseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define TEST_DURATION_PIC(elapsed, actual) \
_TEST_DURATION_PIC(elapsed, actual)
/**
* @brief Define macro for reporting test duration in femtoseconds.
*
* This macro is a shorthand for reporting test duration in femtoseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in femtoseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define TEST_DURATION_FEM(elapsed, actual) \
_TEST_DURATION_FEM(elapsed, actual)
/**
* @brief Define macro for reporting test duration in attoseconds.
*
* This macro is a shorthand for reporting test duration in attoseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in attoseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define TEST_DURATION_ATT(elapsed, actual) \
_TEST_DURATION_ATT(elapsed, actual)
/**
* @brief Define macro for reporting test duration in zeptoseconds.
*
* This macro is a shorthand for reporting test duration in zeptoseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in zeptoseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define TEST_DURATION_ZEP(elapsed, actual) \
_TEST_DURATION_ZEP(elapsed, actual)
/**
* @brief Define macro for reporting test duration in yoctoseconds.
*
* This macro is a shorthand for reporting test duration in yoctoseconds using TEST_DURATION.
* It takes the elapsed time and actual duration as arguments and reports the results
* in yoctoseconds.
*
* @param elapsed The elapsed time since the benchmark started.
* @param actual The actual duration of the test.
*/
#define TEST_DURATION_YOC(elapsed, actual) \
_TEST_DURATION_YOC(elapsed, actual)
#ifdef __cplusplus
}
#endifC SAMPLE #
#include "fossil/maip/framework.h"
// * * * * * * * * * * * * * * * * * * * * * * * *
// * Fossil Logic Test Utilites
// * * * * * * * * * * * * * * * * * * * * * * * *
// Setup steps for things like test fixtures and
// mock objects are set here.
// * * * * * * * * * * * * * * * * * * * * * * * *
// Define the test suite and add test cases
FOSSIL_SUITE(c_mark_suite);
// Setup function for the test suite
FOSSIL_SETUP(c_mark_suite) {
// Setup code here
}
// Teardown function for the test suite
FOSSIL_TEARDOWN(c_mark_suite) {
// Teardown code here
}
// * * * * * * * * * * * * * * * * * * * * * * * *
// * Fossil Logic Test Cases
// * * * * * * * * * * * * * * * * * * * * * * * *
// The test cases below are provided as samples, inspired
// by the Meson build system's approach of using test cases
// as samples for library usage.
// * * * * * * * * * * * * * * * * * * * * * * * *
// A test case to check if the benchmark stop works correctly
FOSSIL_TEST(c_mark_start_and_stop) {
MARK_BENCHMARK(stop_test);
MARK_START(stop_test);
MARK_STOP(stop_test);
ASSUME_ITS_EQUAL_CSTR(benchmark_stop_test.name, "stop_test");
}
// Test case for MARK_BENCHMARK
FOSSIL_TEST(c_mark_benchmark) {
MARK_BENCHMARK(test_benchmark);
ASSUME_ITS_EQUAL_CSTR(benchmark_test_benchmark.name, "test_benchmark");
}
// Test case for MARK_START
FOSSIL_TEST(c_mark_start) {
MARK_BENCHMARK(start_test);
MARK_START(start_test);
ASSUME_ITS_TRUE(benchmark_start_test.running);
}
// Test case for MARK_STOP
FOSSIL_TEST(c_mark_stop) {
MARK_BENCHMARK(stop_test);
MARK_START(stop_test);
MARK_STOP(stop_test);
ASSUME_ITS_FALSE(benchmark_stop_test.running);
}
// Test case for MARK_BENCHMARK with multiple benchmarks
FOSSIL_TEST(c_mark_multiple_benchmarks) {
MARK_BENCHMARK(benchmark1);
MARK_BENCHMARK(benchmark2);
ASSUME_ITS_EQUAL_CSTR(benchmark_benchmark1.name, "benchmark1");
ASSUME_ITS_EQUAL_CSTR(benchmark_benchmark2.name, "benchmark2");
}
// Test case for MARK_BENCHMARK with invalid name
FOSSIL_TEST(c_mark_invalid_benchmark_name) {
MARK_BENCHMARK(null_benchmark);
ASSUME_NOT_CNULL(benchmark_null_benchmark.name);
}
// Test case for MARK_STOP without MARK_START
FOSSIL_TEST(c_mark_stop_without_start) {
MARK_BENCHMARK(stop_without_start);
MARK_STOP(stop_without_start);
ASSUME_ITS_FALSE(benchmark_stop_without_start.running);
}
// Test case for MARK_BENCHMARK with nested benchmarks
FOSSIL_TEST(c_mark_nested_benchmarks) {
MARK_BENCHMARK(outer_benchmark);
MARK_START(outer_benchmark);
MARK_BENCHMARK(inner_benchmark);
MARK_START(inner_benchmark);
MARK_STOP(inner_benchmark);
MARK_STOP(outer_benchmark);
ASSUME_ITS_TRUE(benchmark_outer_benchmark.total_duration >= benchmark_inner_benchmark.total_duration);
}
// Test case for resetting a benchmark
FOSSIL_TEST(c_mark_reset_benchmark) {
MARK_BENCHMARK(reset_test);
MARK_START(reset_test);
MARK_STOP(reset_test);
fossil_benchmark_reset(&benchmark_reset_test);
ASSUME_ITS_EQUAL_I32(benchmark_reset_test.total_duration, 0.0);
ASSUME_ITS_EQUAL_I32(benchmark_reset_test.num_samples, 0);
}
// * * * * * * * * * * * * * * * * * * * * * * * *
// * Fossil Logic Test Pool
// * * * * * * * * * * * * * * * * * * * * * * * *
FOSSIL_TEST_GROUP(c_mark_test_cases) {
FOSSIL_ADD_TEST(c_mark_suite, c_mark_start_and_stop);
FOSSIL_ADD_TEST(c_mark_suite, c_mark_benchmark);
FOSSIL_ADD_TEST(c_mark_suite, c_mark_start);
FOSSIL_ADD_TEST(c_mark_suite, c_mark_stop);
FOSSIL_ADD_TEST(c_mark_suite, c_mark_multiple_benchmarks);
FOSSIL_ADD_TEST(c_mark_suite, c_mark_invalid_benchmark_name);
FOSSIL_ADD_TEST(c_mark_suite, c_mark_stop_without_start);
FOSSIL_ADD_TEST(c_mark_suite, c_mark_nested_benchmarks);
FOSSIL_ADD_TEST(c_mark_suite, c_mark_reset_benchmark);
FOSSIL_ADD_SUITE(c_mark_suite);
}C++ SAMPLE #
#include "fossil/maip/framework.h"
// * * * * * * * * * * * * * * * * * * * * * * * *
// * Fossil Logic Test Utilites
// * * * * * * * * * * * * * * * * * * * * * * * *
// Setup steps for things like test fixtures and
// mock objects are set here.
// * * * * * * * * * * * * * * * * * * * * * * * *
// Define the test suite and add test cases
FOSSIL_SUITE(cpp_mark_suite);
// Setup function for the test suite
FOSSIL_SETUP(cpp_mark_suite) {
// Setup code here
}
// Teardown function for the test suite
FOSSIL_TEARDOWN(cpp_mark_suite) {
// Teardown code here
}
// * * * * * * * * * * * * * * * * * * * * * * * *
// * Fossil Logic Test Cases
// * * * * * * * * * * * * * * * * * * * * * * * *
// The test cases below are provided as samples, inspired
// by the Meson build system's approach of using test cases
// as samples for library usage.
// * * * * * * * * * * * * * * * * * * * * * * * *
// A test case to check if the benchmark stop works correctly
FOSSIL_TEST(cpp_mark_start_and_stop) {
MARK_BENCHMARK(stop_test);
MARK_START(stop_test);
MARK_STOP(stop_test);
ASSUME_ITS_EQUAL_CSTR(benchmark_stop_test.name, "stop_test");
}
// Test case for MARK_BENCHMARK
FOSSIL_TEST(cpp_mark_benchmark) {
MARK_BENCHMARK(test_benchmark);
ASSUME_ITS_EQUAL_CSTR(benchmark_test_benchmark.name, "test_benchmark");
}
// Test case for MARK_START
FOSSIL_TEST(cpp_mark_start) {
MARK_BENCHMARK(start_test);
MARK_START(start_test);
ASSUME_ITS_TRUE(benchmark_start_test.running);
}
// Test case for MARK_STOP
FOSSIL_TEST(cpp_mark_stop) {
MARK_BENCHMARK(stop_test);
MARK_START(stop_test);
MARK_STOP(stop_test);
ASSUME_ITS_FALSE(benchmark_stop_test.running);
}
// Test case for MARK_BENCHMARK with multiple benchmarks
FOSSIL_TEST(cpp_mark_multiple_benchmarks) {
MARK_BENCHMARK(benchmark1);
MARK_BENCHMARK(benchmark2);
ASSUME_ITS_EQUAL_CSTR(benchmark_benchmark1.name, "benchmark1");
ASSUME_ITS_EQUAL_CSTR(benchmark_benchmark2.name, "benchmark2");
}
// Test case for MARK_BENCHMARK with invalid name
FOSSIL_TEST(cpp_mark_invalid_benchmark_name) {
MARK_BENCHMARK(null_benchmark);
ASSUME_NOT_CNULL(benchmark_null_benchmark.name);
}
// Test case for MARK_STOP without MARK_START
FOSSIL_TEST(cpp_mark_stop_without_start) {
MARK_BENCHMARK(stop_without_start);
MARK_STOP(stop_without_start);
ASSUME_ITS_FALSE(benchmark_stop_without_start.running);
}
// Test case for MARK_BENCHMARK with nested benchmarks
FOSSIL_TEST(cpp_mark_nested_benchmarks) {
MARK_BENCHMARK(outer_benchmark);
MARK_START(outer_benchmark);
MARK_BENCHMARK(inner_benchmark);
MARK_START(inner_benchmark);
MARK_STOP(inner_benchmark);
MARK_STOP(outer_benchmark);
ASSUME_ITS_TRUE(benchmark_outer_benchmark.total_duration >= benchmark_inner_benchmark.total_duration);
}
// Test case for resetting a benchmark
FOSSIL_TEST(cpp_mark_reset_benchmark) {
MARK_BENCHMARK(reset_test);
MARK_START(reset_test);
MARK_STOP(reset_test);
fossil_benchmark_reset(&benchmark_reset_test);
ASSUME_ITS_EQUAL_I32(benchmark_reset_test.total_duration, 0.0);
ASSUME_ITS_EQUAL_I32(benchmark_reset_test.num_samples, 0);
}
// * * * * * * * * * * * * * * * * * * * * * * * *
// * Fossil Logic Test Pool
// * * * * * * * * * * * * * * * * * * * * * * * *
FOSSIL_TEST_GROUP(cpp_mark_test_cases) {
FOSSIL_ADD_TEST(cpp_mark_suite, cpp_mark_start_and_stop);
FOSSIL_ADD_TEST(cpp_mark_suite, cpp_mark_benchmark);
FOSSIL_ADD_TEST(cpp_mark_suite, cpp_mark_start);
FOSSIL_ADD_TEST(cpp_mark_suite, cpp_mark_stop);
FOSSIL_ADD_TEST(cpp_mark_suite, cpp_mark_multiple_benchmarks);
FOSSIL_ADD_TEST(cpp_mark_suite, cpp_mark_invalid_benchmark_name);
FOSSIL_ADD_TEST(cpp_mark_suite, cpp_mark_stop_without_start);
FOSSIL_ADD_TEST(cpp_mark_suite, cpp_mark_nested_benchmarks);
FOSSIL_ADD_TEST(cpp_mark_suite, cpp_mark_reset_benchmark);
FOSSIL_ADD_SUITE(cpp_mark_suite);
}