blob: 3cbab2111c66b779211cda1bfc83353592bbf4f2 [file] [log] [blame]
// Copyright CHERIoT Contributors.
// SPDX-License-Identifier: MIT
#define TEST_NAME "Test misc APIs"
#include "tests.hh"
#include <ds/pointer.h>
#include <string.h>
#include <timeout.h>
/**
* Test timeouts.
*
* This test checks the following:
*
* - A timeout of zero would not block.
* - `elapse` saturates values, i.e., a `remaining` value of zero will still be
* zero after a call to `elapse`, and an `elapsed` value of `UINT32_MAX`
* would still be `UINT32_MAX` after a call to `elapse`.
* - An unlimited timeout is really unlimited, i.e., a call to `elapse` does
* not modify its `remaining` value, which blocks.
*/
void check_timeouts()
{
debug_log("Test timeouts.");
// Create a zero timeout.
Timeout t{0};
// Ensure that a zero timeout does not block.
TEST(!t.may_block(), "A zero timeout should not block.");
// Create a zero timer with maximum elapsed time.
t = Timeout{UINT32_MAX /* elapsed */, 0 /* remaining */};
// Ensure that a call to `elapse` saturates both `elapsed` and
// `remaining`.
t.elapse(42);
TEST(t.remaining == 0,
"`elapse` does not saturate the `remaining` value of a zero timer.");
TEST(t.elapsed == UINT32_MAX,
"`elapse` does not saturate the `elapsed` value of a zero timer.");
// Create an unlimited timeout.
t = Timeout{UnlimitedTimeout /* remaining */};
// Ensure that a call to `elapse` does not modify the `remaining` value
// of the unlimited timeout.
t.elapse(42);
TEST(t.remaining == UnlimitedTimeout,
"`elapse` alters the remaining value of an unlimited timeout.");
// Ensure that an unlimited timeout blocks.
TEST(t.may_block(), "An unlimited timeout should block.");
}
/**
* Test memchr.
*
* This test checks the following:
*
* - memchr finds the first occurrence of the character when it is present
* (test for different values, particularly the first and the last one).
* - memchr returns NULL when the string does not contain the character (test
* for non-NULL terminated string).
* - memchr does not stop at \0 characters.
* - memchr returns NULL for 0-size pointers.
*/
void check_memchr()
{
debug_log("Test memchr.");
char string[] = {'C', 'H', 'E', 'R', 'R', 'I', 'E', 'S'};
TEST(memchr(string, 'C', sizeof(string)) == &string[0],
"memchr must return the first occurence of the character.");
TEST(memchr(string, 'R', sizeof(string)) == &string[3],
"memchr must return the first occurence of the character.");
TEST(memchr(string, 'S', sizeof(string)) == &string[7],
"memchr must return the first occurence of the character.");
TEST(memchr(string, 'X', sizeof(string)) == NULL,
"memchr must return NULL when a character is not present.");
char stringWithNull[] = {'Y', 'E', 'S', '\0', 'N', 'O', '\0'};
TEST(memchr(stringWithNull, 'N', sizeof(stringWithNull)) ==
&stringWithNull[4],
"memchr must not stop at NULL characters.");
TEST(memchr(stringWithNull, 'N', 0) == NULL,
"memchr must return NULL for zero-size pointers.");
}
/**
* Test pointer utilities.
*
* Not comprehensive, would benefit from being expanded at some point.
*/
void check_pointer_utilities()
{
debug_log("Test pointer utilities.");
int integer = 42;
int *integerPointer = &integer;
ds::pointer::proxy::Pointer<int> pointer{integerPointer};
TEST((pointer == integerPointer) && (*pointer == 42),
"The pointer proxy does not return the value of its proxy.");
int anotherInteger = -100;
int *anotherIntegerPointer = &anotherInteger;
ds::pointer::proxy::Pointer<int> anotherPointer{anotherIntegerPointer};
pointer = anotherPointer;
TEST((pointer == anotherIntegerPointer) && (*pointer == -100),
"The pointer proxy `=` operator does not correctly set the pointer.");
}
void test_misc()
{
check_timeouts();
check_memchr();
check_pointer_utilities();
}