* SPDX-License-Identifier: MIT
* Copyright (c) Huawei Technologies Co., Ltd. 2025-2026. All rights reserved.
* Description: URMA util and clock unit tests.
*/
#include "common_fixture.h"
using namespace urma_test_common;
TEST(UrmaCommonTest, UtilBitSearchCoversSetAndZeroPaths)
{
unsigned long bits[3] = {};
EXPECT_EQ(0U, ub_find_first_bit(bits, 0));
EXPECT_EQ(130U, ub_find_first_bit(bits, 130));
EXPECT_EQ(0U, ub_find_first_zero_bit(bits, 130));
EXPECT_EQ(130U, ub_find_next_bit(bits, 130, 130));
bits[0] = ~0UL;
bits[1] = 0;
bits[2] = 1UL << 1;
EXPECT_EQ(64U, ub_find_first_zero_bit(bits, 130));
EXPECT_EQ(0U, ub_find_first_bit(bits, 130));
EXPECT_EQ(129U, ub_find_next_bit(bits, 130, 64));
EXPECT_EQ(65U, ub_find_next_zero_bit(bits, 130, 65));
bits[1] = ~0UL;
bits[2] = ~0UL;
EXPECT_EQ(130U, ub_find_first_zero_bit(bits, 130));
EXPECT_EQ(130U, ub_find_next_zero_bit(bits, 130, 130));
}
TEST(UrmaCommonTest, UtilLargeMemAndHugePageBoundaries)
{
uint8_t dst[8] = {};
uint8_t src[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
EXPECT_EQ(0, memset_s_large_buf(dst, sizeof(dst), 0xab, 4));
EXPECT_EQ(0xab, dst[0]);
EXPECT_EQ(0xab, dst[3]);
EXPECT_EQ(0, memset_s_large_buf(dst, sizeof(dst), 0, 0));
EXPECT_EQ(0, memcpy_s_large_buf(dst, sizeof(dst), src, sizeof(src)));
EXPECT_EQ(0, std::memcmp(dst, src, sizeof(src)));
EXPECT_EQ(0, memcpy_s_large_buf(dst, sizeof(dst), src, 0));
EXPECT_EQ(nullptr, ub_hugemalloc(0, UB_HUGE_PAGE_SIZE_ANY, nullptr));
EXPECT_EQ(-EINVAL, ub_hugefree(nullptr, 4096));
}
TEST(UrmaCommonTest, UtilStringConversionsAcceptValidAndRejectInvalid)
{
bool boolValue = false;
uint8_t u8 = 0;
uint16_t u16 = 0;
uint32_t u32 = 0;
uint64_t u64 = 0;
int intValue = 0;
EXPECT_EQ(0, ub_str_to_bool("true", &boolValue));
EXPECT_TRUE(boolValue);
EXPECT_EQ(0, ub_str_to_bool("false", &boolValue));
EXPECT_FALSE(boolValue);
EXPECT_EQ(-EINVAL, ub_str_to_bool(nullptr, &boolValue));
EXPECT_EQ(-EINVAL, ub_str_to_bool("", &boolValue));
EXPECT_EQ(-EINVAL, ub_str_to_bool("yes", &boolValue));
EXPECT_EQ(0, ub_str_to_u8("255", &u8));
EXPECT_EQ(255U, u8);
EXPECT_EQ(-EINVAL, ub_str_to_u8(nullptr, &u8));
EXPECT_EQ(-EINVAL, ub_str_to_u8("-1", &u8));
EXPECT_EQ(-ENOEXEC, ub_str_to_u8("12x", &u8));
EXPECT_EQ(-ERANGE, ub_str_to_u8("256", &u8));
EXPECT_EQ(0, ub_str_to_u16("65535", &u16));
EXPECT_EQ(65535U, u16);
EXPECT_EQ(-ERANGE, ub_str_to_u16("65536", &u16));
EXPECT_EQ(-ENOEXEC, ub_str_to_u16("x", &u16));
EXPECT_EQ(0, ub_str_to_u32("4294967295", &u32));
EXPECT_EQ(UINT_MAX, u32);
EXPECT_EQ(-ERANGE, ub_str_to_u32("4294967296", &u32));
EXPECT_EQ(-ENOEXEC, ub_str_to_u32("x", &u32));
EXPECT_EQ(0, ub_str_to_u64("18446744073709551615", &u64));
EXPECT_EQ(UINT64_MAX, u64);
EXPECT_EQ(-EINVAL, ub_str_to_u64("-1", &u64));
EXPECT_EQ(-ENOEXEC, ub_str_to_u64("x", &u64));
EXPECT_EQ(0, ub_str_to_int("-12", &intValue));
EXPECT_EQ(-12, intValue);
EXPECT_EQ(-EINVAL, ub_str_to_int(nullptr, &intValue));
EXPECT_EQ(-ENOEXEC, ub_str_to_int("1x", &intValue));
EXPECT_EQ(-ERANGE, ub_str_to_int("2147483648", &intValue));
}
TEST(UrmaCommonTest, ClockAndErrorHelpersReturnStableValues)
{
ResetCommonWrap();
g_commonWrap.failCalloc = true;
g_commonWrap.cpuInfo = "cpu MHz : 2400.000\n";
uint64_t firstCycles = get_cycles();
uint64_t secondCycles = get_cycles();
const char *knownError = ub_strerror(EINVAL);
double cpuMhz = get_cpu_mhz(false);
EXPECT_GE(secondCycles, firstCycles);
ASSERT_NE(nullptr, knownError);
EXPECT_GT(std::strlen(knownError), 0U);
EXPECT_DOUBLE_EQ(2400.000, cpuMhz);
}
TEST(UrmaCommonTest, ClockFallsBackToProcWhenSamplingFails)
{
ResetCommonWrap();
g_commonWrap.failCalloc = true;
g_commonWrap.cpuInfo = "processor : 0\ncpu MHz : 2100.500\n";
EXPECT_DOUBLE_EQ(2100.500, get_cpu_mhz(false));
}
TEST(UrmaCommonTest, ClockUsesSampleWhenProcInfoIsUnavailable)
{
ResetCommonWrap();
g_commonWrap.cpuInfo = nullptr;
EXPECT_GT(get_cpu_mhz(false), 0.0);
}
TEST(UrmaCommonTest, ClockReturnsZeroWhenSamplingAndProcAreUnavailable)
{
ResetCommonWrap();
g_commonWrap.failFirstGettimeofday = true;
g_commonWrap.cpuInfo = nullptr;
EXPECT_DOUBLE_EQ(0.0, get_cpu_mhz(false));
}
TEST(UrmaCommonTest, ClockHandlesGettimeofdayAndCpuFrequencyMismatch)
{
ResetCommonWrap();
g_commonWrap.failSecondGettimeofday = true;
g_commonWrap.cpuInfo = "cpu MHz : 2000.000\ncpu MHz : 2500.000\n";
EXPECT_DOUBLE_EQ(2000.000, get_cpu_mhz(true));
}