130 lines
3.9 KiB
C
130 lines
3.9 KiB
C
#include "c_Random.h"
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "c_Test.h"
|
|
|
|
TEST_CASE(test_c_Random_RangeU64_Bounds) {
|
|
// 设置随机数种子以保证单次测试的稳定性
|
|
srand(12345);
|
|
|
|
uint64_t min = 10;
|
|
uint64_t max = 20;
|
|
|
|
// 1. 验证大量生成时,所有数字绝不越出 [10, 20] 边界
|
|
for (int i = 0; i < 1000; i++) {
|
|
uint64_t val = c_Random_RangeU64(min, max);
|
|
ASSERT_TRUE(val >= min);
|
|
ASSERT_TRUE(val <= max);
|
|
}
|
|
|
|
// 2. 逆序边界防御测试
|
|
ASSERT_LL_EQ(50, c_Random_RangeU64(50, 10));
|
|
ASSERT_LL_EQ(30, c_Random_RangeU64(30, 30));
|
|
}
|
|
|
|
TEST_CASE(test_c_Random_RangeI64_Negative) {
|
|
int64_t min = -50;
|
|
int64_t max = -10;
|
|
|
|
// 3. 验证包含负数区间的生成矩阵安全性
|
|
for (int i = 0; i < 1000; i++) {
|
|
int64_t val = c_Random_RangeI64(min, max);
|
|
ASSERT_TRUE(val >= min);
|
|
ASSERT_TRUE(val <= max);
|
|
}
|
|
|
|
// 跨越 0 的区间测试
|
|
int64_t cross_min = -5;
|
|
int64_t cross_max = 5;
|
|
bool hit_negative = false;
|
|
bool hit_positive = false;
|
|
|
|
for (int i = 0; i < 500; i++) {
|
|
int64_t val = c_Random_RangeI64(cross_min, cross_max);
|
|
ASSERT_TRUE(val >= cross_min && val <= cross_max);
|
|
if (val < 0) hit_negative = true;
|
|
if (val > 0) hit_positive = true;
|
|
}
|
|
// 统计学判定:生成500次,正数和负数应该都有几率被命中
|
|
ASSERT_TRUE(hit_negative && hit_positive);
|
|
}
|
|
|
|
TEST_CASE(test_c_Random_RangeDouble_Distribution) {
|
|
double min = 1.5;
|
|
double max = 2.5;
|
|
|
|
// 4. 验证浮点数边界安全性
|
|
for (int i = 0; i < 1000; i++) {
|
|
double val = c_Random_RangeDouble(min, max);
|
|
ASSERT_TRUE(val >= min);
|
|
ASSERT_TRUE(val < max); // 浮点通常为左闭右开区间
|
|
}
|
|
}
|
|
|
|
TEST_CASE(test_c_Random_ModuloBias_Elimination) {
|
|
// 5. 验证极小范围下的去偏效果,频繁抽取测试是否出现死循环
|
|
uint64_t small_min = 0;
|
|
uint64_t small_max = 1; // 仅生成 0 或 1
|
|
|
|
int count_0 = 0;
|
|
int count_1 = 0;
|
|
|
|
for (int i = 0; i < 2000; i++) {
|
|
uint64_t val = c_Random_RangeU64(small_min, small_max);
|
|
if (val == 0) count_0++;
|
|
if (val == 1) count_1++;
|
|
}
|
|
|
|
ASSERT_TRUE(count_0 > 0);
|
|
ASSERT_TRUE(count_1 > 0);
|
|
// 2000次抽取中,在去偏机制下,0和1的频次应当大致平分秋色(此处做宽泛判定确保随机性生效)
|
|
ASSERT_TRUE(abs(count_0 - count_1) < 400);
|
|
}
|
|
|
|
TEST_CASE(test_c_Random_Init_EntropyBreak) {
|
|
// 1. 验证初始化函数可以正常被重复安全执行,不引发任何异常或崩溃
|
|
c_Random_Init();
|
|
uint64_t first_rand = c_Random_RangeU64(1, 1000000);
|
|
|
|
// 2. 连续快速进行二次初始化(模拟极高频率的重新播种)
|
|
c_Random_Init();
|
|
uint64_t second_rand = c_Random_RangeU64(1, 1000000);
|
|
|
|
// 在高精度混合熵的保障下,这两次连续抽出的百万级别随机数在统计学上几乎不可能相等
|
|
// (如果使用了差劲的普通 time(NULL) 播种,它们必然相等,因为处于同一秒内)
|
|
ASSERT_TRUE(first_rand != second_rand);
|
|
}
|
|
|
|
TEST_CASE(test_c_Random_Init_Stability) {
|
|
// 3. 验证初始化后生成的随机数仍在预期范围内
|
|
c_Random_Init();
|
|
|
|
uint64_t min_val = 5;
|
|
uint64_t max_val = 15;
|
|
|
|
for (int i = 0; i < 50; i++) {
|
|
uint64_t val = c_Random_RangeU64(min_val, max_val);
|
|
ASSERT_TRUE(val >= min_val);
|
|
ASSERT_TRUE(val <= max_val);
|
|
}
|
|
}
|
|
|
|
|
|
int main(int argc, char** argv){
|
|
|
|
TEST_START(Unit Tests);
|
|
|
|
// 运行普通无环境要求的用例
|
|
RUN_TEST(test_c_Random_Init_EntropyBreak);
|
|
RUN_TEST(test_c_Random_Init_Stability);
|
|
RUN_TEST(test_c_Random_RangeU64_Bounds);
|
|
RUN_TEST(test_c_Random_RangeI64_Negative);
|
|
RUN_TEST(test_c_Random_RangeDouble_Distribution);
|
|
RUN_TEST(test_c_Random_ModuloBias_Elimination);
|
|
|
|
// 打印最终统计报告
|
|
TEST_REPORT();
|
|
|
|
RETURN_TEST_STATUS;
|
|
}
|