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

refine alsabat test script #401

Closed
wants to merge 3 commits into from

Conversation

keqiaozhang
Copy link
Contributor

No description provided.

@keqiaozhang keqiaozhang requested a review from a team as a code owner September 23, 2020 08:12
Copy link
Collaborator

@marc-hb marc-hb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for a shellcheck-clean PR! Saves a lot of review time.

Any idea about the many check-alsabat-headset-playback.sh failures in https://sof-ci.01.org/softestpr/PR401/build216/devicetest/ ? This doesn't look great in an alsabat PR :-(

I think you can write a much less vague PR title and summary than "refine", just summarize the commit messages.

uname -r |grep "nocodec" >> /dev/null &&
echo "nocodec"
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid strings when they're not needed.

nocodec_mode()
{
    uname -r | grep -q "nocodec"
}
...
if nocodec_mode; then
...

``

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If running uname -r were time-consuming (it's not!) then you could want to save and re-use the result in a pseudo-boolean variable with this longer code.

I repeat this is NOT needed here, just an example for other cases.

codec_mode() # avoids one negation
{
    if time_consuming_uname -r | grep -q "nocodec"; then
      printf 'false'
    else
     printf 'true'
   fi
}
...
codec_m=$(codec_mode)
...
if "$codec_m"; then # (this runs the $codec_m command)
..
fi
...
"$codec_m" || ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see any update for this. but I have same idea with this.

if [ "$codec_mode" != "nocodec" ]; then
# USB sound card only supports 1 channel S16_LE format.
format_c=S16_LE
channel_c=1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit strange to run multiple times the same format on nocodec mode. Can you override and reduce the $fmts list instead before the loop? This will make the loop not care about special cases and simpler.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nocodec tplgs also support different formats like s16_le/s24_le and s32_le, not passthrough mode. so we can check each format in the loop.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we real need alsabat for all fmts?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking all formats available is good idea. but S24_LE is always ignored, isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes,S24_4LE is not supported by alsabat

find /tmp -maxdepth 1 -type f -name "bat.wav.*" -size +0 -exec cp {} "$LOG_ROOT/" \;
exit 1
}
timeout 5 tail --pid=$alsabat_P -f /dev/null || die "Failed to stop alsabat playback"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeout tail trick seems to work but it's not intuitive to use the tail command without using its main feature. We already discussed an alternative in this other review: #316 (comment)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Failed to stop alsabat" message is misleading, it sounds like kill failed. You mean: "alsabat -P failed to stop"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated.


dlogc "alsabat -C $pcm_c -F $frequency -f $format_c -c $channel_c -r $rate"
alsabat -C "$pcm_c" -F "$frequency" -f "$format_c" -c "$channel_c" -r "$rate" || {
find /tmp -maxdepth 1 -type f -name "bat.wav.*" -size +0 -exec cp {} "$LOG_ROOT/" \;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes it's good to have a function with a single command only to give a better and clearer name to that command. I think "upload_wav_file" was a very readable name.

PS: same with once-off constants: inlining them makes the code shorter but not always easier to read. It depends.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably want :

alsabat ... || {
  find ... || true
  exit 1
}

... because of set -e. When find fails, it fails with an undocumented return value (!) which could cause serious issues like #385

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion, I have added a new function in lib.sh to upload wav files.

if [ "$codec_mode" != "nocodec" ]; then
# USB sound card only supports 1 channel S16_LE format.
format_c=S16_LE
channel_c=1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we real need alsabat for all fmts?

case-lib/lib.sh Outdated
local file=$2

find "$dir" -maxdepth 1 -type f -name "$file" -size +0 -exec cp {} "$LOG_ROOT/" \;
return 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return 0 will become a no-op when this script is converted to set -e.

I recommend you remove it and you invoke the function like this below:

func_upload_wav_file "/tmp" "bat.wav.*" || true

This gives the caller of the function the choice.

(Cc: @RuiqingX )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

func_upload_wav_file "/tmp" "bat.wav.*"
exit 1
}
wait $alsabatPID || die "alsabat -P failed to stop"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit more complicated, sorry I should have spotted this the first time. To be correct this requires two different error messages. Something like this:

wait $alsabatPID && ret=$?
if [ $ret = 124 ]; then
   die "alsabat -P failed to stop - we timed it out"
elif [ $ret != 0 ] ; then
   die "alsabat -P failed, returned $ret"
fi

Untested code, please double-check in man timeout and test by this code by temporarily setting a very short timeout or wrong parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, if the command times out, and --preserve-status is not set, then exit with status 124.

