Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disabled keep alive #363

Merged
merged 3 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion source/v5/mqtt5_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1069,7 +1069,11 @@ static void s_reset_ping(struct aws_mqtt5_client *client) {

uint64_t keep_alive_interval_nanos =
aws_timestamp_convert(keep_alive_seconds, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_NANOS, NULL);
client->next_ping_time = aws_add_u64_saturating(now, keep_alive_interval_nanos);
if (keep_alive_interval_nanos == 0) {
client->next_ping_time = UINT64_MAX;
} else {
client->next_ping_time = aws_add_u64_saturating(now, keep_alive_interval_nanos);
}

AWS_LOGF_DEBUG(
AWS_LS_MQTT5_CLIENT, "id=%p: next PINGREQ scheduled for time %" PRIu64, (void *)client, client->next_ping_time);
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ add_test_case(mqtt5_client_sub_pub_unsub_qos1)
add_test_case(mqtt5_client_ping_sequence)
add_test_case(mqtt5_client_ping_timeout)
add_test_case(mqtt5_client_ping_timeout_with_keep_alive_conflict)
add_test_case(mqtt5_client_disabled_keep_alive)
add_test_case(mqtt5_client_reconnect_failure_backoff)
add_test_case(mqtt5_client_reconnect_backoff_insufficient_reset)
add_test_case(mqtt5_client_reconnect_backoff_sufficient_reset)
Expand Down
73 changes: 69 additions & 4 deletions tests/v5/mqtt5_client_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -986,10 +986,7 @@ struct aws_mqtt5_client_test_wait_for_n_context {
struct aws_mqtt5_client_mock_test_fixture *test_fixture;
};

static bool s_received_at_least_n_pingreqs(void *arg) {
struct aws_mqtt5_client_test_wait_for_n_context *ping_context = arg;
struct aws_mqtt5_client_mock_test_fixture *test_fixture = ping_context->test_fixture;

static size_t s_count_pingreqs(struct aws_mqtt5_client_mock_test_fixture *test_fixture) {
size_t ping_count = 0;
size_t packet_count = aws_array_list_length(&test_fixture->server_received_packets);
for (size_t i = 0; i < packet_count; ++i) {
Expand All @@ -1001,6 +998,15 @@ static bool s_received_at_least_n_pingreqs(void *arg) {
}
}

return ping_count;
}

static bool s_received_at_least_n_pingreqs(void *arg) {
struct aws_mqtt5_client_test_wait_for_n_context *ping_context = arg;
struct aws_mqtt5_client_mock_test_fixture *test_fixture = ping_context->test_fixture;

size_t ping_count = s_count_pingreqs(test_fixture);

return ping_count >= ping_context->required_event_count;
}

Expand Down Expand Up @@ -1413,6 +1419,65 @@ AWS_TEST_CASE(
mqtt5_client_ping_timeout_with_keep_alive_conflict,
s_mqtt5_client_ping_timeout_with_keep_alive_conflict_fn)

/*
* Set up a zero keep alive and verify no pings get sent over an interval of time.
*/
static int s_mqtt5_client_disabled_keep_alive_fn(struct aws_allocator *allocator, void *ctx) {
(void)ctx;

aws_mqtt_library_init(allocator);

struct mqtt5_client_test_options test_options;
aws_mqtt5_client_test_init_default_options(&test_options);

/* no keep alive at all */
test_options.connect_options.keep_alive_interval_seconds = 0;

struct aws_mqtt5_client_mqtt5_mock_test_fixture_options test_fixture_options = {
.client_options = &test_options.client_options,
.server_function_table = &test_options.server_function_table,
};

struct aws_mqtt5_client_mock_test_fixture test_context;
ASSERT_SUCCESS(aws_mqtt5_client_mock_test_fixture_init(&test_context, allocator, &test_fixture_options));

struct aws_mqtt5_client *client = test_context.client;
ASSERT_SUCCESS(aws_mqtt5_client_start(client));

aws_wait_for_connected_lifecycle_event(&test_context);

uint16_t negotiated_keep_alive = 65535;
aws_mutex_lock(&test_context.lock);
size_t event_count = aws_array_list_length(&test_context.lifecycle_events);
struct aws_mqtt5_lifecycle_event_record *record = NULL;
aws_array_list_get_at(&test_context.lifecycle_events, &record, event_count - 1);
ASSERT_TRUE(AWS_MQTT5_CLET_CONNECTION_SUCCESS == record->event.event_type);
negotiated_keep_alive = record->settings_storage.server_keep_alive;
aws_mutex_unlock(&test_context.lock);

ASSERT_INT_EQUALS(0, negotiated_keep_alive);

// zzz
aws_thread_current_sleep(aws_timestamp_convert(5, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_NANOS, NULL));

ASSERT_SUCCESS(aws_mqtt5_client_stop(client, NULL, NULL));

aws_wait_for_stopped_lifecycle_event(&test_context);

// verify the mock server did not get any PINGREQs
aws_mutex_lock(&test_context.lock);
size_t pingreq_count = s_count_pingreqs(&test_context);
aws_mutex_unlock(&test_context.lock);
ASSERT_INT_EQUALS(0, pingreq_count);

aws_mqtt5_client_mock_test_fixture_clean_up(&test_context);
aws_mqtt_library_clean_up();

return AWS_OP_SUCCESS;
}

AWS_TEST_CASE(mqtt5_client_disabled_keep_alive, s_mqtt5_client_disabled_keep_alive_fn)

struct aws_lifecycle_event_wait_context {
enum aws_mqtt5_client_lifecycle_event_type type;
size_t count;
Expand Down
Loading