mirror of
https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git
synced 2026-10-24 00:48:53 +03:00
Fix shellcheck SC2046[1], SC2068[2], SC2068[3] and SC2206[4], all of which are related to avoiding word splitting and globbing. [1] https://www.shellcheck.net/wiki/SC2046 [2] https://www.shellcheck.net/wiki/SC2068 [3] https://www.shellcheck.net/wiki/SC2086 [4] https://www.shellcheck.net/wiki/SC2206 Signed-off-by: Kent Gibson <warthog618@gmail.com> Link: https://lore.kernel.org/r/20240603115628.102616-9-warthog618@gmail.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
3090 lines
72 KiB
Bash
Executable File
3090 lines
72 KiB
Bash
Executable File
#!/bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
# SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@gmail.com>
|
|
# SPDX-FileCopyrightText: 2022 Kent Gibson <warthog618@gmail.com>
|
|
# SPDX-FileCopyrightText: 2023 Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
|
|
# Simple test harness for the gpio-tools.
|
|
|
|
# Where output from the dut is stored (must be used together
|
|
# with SHUNIT_TMPDIR).
|
|
DUT_OUTPUT=gpio-tools-test-output
|
|
|
|
# Save the PID of coprocess - otherwise we won't be able to wait for it
|
|
# once it exits as the COPROC_PID will be cleared.
|
|
DUT_PID=""
|
|
|
|
SOURCE_DIR=$(dirname "${BASH_SOURCE[0]}")
|
|
|
|
# mappings from local name to system chip name, path, dev name
|
|
declare -A GPIOSIM_CHIP_NAME
|
|
declare -A GPIOSIM_CHIP_PATH
|
|
declare -A GPIOSIM_DEV_NAME
|
|
GPIOSIM_CONFIGFS="/sys/kernel/config/gpio-sim"
|
|
GPIOSIM_SYSFS="/sys/devices/platform/"
|
|
GPIOSIM_APP_NAME="gpio-tools-test"
|
|
|
|
MIN_KERNEL_VERSION="5.17.4"
|
|
MIN_SHUNIT_VERSION="2.1.8"
|
|
|
|
# Run the command in $@ and fail the test if the command succeeds.
|
|
assert_fail() {
|
|
"$@" || return 0
|
|
fail " '$*': command did not fail as expected"
|
|
}
|
|
|
|
# Check if the string in $2 matches against the pattern in $1.
|
|
regex_matches() {
|
|
[[ $2 =~ $1 ]]
|
|
assertEquals " '$2' did not match '$1':" "0" "$?"
|
|
}
|
|
|
|
output_contains_line() {
|
|
assertContains "$1" "$output"
|
|
}
|
|
|
|
output_is() {
|
|
assertEquals " output:" "$1" "$output"
|
|
}
|
|
|
|
num_lines_is() {
|
|
[ "$1" -eq "0" ] || [ -z "$output" ] && return 0
|
|
local NUM_LINES
|
|
NUM_LINES=$(echo "$output" | wc -l)
|
|
assertEquals " number of lines:" "$1" "$NUM_LINES"
|
|
}
|
|
|
|
status_is() {
|
|
assertEquals " status:" "$1" "$status"
|
|
}
|
|
|
|
# Same as above but match against the regex pattern in $1.
|
|
output_regex_match() {
|
|
[[ "$output" =~ $1 ]]
|
|
assertEquals " '$output' did not match '$1'" "0" "$?"
|
|
}
|
|
|
|
gpiosim_chip() {
|
|
local VAR=$1
|
|
local NAME=${GPIOSIM_APP_NAME}-$$-${VAR}
|
|
local DEVPATH=$GPIOSIM_CONFIGFS/$NAME
|
|
local BANKPATH=$DEVPATH/bank0
|
|
|
|
mkdir -p "$BANKPATH"
|
|
|
|
for ARG in "$@"
|
|
do
|
|
local KEY VAL
|
|
KEY=$(echo "$ARG" | cut -d"=" -f1)
|
|
VAL=$(echo "$ARG" | cut -d"=" -f2)
|
|
|
|
if [ "$KEY" = "num_lines" ]
|
|
then
|
|
echo "$VAL" > "$BANKPATH/num_lines"
|
|
elif [ "$KEY" = "line_name" ]
|
|
then
|
|
local OFFSET LINENAME
|
|
OFFSET=$(echo "$VAL" | cut -d":" -f1)
|
|
LINENAME=$(echo "$VAL" | cut -d":" -f2)
|
|
local LINEPATH=$BANKPATH/line$OFFSET
|
|
|
|
mkdir -p "$LINEPATH"
|
|
echo "$LINENAME" > "$LINEPATH/name"
|
|
fi
|
|
done
|
|
|
|
echo 1 > "$DEVPATH/live"
|
|
|
|
local CHIP_NAME
|
|
CHIP_NAME=$(<"$BANKPATH/chip_name")
|
|
GPIOSIM_CHIP_NAME[$1]=$CHIP_NAME
|
|
GPIOSIM_CHIP_PATH[$1]="/dev/$CHIP_NAME"
|
|
GPIOSIM_DEV_NAME[$1]=$(<"$DEVPATH/dev_name")
|
|
}
|
|
|
|
gpiosim_chip_number() {
|
|
local NAME=${GPIOSIM_CHIP_NAME[$1]}
|
|
echo "${NAME#gpiochip}"
|
|
}
|
|
|
|
gpiosim_chip_symlink() {
|
|
GPIOSIM_CHIP_LINK="$2/${GPIOSIM_APP_NAME}-$$-lnk"
|
|
ln -s "${GPIOSIM_CHIP_PATH[$1]}" "$GPIOSIM_CHIP_LINK"
|
|
}
|
|
|
|
gpiosim_chip_symlink_cleanup() {
|
|
if [ -n "$GPIOSIM_CHIP_LINK" ]
|
|
then
|
|
rm "$GPIOSIM_CHIP_LINK"
|
|
fi
|
|
unset GPIOSIM_CHIP_LINK
|
|
}
|
|
|
|
gpiosim_set_pull() {
|
|
local OFFSET=$2
|
|
local PULL=$3
|
|
local DEVNAME=${GPIOSIM_DEV_NAME[$1]}
|
|
local CHIPNAME=${GPIOSIM_CHIP_NAME[$1]}
|
|
|
|
echo "$PULL" > "$GPIOSIM_SYSFS/$DEVNAME/$CHIPNAME/sim_gpio$OFFSET/pull"
|
|
}
|
|
|
|
gpiosim_check_value() {
|
|
local OFFSET=$2
|
|
local EXPECTED=$3
|
|
local DEVNAME=${GPIOSIM_DEV_NAME[$1]}
|
|
local CHIPNAME=${GPIOSIM_CHIP_NAME[$1]}
|
|
|
|
VAL=$(<"$GPIOSIM_SYSFS/$DEVNAME/$CHIPNAME/sim_gpio$OFFSET/value")
|
|
[ "$VAL" = "$EXPECTED" ]
|
|
}
|
|
|
|
gpiosim_wait_value() {
|
|
local OFFSET=$2
|
|
local EXPECTED=$3
|
|
local DEVNAME=${GPIOSIM_DEV_NAME[$1]}
|
|
local CHIPNAME=${GPIOSIM_CHIP_NAME[$1]}
|
|
local PORT=$GPIOSIM_SYSFS/$DEVNAME/$CHIPNAME/sim_gpio$OFFSET/value
|
|
|
|
for _i in {1..30}; do
|
|
[ "$(<"$PORT")" = "$EXPECTED" ] && return
|
|
sleep 0.01
|
|
done
|
|
return 1
|
|
}
|
|
|
|
gpiosim_cleanup() {
|
|
for CHIP in "${!GPIOSIM_CHIP_NAME[@]}"
|
|
do
|
|
local NAME=${GPIOSIM_APP_NAME}-$$-$CHIP
|
|
|
|
local DEVPATH=$GPIOSIM_CONFIGFS/$NAME
|
|
|
|
echo 0 > "$DEVPATH/live"
|
|
find "$DEVPATH" -type d -name hog -exec rmdir '{}' '+'
|
|
find "$DEVPATH" -type d -name "line*" -exec rmdir '{}' '+'
|
|
find "$DEVPATH" -type d -name "bank*" -exec rmdir '{}' '+'
|
|
rmdir "$DEVPATH"
|
|
done
|
|
|
|
gpiosim_chip_symlink_cleanup
|
|
|
|
GPIOSIM_CHIP_NAME=()
|
|
GPIOSIM_CHIP_PATH=()
|
|
GPIOSIM_DEV_NAME=()
|
|
}
|
|
|
|
run_tool() {
|
|
# Executables to test are expected to be in the same directory as the
|
|
# testing script.
|
|
cmd=$1
|
|
shift
|
|
output=$(timeout 10s "$SOURCE_DIR/$cmd" "$@" 2>&1)
|
|
status=$?
|
|
}
|
|
|
|
dut_run() {
|
|
cmd=$1
|
|
shift
|
|
coproc timeout 10s "$SOURCE_DIR/$cmd" "$@" 2>&1
|
|
DUT_PID=$COPROC_PID
|
|
read -r -t1 -n1 -u "${COPROC[0]}" DUT_FIRST_CHAR
|
|
}
|
|
|
|
dut_run_redirect() {
|
|
cmd=$1
|
|
shift
|
|
coproc timeout 10s "$SOURCE_DIR/$cmd" "$@" > "$SHUNIT_TMPDIR/$DUT_OUTPUT" 2>&1
|
|
DUT_PID=$COPROC_PID
|
|
# give the process time to spin up
|
|
# FIXME - find a better solution
|
|
sleep 0.2
|
|
}
|
|
|
|
dut_read_redirect() {
|
|
output=$(<"$SHUNIT_TMPDIR/$DUT_OUTPUT")
|
|
local ORIG_IFS="$IFS"
|
|
IFS=$'\n' mapfile -t lines <<< "$output"
|
|
IFS="$ORIG_IFS"
|
|
}
|
|
|
|
dut_read() {
|
|
local LINE
|
|
lines=()
|
|
while read -r -t 0.2 -u "${COPROC[0]}" LINE
|
|
do
|
|
if [ -n "$DUT_FIRST_CHAR" ]
|
|
then
|
|
LINE=${DUT_FIRST_CHAR}${LINE}
|
|
unset DUT_FIRST_CHAR
|
|
fi
|
|
lines+=("$LINE")
|
|
done
|
|
output="${lines[*]}"
|
|
}
|
|
|
|
dut_readable() {
|
|
read -t 0 -u "${COPROC[0]}" LINE
|
|
}
|
|
|
|
dut_flush() {
|
|
local _JUNK
|
|
lines=()
|
|
output=
|
|
unset DUT_FIRST_CHAR
|
|
while read -t 0 -u "${COPROC[0]}" _JUNK
|
|
do
|
|
read -r -t 0.1 -u "${COPROC[0]}" _JUNK || true
|
|
done
|
|
}
|
|
|
|
# check the next line of output matches the regex
|
|
dut_regex_match() {
|
|
PATTERN=$1
|
|
|
|
read -r -t 0.2 -u "${COPROC[0]}" LINE || (echo Timeout && false)
|
|
if [ -n "$DUT_FIRST_CHAR" ]
|
|
then
|
|
LINE=${DUT_FIRST_CHAR}${LINE}
|
|
unset DUT_FIRST_CHAR
|
|
fi
|
|
[[ $LINE =~ $PATTERN ]]
|
|
assertEquals "'$LINE' did not match '$PATTERN'" "0" "$?"
|
|
}
|
|
|
|
dut_write() {
|
|
echo "$@" >&"${COPROC[1]}"
|
|
}
|
|
|
|
dut_kill() {
|
|
kill "$@" "$DUT_PID"
|
|
}
|
|
|
|
dut_wait() {
|
|
wait "$DUT_PID"
|
|
export status=$?
|
|
unset DUT_PID
|
|
}
|
|
|
|
dut_cleanup() {
|
|
if [ -n "$DUT_PID" ]
|
|
then
|
|
kill -SIGTERM "$DUT_PID" 2> /dev/null
|
|
wait "$DUT_PID" || false
|
|
fi
|
|
rm -f "$SHUNIT_TMPDIR/$DUT_OUTPUT"
|
|
}
|
|
|
|
tearDown() {
|
|
dut_cleanup
|
|
gpiosim_cleanup
|
|
}
|
|
|
|
request_release_line() {
|
|
"$SOURCE_DIR/gpioget" -c "$@" >/dev/null
|
|
}
|
|
|
|
#
|
|
# gpiodetect test cases
|
|
#
|
|
|
|
test_gpiodetect_all_chips() {
|
|
gpiosim_chip sim0 num_lines=4
|
|
gpiosim_chip sim1 num_lines=8
|
|
gpiosim_chip sim2 num_lines=16
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
local sim1=${GPIOSIM_CHIP_NAME[sim1]}
|
|
local sim2=${GPIOSIM_CHIP_NAME[sim2]}
|
|
local sim0dev=${GPIOSIM_DEV_NAME[sim0]}
|
|
local sim1dev=${GPIOSIM_DEV_NAME[sim1]}
|
|
local sim2dev=${GPIOSIM_DEV_NAME[sim2]}
|
|
|
|
run_tool gpiodetect
|
|
|
|
output_regex_match "$sim0 \[${sim0dev}[-:]node0\] \(4 lines\)"
|
|
output_regex_match "$sim1 \[${sim1dev}[-:]node0\] \(8 lines\)"
|
|
output_regex_match "$sim2 \[${sim2dev}[-:]node0\] \(16 lines\)"
|
|
status_is 0
|
|
|
|
# ignoring symlinks
|
|
local initial_output=$output
|
|
gpiosim_chip_symlink sim1 /dev
|
|
|
|
run_tool gpiodetect
|
|
|
|
output_is "$initial_output"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpiodetect_a_chip() {
|
|
gpiosim_chip sim0 num_lines=4
|
|
gpiosim_chip sim1 num_lines=8
|
|
gpiosim_chip sim2 num_lines=16
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
local sim1=${GPIOSIM_CHIP_NAME[sim1]}
|
|
local sim2=${GPIOSIM_CHIP_NAME[sim2]}
|
|
local sim0dev=${GPIOSIM_DEV_NAME[sim0]}
|
|
local sim1dev=${GPIOSIM_DEV_NAME[sim1]}
|
|
local sim2dev=${GPIOSIM_DEV_NAME[sim2]}
|
|
|
|
# by name
|
|
run_tool gpiodetect "$sim0"
|
|
|
|
output_regex_match "$sim0 \[${sim0dev}[-:]node0\] \(4 lines\)"
|
|
num_lines_is 1
|
|
status_is 0
|
|
|
|
# by path
|
|
run_tool gpiodetect "${GPIOSIM_CHIP_PATH[sim1]}"
|
|
|
|
output_regex_match "$sim1 \[${sim1dev}[-:]node0\] \(8 lines\)"
|
|
num_lines_is 1
|
|
status_is 0
|
|
|
|
# by number
|
|
run_tool gpiodetect "$(gpiosim_chip_number sim2)"
|
|
|
|
output_regex_match "$sim2 \[${sim2dev}[-:]node0\] \(16 lines\)"
|
|
num_lines_is 1
|
|
status_is 0
|
|
|
|
# by symlink
|
|
gpiosim_chip_symlink sim2 .
|
|
run_tool gpiodetect "$GPIOSIM_CHIP_LINK"
|
|
|
|
output_regex_match "$sim2 \[${sim2dev}[-:]node0\] \(16 lines\)"
|
|
num_lines_is 1
|
|
status_is 0
|
|
}
|
|
|
|
test_gpiodetect_multiple_chips() {
|
|
gpiosim_chip sim0 num_lines=4
|
|
gpiosim_chip sim1 num_lines=8
|
|
gpiosim_chip sim2 num_lines=16
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
local sim1=${GPIOSIM_CHIP_NAME[sim1]}
|
|
local sim2=${GPIOSIM_CHIP_NAME[sim2]}
|
|
local sim0dev=${GPIOSIM_DEV_NAME[sim0]}
|
|
local sim1dev=${GPIOSIM_DEV_NAME[sim1]}
|
|
local sim2dev=${GPIOSIM_DEV_NAME[sim2]}
|
|
|
|
run_tool gpiodetect "$sim0" "$sim1" "$sim2"
|
|
|
|
output_regex_match "$sim0 \[${sim0dev}[-:]node0\] \(4 lines\)"
|
|
output_regex_match "$sim1 \[${sim1dev}[-:]node0\] \(8 lines\)"
|
|
output_regex_match "$sim2 \[${sim2dev}[-:]node0\] \(16 lines\)"
|
|
num_lines_is 3
|
|
status_is 0
|
|
}
|
|
|
|
test_gpiodetect_with_nonexistent_chip() {
|
|
run_tool gpiodetect nonexistent-chip
|
|
|
|
status_is 1
|
|
output_regex_match \
|
|
".*cannot find GPIO chip character device 'nonexistent-chip'"
|
|
}
|
|
|
|
#
|
|
# gpioinfo test cases
|
|
#
|
|
|
|
test_gpioinfo_all_chips() {
|
|
gpiosim_chip sim0 num_lines=4
|
|
gpiosim_chip sim1 num_lines=8
|
|
|
|
run_tool gpioinfo
|
|
|
|
output_contains_line "${GPIOSIM_CHIP_NAME[sim0]} - 4 lines:"
|
|
output_contains_line "${GPIOSIM_CHIP_NAME[sim1]} - 8 lines:"
|
|
output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+input"
|
|
output_regex_match "\\s+line\\s+7:\\s+unnamed\\s+input"
|
|
status_is 0
|
|
|
|
# ignoring symlinks
|
|
local initial_output=$output
|
|
gpiosim_chip_symlink sim1 /dev
|
|
|
|
run_tool gpioinfo
|
|
|
|
output_is "$initial_output"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioinfo_all_chips_with_some_used_lines() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
|
|
gpiosim_chip sim1 num_lines=8 line_name=3:baz line_name=4:xyz
|
|
|
|
dut_run gpioset --banner --active-low foo=1 baz=0
|
|
|
|
run_tool gpioinfo
|
|
|
|
output_contains_line "${GPIOSIM_CHIP_NAME[sim0]} - 4 lines:"
|
|
output_contains_line "${GPIOSIM_CHIP_NAME[sim1]} - 8 lines:"
|
|
output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+input"
|
|
output_regex_match \
|
|
"\\s+line\\s+1:\\s+\"foo\"\\s+output active-low consumer=\"gpioset\""
|
|
output_regex_match \
|
|
"\\s+line\\s+3:\\s+\"baz\"\\s+output active-low consumer=\"gpioset\""
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioinfo_a_chip() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
gpiosim_chip sim1 num_lines=4
|
|
|
|
local sim1=${GPIOSIM_CHIP_NAME[sim1]}
|
|
|
|
# by name
|
|
run_tool gpioinfo --chip "$sim1"
|
|
|
|
output_contains_line "$sim1 - 4 lines:"
|
|
output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+input"
|
|
output_regex_match "\\s+line\\s+1:\\s+unnamed\\s+input"
|
|
output_regex_match "\\s+line\\s+2:\\s+unnamed\\s+input"
|
|
output_regex_match "\\s+line\\s+3:\\s+unnamed\\s+input"
|
|
num_lines_is 5
|
|
status_is 0
|
|
|
|
# by path
|
|
run_tool gpioinfo --chip "$sim1"
|
|
|
|
output_contains_line "$sim1 - 4 lines:"
|
|
output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+input"
|
|
output_regex_match "\\s+line\\s+1:\\s+unnamed\\s+input"
|
|
output_regex_match "\\s+line\\s+2:\\s+unnamed\\s+input"
|
|
output_regex_match "\\s+line\\s+3:\\s+unnamed\\s+input"
|
|
num_lines_is 5
|
|
status_is 0
|
|
|
|
# by number
|
|
run_tool gpioinfo --chip "$sim1"
|
|
|
|
output_contains_line "$sim1 - 4 lines:"
|
|
output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+input"
|
|
output_regex_match "\\s+line\\s+1:\\s+unnamed\\s+input"
|
|
output_regex_match "\\s+line\\s+2:\\s+unnamed\\s+input"
|
|
output_regex_match "\\s+line\\s+3:\\s+unnamed\\s+input"
|
|
num_lines_is 5
|
|
status_is 0
|
|
|
|
# by symlink
|
|
gpiosim_chip_symlink sim1 .
|
|
run_tool gpioinfo --chip "$GPIOSIM_CHIP_LINK"
|
|
|
|
output_contains_line "$sim1 - 4 lines:"
|
|
output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+input"
|
|
output_regex_match "\\s+line\\s+1:\\s+unnamed\\s+input"
|
|
output_regex_match "\\s+line\\s+2:\\s+unnamed\\s+input"
|
|
output_regex_match "\\s+line\\s+3:\\s+unnamed\\s+input"
|
|
num_lines_is 5
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioinfo_a_line() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=5:bar
|
|
gpiosim_chip sim1 num_lines=4 line_name=2:bar
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
local sim1=${GPIOSIM_CHIP_NAME[sim1]}
|
|
|
|
# by offset
|
|
run_tool gpioinfo --chip "$sim1" 2
|
|
|
|
output_regex_match "$sim1 2\\s+\"bar\"\\s+input"
|
|
num_lines_is 1
|
|
status_is 0
|
|
|
|
# by name
|
|
run_tool gpioinfo bar
|
|
|
|
output_regex_match "$sim0 5\\s+\"bar\"\\s+input"
|
|
num_lines_is 1
|
|
status_is 0
|
|
|
|
# by chip and name
|
|
run_tool gpioinfo --chip "$sim1" 2
|
|
|
|
output_regex_match "$sim1 2\\s+\"bar\"\\s+input"
|
|
num_lines_is 1
|
|
status_is 0
|
|
|
|
# unquoted
|
|
run_tool gpioinfo --unquoted --chip "$sim1" 2
|
|
|
|
output_regex_match "$sim1 2\\s+bar\\s+input"
|
|
num_lines_is 1
|
|
status_is 0
|
|
|
|
}
|
|
|
|
test_gpioinfo_first_matching_named_line() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar \
|
|
line_name=3:foobar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=2:foobar \
|
|
line_name=4:xyz line_name=7:foobar
|
|
gpiosim_chip sim2 num_lines=16
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpioinfo foobar
|
|
|
|
output_regex_match "$sim0 3\\s+\"foobar\"\\s+input"
|
|
num_lines_is 1
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioinfo_multiple_lines() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=5:bar
|
|
gpiosim_chip sim1 num_lines=4 line_name=2:baz
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
local sim1=${GPIOSIM_CHIP_NAME[sim1]}
|
|
|
|
# by offset
|
|
run_tool gpioinfo --chip "$sim1" 1 2
|
|
|
|
output_regex_match "$sim1 1\\s+unnamed\\s+input"
|
|
output_regex_match "$sim1 2\\s+\"baz\"\\s+input"
|
|
num_lines_is 2
|
|
status_is 0
|
|
|
|
# by name
|
|
run_tool gpioinfo bar baz
|
|
|
|
output_regex_match "$sim0 5\\s+\"bar\"\\s+input"
|
|
output_regex_match "$sim1 2\\s+\"baz\"\\s+input"
|
|
num_lines_is 2
|
|
status_is 0
|
|
|
|
# by name and offset
|
|
run_tool gpioinfo --chip "$sim0" bar 3
|
|
|
|
output_regex_match "$sim0 5\\s+\"bar\"\\s+input"
|
|
output_regex_match "$sim0 3\\s+unnamed\\s+input"
|
|
num_lines_is 2
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioinfo_line_attribute_menagerie() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo
|
|
gpiosim_chip sim1 num_lines=8 line_name=3:baz
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
local sim1=${GPIOSIM_CHIP_NAME[sim1]}
|
|
|
|
dut_run gpioset --banner --active-low --bias=pull-up --drive=open-source foo=1 baz=0
|
|
|
|
run_tool gpioinfo foo baz
|
|
|
|
output_regex_match \
|
|
"$sim0 1\\s+\"foo\"\\s+output active-low drive=open-source bias=pull-up consumer=\"gpioset\""
|
|
output_regex_match \
|
|
"$sim1 3\\s+\"baz\"\\s+output active-low drive=open-source bias=pull-up consumer=\"gpioset\""
|
|
num_lines_is 2
|
|
status_is 0
|
|
|
|
dut_kill
|
|
dut_wait
|
|
|
|
dut_run gpioset --banner --bias=pull-down --drive=open-drain foo=1 baz=0
|
|
|
|
run_tool gpioinfo foo baz
|
|
|
|
output_regex_match \
|
|
"$sim0 1\\s+\"foo\"\\s+output drive=open-drain bias=pull-down consumer=\"gpioset\""
|
|
output_regex_match \
|
|
"$sim1 3\\s+\"baz\"\\s+output drive=open-drain bias=pull-down consumer=\"gpioset\""
|
|
num_lines_is 2
|
|
status_is 0
|
|
|
|
dut_kill
|
|
dut_wait
|
|
|
|
dut_run gpiomon --banner --bias=disabled --utc -p 10ms foo baz
|
|
|
|
run_tool gpioinfo foo baz
|
|
|
|
output_regex_match \
|
|
"$sim0 1\\s+\"foo\"\\s+input bias=disabled edges=both event-clock=realtime debounce-period=10ms consumer=\"gpiomon\""
|
|
output_regex_match \
|
|
"$sim1 3\\s+\"baz\"\\s+input bias=disabled edges=both event-clock=realtime debounce-period=10ms consumer=\"gpiomon\""
|
|
num_lines_is 2
|
|
status_is 0
|
|
|
|
dut_kill
|
|
dut_wait
|
|
|
|
dut_run gpiomon --banner --edges=rising --localtime foo baz
|
|
|
|
run_tool gpioinfo foo baz
|
|
|
|
output_regex_match \
|
|
"$sim0 1\\s+\"foo\"\\s+input edges=rising event-clock=realtime consumer=\"gpiomon\""
|
|
output_regex_match \
|
|
"$sim1 3\\s+\"baz\"\\s+input edges=rising event-clock=realtime consumer=\"gpiomon\""
|
|
num_lines_is 2
|
|
status_is 0
|
|
|
|
dut_kill
|
|
dut_wait
|
|
|
|
dut_run gpiomon --banner --edges=falling foo baz
|
|
|
|
run_tool gpioinfo foo baz
|
|
|
|
output_regex_match \
|
|
"$sim0 1\\s+\"foo\"\\s+input edges=falling consumer=\"gpiomon\""
|
|
output_regex_match \
|
|
"$sim1 3\\s+\"baz\"\\s+input edges=falling consumer=\"gpiomon\""
|
|
num_lines_is 2
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioinfo_with_same_line_twice() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
# by offset
|
|
run_tool gpioinfo --chip "$sim0" 1 1
|
|
|
|
output_regex_match "$sim0 1\\s+\"foo\"\\s+input"
|
|
output_regex_match ".*lines '1' and '1' are the same line"
|
|
num_lines_is 2
|
|
status_is 1
|
|
|
|
# by name
|
|
run_tool gpioinfo foo foo
|
|
|
|
output_regex_match "$sim0 1\\s+\"foo\"\\s+input"
|
|
output_regex_match ".*lines 'foo' and 'foo' are the same line"
|
|
num_lines_is 2
|
|
status_is 1
|
|
|
|
# by name and offset
|
|
run_tool gpioinfo --chip "$sim0" foo 1
|
|
|
|
output_regex_match "$sim0 1\\s+\"foo\"\\s+input"
|
|
output_regex_match ".*lines 'foo' and '1' are the same line"
|
|
num_lines_is 2
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioinfo_all_lines_matching_name() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar \
|
|
line_name=3:foobar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=2:foobar \
|
|
line_name=4:xyz line_name=7:foobar
|
|
gpiosim_chip sim2 num_lines=16
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
local sim1=${GPIOSIM_CHIP_NAME[sim1]}
|
|
|
|
run_tool gpioinfo --strict foobar
|
|
|
|
output_regex_match "$sim0 3\\s+\"foobar\"\\s+input"
|
|
output_regex_match "$sim1 2\\s+\"foobar\"\\s+input"
|
|
output_regex_match "$sim1 7\\s+\"foobar\"\\s+input"
|
|
num_lines_is 3
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioinfo_with_lines_strictly_by_name() {
|
|
# not suggesting this setup makes any sense
|
|
# - just test that we can deal with it
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:6 line_name=6:1
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
# first by offset (to show offsets match first)
|
|
run_tool gpioinfo --chip "$sim0" 1 6
|
|
|
|
output_regex_match "$sim0 1\\s+\"6\"\\s+input"
|
|
output_regex_match "$sim0 6\\s+\"1\"\\s+input"
|
|
num_lines_is 2
|
|
status_is 0
|
|
|
|
# then strictly by name
|
|
run_tool gpioinfo --by-name --chip "$sim0" 1
|
|
|
|
output_regex_match "$sim0 6\\s+\"1\"\\s+input"
|
|
num_lines_is 1
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioinfo_with_nonexistent_chip() {
|
|
run_tool gpioinfo --chip nonexistent-chip
|
|
|
|
output_regex_match \
|
|
".*cannot find GPIO chip character device 'nonexistent-chip'"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioinfo_with_nonexistent_line() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
run_tool gpioinfo nonexistent-line
|
|
|
|
output_regex_match ".*cannot find line 'nonexistent-line'"
|
|
status_is 1
|
|
|
|
run_tool gpioinfo --chip "${GPIOSIM_CHIP_NAME[sim0]}" nonexistent-line
|
|
|
|
output_regex_match ".*cannot find line 'nonexistent-line'"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioinfo_with_offset_out_of_range() {
|
|
gpiosim_chip sim0 num_lines=4
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpioinfo --chip "$sim0" 0 1 2 3 4 5
|
|
|
|
output_regex_match "$sim0 0\\s+unnamed\\s+input"
|
|
output_regex_match "$sim0 1\\s+unnamed\\s+input"
|
|
output_regex_match "$sim0 2\\s+unnamed\\s+input"
|
|
output_regex_match "$sim0 3\\s+unnamed\\s+input"
|
|
output_regex_match ".*offset 4 is out of range on chip '$sim0'"
|
|
output_regex_match ".*offset 5 is out of range on chip '$sim0'"
|
|
num_lines_is 6
|
|
status_is 1
|
|
}
|
|
|
|
#
|
|
# gpioget test cases
|
|
#
|
|
|
|
test_gpioget_by_name() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo
|
|
|
|
gpiosim_set_pull sim0 1 pull-up
|
|
|
|
run_tool gpioget foo
|
|
|
|
output_is "\"foo\"=active"
|
|
status_is 0
|
|
|
|
run_tool gpioget --unquoted foo
|
|
|
|
output_is "foo=active"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_by_offset() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
gpiosim_set_pull sim0 1 pull-up
|
|
|
|
run_tool gpioget --chip "${GPIOSIM_CHIP_NAME[sim0]}" 1
|
|
|
|
output_is "\"1\"=active"
|
|
status_is 0
|
|
|
|
run_tool gpioget --unquoted --chip "${GPIOSIM_CHIP_NAME[sim0]}" 1
|
|
|
|
output_is "1=active"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_by_symlink() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
gpiosim_chip_symlink sim0 .
|
|
|
|
gpiosim_set_pull sim0 1 pull-up
|
|
|
|
run_tool gpioget --chip "$GPIOSIM_CHIP_LINK" 1
|
|
|
|
output_is "\"1\"=active"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_by_chip_and_name() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo
|
|
gpiosim_chip sim1 num_lines=8 line_name=3:foo
|
|
|
|
gpiosim_set_pull sim1 3 pull-up
|
|
|
|
run_tool gpioget --chip "${GPIOSIM_CHIP_NAME[sim1]}" foo
|
|
|
|
output_is "\"foo\"=active"
|
|
status_is 0
|
|
|
|
run_tool gpioget --unquoted --chip "${GPIOSIM_CHIP_NAME[sim1]}" foo
|
|
|
|
output_is "foo=active"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_first_matching_named_line() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar \
|
|
line_name=3:foobar line_name=7:foobar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=2:foobar \
|
|
line_name=4:xyz
|
|
gpiosim_chip sim2 num_lines=16
|
|
|
|
gpiosim_set_pull sim0 3 pull-up
|
|
|
|
run_tool gpioget foobar
|
|
|
|
output_is "\"foobar\"=active"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_multiple_lines() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
gpiosim_set_pull sim0 2 pull-up
|
|
gpiosim_set_pull sim0 3 pull-up
|
|
gpiosim_set_pull sim0 5 pull-up
|
|
gpiosim_set_pull sim0 7 pull-up
|
|
|
|
run_tool gpioget --unquoted --chip "${GPIOSIM_CHIP_NAME[sim0]}" 0 1 2 3 4 5 6 7
|
|
|
|
output_is \
|
|
"0=inactive 1=inactive 2=active 3=active 4=inactive 5=active 6=inactive 7=active"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_multiple_lines_by_name_and_offset() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo line_name=6:bar
|
|
gpiosim_chip sim1 num_lines=8 line_name=1:baz line_name=3:bar
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 1 pull-up
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
gpiosim_set_pull sim0 6 pull-up
|
|
|
|
run_tool gpioget --chip "$sim0" 0 foo 4 bar
|
|
|
|
output_is "\"0\"=inactive \"foo\"=active \"4\"=active \"bar\"=active"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_multiple_lines_across_multiple_chips() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=4:xyz
|
|
|
|
gpiosim_set_pull sim0 1 pull-up
|
|
gpiosim_set_pull sim1 4 pull-up
|
|
|
|
run_tool gpioget baz bar foo xyz
|
|
|
|
output_is "\"baz\"=inactive \"bar\"=inactive \"foo\"=active \"xyz\"=active"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_with_numeric_values() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
gpiosim_set_pull sim0 2 pull-up
|
|
gpiosim_set_pull sim0 3 pull-up
|
|
gpiosim_set_pull sim0 5 pull-up
|
|
gpiosim_set_pull sim0 7 pull-up
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpioget --numeric --chip "$sim0" 0 1 2 3 4 5 6 7
|
|
|
|
output_is "0 0 1 1 0 1 0 1"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_with_active_low() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
gpiosim_set_pull sim0 2 pull-up
|
|
gpiosim_set_pull sim0 3 pull-up
|
|
gpiosim_set_pull sim0 5 pull-up
|
|
gpiosim_set_pull sim0 7 pull-up
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpioget --active-low --unquoted --chip "$sim0" 0 1 2 3 4 5 6 7
|
|
|
|
output_is \
|
|
"0=active 1=active 2=inactive 3=inactive 4=active 5=inactive 6=active 7=inactive"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_with_consumer() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
|
|
gpiosim_chip sim1 num_lines=8 line_name=3:baz line_name=4:xyz
|
|
|
|
dut_run gpionotify --banner -F "%l %E %C" foo baz
|
|
|
|
run_tool gpioget --consumer gpio-tools-tests foo baz
|
|
status_is 0
|
|
|
|
dut_read
|
|
output_regex_match "foo requested gpio-tools-tests"
|
|
output_regex_match "baz requested gpio-tools-tests"
|
|
}
|
|
|
|
test_gpioget_with_pull_up() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
gpiosim_set_pull sim0 2 pull-up
|
|
gpiosim_set_pull sim0 3 pull-up
|
|
gpiosim_set_pull sim0 5 pull-up
|
|
gpiosim_set_pull sim0 7 pull-up
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpioget --bias=pull-up --unquoted --chip "$sim0" 0 1 2 3 4 5 6 7
|
|
|
|
output_is \
|
|
"0=active 1=active 2=active 3=active 4=active 5=active 6=active 7=active"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_with_pull_down() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
gpiosim_set_pull sim0 2 pull-up
|
|
gpiosim_set_pull sim0 3 pull-up
|
|
gpiosim_set_pull sim0 5 pull-up
|
|
gpiosim_set_pull sim0 7 pull-up
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpioget --bias=pull-down --unquoted --chip "$sim0" 0 1 2 3 4 5 6 7
|
|
|
|
output_is \
|
|
"0=inactive 1=inactive 2=inactive 3=inactive 4=inactive 5=inactive 6=inactive 7=inactive"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_with_direction_as_is() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
# flip to output
|
|
run_tool gpioset -t0 foo=1
|
|
|
|
status_is 0
|
|
|
|
run_tool gpioinfo foo
|
|
output_regex_match "$sim0 1\\s+\"foo\"\\s+output"
|
|
status_is 0
|
|
|
|
run_tool gpioget --as-is foo
|
|
# note gpio-sim reverts line to its pull when released
|
|
output_is "\"foo\"=inactive"
|
|
status_is 0
|
|
|
|
run_tool gpioinfo foo
|
|
output_regex_match "$sim0 1\\s+\"foo\"\\s+output"
|
|
status_is 0
|
|
|
|
# whereas the default behaviour forces to input
|
|
run_tool gpioget foo
|
|
# note gpio-sim reverts line to its pull when released
|
|
# (defaults to pull-down)
|
|
output_is "\"foo\"=inactive"
|
|
status_is 0
|
|
|
|
run_tool gpioinfo foo
|
|
output_regex_match "$sim0 1\\s+\"foo\"\\s+input"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_with_hold_period() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo
|
|
|
|
# only test parsing - testing the hold-period itself is tricky
|
|
run_tool gpioget --hold-period=100ms foo
|
|
output_is "\"foo\"=inactive"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_with_strict_named_line_check() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar \
|
|
line_name=3:foobar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=2:foobar \
|
|
line_name=4:xyz line_name=7:foobar
|
|
gpiosim_chip sim2 num_lines=16
|
|
|
|
run_tool gpioget --strict foobar
|
|
|
|
output_regex_match ".*line 'foobar' is not unique"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioget_with_lines_by_offset() {
|
|
# not suggesting this setup makes any sense
|
|
# - just test that we can deal with it
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:6 line_name=6:1
|
|
|
|
gpiosim_set_pull sim0 1 pull-up
|
|
gpiosim_set_pull sim0 6 pull-down
|
|
|
|
run_tool gpioget --chip "${GPIOSIM_CHIP_NAME[sim0]}" 1 6
|
|
|
|
output_is "\"1\"=active \"6\"=inactive"
|
|
status_is 0
|
|
|
|
run_tool gpioget --unquoted --chip "${GPIOSIM_CHIP_NAME[sim0]}" 1 6
|
|
|
|
output_is "1=active 6=inactive"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_with_lines_strictly_by_name() {
|
|
# not suggesting this setup makes any sense
|
|
# - just test that we can deal with it
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:6 line_name=6:1
|
|
|
|
gpiosim_set_pull sim0 1 pull-up
|
|
gpiosim_set_pull sim0 6 pull-down
|
|
|
|
run_tool gpioget --by-name --chip "${GPIOSIM_CHIP_NAME[sim0]}" 1 6
|
|
|
|
output_is "\"1\"=inactive \"6\"=active"
|
|
status_is 0
|
|
|
|
run_tool gpioget --by-name --unquoted --chip "${GPIOSIM_CHIP_NAME[sim0]}" 1 6
|
|
|
|
output_is "1=inactive 6=active"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioget_with_no_arguments() {
|
|
run_tool gpioget
|
|
|
|
output_regex_match ".*at least one GPIO line must be specified"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioget_with_chip_but_no_line_specified() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
run_tool gpioget --chip "${GPIOSIM_CHIP_NAME[sim0]}"
|
|
|
|
output_regex_match ".*at least one GPIO line must be specified"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioget_with_offset_out_of_range() {
|
|
gpiosim_chip sim0 num_lines=4
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpioget --chip "$sim0" 0 1 2 3 4 5
|
|
|
|
output_regex_match ".*offset 4 is out of range on chip '$sim0'"
|
|
output_regex_match ".*offset 5 is out of range on chip '$sim0'"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioget_with_nonexistent_line() {
|
|
run_tool gpioget nonexistent-line
|
|
|
|
output_regex_match ".*cannot find line 'nonexistent-line'"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioget_with_same_line_twice() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
# by offset
|
|
run_tool gpioget --chip "$sim0" 0 0
|
|
|
|
output_regex_match ".*lines '0' and '0' are the same line"
|
|
status_is 1
|
|
|
|
# by name
|
|
run_tool gpioget foo foo
|
|
|
|
output_regex_match ".*lines 'foo' and 'foo' are the same line"
|
|
status_is 1
|
|
|
|
# by chip and name
|
|
run_tool gpioget --chip "$sim0" foo foo
|
|
|
|
output_regex_match ".*lines 'foo' and 'foo' are the same line"
|
|
status_is 1
|
|
|
|
# by name and offset
|
|
run_tool gpioget --chip "$sim0" foo 1
|
|
|
|
output_regex_match ".*lines 'foo' and '1' are the same line"
|
|
status_is 1
|
|
|
|
# by offset and name
|
|
run_tool gpioget --chip "$sim0" 1 foo
|
|
|
|
output_regex_match ".*lines '1' and 'foo' are the same line"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioget_with_invalid_bias() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
run_tool gpioget --bias=bad --chip "${GPIOSIM_CHIP_NAME[sim0]}" 0 1
|
|
|
|
output_regex_match ".*invalid bias.*"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioget_with_invalid_hold_period() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
run_tool gpioget --hold-period=bad --chip "${GPIOSIM_CHIP_NAME[sim0]}" 0
|
|
|
|
output_regex_match ".*invalid period.*"
|
|
status_is 1
|
|
}
|
|
|
|
#
|
|
# gpioset test cases
|
|
#
|
|
|
|
test_gpioset_by_name() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo
|
|
|
|
dut_run gpioset --banner foo=1
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
}
|
|
|
|
test_gpioset_by_offset() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
dut_run gpioset --banner --chip "${GPIOSIM_CHIP_NAME[sim0]}" 1=1
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
}
|
|
|
|
test_gpioset_by_symlink() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
gpiosim_chip_symlink sim0 .
|
|
|
|
dut_run gpioset --banner --chip "$GPIOSIM_CHIP_LINK" 1=1
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
}
|
|
|
|
test_gpioset_by_chip_and_name() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo
|
|
gpiosim_chip sim1 num_lines=8 line_name=3:foo
|
|
|
|
dut_run gpioset --banner --chip "${GPIOSIM_CHIP_NAME[sim1]}" foo=1
|
|
|
|
gpiosim_check_value sim1 3 1
|
|
}
|
|
|
|
test_gpioset_first_matching_named_line() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar \
|
|
line_name=3:foobar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=2:foobar \
|
|
line_name=4:xyz line_name=7:foobar
|
|
gpiosim_chip sim2 num_lines=16
|
|
|
|
dut_run gpioset --banner foobar=1
|
|
|
|
gpiosim_check_value sim0 3 1
|
|
}
|
|
|
|
test_gpioset_multiple_lines() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpioset --banner --chip "$sim0" 0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
|
|
|
|
gpiosim_check_value sim0 0 0
|
|
gpiosim_check_value sim0 1 0
|
|
gpiosim_check_value sim0 2 1
|
|
gpiosim_check_value sim0 3 1
|
|
gpiosim_check_value sim0 4 1
|
|
gpiosim_check_value sim0 5 1
|
|
gpiosim_check_value sim0 6 0
|
|
gpiosim_check_value sim0 7 1
|
|
}
|
|
|
|
test_gpioset_multiple_lines_by_name_and_offset() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
|
|
|
|
dut_run gpioset --banner --chip "${GPIOSIM_CHIP_NAME[sim0]}" 0=1 foo=1 bar=1 3=1
|
|
|
|
gpiosim_check_value sim0 0 1
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 2 1
|
|
gpiosim_check_value sim0 3 1
|
|
}
|
|
|
|
|
|
test_gpioset_multiple_lines_across_multiple_chips() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=4:xyz
|
|
|
|
dut_run gpioset --banner foo=1 bar=1 baz=1 xyz=1
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 2 1
|
|
gpiosim_check_value sim1 0 1
|
|
gpiosim_check_value sim1 4 1
|
|
}
|
|
|
|
test_gpioset_with_active_low() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpioset --banner --active-low -c "$sim0" \
|
|
0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
|
|
|
|
gpiosim_check_value sim0 0 1
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 2 0
|
|
gpiosim_check_value sim0 3 0
|
|
gpiosim_check_value sim0 4 0
|
|
gpiosim_check_value sim0 5 0
|
|
gpiosim_check_value sim0 6 1
|
|
gpiosim_check_value sim0 7 0
|
|
}
|
|
|
|
test_gpioset_with_consumer() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
|
|
gpiosim_chip sim1 num_lines=8 line_name=3:baz line_name=4:xyz
|
|
|
|
dut_run gpioset --banner --consumer gpio-tools-tests foo=1 baz=0
|
|
|
|
run_tool gpioinfo
|
|
|
|
output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+input"
|
|
output_regex_match \
|
|
"\\s+line\\s+1:\\s+\"foo\"\\s+output consumer=\"gpio-tools-tests\""
|
|
output_regex_match \
|
|
"\\s+line\\s+3:\\s+\"baz\"\\s+output consumer=\"gpio-tools-tests\""
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioset_with_push_pull() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpioset --banner --drive=push-pull --chip "$sim0" \
|
|
0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
|
|
|
|
gpiosim_check_value sim0 0 0
|
|
gpiosim_check_value sim0 1 0
|
|
gpiosim_check_value sim0 2 1
|
|
gpiosim_check_value sim0 3 1
|
|
gpiosim_check_value sim0 4 1
|
|
gpiosim_check_value sim0 5 1
|
|
gpiosim_check_value sim0 6 0
|
|
gpiosim_check_value sim0 7 1
|
|
}
|
|
|
|
test_gpioset_with_open_drain() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 2 pull-up
|
|
gpiosim_set_pull sim0 3 pull-up
|
|
gpiosim_set_pull sim0 5 pull-up
|
|
gpiosim_set_pull sim0 7 pull-up
|
|
|
|
dut_run gpioset --banner --drive=open-drain --chip "$sim0" \
|
|
0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
|
|
|
|
gpiosim_check_value sim0 0 0
|
|
gpiosim_check_value sim0 1 0
|
|
gpiosim_check_value sim0 2 1
|
|
gpiosim_check_value sim0 3 1
|
|
gpiosim_check_value sim0 4 0
|
|
gpiosim_check_value sim0 5 1
|
|
gpiosim_check_value sim0 6 0
|
|
gpiosim_check_value sim0 7 1
|
|
}
|
|
|
|
test_gpioset_with_open_source() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
gpiosim_set_pull sim0 2 pull-up
|
|
gpiosim_set_pull sim0 3 pull-up
|
|
gpiosim_set_pull sim0 5 pull-up
|
|
gpiosim_set_pull sim0 7 pull-up
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpioset --banner --drive=open-source --chip "$sim0" \
|
|
0=0 1=0 2=1 3=0 4=1 5=1 6=0 7=1
|
|
|
|
gpiosim_check_value sim0 0 0
|
|
gpiosim_check_value sim0 1 0
|
|
gpiosim_check_value sim0 2 1
|
|
gpiosim_check_value sim0 3 1
|
|
gpiosim_check_value sim0 4 1
|
|
gpiosim_check_value sim0 5 1
|
|
gpiosim_check_value sim0 6 0
|
|
gpiosim_check_value sim0 7 1
|
|
}
|
|
|
|
test_gpioset_with_pull_up() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpioset --banner --bias=pull-up --drive=open-drain \
|
|
--chip "$sim0" 0=0 1=0 2=1 3=0 4=1 5=1 6=0 7=1
|
|
|
|
gpiosim_check_value sim0 0 0
|
|
gpiosim_check_value sim0 1 0
|
|
gpiosim_check_value sim0 2 1
|
|
gpiosim_check_value sim0 3 0
|
|
gpiosim_check_value sim0 4 1
|
|
gpiosim_check_value sim0 5 1
|
|
gpiosim_check_value sim0 6 0
|
|
gpiosim_check_value sim0 7 1
|
|
}
|
|
|
|
test_gpioset_with_pull_down() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpioset --banner --bias=pull-down --drive=open-source \
|
|
--chip "$sim0" 0=0 1=0 2=1 3=0 4=1 5=1 6=0 7=1
|
|
|
|
gpiosim_check_value sim0 0 0
|
|
gpiosim_check_value sim0 1 0
|
|
gpiosim_check_value sim0 2 1
|
|
gpiosim_check_value sim0 3 0
|
|
gpiosim_check_value sim0 4 1
|
|
gpiosim_check_value sim0 5 1
|
|
gpiosim_check_value sim0 6 0
|
|
gpiosim_check_value sim0 7 1
|
|
}
|
|
|
|
test_gpioset_with_value_variants() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 0 pull-up
|
|
gpiosim_set_pull sim0 1 pull-down
|
|
gpiosim_set_pull sim0 2 pull-down
|
|
gpiosim_set_pull sim0 3 pull-up
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
gpiosim_set_pull sim0 5 pull-up
|
|
gpiosim_set_pull sim0 6 pull-up
|
|
gpiosim_set_pull sim0 7 pull-down
|
|
|
|
dut_run gpioset --banner --chip "$sim0" 0=0 1=1 2=active \
|
|
3=inactive 4=on 5=off 6=false 7=true
|
|
|
|
gpiosim_check_value sim0 0 0
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 2 1
|
|
gpiosim_check_value sim0 3 0
|
|
gpiosim_check_value sim0 4 1
|
|
gpiosim_check_value sim0 5 0
|
|
gpiosim_check_value sim0 6 0
|
|
gpiosim_check_value sim0 7 1
|
|
}
|
|
|
|
test_gpioset_with_hold_period() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 5 pull-up
|
|
|
|
dut_run gpioset --banner --hold-period=1200ms -t0 --chip "$sim0" 0=1 5=0 7=1
|
|
|
|
gpiosim_check_value sim0 0 1
|
|
gpiosim_check_value sim0 5 0
|
|
gpiosim_check_value sim0 7 1
|
|
|
|
dut_wait
|
|
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioset_interactive_exit() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpioset --interactive --chip "$sim0" 1=0 2=1 5=1 6=0 7=1
|
|
|
|
gpiosim_check_value sim0 1 0
|
|
gpiosim_check_value sim0 2 1
|
|
gpiosim_check_value sim0 5 1
|
|
gpiosim_check_value sim0 6 0
|
|
gpiosim_check_value sim0 7 1
|
|
|
|
dut_write "exit"
|
|
dut_wait
|
|
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioset_interactive_help() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo line_name=4:bar \
|
|
line_name=7:baz
|
|
|
|
dut_run gpioset --interactive foo=1 bar=0 baz=0
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 4 0
|
|
gpiosim_check_value sim0 7 0
|
|
|
|
dut_write "help"
|
|
|
|
dut_read
|
|
output_regex_match "COMMANDS:.*"
|
|
output_regex_match ".*get \[line\]\.\.\..*"
|
|
output_regex_match ".*set <line=value>\.\.\..*"
|
|
output_regex_match ".*toggle \[line\]\.\.\..*"
|
|
output_regex_match ".*sleep <period>.*"
|
|
}
|
|
|
|
test_gpioset_interactive_get() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo line_name=4:bar \
|
|
line_name=7:baz
|
|
|
|
dut_run gpioset --interactive foo=1 bar=0 baz=0
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 4 0
|
|
gpiosim_check_value sim0 7 0
|
|
|
|
dut_write "get"
|
|
|
|
dut_read
|
|
output_regex_match "\"foo\"=active \"bar\"=inactive \"baz\"=inactive"
|
|
|
|
dut_write "get bar"
|
|
|
|
dut_read
|
|
output_regex_match "\"bar\"=inactive"
|
|
}
|
|
|
|
test_gpioset_interactive_get_unquoted() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo line_name=4:bar \
|
|
line_name=7:baz
|
|
|
|
dut_run gpioset --interactive --unquoted foo=1 bar=0 baz=0
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 4 0
|
|
gpiosim_check_value sim0 7 0
|
|
|
|
dut_write "get"
|
|
|
|
dut_read
|
|
output_regex_match "foo=active bar=inactive baz=inactive"
|
|
|
|
dut_write "get bar"
|
|
|
|
dut_read
|
|
output_regex_match "bar=inactive"
|
|
}
|
|
|
|
test_gpioset_interactive_set() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo line_name=4:bar \
|
|
line_name=7:baz
|
|
|
|
dut_run gpioset --interactive foo=1 bar=0 baz=0
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 4 0
|
|
gpiosim_check_value sim0 7 0
|
|
|
|
dut_write "set bar=active"
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 4 1
|
|
gpiosim_check_value sim0 7 0
|
|
dut_write "get"
|
|
dut_read
|
|
output_regex_match "\"foo\"=active \"bar\"=active \"baz\"=inactive"
|
|
}
|
|
|
|
test_gpioset_interactive_toggle() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo line_name=4:bar \
|
|
line_name=7:baz
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
gpiosim_set_pull sim0 7 pull-up
|
|
|
|
dut_run gpioset -i foo=1 bar=0 baz=0
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 4 0
|
|
gpiosim_check_value sim0 7 0
|
|
|
|
dut_write "toggle"
|
|
|
|
gpiosim_check_value sim0 1 0
|
|
gpiosim_check_value sim0 4 1
|
|
gpiosim_check_value sim0 7 1
|
|
dut_write "get"
|
|
dut_read
|
|
output_regex_match "\"foo\"=inactive\\s+\"bar\"=active\\s+\"baz\"=active\\s*"
|
|
|
|
dut_write "toggle baz"
|
|
|
|
gpiosim_check_value sim0 1 0
|
|
gpiosim_check_value sim0 4 1
|
|
gpiosim_check_value sim0 7 0
|
|
dut_write "get"
|
|
dut_read
|
|
output_regex_match "\"foo\"=inactive\\s+\"bar\"=active\\s+\"baz\"=inactive\\s*"
|
|
}
|
|
|
|
test_gpioset_interactive_sleep() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo line_name=4:bar \
|
|
line_name=7:baz
|
|
|
|
dut_run gpioset --interactive foo=1 bar=0 baz=0
|
|
|
|
dut_write "sleep 500ms"
|
|
dut_flush
|
|
|
|
assert_fail dut_readable
|
|
|
|
sleep 1
|
|
|
|
# prompt, but not a full line...
|
|
dut_readable
|
|
}
|
|
|
|
test_gpioset_toggle_continuous() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo line_name=4:bar \
|
|
line_name=7:baz
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
gpiosim_set_pull sim0 7 pull-up
|
|
|
|
dut_run gpioset --banner --toggle 100ms foo=1 bar=0 baz=0
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 4 0
|
|
gpiosim_check_value sim0 7 0
|
|
|
|
gpiosim_wait_value sim0 1 0
|
|
gpiosim_check_value sim0 4 1
|
|
gpiosim_check_value sim0 7 1
|
|
|
|
|
|
gpiosim_wait_value sim0 1 1
|
|
gpiosim_check_value sim0 4 0
|
|
gpiosim_check_value sim0 7 0
|
|
|
|
gpiosim_wait_value sim0 1 0
|
|
gpiosim_check_value sim0 4 1
|
|
gpiosim_check_value sim0 7 1
|
|
}
|
|
|
|
test_gpioset_toggle_terminated() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo line_name=4:bar \
|
|
line_name=7:baz
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
|
|
# hold-period to allow test to sample before gpioset exits
|
|
dut_run gpioset --banner --toggle 1s,0 -p 600ms foo=1 bar=0 baz=1
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 4 0
|
|
gpiosim_check_value sim0 7 1
|
|
|
|
sleep 1
|
|
|
|
gpiosim_check_value sim0 1 0
|
|
gpiosim_check_value sim0 4 1
|
|
gpiosim_check_value sim0 7 0
|
|
|
|
dut_wait
|
|
|
|
status_is 0
|
|
|
|
# using --toggle 0 to exit
|
|
# hold-period to allow test to sample before gpioset exits
|
|
dut_run gpioset --banner -t0 -p 600ms foo=1 bar=0 baz=1
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 4 0
|
|
gpiosim_check_value sim0 7 1
|
|
|
|
dut_wait
|
|
|
|
status_is 0
|
|
}
|
|
|
|
test_gpioset_with_invalid_toggle_period() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo line_name=4:bar \
|
|
line_name=7:baz
|
|
|
|
run_tool gpioset --toggle 1ns foo=1 bar=0 baz=0
|
|
|
|
output_regex_match ".*invalid period.*"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioset_with_strict_named_line_check() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar \
|
|
line_name=3:foobar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=2:foobar \
|
|
line_name=4:xyz line_name=7:foobar
|
|
gpiosim_chip sim2 num_lines=16
|
|
|
|
run_tool gpioset --strict foobar=active
|
|
|
|
output_regex_match ".*line 'foobar' is not unique"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioset_with_lines_by_offset() {
|
|
# not suggesting this setup makes any sense
|
|
# - just test that we can deal with it
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:6 line_name=6:1
|
|
|
|
gpiosim_set_pull sim0 1 pull-down
|
|
gpiosim_set_pull sim0 6 pull-up
|
|
|
|
dut_run gpioset --banner --chip "${GPIOSIM_CHIP_NAME[sim0]}" 6=1 1=0
|
|
|
|
gpiosim_check_value sim0 1 0
|
|
gpiosim_check_value sim0 6 1
|
|
}
|
|
|
|
test_gpioset_with_lines_strictly_by_name() {
|
|
# not suggesting this setup makes any sense
|
|
# - just test that we can deal with it
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:6 line_name=6:1
|
|
|
|
gpiosim_set_pull sim0 1 pull-down
|
|
gpiosim_set_pull sim0 6 pull-up
|
|
|
|
dut_run gpioset --banner --by-name --chip "${GPIOSIM_CHIP_NAME[sim0]}" 6=1 1=0
|
|
|
|
gpiosim_check_value sim0 1 1
|
|
gpiosim_check_value sim0 6 0
|
|
}
|
|
|
|
test_gpioset_interactive_after_SIGINT() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo
|
|
|
|
dut_run gpioset -i foo=1
|
|
|
|
dut_kill -SIGINT
|
|
dut_wait
|
|
|
|
status_is 130
|
|
}
|
|
|
|
test_gpioset_interactive_after_SIGTERM() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo
|
|
|
|
dut_run gpioset -i foo=1
|
|
|
|
dut_kill -SIGTERM
|
|
dut_wait
|
|
|
|
status_is 143
|
|
}
|
|
|
|
test_gpioset_with_no_arguments() {
|
|
run_tool gpioset
|
|
|
|
status_is 1
|
|
output_regex_match ".*at least one GPIO line value must be specified"
|
|
}
|
|
|
|
test_gpioset_with_chip_but_no_line_specified() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
run_tool gpioset --chip "${GPIOSIM_CHIP_NAME[sim0]}"
|
|
|
|
output_regex_match ".*at least one GPIO line value must be specified"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioset_with_offset_out_of_range() {
|
|
gpiosim_chip sim0 num_lines=4
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpioset --chip "$sim0" 0=1 1=1 2=1 3=1 4=1 5=1
|
|
|
|
output_regex_match ".*offset 4 is out of range on chip '$sim0'"
|
|
output_regex_match ".*offset 5 is out of range on chip '$sim0'"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioset_with_invalid_hold_period() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpioset --hold-period=bad --chip "$sim0" 0=1
|
|
|
|
output_regex_match ".*invalid period.*"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioset_with_invalid_value() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
# by name
|
|
run_tool gpioset --chip "$sim0" 0=c
|
|
|
|
output_regex_match ".*invalid line value.*"
|
|
status_is 1
|
|
|
|
# by value
|
|
run_tool gpioset --chip "$sim0" 0=3
|
|
|
|
output_regex_match ".*invalid line value.*"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioset_with_invalid_offset() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
run_tool gpioset --chip "${GPIOSIM_CHIP_NAME[sim0]}" 4000000000=0
|
|
|
|
output_regex_match ".*cannot find line '4000000000'"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioset_with_invalid_bias() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
run_tool gpioset --bias=bad --chip "${GPIOSIM_CHIP_NAME[sim0]}" 0=1 1=1
|
|
|
|
output_regex_match ".*invalid bias.*"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioset_with_invalid_drive() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
run_tool gpioset --drive=bad --chip "${GPIOSIM_CHIP_NAME[sim0]}" 0=1 1=1
|
|
|
|
output_regex_match ".*invalid drive.*"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioset_with_interactive_and_toggle() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpioset --interactive --toggle 1s --chip "$sim0" 0=1
|
|
|
|
output_regex_match ".*can't combine interactive with toggle"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioset_with_nonexistent_line() {
|
|
run_tool gpioset nonexistent-line=0
|
|
|
|
output_regex_match ".*cannot find line 'nonexistent-line'"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpioset_with_same_line_twice() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
# by offset
|
|
run_tool gpioset --chip "$sim0" 0=1 0=1
|
|
|
|
output_regex_match ".*lines '0' and '0' are the same line"
|
|
status_is 1
|
|
|
|
# by name
|
|
run_tool gpioset --chip "$sim0" foo=1 foo=1
|
|
|
|
output_regex_match ".*lines 'foo' and 'foo' are the same line"
|
|
status_is 1
|
|
|
|
# by name and offset
|
|
run_tool gpioset --chip "$sim0" foo=1 1=1
|
|
|
|
output_regex_match ".*lines 'foo' and '1' are the same line"
|
|
status_is 1
|
|
|
|
# by offset and name
|
|
run_tool gpioset --chip "$sim0" 1=1 foo=1
|
|
|
|
output_regex_match ".*lines '1' and 'foo' are the same line"
|
|
status_is 1
|
|
}
|
|
|
|
#
|
|
# gpiomon test cases
|
|
#
|
|
|
|
test_gpiomon_by_name() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=4:foo
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
|
|
dut_run gpiomon --banner --edges=rising foo
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+\"foo\""
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_by_offset() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
|
|
dut_run gpiomon --banner --edges=rising --chip "$sim0" 4
|
|
dut_regex_match "Monitoring line .*"
|
|
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+$sim0 4"
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_by_symlink() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
gpiosim_chip_symlink sim0 .
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
|
|
dut_run gpiomon --banner --edges=rising --chip "$GPIOSIM_CHIP_LINK" 4
|
|
dut_regex_match "Monitoring line .*"
|
|
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+$sim0\\s+4"
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
|
|
test_gpiomon_by_chip_and_name() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=0:foo
|
|
gpiosim_chip sim1 num_lines=8 line_name=2:foo
|
|
|
|
local sim1=${GPIOSIM_CHIP_NAME[sim1]}
|
|
|
|
gpiosim_set_pull sim1 0 pull-up
|
|
|
|
dut_run gpiomon --banner --edges=rising --chip "$sim1" foo
|
|
dut_regex_match "Monitoring line .*"
|
|
|
|
gpiosim_set_pull sim1 2 pull-down
|
|
gpiosim_set_pull sim1 2 pull-up
|
|
gpiosim_set_pull sim1 2 pull-down
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+$sim1 2 \"foo\""
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_first_matching_named_line() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar \
|
|
line_name=3:foobar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=2:foobar \
|
|
line_name=4:xyz line_name=7:foobar
|
|
gpiosim_chip sim2 num_lines=16
|
|
|
|
dut_run gpiomon --banner foobar
|
|
dut_regex_match "Monitoring line .*"
|
|
|
|
gpiosim_set_pull sim0 3 pull-up
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+\"foobar\""
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_rising_edge() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
|
|
dut_run gpiomon --banner --edges=rising --chip "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+$sim0 4"
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_falling_edge() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
|
|
dut_run gpiomon --banner --edges=falling --chip "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+falling\\s+$sim0 4"
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_both_edges() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner --edges=both --chip "$sim0" 4
|
|
dut_regex_match "Monitoring line .*"
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+$sim0 4"
|
|
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+falling\\s+$sim0 4"
|
|
}
|
|
|
|
test_gpiomon_with_pull_up() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
|
|
dut_run gpiomon --banner --bias=pull-up --chip "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+falling\\s+$sim0 4"
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_with_pull_down() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
|
|
dut_run gpiomon --banner --bias=pull-down --chip "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+$sim0 4"
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_with_active_low() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
|
|
dut_run gpiomon --banner --active-low --chip "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+$sim0 4"
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+falling\\s+$sim0 4"
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_with_consumer() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
|
|
gpiosim_chip sim1 num_lines=8 line_name=3:baz line_name=4:xyz
|
|
|
|
dut_run gpiomon --banner --consumer gpio-tools-tests foo baz
|
|
|
|
run_tool gpioinfo
|
|
|
|
output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+input"
|
|
output_regex_match \
|
|
"\\s+line\\s+1:\\s+\"foo\"\\s+input edges=both consumer=\"gpio-tools-tests\""
|
|
output_regex_match \
|
|
"\\s+line\\s+3:\\s+\"baz\"\\s+input edges=both consumer=\"gpio-tools-tests\""
|
|
status_is 0
|
|
}
|
|
|
|
test_gpiomon_with_quiet_mode() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner --edges=rising --quiet --chip "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_with_unquoted() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=4:foo
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
|
|
dut_run gpiomon --banner --unquoted --edges=rising foo
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+foo"
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_with_num_events() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
# redirect, as gpiomon exits after 4 events
|
|
dut_run_redirect gpiomon --num-events=4 --chip "$sim0" 4
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
sleep 0.01
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
sleep 0.01
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
sleep 0.01
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
sleep 0.01
|
|
|
|
dut_wait
|
|
status_is 0
|
|
dut_read_redirect
|
|
|
|
regex_matches "[0-9]+\.[0-9]+\\s+rising\\s+$sim0 4" "${lines[0]}"
|
|
regex_matches "[0-9]+\.[0-9]+\\s+falling\\s+$sim0 4" "${lines[1]}"
|
|
regex_matches "[0-9]+\.[0-9]+\\s+rising\\s+$sim0 4" "${lines[2]}"
|
|
regex_matches "[0-9]+\.[0-9]+\\s+falling\\s+$sim0 4" "${lines[3]}"
|
|
num_lines_is 4
|
|
}
|
|
|
|
test_gpiomon_with_debounce_period() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
|
|
gpiosim_chip sim1 num_lines=8 line_name=3:baz line_name=4:xyz
|
|
|
|
dut_run gpiomon --banner --debounce-period 123us foo baz
|
|
|
|
run_tool gpioinfo
|
|
|
|
output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+input"
|
|
output_regex_match \
|
|
"\\s+line\\s+1:\\s+\"foo\"\\s+input edges=both debounce-period=123us"
|
|
output_regex_match \
|
|
"\\s+line\\s+3:\\s+\"baz\"\\s+input edges=both debounce-period=123us"
|
|
status_is 0
|
|
}
|
|
|
|
test_gpiomon_with_idle_timeout() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
# redirect, as gpiomon exits
|
|
dut_run_redirect gpiomon --idle-timeout 10ms --chip "$sim0" 4
|
|
|
|
dut_wait
|
|
status_is 0
|
|
dut_read_redirect
|
|
num_lines_is 0
|
|
}
|
|
|
|
test_gpiomon_multiple_lines() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner --format=%o --chip "$sim0" 1 3 2 5 4
|
|
dut_regex_match "Monitoring lines .*"
|
|
|
|
gpiosim_set_pull sim0 2 pull-up
|
|
dut_regex_match "2"
|
|
gpiosim_set_pull sim0 3 pull-up
|
|
dut_regex_match "3"
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_regex_match "4"
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_multiple_lines_by_name_and_offset() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner --format=%o --chip "$sim0" foo bar 3
|
|
dut_regex_match "Monitoring lines .*"
|
|
|
|
gpiosim_set_pull sim0 2 pull-up
|
|
dut_regex_match "2"
|
|
gpiosim_set_pull sim0 3 pull-up
|
|
dut_regex_match "3"
|
|
gpiosim_set_pull sim0 1 pull-up
|
|
dut_regex_match "1"
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_multiple_lines_across_multiple_chips() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=4:xyz
|
|
|
|
dut_run gpiomon --banner --format=%l foo bar baz
|
|
dut_regex_match "Monitoring lines .*"
|
|
|
|
gpiosim_set_pull sim0 2 pull-up
|
|
dut_regex_match "bar"
|
|
gpiosim_set_pull sim1 0 pull-up
|
|
dut_regex_match "baz"
|
|
gpiosim_set_pull sim0 1 pull-up
|
|
dut_regex_match "foo"
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_exit_after_SIGINT() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner --chip "$sim0" 4
|
|
dut_regex_match "Monitoring line .*"
|
|
|
|
dut_kill -SIGINT
|
|
dut_wait
|
|
|
|
status_is 130
|
|
}
|
|
|
|
test_gpiomon_exit_after_SIGTERM() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner --chip "$sim0" 4
|
|
dut_regex_match "Monitoring line .*"
|
|
|
|
dut_kill -SIGTERM
|
|
dut_wait
|
|
|
|
status_is 143
|
|
}
|
|
|
|
test_gpiomon_with_nonexistent_line() {
|
|
run_tool gpiomon nonexistent-line
|
|
|
|
status_is 1
|
|
output_regex_match ".*cannot find line 'nonexistent-line'"
|
|
}
|
|
|
|
test_gpiomon_with_same_line_twice() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
# by offset
|
|
run_tool gpiomon --chip "$sim0" 0 0
|
|
|
|
output_regex_match ".*lines '0' and '0' are the same line"
|
|
status_is 1
|
|
|
|
# by name
|
|
run_tool gpiomon foo foo
|
|
|
|
output_regex_match ".*lines 'foo' and 'foo' are the same line"
|
|
status_is 1
|
|
|
|
# by name and offset
|
|
run_tool gpiomon --chip "$sim0" 1 foo
|
|
|
|
output_regex_match ".*lines '1' and 'foo' are the same line"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpiomon_with_strict_named_line_check() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar \
|
|
line_name=3:foobar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=2:foobar \
|
|
line_name=4:xyz line_name=7:foobar
|
|
gpiosim_chip sim2 num_lines=16
|
|
|
|
run_tool gpiomon --strict foobar
|
|
|
|
output_regex_match ".*line 'foobar' is not unique"
|
|
status_is 1
|
|
}
|
|
test_gpiomon_with_lines_by_offset() {
|
|
# not suggesting this setup makes any sense
|
|
# - just test that we can deal with it
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:6 line_name=6:1
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 1 pull-up
|
|
|
|
dut_run gpiomon --banner --chip "$sim0" 6 1
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 1 pull-down
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+falling\\s+$sim0 1"
|
|
|
|
gpiosim_set_pull sim0 1 pull-up
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+$sim0 1"
|
|
|
|
gpiosim_set_pull sim0 6 pull-up
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+$sim0 6"
|
|
|
|
gpiosim_set_pull sim0 6 pull-down
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+falling\\s+$sim0 6"
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_with_lines_strictly_by_name() {
|
|
# not suggesting this setup makes sense
|
|
# - just test that we can deal with it
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:42 line_name=6:13
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 1 pull-up
|
|
|
|
dut_run gpiomon --banner --by-name --chip "$sim0" 42 13
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 1 pull-down
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+falling\\s+$sim0 1"
|
|
|
|
gpiosim_set_pull sim0 1 pull-up
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+$sim0 1"
|
|
|
|
gpiosim_set_pull sim0 6 pull-up
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+rising\\s+$sim0 6"
|
|
|
|
gpiosim_set_pull sim0 6 pull-down
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+falling\\s+$sim0 6"
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpiomon_with_no_arguments() {
|
|
run_tool gpiomon
|
|
|
|
output_regex_match ".*at least one GPIO line must be specified"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpiomon_with_no_line_specified() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
run_tool gpiomon --chip "${GPIOSIM_CHIP_NAME[sim0]}"
|
|
|
|
output_regex_match ".*at least one GPIO line must be specified"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpiomon_with_offset_out_of_range() {
|
|
gpiosim_chip sim0 num_lines=4
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpiomon --chip "$sim0" 5
|
|
|
|
output_regex_match ".*offset 5 is out of range on chip '$sim0'"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpiomon_with_invalid_bias() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpiomon --bias=bad -c "$sim0" 0 1
|
|
|
|
output_regex_match ".*invalid bias.*"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpiomon_with_invalid_debounce_period() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpiomon --debounce-period bad -c "$sim0" 0 1
|
|
|
|
output_regex_match ".*invalid period: bad"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpiomon_with_invalid_idle_timeout() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpiomon --idle-timeout bad -c "$sim0" 0 1
|
|
|
|
output_regex_match ".*invalid period: bad"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpiomon_with_custom_format_event_type_offset() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner "--format=%e %o" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_read
|
|
output_is "1 4"
|
|
}
|
|
|
|
test_gpiomon_with_custom_format_event_type_offset_joined() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner "--format=%e%o" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_read
|
|
output_is "14"
|
|
}
|
|
|
|
test_gpiomon_with_custom_format_edge_chip_and_line() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=4:baz
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner "--format=%e %o %E %c %l" -c "$sim0" baz
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_regex_match "1 4 rising $sim0 baz"
|
|
}
|
|
|
|
test_gpiomon_with_custom_format_seconds_timestamp() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner "--format=%e %o %S" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_regex_match "1 4 [0-9]+\\.[0-9]+"
|
|
}
|
|
|
|
test_gpiomon_with_custom_format_UTC_timestamp() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner "--format=%U %e %o " --event-clock=realtime \
|
|
-c "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_regex_match \
|
|
"[0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-5][0-9]\\.[0-9]+Z 1 4"
|
|
}
|
|
|
|
test_gpiomon_with_custom_format_localtime_timestamp() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner "--format=%L %e %o" --event-clock=realtime \
|
|
-c "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_regex_match \
|
|
"[0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-5][0-9]\\.[0-9]+ 1 4"
|
|
}
|
|
|
|
test_gpiomon_with_custom_format_double_percent_sign() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner "--format=start%%end" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_read
|
|
output_is "start%end"
|
|
}
|
|
|
|
test_gpiomon_with_custom_format_double_percent_sign_event_type_specifier() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner "--format=%%e" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_read
|
|
output_is "%e"
|
|
}
|
|
|
|
test_gpiomon_with_custom_format_single_percent_sign() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner "--format=%" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_read
|
|
output_is "%"
|
|
}
|
|
|
|
test_gpiomon_with_custom_format_single_percent_sign_between_other_characters() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner "--format=foo % bar" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_read
|
|
output_is "foo % bar"
|
|
}
|
|
|
|
test_gpiomon_with_custom_format_unknown_specifier() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpiomon --banner "--format=%x" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
dut_read
|
|
output_is "%x"
|
|
}
|
|
|
|
#
|
|
# gpionotify test cases
|
|
#
|
|
|
|
test_gpionotify_by_name() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=4:foo
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner foo
|
|
dut_regex_match "Watching line .*"
|
|
|
|
request_release_line "$sim0" 4
|
|
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+\"foo\""
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+\"foo\""
|
|
# tools currently have no way to generate a reconfig event
|
|
}
|
|
|
|
test_gpionotify_by_offset() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --chip "$sim0" 4
|
|
dut_regex_match "Watching line .*"
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+$sim0 4"
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+$sim0 4"
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpionotify_by_symlink() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
gpiosim_chip_symlink sim0 .
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --chip "$GPIOSIM_CHIP_LINK" 4
|
|
dut_regex_match "Watching line .*"
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+$sim0\\s+4"
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+$sim0\\s+4"
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpionotify_by_chip_and_name() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=4:foo
|
|
gpiosim_chip sim1 num_lines=8 line_name=2:foo
|
|
|
|
local sim1=${GPIOSIM_CHIP_NAME[sim1]}
|
|
|
|
dut_run gpionotify --banner --chip "$sim1" foo
|
|
dut_regex_match "Watching line .*"
|
|
|
|
request_release_line "$sim1" 2
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+$sim1 2 \"foo\""
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+$sim1 2 \"foo\""
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpionotify_first_matching_named_line() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar \
|
|
line_name=3:foobar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=2:foobar \
|
|
line_name=4:xyz line_name=7:foobar
|
|
gpiosim_chip sim2 num_lines=16
|
|
|
|
dut_run gpionotify --banner foobar
|
|
dut_regex_match "Watching line .*"
|
|
|
|
request_release_line "${GPIOSIM_CHIP_NAME[sim0]}" 3
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+\"foobar\""
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+\"foobar\""
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpionotify_with_requested() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 4 pull-up
|
|
|
|
dut_run gpionotify --banner --event=requested --chip "$sim0" 4
|
|
dut_flush
|
|
|
|
request_release_line "${GPIOSIM_CHIP_NAME[sim0]}" 4
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+$sim0 4"
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpionotify_with_released() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
gpiosim_set_pull sim0 4 pull-down
|
|
|
|
dut_run gpionotify --banner --event=released --chip "$sim0" 4
|
|
dut_flush
|
|
|
|
request_release_line "${GPIOSIM_CHIP_NAME[sim0]}" 4
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+$sim0 4"
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpionotify_with_quiet_mode() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --quiet --chip "$sim0" 4
|
|
dut_flush
|
|
|
|
request_release_line "${GPIOSIM_CHIP_NAME[sim0]}" 4
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpionotify_with_unquoted() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=4:foo
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --unquoted foo
|
|
dut_regex_match "Watching line .*"
|
|
|
|
request_release_line "$sim0" 4
|
|
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+foo"
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+foo"
|
|
}
|
|
|
|
test_gpionotify_with_num_events() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
# redirect, as gpionotify exits after 4 events
|
|
dut_run_redirect gpionotify --num-events=4 --chip "$sim0" 3 4
|
|
|
|
|
|
request_release_line "${GPIOSIM_CHIP_NAME[sim0]}" 4
|
|
request_release_line "${GPIOSIM_CHIP_NAME[sim0]}" 3
|
|
|
|
dut_wait
|
|
status_is 0
|
|
dut_read_redirect
|
|
|
|
regex_matches "[0-9]+\.[0-9]+\\s+requested\\s+$sim0 4" "${lines[0]}"
|
|
regex_matches "[0-9]+\.[0-9]+\\s+released\\s+$sim0 4" "${lines[1]}"
|
|
regex_matches "[0-9]+\.[0-9]+\\s+requested\\s+$sim0 3" "${lines[2]}"
|
|
regex_matches "[0-9]+\.[0-9]+\\s+released\\s+$sim0 3" "${lines[3]}"
|
|
num_lines_is 4
|
|
}
|
|
|
|
test_gpionotify_with_idle_timeout() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
# redirect, as gpionotify exits
|
|
dut_run_redirect gpionotify --idle-timeout 10ms --chip "$sim0" 3 4
|
|
|
|
dut_wait
|
|
status_is 0
|
|
dut_read_redirect
|
|
|
|
num_lines_is 0
|
|
}
|
|
|
|
test_gpionotify_multiple_lines() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --chip "$sim0" 1 2 3 4 5
|
|
dut_regex_match "Watching lines .*"
|
|
|
|
request_release_line "$sim0" 2
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+$sim0 2"
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+$sim0 2"
|
|
|
|
request_release_line "$sim0" 3
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+$sim0 3"
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+$sim0 3"
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+$sim0 4"
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+$sim0 4"
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpionotify_multiple_lines_by_name_and_offset() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --chip "$sim0" bar foo 3
|
|
dut_regex_match "Watching lines .*"
|
|
|
|
request_release_line "$sim0" 2
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+$sim0 2\\s+\"bar\""
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+$sim0 2\\s+\"bar\""
|
|
|
|
request_release_line "$sim0" 1
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+$sim0 1\\s+\"foo\""
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+$sim0 1\\s+\"foo\""
|
|
|
|
request_release_line "$sim0" 3
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+$sim0 3"
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+$sim0 3"
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpionotify_multiple_lines_across_multiple_chips() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=4:xyz
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
local sim1=${GPIOSIM_CHIP_NAME[sim1]}
|
|
|
|
dut_run gpionotify --banner baz bar foo xyz
|
|
dut_regex_match "Watching lines .*"
|
|
|
|
request_release_line "$sim0" 2
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+\"bar\""
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+\"bar\""
|
|
|
|
request_release_line "$sim0" 1
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+\"foo\""
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+\"foo\""
|
|
|
|
request_release_line "$sim1" 4
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+\"xyz\""
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+\"xyz\""
|
|
|
|
request_release_line "$sim1" 0
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+\"baz\""
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+\"baz\""
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpionotify_exit_after_SIGINT() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
dut_run gpionotify --banner --chip "${GPIOSIM_CHIP_NAME[sim0]}" 4
|
|
dut_regex_match "Watching line .*"
|
|
|
|
dut_kill -SIGINT
|
|
dut_wait
|
|
|
|
status_is 130
|
|
}
|
|
|
|
test_gpionotify_exit_after_SIGTERM() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
dut_run gpionotify --banner --chip "${GPIOSIM_CHIP_NAME[sim0]}" 4
|
|
dut_regex_match "Watching line .*"
|
|
|
|
dut_kill -SIGTERM
|
|
dut_wait
|
|
|
|
status_is 143
|
|
}
|
|
|
|
test_gpionotify_with_nonexistent_line() {
|
|
run_tool gpionotify nonexistent-line
|
|
|
|
status_is 1
|
|
output_regex_match ".*cannot find line 'nonexistent-line'"
|
|
}
|
|
|
|
test_gpionotify_with_same_line_twice() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:foo
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
# by offset
|
|
run_tool gpionotify --chip "$sim0" 0 0
|
|
|
|
output_regex_match ".*lines '0' and '0' are the same line"
|
|
num_lines_is 1
|
|
status_is 1
|
|
|
|
# by name
|
|
run_tool gpionotify foo foo
|
|
|
|
output_regex_match ".*lines 'foo' and 'foo' are the same line"
|
|
num_lines_is 1
|
|
status_is 1
|
|
|
|
# by name and offset
|
|
run_tool gpionotify --chip "$sim0" 1 foo
|
|
|
|
output_regex_match ".*lines '1' and 'foo' are the same line"
|
|
num_lines_is 1
|
|
status_is 1
|
|
}
|
|
|
|
test_gpionotify_with_strict_named_line_check() {
|
|
gpiosim_chip sim0 num_lines=4 line_name=1:foo line_name=2:bar \
|
|
line_name=3:foobar
|
|
gpiosim_chip sim1 num_lines=8 line_name=0:baz line_name=2:foobar \
|
|
line_name=4:xyz line_name=7:foobar
|
|
gpiosim_chip sim2 num_lines=16
|
|
|
|
run_tool gpionotify --strict foobar
|
|
|
|
output_regex_match ".*line 'foobar' is not unique"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpionotify_with_lines_by_offset() {
|
|
# not suggesting this setup makes any sense
|
|
# - just test that we can deal with it
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:6 line_name=6:1
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --chip "$sim0" 1
|
|
dut_flush
|
|
|
|
request_release_line "$sim0" 1
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+$sim0 1"
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+$sim0 1"
|
|
|
|
request_release_line "$sim0" 6
|
|
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpionotify_with_lines_strictly_by_name() {
|
|
# not suggesting this setup makes any sense
|
|
# - just test that we can deal with it
|
|
gpiosim_chip sim0 num_lines=8 line_name=1:6 line_name=6:1
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --by-name --chip "$sim0" 1
|
|
dut_flush
|
|
|
|
request_release_line "$sim0" 6
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+requested\\s+$sim0 6 \"1\""
|
|
dut_regex_match "[0-9]+\.[0-9]+\\s+released\\s+$sim0 6 \"1\""
|
|
|
|
request_release_line "$sim0" 1
|
|
assert_fail dut_readable
|
|
}
|
|
|
|
test_gpionotify_with_no_arguments() {
|
|
run_tool gpionotify
|
|
|
|
output_regex_match ".*at least one GPIO line must be specified"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpionotify_with_no_line_specified() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
run_tool gpionotify --chip "${GPIOSIM_CHIP_NAME[sim0]}"
|
|
|
|
output_regex_match ".*at least one GPIO line must be specified"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpionotify_with_offset_out_of_range() {
|
|
gpiosim_chip sim0 num_lines=4
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpionotify --chip "$sim0" 5
|
|
|
|
output_regex_match ".*offset 5 is out of range on chip '$sim0'"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpionotify_with_invalid_idle_timeout() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
run_tool gpionotify --idle-timeout bad -c "$sim0" 0 1
|
|
|
|
output_regex_match ".*invalid period: bad"
|
|
status_is 1
|
|
}
|
|
|
|
test_gpionotify_with_custom_format_event_type_offset() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --event=requested "--format=%e %o" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_read
|
|
output_is "1 4"
|
|
}
|
|
|
|
test_gpionotify_with_custom_format_event_type_offset_joined() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --event=requested "--format=%e%o" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_read
|
|
output_is "14"
|
|
}
|
|
|
|
test_gpionotify_with_custom_format_event_chip_and_line() {
|
|
gpiosim_chip sim0 num_lines=8 line_name=4:baz
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --event=released \
|
|
"--format=%e %o %E %c %l" -c "$sim0" baz
|
|
dut_flush
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_regex_match "2 4 released $sim0 baz"
|
|
}
|
|
|
|
test_gpionotify_with_custom_format_seconds_timestamp() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --event=requested "--format=%e %o %S" \
|
|
-c "$sim0" 4
|
|
dut_flush
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_regex_match "1 4 [0-9]+\\.[0-9]+"
|
|
}
|
|
|
|
test_gpionotify_with_custom_format_UTC_timestamp() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --event=released \
|
|
"--format=%U %e %o" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_regex_match \
|
|
"[0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-5][0-9]\\.[0-9]+Z 2 4"
|
|
}
|
|
|
|
test_gpionotify_with_custom_format_localtime_timestamp() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --event=released \
|
|
"--format=%L %e %o" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_regex_match \
|
|
"[0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-5][0-9]\\.[0-9]+ 2 4"
|
|
}
|
|
|
|
test_gpionotify_with_custom_format_double_percent_sign() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --event=requested "--format=start%%end" \
|
|
-c "$sim0" 4
|
|
dut_flush
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_read
|
|
output_is "start%end"
|
|
}
|
|
|
|
test_gpionotify_with_custom_format_double_percent_sign_event_type_specifier() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --event=requested "--format=%%e" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_read
|
|
output_is "%e"
|
|
}
|
|
|
|
test_gpionotify_with_custom_format_single_percent_sign() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --event=requested "--format=%" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_read
|
|
output_is "%"
|
|
}
|
|
|
|
test_gpionotify_with_custom_format_single_percent_sign_between_other_characters() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --event=requested "--format=foo % bar" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_read
|
|
output_is "foo % bar"
|
|
}
|
|
|
|
test_gpionotify_with_custom_format_unknown_specifier() {
|
|
gpiosim_chip sim0 num_lines=8
|
|
|
|
local sim0=${GPIOSIM_CHIP_NAME[sim0]}
|
|
|
|
dut_run gpionotify --banner --event=requested "--format=%x" -c "$sim0" 4
|
|
dut_flush
|
|
|
|
request_release_line "$sim0" 4
|
|
dut_read
|
|
output_is "%x"
|
|
}
|
|
|
|
die() {
|
|
echo "$@" 1>&2
|
|
exit 1
|
|
}
|
|
|
|
# Must be done after we sources shunit2 as we need SHUNIT_VERSION to be set.
|
|
oneTimeSetUp() {
|
|
test "$SHUNIT_VERSION" = "$MIN_SHUNIT_VERSION" && return 0
|
|
local FIRST
|
|
FIRST=$(printf "%s\n%s\n" "$SHUNIT_VERSION" "$MIN_SHUNIT_VERSION" | sort -Vr | head -1)
|
|
test "$FIRST" = "$MIN_SHUNIT_VERSION" && \
|
|
die "minimum shunit version required is $MIN_SHUNIT_VERSION (current version is $SHUNIT_VERSION"
|
|
}
|
|
|
|
check_kernel() {
|
|
local REQUIRED=$1
|
|
local CURRENT
|
|
CURRENT=$(uname -r)
|
|
|
|
SORTED=$(printf "%s\n%s" "$REQUIRED" "$CURRENT" | sort -V | head -n 1)
|
|
|
|
if [ "$SORTED" != "$REQUIRED" ]
|
|
then
|
|
die "linux kernel version must be at least: v$REQUIRED - got: v$CURRENT"
|
|
fi
|
|
}
|
|
|
|
check_prog() {
|
|
local PROG=$1
|
|
|
|
if ! which "$PROG" > /dev/null
|
|
then
|
|
die "$PROG not found - needed to run the tests"
|
|
fi
|
|
}
|
|
|
|
# Check all required non-coreutils tools
|
|
check_prog shunit2
|
|
check_prog modprobe
|
|
check_prog timeout
|
|
|
|
# Check if we're running a kernel at the required version or later
|
|
check_kernel $MIN_KERNEL_VERSION
|
|
|
|
modprobe gpio-sim || die "unable to load the gpio-sim module"
|
|
mountpoint /sys/kernel/config/ > /dev/null 2> /dev/null || \
|
|
die "configfs not mounted at /sys/kernel/config/"
|
|
|
|
# shellcheck source=/dev/null
|
|
. shunit2
|