Copy link
Collaborator

@marc-hb marc-hb Sep 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Untested code, please double-check in man timeout and test by this code by temporarily setting a very short timeout or wrong parameters.

With a clearer, Monday morning brain I see the untested code I gave you was wrong: ret never gets initialized when wait fails because of short circuit evaluation. I'm afraid this means you didn't inject any one-line error in the alsabat command, didn't test it locally and never saw these messages printed. This is worrying.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marc-hb , I did performed the negative tests to verify this part of code, tried with wrong channel count "3" in alsabat command and returned 1. if alsabat -P does not stop within the specified time, it will return 124. so which scenario you are talking above?

Copy link
Collaborator

@marc-hb marc-hb Oct 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean this:

ret=0
(exit 124) && ret=$?
echo $ret

=> 0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are overaction here. just put the alsabat -P in background and use wait to check the exit code, if exit code is non-zero, then exit with "alsabat -P failure".

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK @keqiaozhang didn't recommend to remove the timeout command, he only recommended to handle timeout errors exactly like non-timeout errors.

Question for people with alsabat experience: can alsabat get stuck when something goes wrong?

wait $alsabatPID || die "alsabat -P failed to stop"
done

exit 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing newline. There's probably a setting in your editor that you can change to avoid this.

[[ $(aplay -Dplug$pcm_p -d 1 /dev/zero -q) ]] && die "Failed to play on PCM: $pcm_p"
[[ $(arecord -Dplug$pcm_c -d 1 /dev/null -q) ]] && die "Failed to capture on PCM: $pcm_c"
[[ $(aplay -Dplug"$pcm_p" -d 1 /dev/zero -q) ]] && die "Failed to play on PCM: $pcm_p"
[[ $(arecord -Dplug"$pcm_c" -d 1 /dev/null -q) ]] && die "Failed to capture on PCM: $pcm_c"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not something you're changing but it looks like this code was wrong. Can you take the opportunity to try to fix it and change it to:

aplay -Dplug"$pcm_p" -d 1 /dev/zero -q || die "Failed to play on PCM: $pcm_p"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, die will never be executed.

[[ $(aplay -Dplug$pcm_p -d 1 /dev/zero -q) ]] && die "Failed to play on PCM: $pcm_p"
[[ $(arecord -Dplug$pcm_c -d 1 /dev/null -q) ]] && die "Failed to capture on PCM: $pcm_c"
aplay -Dplug"$pcm_p" -d 1 /dev/zero -q || die "Failed to play on PCM: $pcm_p"
arecord -Dplug"$pcm_c" -d 1 /dev/null -q || die "Failed to capture on PCM: $pcm_c"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks like an unrelated cleanup?

Copy link
Collaborator

@marc-hb marc-hb Oct 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I requested this (serious!) bug fix, see earlier comments. Agreed it should ideally be in a different commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have separated it as a new commit.

else
# USB sound card only supports 1 channel S16_LE format.
format_c=S16_LE
channel_c=1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You guys need to buy better USB cards, this is not acceptable for channel swap tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same idea here, we are looking for new cards now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internal issue 601 just filed about new USB cards, thanks @singalsu.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you all. Let's hold this PR. Now we are trying to find a new USB cards w/ stereo capture support, then we can remove the plug completely.

exit 1
}
wait $alsabatPID && ret=$?
if [ $ret == 124 ]; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what the hell does 124 mean?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meaning of 124 is (again) in the man timeout page, in a previous review command and much better it is on the very next line: "alsabat -P failed to stop, we timed it out."

fi

dlogc "alsabat -P $pcm_p --standalone -n $frames -F $frequency -c $channel -r $rate -f $format"
timeout -k 2 6 alsabat -P "$pcm_p" --standalone -n "$frames" -F "$frequency" -c "$channel" \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does 2 6 mean? seriously add comments on what this does.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meanings of 2 and 6 are at the top of the man timeout page. I don't think we need to copy/paste into this script the start of the man page of every unusual command but maybe we can have the --long options like this:

timeout --kill-after 2 6 alsabat ...

dlogc "alsabat -P $pcm_p --standalone -n $frames -F $frequency -c $channel -r $rate -f $format"
timeout -k 2 6 alsabat -P "$pcm_p" --standalone -n "$frames" -F "$frequency" -c "$channel" \
-r "$rate" -f "$format" & alsabatPID=$!
# playback may have low latency, add one second delay to aviod recording zero at beginning.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid

