|
18 | 18 | #include <aws/testing/aws_test_harness.h> |
19 | 19 |
|
20 | 20 | #include <math.h> |
| 21 | +/* The delay margin accounts for system-level latencies, particularly when scheduling tasks on dispatch queues. In |
| 22 | + * typical test environments, we observe delays of around 150–170ms before the task begins execution. To ensure |
| 23 | + * stability, we define a margin of 200ms (AWS_MQTT5_TESTING_DELAY_NS). If related tests fail, it may indicate this |
| 24 | + * margin is insufficient—consider increasing the value. */ |
| 25 | +#define AWS_MQTT5_TESTING_DELAY_NS 200 * 1000 * 1000 /*200ms*/ |
21 | 26 |
|
22 | 27 | static bool s_is_within_percentage_of(uint64_t expected_time, uint64_t actual_time, double percentage) { |
23 | 28 | double actual_percent = 1.0 - (double)actual_time / (double)expected_time; |
24 | 29 | return fabs(actual_percent) <= percentage; |
25 | 30 | } |
26 | 31 |
|
| 32 | +/* The function is used to validate the time interval for the expected and actual time. We used a user determined |
| 33 | + * percentage for margin and a minimal of AWS_MQTT5_TESTING_DELAY_NS considering the system delay. */ |
| 34 | +static bool s_validate_time_interval(uint64_t expected_time, uint64_t actual_time, double percentage) { |
| 35 | + uint64_t delta = actual_time > expected_time ? actual_time - expected_time : expected_time - actual_time; |
| 36 | + return delta < AWS_MQTT5_TESTING_DELAY_NS || s_is_within_percentage_of(expected_time, actual_time, percentage); |
| 37 | +} |
| 38 | + |
| 39 | +static bool s_check_time_lower_bound(uint64_t expected_time, uint64_t actual_time) { |
| 40 | + return actual_time >= expected_time; |
| 41 | +} |
| 42 | + |
27 | 43 | int aws_mqtt5_mock_server_handle_connect_always_succeed( |
28 | 44 | void *packet, |
29 | 45 | struct aws_mqtt5_server_mock_connection_context *connection, |
@@ -1508,7 +1524,7 @@ int aws_verify_reconnection_exponential_backoff_timestamps(struct aws_mqtt5_clie |
1508 | 1524 | uint64_t time_diff = aws_timestamp_convert( |
1509 | 1525 | record->timestamp - last_timestamp, AWS_TIMESTAMP_NANOS, AWS_TIMESTAMP_MILLIS, NULL); |
1510 | 1526 |
|
1511 | | - if (!s_is_within_percentage_of(expected_backoff, time_diff, .3)) { |
| 1527 | + if (!s_check_time_lower_bound(expected_backoff, time_diff)) { |
1512 | 1528 | return AWS_OP_ERR; |
1513 | 1529 | } |
1514 | 1530 |
|
@@ -1717,7 +1733,13 @@ static int s_verify_reconnection_after_success_used_backoff( |
1717 | 1733 | AWS_TIMESTAMP_MILLIS, |
1718 | 1734 | NULL); |
1719 | 1735 |
|
1720 | | - if (!s_is_within_percentage_of(expected_reconnect_delay_ms, post_success_reconnect_time_ms, .3)) { |
| 1736 | + /* The reconnect delay should be at least the expected backoff time. |
| 1737 | + * Meanwhile, to make sure the backoff time is reset to minimal properly, we also would like to validate the upper |
| 1738 | + * bound of the reconnect time. With function `s_validate_time_interval()`, we used a 30% margin and a minimal of |
| 1739 | + * AWS_MQTT5_TESTING_DELAY_NS for system delay to validate the upper bound. |
| 1740 | + */ |
| 1741 | + if (!s_check_time_lower_bound(expected_reconnect_delay_ms, post_success_reconnect_time_ms) && |
| 1742 | + !s_validate_time_interval(expected_reconnect_delay_ms, post_success_reconnect_time_ms, .3)) { |
1721 | 1743 | return AWS_OP_ERR; |
1722 | 1744 | } |
1723 | 1745 |
|
|
0 commit comments