3 # Copyright (C) 2017 Jonathan Rajotte <jonathan.rajotte-julien@efficiso.com>>
5 # SPDX-License-Identifier: LGPL-2.1-only
7 TEST_DESC
="Notification"
10 TESTDIR
=$CURDIR/..
/..
/..
/
12 TESTPOINT
=$
(readlink
-f ${CURDIR}/.libs
/libpause_consumer.so
)
14 TESTAPP_PATH
="$TESTDIR/utils/testapp"
15 TESTAPP_NAME
="gen-ust-events"
16 TESTAPP_BIN
="$TESTAPP_PATH/$TESTAPP_NAME/$TESTAPP_NAME"
17 TESTAPP_STATE_FILE
="$(mktemp -u -t tmp.test_notification_multi_app_state_file.XXXXXX)"
22 SESSION_NAME
="my_session"
23 CHANNEL_NAME
="my_channel"
26 DIR
=$
(readlink
-f $TESTDIR)
28 PAGE_SIZE
=$
(getconf PAGE_SIZE
)
32 NUM_TESTS
=$
(($NUM_TEST_UST + $NUM_TEST_KERNEL))
34 source $TESTDIR/utils
/utils.sh
35 source $CURDIR/util_event_generator.sh
38 file_sync_after_first_event
=$
(mktemp
-u -t tmp.test_notification_multi_app_sync_after_first.XXXXXX
)
40 # MUST set TESTDIR before calling those functions
43 print_test_banner
"$TEST_DESC"
47 function start_client
{
53 local buffer_usage_type
=$5
54 local buffer_usage_threshold_type
=$6
55 local buffer_usage_threshold_value
=$7
56 local nr_expected_notification
=$8
57 local use_action_list
=$9
59 ${CURDIR}/base_client ${session_name} ${channel_name} ${domain_type} ${buffer_usage_type} ${buffer_usage_threshold_type} ${buffer_usage_threshold_value} ${nr_expected_notification} ${use_action_list} > ${output_file} &
65 function wait_for_message
()
71 for file in $directory/${file_pattern}*; do
73 # Check for "error" message
74 grep -q "error:" ${file}
76 if [ $app_error -eq "0" ] ; then
78 fail
"Waiting message: error logged see file content: ${message}, ${file}"
82 grep -q "${message}" ${file}
83 if [[ "$?" -ne "0" ]]; then
84 # Lookup failed restart loop
85 diag
"Lookup failed sleep and retry grep for: ${message}, ${file}"
92 pass
"Message received: ${message}"
96 function print_errors
()
101 for file in $directory/${file_pattern}*; do
102 # Check for "error" message
103 error_message
=$
(grep "error:" ${file})
104 if [[ "${error_message}x" != "x" ]]; then
105 diag
"Errors for application ${file}:"
106 diag
"${error_message}"
111 function comm_consumerd
()
115 echo -ne "${message}" > "${pipe}"
118 function stop_consumerd
()
121 comm_consumerd
"1" "$pipe"
124 function resume_consumerd
()
127 comm_consumerd
"\0" "$pipe"
130 function test_multi_app
()
133 local event_generator_pid
=$2
136 local low_output_file_pattern
="low_app_output_file_"
137 local high_output_file_pattern
="high_app_output_file_"
138 local output_dir
=$
(mktemp
-d -t "tmp.test_${FUNCNAME[0]}_output_dir.XXXXXX")
140 local testpoint_base_path
=$
(readlink
-f "$output_dir/lttng.t_p_n_multi_app")
141 local testpoint_pipe_path
=$
(TMPDIR
="$output_dir" mktemp
-u -t "lttng.t_p_n_multi_app.XXXXXX")
143 local nr_notification_expected
=5
144 local nr_client_app
=50
145 local domain_string
=""
150 domain_string
=LTTNG_DOMAIN_UST
151 event_name
="tp:tptest"
154 domain_string
=LTTNG_DOMAIN_KERNEL
155 event_name
="lttng_test_filter_event"
158 fail
"Invalid domain type"
164 LTTNG_SESSIOND_ENV_VARS
="LTTNG_TESTPOINT_ENABLE=1 CONSUMER_PAUSE_PIPE_PATH=${testpoint_pipe_path} LD_PRELOAD=${TESTPOINT}"
167 create_lttng_session_ok
$SESSION_NAME $TRACE_PATH
168 enable_
${domain_type}_lttng_channel_ok
$SESSION_NAME $CHANNEL_NAME --subbuf-size=$PAGE_SIZE
169 enable_
${domain_type}_lttng_event_ok
$SESSION_NAME $event_name $CHANNEL_NAME
171 # Fetch consumerd testpoint pipe information
172 # This is needed since the testpoint create a pipe with the consumer type suffixed
174 for f
in "$testpoint_pipe_path"*; do
175 consumerd_pipe
+=("$f")
178 for (( i
= 0; i
< $nr_client_app; i
++ )); do
179 low_app_output_file
=$output_dir/${low_output_file_pattern}${i}
180 high_app_output_file
=$output_dir/${high_output_file_pattern}${i}
181 start_client
$low_app_output_file $SESSION_NAME $CHANNEL_NAME $domain_string LOW RATIO
0.0 $nr_notification_expected $
(( $i % 2))
182 start_client
$high_app_output_file $SESSION_NAME $CHANNEL_NAME $domain_string HIGH RATIO
0.420 $nr_notification_expected $
(( $i % 2))
185 wait_for_message
$output_dir "${low_output_file_pattern}" "sync: ready"
186 wait_for_message
$output_dir "${high_output_file_pattern}" "sync: ready"
188 # Test notification reception
189 for (( i
= 0; i
< $nr_notification_expected; i
++ )); do
191 # Stop consumerd consumption to force high notification
192 start_lttng_tracing_ok
$SESSION_NAME
193 for pipe
in "${consumerd_pipe[@]}"; do
194 stop_consumerd
"${pipe}"
197 wait_for_message
$output_dir "${high_output_file_pattern}" "notification: high $i"
199 # Put application in suspend mode to prevent double low
200 # notification and synchronize on state file.
201 kill -s SIGUSR1
$event_generator_pid
202 while [ ! -f "${TESTAPP_STATE_FILE}" ]; do
207 for pipe
in "${consumerd_pipe[@]}"; do
208 resume_consumerd
"${pipe}"
210 # Stop tracing forcing full buffer consumption
211 stop_lttng_tracing_ok
$SESSION_NAME
213 # Check for notifications reception
214 wait_for_message
$output_dir "${low_output_file_pattern}" "notification: low $i"
216 ok
$ret "Notifications $i received"
217 if [[ $ret -ne "0" ]]; then
218 # Error occurred bail out
222 # Put application in active mode and synchronize on state file.
223 kill -s SIGUSR1
$event_generator_pid
224 while [ -f "${TESTAPP_STATE_FILE}" ]; do
229 wait_for_message
$output_dir "${low_output_file_pattern}" "exit: 0"
231 ok
$ret "Application for low notification terminated normally"
232 if [[ $ret -ne "0" ]]; then
233 print_errors
$output_dir "${low_output_file_pattern}"
236 wait_for_message
$output_dir "${high_output_file_pattern}" "exit: 0"
238 ok
$ret "Application for high notification terminated normally"
239 if [[ $ret -ne "0" ]]; then
240 print_errors
$output_dir "${high_output_file_pattern}"
244 destroy_lttng_session_ok
$SESSION_NAME
247 for pipe
in "${consumerd_pipe[@]}"; do
254 function test_multi_app_ust
()
256 diag
"Multi client app UST notification"
257 ust_event_generator
"$TESTAPP_BIN" "$TESTAPP_STATE_FILE" &
258 local generator_pid
=$
!
260 test_multi_app ust
$generator_pid
262 kill -s SIGUSR2
$generator_pid 2> /dev
/null
263 wait $generator_pid 2> /dev
/null
264 rm -rf ${TESTAPP_STATE_FILE} 2> /dev
/null
267 function test_multi_app_kernel
()
269 diag
"Multi client app kernel notification"
272 kernel_event_generator generate_filter_events
$TESTAPP_STATE_FILE &
273 local generator_pid
=$
!
275 test_multi_app kernel
$generator_pid
278 kill -s SIGUSR2
$generator_pid 2> /dev
/null
279 wait $generator_pid 2> /dev
/null
280 rm -rf ${TESTAPP_STATE_FILE} 2> /dev
/null
282 modprobe
--remove lttng-test
285 function test_on_register_evaluation_ust
()
287 diag
"On register notification UST"
289 # Start app in infinite loop
290 ust_event_generator
"$TESTAPP_BIN" "$TESTAPP_STATE_FILE" &
291 local generator_pid
=$
!
293 test_on_register_evaluation ust
$generator_pid
295 kill -s SIGUSR2
$generator_pid 2> /dev
/null
296 wait $generator_pid 2> /dev
/null
297 rm -rf ${TESTAPP_STATE_FILE} 2> /dev
/null
301 function test_on_register_evaluation_kernel
()
303 diag
"On register notification kernel"
307 kernel_event_generator generate_filter_events
$TESTAPP_STATE_FILE &
308 local generator_pid
=$
!
310 test_on_register_evaluation kernel
$generator_pid
313 kill -s SIGUSR2
$generator_pid 2> /dev
/null
314 wait $generator_pid 2> /dev
/null
315 rm -rf ${TESTAPP_STATE_FILE} 2> /dev
/null
317 modprobe
--remove lttng-test
320 function test_on_register_evaluation
()
323 local event_generator_pid
=$2
326 local high_output_file_pattern
="high_app_output_file_on_register_evaluation"
328 local output_dir
=$
(mktemp
-d -t "tmp.test_${FUNCNAME[0]}_output_dir.XXXXXX")
329 local testpoint_base_path
=$
(readlink
-f "$output_dir/lttng.t_p_n_register_evaluation")
330 local testpoint_pipe_path
=$
(TMPDIR
="$output_dir" mktemp
-u -t "lttng.t_p_n_register_evaluation.XXXXXX")
331 local domain_string
=""
336 domain_string
=LTTNG_DOMAIN_UST
337 event_name
="tp:tptest"
340 domain_string
=LTTNG_DOMAIN_KERNEL
341 event_name
="lttng_test_filter_event"
344 fail
"Invalid domain type"
350 LTTNG_SESSIOND_ENV_VARS
="LTTNG_TESTPOINT_ENABLE=1 CONSUMER_PAUSE_PIPE_PATH=${testpoint_pipe_path} LD_PRELOAD=${TESTPOINT}"
353 create_lttng_session_ok
$SESSION_NAME $TRACE_PATH
354 enable_
${domain_type}_lttng_channel_ok
$SESSION_NAME $CHANNEL_NAME --subbuf-size=$PAGE_SIZE
355 enable_
${domain_type}_lttng_event_ok
$SESSION_NAME $event_name $CHANNEL_NAME
357 # Fetch consumerd testpoint pipe information
358 # This is needed since the testpoint create a pipe with the consumer type suffixed
360 for f
in "$testpoint_pipe_path"*; do
361 consumerd_pipe
+=("$f")
364 high_app_output_file
=${high_output_file_pattern}.first_receiver
365 high_app_output_path
=$output_dir/${high_app_output_file}
366 start_client
$high_app_output_path $SESSION_NAME $CHANNEL_NAME $domain_string HIGH RATIO
0.420 1 0
368 wait_for_message
$output_dir "${high_app_output_file}" "sync: ready"
370 # Stop consumerd consumption to force high notification
371 start_lttng_tracing_ok
$SESSION_NAME
373 for pipe
in "${consumerd_pipe[@]}"; do
374 stop_consumerd
"${pipe}"
377 wait_for_message
$output_dir "${high_app_output_file}" "notification: high 0"
379 # Start a second receiver, the receiver should receive a high
380 # notification on subscription
381 high_app_output_file
=${high_output_file_pattern}.second_receiver
382 high_app_output_path
=$output_dir/${high_app_output_file}
383 start_client
$high_app_output_path $SESSION_NAME $CHANNEL_NAME $domain_string HIGH RATIO
0.420 1 0
384 wait_for_message
$output_dir "${high_app_output_file}" "sync: ready"
385 wait_for_message
$output_dir "${high_app_output_file}" "notification: high 0"
388 for pipe
in "${consumerd_pipe[@]}"; do
389 resume_consumerd
"${pipe}"
392 wait_for_message
$output_dir "${high_output_file_pattern}" "exit: 0"
394 ok
$ret "Application for high notification terminated normally"
395 if [[ $ret -ne "0" ]]; then
397 print_errors
"${high_output_file_pattern}"
401 destroy_lttng_session_ok
$SESSION_NAME
404 kill -s SIGUSR2
$generator_pid 2> /dev
/null
405 wait $generator_pid 2> /dev
/null
407 for pipe
in "${consumerd_pipe[@]}"; do
416 test_on_register_evaluation_ust
419 check_skip_kernel_test
"$NUM_TEST_KERNEL" "Skipping kernel multi-app notification tests." ||
{
420 validate_lttng_modules_present
422 test_multi_app_kernel
423 test_on_register_evaluation_kernel
427 for fct_test
in ${TESTS[@]};
429 TRACE_PATH
=$
(mktemp
-d -t tmp.test_notification_multi_app_trace_path.XXXXXX
)
432 if [ $?
-ne 0 ]; then
436 # Only delete if successful