Copy link
Collaborator

@marc-hb marc-hb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still concerned about the lack of negative wait testing mentioned at
#401 (comment)

exit 1
}
wait $alsabatPID && ret=$?
if [ $ret == 124 ]; then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meaning of 124 is (again) in the man timeout page, in a previous review command and much better it is on the very next line: "alsabat -P failed to stop, we timed it out."

fi

dlogc "alsabat -P $pcm_p --standalone -n $frames -F $frequency -c $channel -r $rate -f $format"
timeout -k 2 6 alsabat -P "$pcm_p" --standalone -n "$frames" -F "$frequency" -c "$channel" \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meanings of 2 and 6 are at the top of the man timeout page. I don't think we need to copy/paste into this script the start of the man page of every unusual command but maybe we can have the --long options like this:

timeout --kill-after 2 6 alsabat ...

[[ $(aplay -Dplug$pcm_p -d 1 /dev/zero -q) ]] && die "Failed to play on PCM: $pcm_p"
[[ $(arecord -Dplug$pcm_c -d 1 /dev/null -q) ]] && die "Failed to capture on PCM: $pcm_c"
aplay -Dplug"$pcm_p" -d 1 /dev/zero -q || die "Failed to play on PCM: $pcm_p"
arecord -Dplug"$pcm_c" -d 1 /dev/null -q || die "Failed to capture on PCM: $pcm_c"
Copy link
Collaborator

@marc-hb marc-hb Oct 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I requested this (serious!) bug fix, see earlier comments. Agreed it should ideally be in a different commit.

add 2 functions to lib.sh. The first is to check whether sof
is running in nocodec mode. The second is to add a function
to upload wav files.

Signed-off-by: Zhang Keqiao <keqiao.zhang@linux.intel.com>
remove use of plughw to run alsabat test at hw level driectly
without any conversions done by alsa-lib and refine the script.

Signed-off-by: Zhang Keqiao <keqiao.zhang@linux.intel.com>
Use double quote to prevent globbing and fix the logic issue or
die will never be executed.

Signed-off-by: Zhang Keqiao <keqiao.zhang@linux.intel.com>
Copy link
Contributor

@xiulipan xiulipan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some update is needed. Please check

@@ -252,6 +252,19 @@ func_lib_get_tplg_path()
return 0
}

func_nocodec_mode()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we dump the result at first and only use the variable later? Three is no need to check this mode multiple time

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we dump the result at first and only use the variable later?

This would be premature optimization. This command is only forking two additional and small processes per alsabat test, that's negligible.

uname -r |grep "nocodec" >> /dev/null &&
echo "nocodec"
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see any update for this. but I have same idea with this.

@@ -252,6 +252,19 @@ func_lib_get_tplg_path()
return 0
}

func_nocodec_mode()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we dump the result at first and only use the variable later?

This would be premature optimization. This command is only forking two additional and small processes per alsabat test, that's negligible.

func_upload_wav_file()
{
local dir=$1
local file=$2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While double quotes are technically not required for assignments it's safer and good role modelling to just always quote.

@@ -48,39 +54,54 @@ then
exit 2
fi

pcmid_p=${pcm_p:-1}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, please double quote for consistency.

# playback may have low latency, add one second delay to aviod recording zero at beginning.
sleep 1

if func_nocodec_mode; then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if nocodec_mode; then would read like plain English.

}
# check the alsabat -P exit code
if ! wait $alsabatPID; then
die "alsabat -P failure"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for the ! negation

wait $alsabatPID || die "alsabat $alsabatPID failed"

func_upload_wav_file "/tmp" "bat.wav.*"
exit 1
}
wait $alsabatPID || die "alsabat -P failed to stop"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK @keqiaozhang didn't recommend to remove the timeout command, he only recommended to handle timeout errors exactly like non-timeout errors.

Question for people with alsabat experience: can alsabat get stuck when something goes wrong?

Copy link
Contributor

@xiulipan xiulipan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@keqiaozhang The PR is almost good, please fix some typo and address the advice to use a variable instead of call func_nocodec_mode multiple times

@xiulipan
Copy link
Contributor

xiulipan commented Dec 3, 2020

@keqiaozhang Ping for update or close.

@keqiaozhang
Copy link
Contributor Author

@keqiaozhang Ping for update or close.

I just received the new USB card, will try with the new card and refine this patch soon.

@keqiaozhang
Copy link
Contributor Author

Submitted a new one #554.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants