-
Notifications
You must be signed in to change notification settings - Fork 59
test-case: add test jack detection playback #1280
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| #!/bin/bash | ||
|
|
||
| # SPDX-License-Identifier: BSD-3-Clause | ||
| # Copyright(c) 2021-2025 Intel Corporation. All rights reserved. | ||
|
|
||
| # needs usbrelay package: https://github.com/darrylb123/usbrelay | ||
| # param1: --debug | switch name | ||
| # param2: switch state | ||
| usbrelay_switch() | ||
| { | ||
| if [[ "$1" == "--debug" ]]; then | ||
| dlogi "Debug mode: Current status of all relays:" | ||
| usbrelay || { | ||
| die "Failed to get usbrelay status. | ||
| The usbrelay hw module is not responding or no relays detected. | ||
| Check hardware connection." | ||
| } | ||
| fi | ||
|
|
||
| # Declare a constant for the relay settle time | ||
| local USBRELAY_SETTLE_TIME=0.5 | ||
|
|
||
| local switch_name=$1 | ||
| local state=$2 | ||
|
|
||
| dlogi "Setting usbrelay switch $switch_name to $state." | ||
| usbrelay "$switch_name=$state" --quiet || { | ||
| die "Failed to set usbrelay switch $switch_name to $state. | ||
| The usbrelay hw module is not responding or no relays detected. | ||
| Check hardware connection." | ||
| } | ||
|
|
||
| # wait for the switch to settle | ||
| sleep "$USBRELAY_SETTLE_TIME" | ||
|
|
||
| # Display current state of the switch | ||
| current_state=$(usbrelay | awk -F= -v name="$switch_name" '$1 == name { print $2 }') | ||
|
|
||
| # Check if current_state is equal to the requested state | ||
| [[ "$current_state" == "$state" ]] || { | ||
| die "usbrelay switch $switch_name failed to set to $state (current: $current_state)" | ||
| } | ||
|
|
||
| case "$current_state" in | ||
| '1') dlogi "Current state of $switch_name is: on";; | ||
| '0') dlogi "Current state of $switch_name is: off";; | ||
| *) die "Invalid state for $switch_name: $current_state";; | ||
| esac | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,208 @@ | ||
| #!/bin/bash | ||
|
|
||
| # SPDX-License-Identifier: BSD-3-Clause | ||
| # Copyright(c) 2025 Intel Corporation. All rights reserved. | ||
|
|
||
| ## | ||
| ## Preconditions | ||
| # USB relay switch is available and configured. | ||
| # Jack detection header should be connected to the USB relay switch | ||
| # to the port HURTM_2 (NC) connector. | ||
|
|
||
| ## Test Description | ||
| # Verify jack detection functionality by simulating plugging and unplugging | ||
| # of audio jack using a USB relay switch. | ||
| # The unplugging and plugging of the jack will be during playback operations | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the test also try jack detection while no playback is running and its handling is correct in this mode ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this scenario will test in a different test - test_jack_detection_during_suspend |
||
| # to ensure the system can handle jack detection events correctly. | ||
| # The test will check if the jack detection status is updated correctly | ||
| # when the jack is plugged in and unplugged. | ||
|
|
||
| ## Case Steps | ||
| # 1. Ensure the USB relay switch is configured to control the jack detection header. | ||
| # 2. Ensure the aplay (playback) command works properly. | ||
| # 3. Set the USB relay switch to state on (1), simulate unplugging the headset from the jack. | ||
| # 4. Check the jack detection status via amixer. The status should indicate **off**. | ||
| # 5. Check if the aplay process is still running after unplugging the jack. | ||
| # If the process is not running, the test fails. | ||
| # If the process is still running, continue to the next step. | ||
| # 6. Set the USB relay switch to state off (0), simulate plugging the headset. | ||
| # 7. Check the jack detection status via amixer. The status should indicate **on**. | ||
| # 8. Check if the aplay process is still running after plugging the jack. | ||
| # If the process is not running, the test fails. | ||
| # If the process is still running, continue to the next step. | ||
| # 9. Terminate the aplay process. | ||
| # 10. Check if the aplay process is terminated successfully. | ||
| # If the process is still running, the test fails. | ||
| # If the process is terminated successfully, the test passes. | ||
| # 11. Check dmesg for any unexpected errors. | ||
| # | ||
| # Repeat steps 3-11 for all pcm jack playback devices. | ||
|
|
||
| TESTDIR=$(realpath -e "$(dirname "${BASH_SOURCE[0]}")/..") | ||
| TESTLIB="${TESTDIR}/case-lib" | ||
|
|
||
| # shellcheck disable=SC1091 source=case-lib/lib.sh | ||
| source "${TESTLIB}/lib.sh" | ||
| # shellcheck disable=SC1091 source=case-lib/relay.sh | ||
| source "${TESTLIB}/relay.sh" | ||
|
|
||
| # shellcheck disable=SC2153 | ||
| OPT_NAME['t']='tplg' OPT_DESC['t']="tplg file, default value is env TPLG: $TPLG" | ||
| OPT_HAS_ARG['t']=1 OPT_VAL['t']="$TPLG" | ||
|
|
||
| OPT_NAME['l']='loop' OPT_DESC['l']='loop count' | ||
| OPT_HAS_ARG['l']=1 OPT_VAL['l']=1 | ||
|
|
||
| OPT_NAME['s']='sof-logger' OPT_DESC['s']="Open sof-logger trace the data will store at $LOG_ROOT" | ||
| OPT_HAS_ARG['s']=0 OPT_VAL['s']=1 | ||
|
|
||
| OPT_NAME['u']='relay' OPT_DESC['u']='name of usbrelay switch, default value is HURTM_2' | ||
| OPT_HAS_ARG['u']=1 OPT_VAL['u']="HURTM_2" | ||
|
|
||
| func_opt_parse_option "$@" | ||
|
|
||
| tplg=${OPT_VAL['t']} | ||
| relay=${OPT_VAL['u']} | ||
| loop_cnt=${OPT_VAL['l']} | ||
|
|
||
| DSP_SETTLE_TIME=2 | ||
|
|
||
| check_control_switch_state() | ||
| { | ||
| # Check the state of the switch using amixer. | ||
| # The switch name is passed as the first argument, and the expected state (on/off) | ||
| # is passed as the second argument. | ||
| # Returns 0 if the state matches, 1 otherwise. | ||
| local control_name="$1" | ||
| local expected_control_state="$2" | ||
| local control_state | ||
|
|
||
| control_state=$(amixer -c "$SOFCARD" contents | awk -v name="$control_name" ' | ||
| BEGIN { | ||
| RS = ""; | ||
| IGNORECASE = 1; | ||
| split(name, parts, " "); | ||
| }; | ||
| $0 ~ parts[1] && $0 ~ parts[2] { | ||
| if (match($0, /values=(on|off)/, m)) print m[1]; | ||
| } | ||
| ') | ||
| dlogi "$control_name switch is: $control_state" | ||
|
|
||
| if [[ "$expected_control_state" == "$control_state" ]]; then | ||
| return 0 | ||
| else | ||
| return 1 | ||
| fi | ||
| } | ||
|
|
||
| testing_one_pcm() | ||
| { | ||
| dlogi "===== Testing: (PCM: $pcm [$dev]<$type>) (Loop: $i/$loop_cnt) =====" | ||
| dlogi "DEVICE: $dev, TYPE: $type, PCM: $pcm, RATE: $rate, CHANNEL: $channel" | ||
|
|
||
| dlogi "Command: aplay -Dplug$dev -q /dev/zero" | ||
| # Start alsabat in background with longer duration | ||
| dlogi "Starting aplay in background..." | ||
| aplay "-Dplug$dev" -d10 -q /dev/zero & pid_playback=$! || { | ||
| func_lib_lsof_error_dump "$snd" | ||
| die "Failed to start aplay on PCM: $pcm" | ||
| } | ||
| # Wait briefly to ensure the device is ready and avoid read errors | ||
| sleep 1 | ||
| dlogi "aplay started with PID: $pid_playback" | ||
|
|
||
| dlogi "Unplug jack audio." | ||
| usbrelay_switch "$relay" 1 | ||
|
|
||
| # Wait for a short period to allow the system to detect the unplug event | ||
| sleep $DSP_SETTLE_TIME | ||
|
|
||
| # check if the aplay process is still running after unplugging the jack | ||
| ps -p "$pid_playback" > /dev/null || { | ||
| func_lib_lsof_error_dump "$snd" | ||
| die "Playback process terminated unexpectedly after unplugging the jack." | ||
| } | ||
|
|
||
| check_control_switch_state "headset" "off" || { | ||
| die "unplug headset jack failed." | ||
| } | ||
|
|
||
| check_control_switch_state "headphone" 'off' || { | ||
| die "unplug headphone jack failed." | ||
| } | ||
|
|
||
| dlogi "Plug jack audio." | ||
| usbrelay_switch "$relay" 0 | ||
|
|
||
| # Wait for a short period to allow the system to detect the plug event | ||
| sleep $DSP_SETTLE_TIME | ||
|
|
||
| # check if the aplay process is still running after unplugging the jack | ||
| ps -p "$pid_playback" > /dev/null || { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I hope we already have some code for this, maybe in case-lib/
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO ps -p is more explicit about checking for a process |
||
| func_lib_lsof_error_dump "$snd" | ||
| die "Playback process terminated unexpectedly after plugging the jack." | ||
| } | ||
|
|
||
| check_control_switch_state "headset" "on" || { | ||
| die "Plug headset jack failed." | ||
| } | ||
|
|
||
| check_control_switch_state "headphone" "on" || { | ||
| die "Plug headphone jack failed." | ||
| } | ||
|
|
||
| kill -9 $pid_playback > /dev/null 2>&1 | ||
| wait $pid_playback 2>/dev/null || true | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I hope we already have some code for this, maybe in (every script tries to re-invent this) |
||
| ps -p "$pid_playback" > /dev/null && { | ||
| dloge "Failed to kill playback process." | ||
| func_lib_lsof_error_dump "$snd" | ||
| die "Playback process did not terminate as expected." | ||
| } | ||
| dlogi "Playback process terminated." | ||
| dlogi "===== Testing: PASSED =====" | ||
| } | ||
|
|
||
| main() | ||
| { | ||
| func_pipeline_export "$tplg" "type:playback" | ||
|
|
||
| setup_kernel_check_point | ||
|
|
||
| start_test | ||
|
|
||
| logger_disabled || func_lib_start_log_collect | ||
|
|
||
| # Check if usbrelay tool is installed | ||
| command -v usbrelay || { | ||
| # If usbrelay package is not installed | ||
| skip_test "usbrelay command not found. Please install usbrelay package." | ||
| } | ||
|
|
||
| # display current status of relays | ||
| usbrelay --debug | ||
|
|
||
| dlogi "Reset - plug jack audio" | ||
| usbrelay_switch "$relay" 0 | ||
|
|
||
| for idx in $(seq 0 $((PIPELINE_COUNT - 1))) | ||
| do | ||
| initialize_audio_params "$idx" | ||
|
|
||
| [[ "$pcm" == *Jack* ]] || { | ||
| dlogi "PCM $pcm is not a Jack, skipping..." | ||
| continue | ||
| } | ||
|
|
||
| for i in $(seq 1 "$loop_cnt") | ||
| do | ||
| testing_one_pcm | ||
| sof-kernel-log-check.sh "$KERNEL_CHECKPOINT" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think in these two nested loops it should either die on the first errors here, or set new kernel check point on each iteration. |
||
| setup_kernel_check_point | ||
| done | ||
| done | ||
| } | ||
|
|
||
| { | ||
| main "$@"; exit "$?" | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does it run with $1 ==
--debug?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
https://github.com/arikgreen/sof-test/blob/13d9d4e61b71c5601869bc5b66ab78494287182e/test-case/test-jack-detection-playback-capture.sh#L185