blob: b756c438e426cc7b1b639621b0fd8ebf2508d10f [file] [log] [blame]
#!/usr/bin/env bats
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of libgpiod.
#
# Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
#
# Simple test harness for the gpio-tools.
# Where output from coprocesses is stored
COPROC_OUTPUT=$BATS_TMPDIR/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.
COPROC_SAVED_PID=""
# Run the command in $* and return 0 if the command failed. The way we do it
# here is a workaround for the way bats handles failing processes.
assert_fail() {
$* || return 0
return 1
}
# Check if the string in $2 matches against the pattern in $1.
regex_matches() {
local PATTERN=$1
local STRING=$2
[[ $STRING =~ $PATTERN ]]
}
# Iterate over all lines in the output of the last command invoked with bats'
# 'run' or the coproc helper and check if at least one is equal to $1.
output_contains_line() {
local LINE=$1
for line in "${lines[@]}"
do
test "$line" = "$LINE" && return 0
done
return 1
}
# Same as above but match against the regex pattern in $1.
output_regex_match() {
local PATTERN=$1
for line in "${lines[@]}"
do
regex_matches "$PATTERN" "$line" && return 0
done
return 1
}
# Probe the gpio-mockup kernel module. The routine expects a list of chip
# sizes and optionally the 'named-lines' flag.
gpio_mockup_probe() {
local CMDLINE="gpio_mockup_ranges="
for ARG in $*
do
if [ $ARG = "named-lines" ]
then
CMDLINE="gpio_mockup_named_lines $CMDLINE"
continue
fi
regex_matches "[0-9]+" "$ARG"
CMDLINE="$CMDLINE-1,$ARG,"
done
CMDLINE=${CMDLINE%?}
modprobe gpio-mockup $CMDLINE
udevadm settle
}
gpio_mockup_remove() {
if [ -d /sys/module/gpio_mockup ]
then
rmmod gpio-mockup
fi
}
gpio_mockup_chip_name() {
local CHIPNUM=$1
test -d /sys/devices/platform/gpio-mockup.$CHIPNUM/ || return 1
echo $(ls /sys/devices/platform/gpio-mockup.$CHIPNUM/ | grep gpiochip)
}
gpio_mockup_set_pull() {
local CHIPNUM=$1
local LINE=$2
local PULL=$3
FILE="/sys/kernel/debug/gpio-mockup/$(gpio_mockup_chip_name $CHIPNUM)/$LINE"
test -f $FILE || return 1
echo "$PULL" > $FILE
}
gpio_mockup_check_value() {
local CHIPNUM=$1
local LINE=$2
local EXPECTED=$3
FILE="/sys/kernel/debug/gpio-mockup/$(gpio_mockup_chip_name $CHIPNUM)/$LINE"
test -f $FILE || return 1
VAL=$(cat $FILE)
test $VAL -eq $EXPECTED || return 1
}
run_tool() {
# Executables to test are expected to be in the same directory as the
# testing script.
run timeout 10s $BATS_TEST_DIRNAME/"$@"
}
coproc_run_tool() {
rm -f $BR_PROC_OUTPUT
coproc timeout 10s $BATS_TEST_DIRNAME/"$@" > $COPROC_OUTPUT 2> $COPROC_OUTPUT
COPROC_SAVED_PID=$COPROC_PID
# FIXME We're giving the background process some time to get up, but really this
# should be more reliable...
sleep 0.2
}
coproc_tool_stdin_write() {
echo $* >&${COPROC[1]}
}
coproc_tool_kill() {
SIGNUM=$1
kill $SIGNUM $COPROC_SAVED_PID
}
coproc_tool_wait() {
status="0"
# A workaround for the way bats handles command failures.
wait $COPROC_SAVED_PID || export status=$?
test "$status" -ne 0 || export status="0"
output=$(cat $COPROC_OUTPUT)
local ORIG_IFS="$IFS"
IFS=$'\n' lines=($output)
IFS="$ORIG_IFS"
rm -f $COPROC_OUTPUT
}
setup() {
gpio_mockup_remove
}
teardown() {
if [ -n "$BG_PROC_PID" ]
then
kill -9 $BG_PROC_PID
run wait $BG_PROC_PID
BG_PROC_PID=""
fi
gpio_mockup_remove
}
#
# gpiodetect test cases
#
@test "gpiodetect: list chips" {
gpio_mockup_probe 4 8 16
run_tool gpiodetect
test "$status" -eq 0
output_contains_line "$(gpio_mockup_chip_name 0) [gpio-mockup-A] (4 lines)"
output_contains_line "$(gpio_mockup_chip_name 1) [gpio-mockup-B] (8 lines)"
output_contains_line "$(gpio_mockup_chip_name 2) [gpio-mockup-C] (16 lines)"
}
@test "gpiodetect: invalid args" {
run_tool gpiodetect unimplemented-arg
test "$status" -eq 1
}
#
# gpioinfo test cases
#
@test "gpioinfo: dump all chips" {
gpio_mockup_probe 4 8
run_tool gpioinfo
test "$status" -eq 0
output_contains_line "$(gpio_mockup_chip_name 0) - 4 lines:"
output_contains_line "$(gpio_mockup_chip_name 1) - 8 lines:"
output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high"
output_regex_match "\\s+line\\s+7:\\s+unnamed\\s+unused\\s+input\\s+active-high"
}
@test "gpioinfo: dump all chips with one line exported" {
gpio_mockup_probe 4 8
coproc_run_tool gpioset --mode=signal --active-low "$(gpio_mockup_chip_name 1)" 7=1
run_tool gpioinfo
test "$status" -eq 0
output_contains_line "$(gpio_mockup_chip_name 0) - 4 lines:"
output_contains_line "$(gpio_mockup_chip_name 1) - 8 lines:"
output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high"
output_regex_match "\\s+line\\s+7:\\s+unnamed\\s+\\\"gpioset\\\"\\s+output\\s+active-low"
coproc_tool_kill
coproc_tool_wait
}
@test "gpioinfo: dump one chip" {
gpio_mockup_probe 8 4
run_tool gpioinfo "$(gpio_mockup_chip_name 1)"
test "$status" -eq 0
assert_fail output_contains_line "$(gpio_mockup_chip_name 0) - 8 lines:"
output_contains_line "$(gpio_mockup_chip_name 1) - 4 lines:"
output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high"
assert_fail output_regex_match "\\s+line\\s+7:\\s+unnamed\\s+unused\\s+input\\s+active-high"
}
@test "gpioinfo: dump all but one chip" {
gpio_mockup_probe 4 4 8 4
run_tool gpioinfo "$(gpio_mockup_chip_name 0)" \
"$(gpio_mockup_chip_name 1)" "$(gpio_mockup_chip_name 3)"
test "$status" -eq 0
output_contains_line "$(gpio_mockup_chip_name 0) - 4 lines:"
output_contains_line "$(gpio_mockup_chip_name 1) - 4 lines:"
assert_fail output_contains_line "$(gpio_mockup_chip_name 2) - 8 lines:"
output_contains_line "$(gpio_mockup_chip_name 3) - 4 lines:"
output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high"
assert_fail output_regex_match "\\s+line\\s+7:\\s+unnamed\\s+unused\\s+input\\s+active-high"
}
@test "gpioinfo: inexistent chip" {
run_tool gpioinfo "inexistent"
test "$status" -eq 1
}
#
# gpiofind test cases
#
@test "gpiofind: line found" {
gpio_mockup_probe named-lines 4 8 16
run_tool gpiofind gpio-mockup-B-7
test "$status" -eq "0"
test "$output" = "$(gpio_mockup_chip_name 1) 7"
}
@test "gpiofind: line not found" {
gpio_mockup_probe named-lines 4 8 16
run_tool gpiofind nonexistent-line
test "$status" -eq "1"
}
@test "gpiofind: invalid args" {
run_tool gpiodetect unimplemented-arg
test "$status" -eq 1
}
#
# gpioget test cases
#
@test "gpioget: read all lines" {
gpio_mockup_probe 8 8 8
gpio_mockup_set_pull 1 2 1
gpio_mockup_set_pull 1 3 1
gpio_mockup_set_pull 1 5 1
gpio_mockup_set_pull 1 7 1
run_tool gpioget "$(gpio_mockup_chip_name 1)" 0 1 2 3 4 5 6 7
test "$status" -eq "0"
test "$output" = "0 0 1 1 0 1 0 1"
}
@test "gpioget: read all lines (active-low)" {
gpio_mockup_probe 8 8 8
gpio_mockup_set_pull 1 2 1
gpio_mockup_set_pull 1 3 1
gpio_mockup_set_pull 1 5 1
gpio_mockup_set_pull 1 7 1
run_tool gpioget --active-low "$(gpio_mockup_chip_name 1)" 0 1 2 3 4 5 6 7
test "$status" -eq "0"
test "$output" = "1 1 0 0 1 0 1 0"
}
@test "gpioget: read all lines (pull-up)" {
gpio_mockup_probe 8 8 8
gpio_mockup_set_pull 1 2 1
gpio_mockup_set_pull 1 3 1
gpio_mockup_set_pull 1 5 1
gpio_mockup_set_pull 1 7 1
run_tool gpioget --bias=pull-up "$(gpio_mockup_chip_name 1)" 0 1 2 3 4 5 6 7
test "$status" -eq "0"
test "$output" = "1 1 1 1 1 1 1 1"
}
@test "gpioget: read all lines (pull-down)" {
gpio_mockup_probe 8 8 8
gpio_mockup_set_pull 1 2 1
gpio_mockup_set_pull 1 3 1
gpio_mockup_set_pull 1 5 1
gpio_mockup_set_pull 1 7 1
run_tool gpioget --bias=pull-down "$(gpio_mockup_chip_name 1)" 0 1 2 3 4 5 6 7
test "$status" -eq "0"
test "$output" = "0 0 0 0 0 0 0 0"
}
@test "gpioget: read some lines" {
gpio_mockup_probe 8 8 8
gpio_mockup_set_pull 1 1 1
gpio_mockup_set_pull 1 4 1
gpio_mockup_set_pull 1 6 1
run_tool gpioget "$(gpio_mockup_chip_name 1)" 0 1 4 6
test "$status" -eq "0"
test "$output" = "0 1 1 1"
}
@test "gpioget: no arguments" {
run_tool gpioget
test "$status" -eq "1"
output_regex_match ".*gpiochip must be specified"
}
@test "gpioget: no lines specified" {
gpio_mockup_probe 8 8 8
run_tool gpioget "$(gpio_mockup_chip_name 1)"
test "$status" -eq "1"
output_regex_match ".*at least one GPIO line offset must be specified"
}
@test "gpioget: too many lines specified" {
gpio_mockup_probe 4
run_tool gpioget "$(gpio_mockup_chip_name 1)" 0 1 2 3 4
test "$status" -eq "1"
output_regex_match ".*error reading GPIO values"
}
@test "gpioget: same line twice" {
gpio_mockup_probe 8 8 8
run_tool gpioget "$(gpio_mockup_chip_name 1)" 0 0
test "$status" -eq "1"
output_regex_match ".*error reading GPIO values.*"
}
@test "gpioget: invalid bias" {
gpio_mockup_probe 8 8 8
run_tool gpioget --bias=bad "$(gpio_mockup_chip_name 1)" 0 1
test "$status" -eq "1"
output_regex_match ".*invalid bias.*"
}
#
# gpioset test cases
#
@test "gpioset: set lines and wait for SIGTERM" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpioset --mode=signal "$(gpio_mockup_chip_name 2)" \
0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
gpio_mockup_check_value 2 0 0
gpio_mockup_check_value 2 1 0
gpio_mockup_check_value 2 2 1
gpio_mockup_check_value 2 3 1
gpio_mockup_check_value 2 4 1
gpio_mockup_check_value 2 5 1
gpio_mockup_check_value 2 6 0
gpio_mockup_check_value 2 7 1
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
}
@test "gpioset: set lines and wait for SIGTERM (active-low)" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpioset --active-low --mode=signal "$(gpio_mockup_chip_name 2)" \
0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
gpio_mockup_check_value 2 0 1
gpio_mockup_check_value 2 1 1
gpio_mockup_check_value 2 2 0
gpio_mockup_check_value 2 3 0
gpio_mockup_check_value 2 4 0
gpio_mockup_check_value 2 5 0
gpio_mockup_check_value 2 6 1
gpio_mockup_check_value 2 7 0
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
}
@test "gpioset: set lines and wait for SIGTERM (push-pull)" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpioset --drive=push-pull --mode=signal "$(gpio_mockup_chip_name 2)" \
0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
gpio_mockup_check_value 2 0 0
gpio_mockup_check_value 2 1 0
gpio_mockup_check_value 2 2 1
gpio_mockup_check_value 2 3 1
gpio_mockup_check_value 2 4 1
gpio_mockup_check_value 2 5 1
gpio_mockup_check_value 2 6 0
gpio_mockup_check_value 2 7 1
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
}
@test "gpioset: set lines and wait for SIGTERM (open-drain)" {
gpio_mockup_probe 8 8 8
gpio_mockup_set_pull 2 2 1
gpio_mockup_set_pull 2 3 1
gpio_mockup_set_pull 2 5 1
gpio_mockup_set_pull 2 7 1
coproc_run_tool gpioset --drive=open-drain --mode=signal "$(gpio_mockup_chip_name 2)" \
0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
gpio_mockup_check_value 2 0 0
gpio_mockup_check_value 2 1 0
gpio_mockup_check_value 2 2 1
gpio_mockup_check_value 2 3 1
gpio_mockup_check_value 2 4 0
gpio_mockup_check_value 2 5 1
gpio_mockup_check_value 2 6 0
gpio_mockup_check_value 2 7 1
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
}
@test "gpioset: set lines and wait for SIGTERM (open-source)" {
gpio_mockup_probe 8 8 8
gpio_mockup_set_pull 2 2 1
gpio_mockup_set_pull 2 3 1
gpio_mockup_set_pull 2 5 1
gpio_mockup_set_pull 2 7 1
coproc_run_tool gpioset --drive=open-source --mode=signal "$(gpio_mockup_chip_name 2)" \
0=0 1=0 2=1 3=0 4=1 5=1 6=0 7=1
gpio_mockup_check_value 2 0 0
gpio_mockup_check_value 2 1 0
gpio_mockup_check_value 2 2 1
gpio_mockup_check_value 2 3 1
gpio_mockup_check_value 2 4 1
gpio_mockup_check_value 2 5 1
gpio_mockup_check_value 2 6 0
gpio_mockup_check_value 2 7 1
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
}
@test "gpioset: set some lines and wait for ENTER" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpioset --mode=wait "$(gpio_mockup_chip_name 2)" \
1=0 2=1 5=1 6=0 7=1
gpio_mockup_check_value 2 1 0
gpio_mockup_check_value 2 2 1
gpio_mockup_check_value 2 5 1
gpio_mockup_check_value 2 6 0
gpio_mockup_check_value 2 7 1
coproc_tool_stdin_write ""
coproc_tool_wait
test "$status" -eq "0"
}
@test "gpioset: set some lines and wait for SIGINT" {
gpio_mockup_probe 8
coproc_run_tool gpioset --mode=signal "$(gpio_mockup_chip_name 0)" 0=1
gpio_mockup_check_value 0 0 1
coproc_tool_kill -SIGINT
coproc_tool_wait
test "$status" -eq "0"
}
@test "gpioset: set some lines and wait with --mode=time" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpioset --mode=time --sec=1 --usec=200000 \
"$(gpio_mockup_chip_name 1)" 0=1 5=0 7=1
gpio_mockup_check_value 1 0 1
gpio_mockup_check_value 1 5 0
gpio_mockup_check_value 1 7 1
coproc_tool_wait
test "$status" -eq "0"
}
@test "gpioset: no arguments" {
run_tool gpioset
test "$status" -eq "1"
output_regex_match ".*gpiochip must be specified"
}
@test "gpioset: no lines specified" {
gpio_mockup_probe 8 8 8
run_tool gpioset "$(gpio_mockup_chip_name 1)"
test "$status" -eq "1"
output_regex_match ".*at least one GPIO line offset to value mapping must be specified"
}
@test "gpioset: too many lines specified" {
gpio_mockup_probe 4
run_tool gpioset "$(gpio_mockup_chip_name 1)" 0=1 1=1 2=1 3=1 4=1 5=1
test "$status" -eq "1"
output_regex_match ".*error setting the GPIO line values"
}
@test "gpioset: use --sec without --mode=time" {
gpio_mockup_probe 8 8 8
run_tool gpioset --mode=exit --sec=1 "$(gpio_mockup_chip_name 1)" 0=1
test "$status" -eq "1"
output_regex_match ".*can't specify wait time in this mode"
}
@test "gpioset: use --usec without --mode=time" {
gpio_mockup_probe 8 8 8
run_tool gpioset --mode=exit --usec=1 "$(gpio_mockup_chip_name 1)" 0=1
test "$status" -eq "1"
output_regex_match ".*can't specify wait time in this mode"
}
@test "gpioset: invalid mapping" {
gpio_mockup_probe 8 8 8
run_tool gpioset "$(gpio_mockup_chip_name 1)" 0=c
test "$status" -eq "1"
output_regex_match ".*invalid offset<->value mapping"
}
@test "gpioset: invalid value" {
gpio_mockup_probe 8 8 8
run_tool gpioset "$(gpio_mockup_chip_name 1)" 0=3
test "$status" -eq "1"
output_regex_match ".*value must be 0 or 1"
}
@test "gpioset: invalid offset" {
gpio_mockup_probe 8 8 8
run_tool gpioset "$(gpio_mockup_chip_name 1)" 4000000000=0
test "$status" -eq "1"
output_regex_match ".*invalid offset"
}
@test "gpioset: invalid bias" {
gpio_mockup_probe 8 8 8
run_tool gpioset --bias=bad "$(gpio_mockup_chip_name 1)" 0=1 1=1
test "$status" -eq "1"
output_regex_match ".*invalid bias.*"
}
@test "gpioset: invalid drive" {
gpio_mockup_probe 8 8 8
run_tool gpioset --drive=bad "$(gpio_mockup_chip_name 1)" 0=1 1=1
test "$status" -eq "1"
output_regex_match ".*invalid drive.*"
}
@test "gpioset: daemonize in invalid mode" {
gpio_mockup_probe 8 8 8
run_tool gpioset --background "$(gpio_mockup_chip_name 1)" 0=1
test "$status" -eq "1"
output_regex_match ".*can't daemonize in this mode"
}
@test "gpioset: same line twice" {
gpio_mockup_probe 8 8 8
run_tool gpioset "$(gpio_mockup_chip_name 1)" 0=1 0=1
test "$status" -eq "1"
output_regex_match ".*error setting the GPIO line values.*"
}
#
# gpiomon test cases
#
@test "gpiomon: single rising edge event" {
gpio_mockup_probe 8 8
coproc_run_tool gpiomon --rising-edge "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
output_regex_match \
"event:\\s+RISING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[\s*[0-9]+\.[0-9]+\]"
}
@test "gpiomon: single falling edge event" {
gpio_mockup_probe 8 8
coproc_run_tool gpiomon --falling-edge "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
gpio_mockup_set_pull 1 4 0
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
output_regex_match \
"event:\\s+FALLING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[\s*[0-9]+\.[0-9]+\]"
}
@test "gpiomon: single falling edge event (pull-up)" {
gpio_mockup_probe 8 8
gpio_mockup_set_pull 1 4 0
coproc_run_tool gpiomon --bias=pull-up "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 0
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
output_regex_match \
"event:\\s+FALLING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[\s*[0-9]+\.[0-9]+\]"
}
@test "gpiomon: single rising edge event (pull-down)" {
gpio_mockup_probe 8 8
gpio_mockup_set_pull 1 4 1
coproc_run_tool gpiomon --bias=pull-down "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
output_regex_match \
"event:\\s+RISING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[\s*[0-9]+\.[0-9]+\]"
}
@test "gpiomon: single rising edge event (active-low)" {
gpio_mockup_probe 8 8
gpio_mockup_set_pull 1 4 1
coproc_run_tool gpiomon --rising-edge --active-low "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 0
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
output_regex_match \
"event:\\s+RISING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[\s*[0-9]+\.[0-9]+\]"
}
@test "gpiomon: single rising edge event (silent mode)" {
gpio_mockup_probe 8 8
coproc_run_tool gpiomon --rising-edge --silent "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
test -z "$output"
}
@test "gpiomon: four alternating events" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon --num-events=4 "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
sleep 0.2
gpio_mockup_set_pull 1 4 0
sleep 0.2
gpio_mockup_set_pull 1 4 1
sleep 0.2
gpio_mockup_set_pull 1 4 0
sleep 0.2
coproc_tool_wait
test "$status" -eq "0"
output_regex_match \
"event\\:\\s+FALLING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[\s*[0-9]+\\.[0-9]+\\]"
output_regex_match \
"event\\:\\s+RISING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[\s*[0-9]+\\.[0-9]+\\]"
}
@test "gpiomon: exit after SIGINT" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon "$(gpio_mockup_chip_name 1)" 4
coproc_tool_kill -SIGINT
coproc_tool_wait
test "$status" -eq "0"
test -z "$output"
}
@test "gpiomon: exit after SIGTERM" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon "$(gpio_mockup_chip_name 1)" 4
coproc_tool_kill -SIGTERM
coproc_tool_wait
test "$status" -eq "0"
test -z "$output"
}
@test "gpiomon: both event flags" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon --falling-edge --rising-edge "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
sleep 0.2
gpio_mockup_set_pull 1 4 0
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
output_regex_match \
"event\\:\\s+FALLING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[\s*[0-9]+\\.[0-9]+\\]"
output_regex_match \
"event\\:\\s+RISING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[\s*[0-9]+\\.[0-9]+\\]"
}
@test "gpiomon: watch multiple lines" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon --format=%o "$(gpio_mockup_chip_name 1)" 1 2 3 4 5
gpio_mockup_set_pull 1 2 1
gpio_mockup_set_pull 1 3 1
gpio_mockup_set_pull 1 4 1
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
test "${lines[0]}" = "2"
test "${lines[1]}" = "3"
test "${lines[2]}" = "4"
}
@test "gpiomon: watch multiple lines (lines in mixed-up order)" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon --format=%o "$(gpio_mockup_chip_name 1)" 5 2 7 1 6
gpio_mockup_set_pull 1 2 1
gpio_mockup_set_pull 1 1 1
gpio_mockup_set_pull 1 6 1
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
test "${lines[0]}" = "2"
test "${lines[1]}" = "1"
test "${lines[2]}" = "6"
}
@test "gpiomon: same line twice" {
gpio_mockup_probe 8 8 8
run_tool gpiomon "$(gpio_mockup_chip_name 1)" 0 0
test "$status" -eq "1"
output_regex_match ".*error waiting for events.*"
}
@test "gpiomon: no arguments" {
run_tool gpiomon
test "$status" -eq "1"
output_regex_match ".*gpiochip must be specified"
}
@test "gpiomon: line not specified" {
gpio_mockup_probe 8 8 8
run_tool gpiomon "$(gpio_mockup_chip_name 1)"
test "$status" -eq "1"
output_regex_match ".*GPIO line offset must be specified"
}
@test "gpiomon: line out of range" {
gpio_mockup_probe 4
run_tool gpiomon "$(gpio_mockup_chip_name 0)" 5
test "$status" -eq "1"
output_regex_match ".*error waiting for events"
}
@test "gpiomon: invalid bias" {
gpio_mockup_probe 8 8 8
run_tool gpiomon --bias=bad "$(gpio_mockup_chip_name 1)" 0 1
test "$status" -eq "1"
output_regex_match ".*invalid bias.*"
}
@test "gpiomon: custom format (event type + offset)" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon "--format=%e %o" "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
test "$output" = "1 4"
}
@test "gpiomon: custom format (event type + offset joined)" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon "--format=%e%o" "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
test "$output" = "14"
}
@test "gpiomon: custom format (timestamp)" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon "--format=%e %o %s.%n" "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
output_regex_match "1 4 [0-9]+\\.[0-9]+"
}
@test "gpiomon: custom format (double percent sign)" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon "--format=%%" "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
test "$output" = "%"
}
@test "gpiomon: custom format (double percent sign + event type specifier)" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon "--format=%%e" "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
test "$output" = "%e"
}
@test "gpiomon: custom format (single percent sign)" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon "--format=%" "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
test "$output" = "%"
}
@test "gpiomon: custom format (single percent sign between other characters)" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon "--format=foo % bar" "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
test "$output" = "foo % bar"
}
@test "gpiomon: custom format (unknown specifier)" {
gpio_mockup_probe 8 8 8
coproc_run_tool gpiomon "--format=%x" "$(gpio_mockup_chip_name 1)" 4
gpio_mockup_set_pull 1 4 1
sleep 0.2
coproc_tool_kill
coproc_tool_wait
test "$status" -eq "0"
test "$output" = "%x"
}