Merge pull request #104793 from YYF233333/remove_astar_stress_test
Remove stress unit tests
This commit is contained in:
@ -211,149 +211,4 @@ TEST_CASE("[AStar3D] Add/Remove") {
|
||||
}
|
||||
// It's been great work, cheers. \(^ ^)/
|
||||
}
|
||||
|
||||
TEST_CASE("[Stress][AStar3D] Find paths") {
|
||||
// Random stress tests with Floyd-Warshall.
|
||||
constexpr int N = 30;
|
||||
Math::seed(0);
|
||||
|
||||
for (int test = 0; test < 1000; test++) {
|
||||
AStar3D a;
|
||||
Vector3 p[N];
|
||||
bool adj[N][N] = { { false } };
|
||||
|
||||
// Assign initial coordinates.
|
||||
for (int u = 0; u < N; u++) {
|
||||
p[u].x = Math::rand() % 100;
|
||||
p[u].y = Math::rand() % 100;
|
||||
p[u].z = Math::rand() % 100;
|
||||
a.add_point(u, p[u]);
|
||||
}
|
||||
// Generate a random sequence of operations.
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
// Pick two different vertices.
|
||||
int u, v;
|
||||
u = Math::rand() % N;
|
||||
v = Math::rand() % (N - 1);
|
||||
if (u == v) {
|
||||
v = N - 1;
|
||||
}
|
||||
// Pick a random operation.
|
||||
int op = Math::rand();
|
||||
switch (op % 9) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
// Add edge (u, v); possibly bidirectional.
|
||||
a.connect_points(u, v, op % 2);
|
||||
adj[u][v] = true;
|
||||
if (op % 2) {
|
||||
adj[v][u] = true;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
// Remove edge (u, v); possibly bidirectional.
|
||||
a.disconnect_points(u, v, op % 2);
|
||||
adj[u][v] = false;
|
||||
if (op % 2) {
|
||||
adj[v][u] = false;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
// Remove point u and add it back; clears adjacent edges and changes coordinates.
|
||||
a.remove_point(u);
|
||||
p[u].x = Math::rand() % 100;
|
||||
p[u].y = Math::rand() % 100;
|
||||
p[u].z = Math::rand() % 100;
|
||||
a.add_point(u, p[u]);
|
||||
for (v = 0; v < N; v++) {
|
||||
adj[u][v] = adj[v][u] = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Floyd-Warshall.
|
||||
float d[N][N];
|
||||
for (int u = 0; u < N; u++) {
|
||||
for (int v = 0; v < N; v++) {
|
||||
d[u][v] = (u == v || adj[u][v]) ? p[u].distance_to(p[v]) : Math::INF;
|
||||
}
|
||||
}
|
||||
for (int w = 0; w < N; w++) {
|
||||
for (int u = 0; u < N; u++) {
|
||||
for (int v = 0; v < N; v++) {
|
||||
if (d[u][v] > d[u][w] + d[w][v]) {
|
||||
d[u][v] = d[u][w] + d[w][v];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Display statistics.
|
||||
int count = 0;
|
||||
for (int u = 0; u < N; u++) {
|
||||
for (int v = 0; v < N; v++) {
|
||||
if (adj[u][v]) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
print_verbose(vformat("Test #%4d: %3d edges, ", test + 1, count));
|
||||
count = 0;
|
||||
for (int u = 0; u < N; u++) {
|
||||
for (int v = 0; v < N; v++) {
|
||||
if (!Math::is_inf(d[u][v])) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
print_verbose(vformat("%3d/%d pairs of reachable points\n", count - N, N * (N - 1)));
|
||||
|
||||
// Check A*'s output.
|
||||
bool match = true;
|
||||
for (int u = 0; u < N; u++) {
|
||||
for (int v = 0; v < N; v++) {
|
||||
if (u != v) {
|
||||
Vector<int64_t> route = a.get_id_path(u, v);
|
||||
if (!Math::is_inf(d[u][v])) {
|
||||
// Reachable.
|
||||
if (route.size() == 0) {
|
||||
print_verbose(vformat("From %d to %d: A* did not find a path\n", u, v));
|
||||
match = false;
|
||||
goto exit;
|
||||
}
|
||||
float astar_dist = 0;
|
||||
for (int i = 1; i < route.size(); i++) {
|
||||
if (!adj[route[i - 1]][route[i]]) {
|
||||
print_verbose(vformat("From %d to %d: edge (%d, %d) does not exist\n",
|
||||
u, v, route[i - 1], route[i]));
|
||||
match = false;
|
||||
goto exit;
|
||||
}
|
||||
astar_dist += p[route[i - 1]].distance_to(p[route[i]]);
|
||||
}
|
||||
if (!Math::is_equal_approx(astar_dist, d[u][v])) {
|
||||
print_verbose(vformat("From %d to %d: Floyd-Warshall gives %.6f, A* gives %.6f\n",
|
||||
u, v, d[u][v], astar_dist));
|
||||
match = false;
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
// Unreachable.
|
||||
if (route.size() > 0) {
|
||||
print_verbose(vformat("From %d to %d: A* somehow found a nonexistent path\n", u, v));
|
||||
match = false;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exit:
|
||||
CHECK_MESSAGE(match, "Found all paths.");
|
||||
}
|
||||
}
|
||||
} // namespace TestAStar
|
||||
|
||||
@ -189,32 +189,6 @@ TEST_CASE("[Basis] Euler conversions") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("[Stress][Basis] Euler conversions") {
|
||||
Vector<EulerOrder> euler_order_to_test;
|
||||
euler_order_to_test.push_back(EulerOrder::XYZ);
|
||||
euler_order_to_test.push_back(EulerOrder::XZY);
|
||||
euler_order_to_test.push_back(EulerOrder::YZX);
|
||||
euler_order_to_test.push_back(EulerOrder::YXZ);
|
||||
euler_order_to_test.push_back(EulerOrder::ZXY);
|
||||
euler_order_to_test.push_back(EulerOrder::ZYX);
|
||||
|
||||
Vector<Vector3> vectors_to_test;
|
||||
// Add 1000 random vectors with weirds numbers.
|
||||
RandomNumberGenerator rng;
|
||||
for (int _ = 0; _ < 1000; _ += 1) {
|
||||
vectors_to_test.push_back(Vector3(
|
||||
rng.randf_range(-1800, 1800),
|
||||
rng.randf_range(-1800, 1800),
|
||||
rng.randf_range(-1800, 1800)));
|
||||
}
|
||||
|
||||
for (int h = 0; h < euler_order_to_test.size(); h += 1) {
|
||||
for (int i = 0; i < vectors_to_test.size(); i += 1) {
|
||||
test_rotation(vectors_to_test[i], euler_order_to_test[h]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("[Basis] Set axis angle") {
|
||||
Vector3 axis;
|
||||
real_t angle;
|
||||
|
||||
@ -406,33 +406,6 @@ void test_quat_vec_rotate(Vector3 euler_yzx, Vector3 v_in) {
|
||||
CHECK(v_rot.is_equal_approx(v_compare));
|
||||
}
|
||||
|
||||
TEST_CASE("[Stress][Quaternion] Many vector xforms") {
|
||||
// Many arbitrary quaternions rotate many arbitrary vectors.
|
||||
// For each trial, check that rotation by Quaternion yields same result as
|
||||
// rotation by Basis.
|
||||
constexpr int STEPS = 100; // Number of test steps in each dimension
|
||||
constexpr double delta = 2.0 * Math::PI / STEPS; // Angle increment per step
|
||||
constexpr double delta_vec = 20.0 / STEPS; // Vector increment per step
|
||||
Vector3 vec_arb(1.0, 1.0, 1.0);
|
||||
double x_angle = -Math::PI;
|
||||
double y_angle = -Math::PI;
|
||||
double z_angle = -Math::PI;
|
||||
for (double i = 0; i < STEPS; ++i) {
|
||||
vec_arb[0] = -10.0 + i * delta_vec;
|
||||
x_angle = i * delta - Math::PI;
|
||||
for (double j = 0; j < STEPS; ++j) {
|
||||
vec_arb[1] = -10.0 + j * delta_vec;
|
||||
y_angle = j * delta - Math::PI;
|
||||
for (double k = 0; k < STEPS; ++k) {
|
||||
vec_arb[2] = -10.0 + k * delta_vec;
|
||||
z_angle = k * delta - Math::PI;
|
||||
Vector3 euler_yzx(x_angle, y_angle, z_angle);
|
||||
test_quat_vec_rotate(euler_yzx, vec_arb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("[Quaternion] Finite number checks") {
|
||||
constexpr real_t x = Math::NaN;
|
||||
|
||||
|
||||
@ -2185,22 +2185,4 @@ TEST_CASE("[String][URL] Parse URL") {
|
||||
|
||||
#undef CHECK_URL
|
||||
}
|
||||
|
||||
TEST_CASE("[Stress][String] Empty via ' == String()'") {
|
||||
for (int i = 0; i < 100000; ++i) {
|
||||
String str = "Hello World!";
|
||||
if (str == String()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("[Stress][String] Empty via `is_empty()`") {
|
||||
for (int i = 0; i < 100000; ++i) {
|
||||
String str = "Hello World!";
|
||||
if (str.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace TestString
|
||||
|
||||
@ -442,48 +442,6 @@ TEST_CASE("[CommandQueue] Test Queue Lapping") {
|
||||
ProjectSettings::get_singleton()->property_get_revert(COMMAND_QUEUE_SETTING));
|
||||
}
|
||||
|
||||
TEST_CASE("[Stress][CommandQueue] Stress test command queue") {
|
||||
const char *COMMAND_QUEUE_SETTING = "memory/limits/command_queue/multithreading_queue_size_kb";
|
||||
ProjectSettings::get_singleton()->set_setting(COMMAND_QUEUE_SETTING, 1);
|
||||
SharedThreadState sts;
|
||||
sts.init_threads();
|
||||
|
||||
RandomNumberGenerator rng;
|
||||
|
||||
rng.set_seed(1837267);
|
||||
|
||||
int msgs_to_add = 2048;
|
||||
|
||||
for (int i = 0; i < msgs_to_add; i++) {
|
||||
// randi_range is inclusive, so allow any enum value except MAX.
|
||||
sts.add_msg_to_write((SharedThreadState::TestMsgType)rng.randi_range(0, SharedThreadState::TEST_MSG_MAX - 1));
|
||||
}
|
||||
sts.writer_threadwork.main_start_work();
|
||||
|
||||
int max_loop_iters = msgs_to_add * 2;
|
||||
int loop_iters = 0;
|
||||
while (sts.func1_count < msgs_to_add && loop_iters < max_loop_iters) {
|
||||
int remaining = (msgs_to_add - sts.func1_count);
|
||||
sts.message_count_to_read = rng.randi_range(1, remaining < 128 ? remaining : 128);
|
||||
if (loop_iters % 3 == 0) {
|
||||
sts.message_count_to_read = -1;
|
||||
}
|
||||
sts.reader_threadwork.main_start_work();
|
||||
sts.reader_threadwork.main_wait_for_done();
|
||||
loop_iters++;
|
||||
}
|
||||
CHECK_MESSAGE(loop_iters < max_loop_iters,
|
||||
"Reader needed too many iterations to read messages!");
|
||||
sts.writer_threadwork.main_wait_for_done();
|
||||
|
||||
sts.destroy_threads();
|
||||
|
||||
CHECK_MESSAGE(sts.func1_count == msgs_to_add,
|
||||
"Reader should have read no additional messages after join");
|
||||
ProjectSettings::get_singleton()->set_setting(COMMAND_QUEUE_SETTING,
|
||||
ProjectSettings::get_singleton()->property_get_revert(COMMAND_QUEUE_SETTING));
|
||||
}
|
||||
|
||||
TEST_CASE("[CommandQueue] Test Parameter Passing Semantics") {
|
||||
SharedThreadState sts;
|
||||
sts.init_threads();
|
||||
|
||||
@ -545,57 +545,4 @@ TEST_CASE("[List] Swap adjacent back and front (reverse order of elements)") {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void swap_random(List<int> &p_list, List<int>::Element *r_elements[], size_t p_size, size_t p_iterations) {
|
||||
Math::seed(0);
|
||||
|
||||
for (size_t test_i = 0; test_i < p_iterations; ++test_i) {
|
||||
// A and B elements have corresponding indices as values.
|
||||
const int a_idx = static_cast<int>(Math::rand() % p_size);
|
||||
const int b_idx = static_cast<int>(Math::rand() % p_size);
|
||||
List<int>::Element *a = p_list.find(a_idx); // via find.
|
||||
List<int>::Element *b = r_elements[b_idx]; // via pointer.
|
||||
|
||||
int va = a->get();
|
||||
int vb = b->get();
|
||||
|
||||
p_list.swap(a, b);
|
||||
|
||||
CHECK(va == a->get());
|
||||
CHECK(vb == b->get());
|
||||
|
||||
size_t element_count = 0;
|
||||
|
||||
// Fully traversable after swap?
|
||||
List<int>::Element *it = p_list.front();
|
||||
while (it) {
|
||||
element_count += 1;
|
||||
List<int>::Element *prev_it = it;
|
||||
it = it->next();
|
||||
if (it == prev_it) {
|
||||
FAIL_CHECK("Infinite loop detected.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// We should not lose anything in the process.
|
||||
if (element_count != p_size) {
|
||||
FAIL_CHECK("Element count mismatch.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("[Stress][List] Swap random 100 elements, 500 iterations.") {
|
||||
List<int> list;
|
||||
List<int>::Element *n[100];
|
||||
populate_integers(list, n, 100);
|
||||
swap_random(list, n, 100, 500);
|
||||
}
|
||||
|
||||
TEST_CASE("[Stress][List] Swap random 10 elements, 1000 iterations.") {
|
||||
List<int> list;
|
||||
List<int>::Element *n[10];
|
||||
populate_integers(list, n, 10);
|
||||
swap_random(list, n, 10, 1000);
|
||||
}
|
||||
} // namespace TestList
|
||||
|
||||
Reference in New Issue
Block a user