This fixes two problems with the current test.
1. Starting the tracing before pausing the consumption can result
in an arbitrary number of buffer usage conditions being sent to
the client as the buffers can be filled and emptied a number of
times.
2. Resuming the consumption before stopping tracing can, in a
similar way as '1', result in an arbitrary number of notifications
being sent to the client.
Note that the non-blocking stop is used since the blocking
variant would wait for pending data to be flushed forever since
the consumption is paused. Hence, we stop the tracing, resume
the consumption, and wait for the buffers to be flushed explicitly
using the lttng_data_pending() call. No sleeps are performed in
that loop since those could hide races triggered by this test.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
lttng_action_destroy(action);
}
lttng_action_destroy(action);
}
+static
+void wait_data_pending(const char *session_name)
+{
+ int ret;
+
+ do {
+ ret = lttng_data_pending(session_name);
+ assert(ret >= 0);
+ } while (ret != 0);
+}
+
void test_notification_channel(const char *session_name, const char *channel_name, const enum lttng_domain_type domain_type, const char **argv)
{
int ret = 0;
void test_notification_channel(const char *session_name, const char *channel_name, const enum lttng_domain_type domain_type, const char **argv)
{
int ret = 0;
ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_ALREADY_SUBSCRIBED, "Subscribe to a condition for which subscription was already done");
/* Wait for notification to happen */
ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_ALREADY_SUBSCRIBED, "Subscribe to a condition for which subscription was already done");
/* Wait for notification to happen */
- lttng_start_tracing(session_name);
+ lttng_start_tracing(session_name);
/* Wait for high notification */
nc_status = lttng_notification_channel_get_next_notification(notification_channel, ¬ification);
/* Wait for high notification */
nc_status = lttng_notification_channel_get_next_notification(notification_channel, ¬ification);
notification = NULL;
suspend_application();
notification = NULL;
suspend_application();
+ lttng_stop_tracing_no_wait(session_name);
- lttng_stop_tracing(session_name);
+ wait_data_pending(session_name);
/*
* Test that communication still work even if there is notification
/*
* Test that communication still work even if there is notification
notification = NULL;
/* Stop consumer to force a high notification */
notification = NULL;
/* Stop consumer to force a high notification */
resume_application();
lttng_start_tracing(session_name);
resume_application();
lttng_start_tracing(session_name);
nc_status = lttng_notification_channel_get_next_notification(notification_channel, ¬ification);
ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
nc_status = lttng_notification_channel_get_next_notification(notification_channel, ¬ification);
ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
notification = NULL;
suspend_application();
notification = NULL;
suspend_application();
- /* Resume consumer to allow event consumption */
+ lttng_stop_tracing_no_wait(session_name);
- lttng_stop_tracing(session_name);
+ wait_data_pending(session_name);
nc_status = lttng_notification_channel_get_next_notification(notification_channel, ¬ification);
ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
nc_status = lttng_notification_channel_get_next_notification(notification_channel, ¬ification);
ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
lttng_notification_destroy(notification);
notification = NULL;
lttng_notification_destroy(notification);
notification = NULL;
resume_application();
/* Stop consumer to force a high notification */
lttng_start_tracing(session_name);
resume_application();
/* Stop consumer to force a high notification */
lttng_start_tracing(session_name);
nc_status = lttng_notification_channel_get_next_notification(notification_channel, ¬ification);
ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
nc_status = lttng_notification_channel_get_next_notification(notification_channel, ¬ification);
ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
notification = NULL;
/* Resume consumer to allow event consumption */
notification = NULL;
/* Resume consumer to allow event consumption */
+ suspend_application();
+ lttng_stop_tracing_no_wait(session_name);
- lttng_stop_tracing(session_name);
+ wait_data_pending(session_name);
nc_status = lttng_notification_channel_unsubscribe(notification_channel, low_condition);
ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK, "Unsubscribe low condition with pending notification");
nc_status = lttng_notification_channel_unsubscribe(notification_channel, low_condition);
ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK, "Unsubscribe low condition with pending notification");