blob: ab7b5147c58423282d4753eace79e0f59a3496cc [file] [log] [blame]
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* This file is part of libgpiod.
*
* Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
*/
/* Test cases for the gpioset program. */
#include <signal.h>
#include <unistd.h>
#include "gpiod-test.h"
static void gpioset_set_lines_and_exit(void)
{
unsigned int offsets[8];
int rv, values[8];
test_tool_run("gpioset", test_chip_name(2),
"0=0", "1=0", "2=1", "3=1",
"4=1", "5=1", "6=0", "7=1", (char *)NULL);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_RET_OK(test_tool_exit_status());
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NULL(test_tool_stderr());
offsets[0] = 0;
offsets[1] = 1;
offsets[2] = 2;
offsets[3] = 3;
offsets[4] = 4;
offsets[5] = 5;
offsets[6] = 6;
offsets[7] = 7;
rv = gpiod_ctxless_get_value_multiple(test_chip_name(2), offsets,
values, 8, false, TEST_CONSUMER);
TEST_ASSERT_RET_OK(rv);
TEST_ASSERT_EQ(values[0], 0);
TEST_ASSERT_EQ(values[1], 0);
TEST_ASSERT_EQ(values[2], 1);
TEST_ASSERT_EQ(values[3], 1);
TEST_ASSERT_EQ(values[4], 1);
TEST_ASSERT_EQ(values[5], 1);
TEST_ASSERT_EQ(values[6], 0);
TEST_ASSERT_EQ(values[7], 1);
}
TEST_DEFINE(gpioset_set_lines_and_exit,
"tools: gpioset - set lines and exit",
0, { 8, 8, 8 });
static void gpioset_set_lines_and_exit_active_low(void)
{
unsigned int offsets[8];
int rv, values[8];
test_tool_run("gpioset", "--active-low", test_chip_name(2),
"0=0", "1=0", "2=1", "3=1",
"4=1", "5=1", "6=0", "7=1", (char *)NULL);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_RET_OK(test_tool_exit_status());
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NULL(test_tool_stderr());
offsets[0] = 0;
offsets[1] = 1;
offsets[2] = 2;
offsets[3] = 3;
offsets[4] = 4;
offsets[5] = 5;
offsets[6] = 6;
offsets[7] = 7;
rv = gpiod_ctxless_get_value_multiple(test_chip_name(2), offsets,
values, 8, false, TEST_CONSUMER);
TEST_ASSERT_RET_OK(rv);
TEST_ASSERT_EQ(values[0], 1);
TEST_ASSERT_EQ(values[1], 1);
TEST_ASSERT_EQ(values[2], 0);
TEST_ASSERT_EQ(values[3], 0);
TEST_ASSERT_EQ(values[4], 0);
TEST_ASSERT_EQ(values[5], 0);
TEST_ASSERT_EQ(values[6], 1);
TEST_ASSERT_EQ(values[7], 0);
}
TEST_DEFINE(gpioset_set_lines_and_exit_active_low,
"tools: gpioset - set lines and exit (active-low)",
0, { 8, 8, 8 });
static void gpioset_set_lines_and_exit_explicit_mode(void)
{
unsigned int offsets[8];
int rv, values[8];
test_tool_run("gpioset", "--mode=exit", test_chip_name(2),
"0=0", "1=0", "2=1", "3=1",
"4=1", "5=1", "6=0", "7=1", (char *)NULL);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_RET_OK(test_tool_exit_status());
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NULL(test_tool_stderr());
offsets[0] = 0;
offsets[1] = 1;
offsets[2] = 2;
offsets[3] = 3;
offsets[4] = 4;
offsets[5] = 5;
offsets[6] = 6;
offsets[7] = 7;
rv = gpiod_ctxless_get_value_multiple(test_chip_name(2), offsets,
values, 8, false, TEST_CONSUMER);
TEST_ASSERT_RET_OK(rv);
TEST_ASSERT_EQ(values[0], 0);
TEST_ASSERT_EQ(values[1], 0);
TEST_ASSERT_EQ(values[2], 1);
TEST_ASSERT_EQ(values[3], 1);
TEST_ASSERT_EQ(values[4], 1);
TEST_ASSERT_EQ(values[5], 1);
TEST_ASSERT_EQ(values[6], 0);
TEST_ASSERT_EQ(values[7], 1);
}
TEST_DEFINE(gpioset_set_lines_and_exit_explicit_mode,
"tools: gpioset - set lines and exit (explicit mode argument)",
0, { 8, 8, 8 });
static void gpioset_set_some_lines_and_wait_for_enter(void)
{
unsigned int offsets[5];
int rv, values[5];
test_tool_run("gpioset", "--mode=wait", test_chip_name(2),
"1=0", "2=1", "5=1", "6=0", "7=1", (char *)NULL);
test_tool_stdin_write("\n");
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_RET_OK(test_tool_exit_status());
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NULL(test_tool_stderr());
offsets[0] = 1;
offsets[1] = 2;
offsets[2] = 5;
offsets[3] = 6;
offsets[4] = 7;
rv = gpiod_ctxless_get_value_multiple(test_chip_name(2), offsets,
values, 5, false, TEST_CONSUMER);
TEST_ASSERT_RET_OK(rv);
TEST_ASSERT_EQ(values[0], 0);
TEST_ASSERT_EQ(values[1], 1);
TEST_ASSERT_EQ(values[2], 1);
TEST_ASSERT_EQ(values[3], 0);
TEST_ASSERT_EQ(values[4], 1);
}
TEST_DEFINE(gpioset_set_some_lines_and_wait_for_enter,
"tools: gpioset - set some lines and wait for enter",
0, { 8, 8, 8 });
static void gpioset_set_some_lines_and_wait_for_signal(void)
{
static const int signals[] = { SIGTERM, SIGINT };
unsigned int offsets[5], i;
int rv, values[5];
for (i = 0; i < TEST_ARRAY_SIZE(signals); i++) {
test_tool_run("gpioset", "--mode=signal", test_chip_name(2),
"1=0", "2=1", "5=0", "6=0", "7=1", (char *)NULL);
usleep(200000);
test_tool_signal(signals[i]);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_RET_OK(test_tool_exit_status());
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NULL(test_tool_stderr());
offsets[0] = 1;
offsets[1] = 2;
offsets[2] = 5;
offsets[3] = 6;
offsets[4] = 7;
rv = gpiod_ctxless_get_value_multiple(test_chip_name(2),
offsets, values,
5, false, TEST_CONSUMER);
TEST_ASSERT_RET_OK(rv);
TEST_ASSERT_EQ(values[0], 0);
TEST_ASSERT_EQ(values[1], 1);
TEST_ASSERT_EQ(values[2], 0);
TEST_ASSERT_EQ(values[3], 0);
TEST_ASSERT_EQ(values[4], 1);
}
}
TEST_DEFINE(gpioset_set_some_lines_and_wait_for_signal,
"tools: gpioset - set some lines and wait for signal",
0, { 8, 8, 8 });
static void gpioset_set_some_lines_and_wait_time(void)
{
unsigned int offsets[3];
int rv, values[3];
test_tool_run("gpioset", "--mode=time",
"--usec=100000", "--sec=0", test_chip_name(0),
"1=1", "2=0", "5=1", (char *)NULL);
usleep(200000);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_RET_OK(test_tool_exit_status());
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NULL(test_tool_stderr());
offsets[0] = 1;
offsets[1] = 2;
offsets[2] = 5;
rv = gpiod_ctxless_get_value_multiple(test_chip_name(0), offsets,
values, 3, false, TEST_CONSUMER);
TEST_ASSERT_RET_OK(rv);
TEST_ASSERT_EQ(values[0], 1);
TEST_ASSERT_EQ(values[1], 0);
TEST_ASSERT_EQ(values[2], 1);
}
TEST_DEFINE(gpioset_set_some_lines_and_wait_time,
"tools: gpioset - set some lines and wait for specified time",
0, { 8, 8, 8 });
static void gpioset_no_arguments(void)
{
test_tool_run("gpioset", (char *)NULL);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_EQ(test_tool_exit_status(), 1);
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NOT_NULL(test_tool_stderr());
TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
"gpiochip must be specified");
}
TEST_DEFINE(gpioset_no_arguments,
"tools: gpioset - no arguments",
0, { });
static void gpioset_no_lines_specified(void)
{
test_tool_run("gpioset", test_chip_name(1), (char *)NULL);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_EQ(test_tool_exit_status(), 1);
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NOT_NULL(test_tool_stderr());
TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
"at least one GPIO line offset to value mapping must be specified");
}
TEST_DEFINE(gpioset_no_lines_specified,
"tools: gpioset - no lines specified",
0, { 4, 4 });
static void gpioset_too_many_lines_specified(void)
{
test_tool_run("gpioset", test_chip_name(0),
"0=1", "1=1", "2=1", "3=1", "4=1", (char *)NULL);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_EQ(test_tool_exit_status(), 1);
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NOT_NULL(test_tool_stderr());
TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
"error setting the GPIO line values");
}
TEST_DEFINE(gpioset_too_many_lines_specified,
"tools: gpioset - too many lines specified",
0, { 4 });
static void gpioset_sec_usec_without_time(void)
{
test_tool_run("gpioset", "--mode=exit", "--sec=1",
test_chip_name(0), "0=1", (char *)NULL);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_EQ(test_tool_exit_status(), 1);
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NOT_NULL(test_tool_stderr());
TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
"can't specify wait time in this mode");
test_tool_run("gpioset", "--mode=exit", "--usec=100",
test_chip_name(0), "0=1", (char *)NULL);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_EQ(test_tool_exit_status(), 1);
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NOT_NULL(test_tool_stderr());
TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
"can't specify wait time in this mode");
}
TEST_DEFINE(gpioset_sec_usec_without_time,
"tools: gpioset - using --sec/--usec with mode other than 'time'",
0, { 4 });
static void gpioset_invalid_mapping(void)
{
test_tool_run("gpioset", test_chip_name(0), "0=c", (char *)NULL);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_EQ(test_tool_exit_status(), 1);
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NOT_NULL(test_tool_stderr());
TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
"invalid offset<->value mapping");
}
TEST_DEFINE(gpioset_invalid_mapping,
"tools: gpioset - invalid offset<->value mapping",
0, { 4 });
static void gpioset_invalid_value(void)
{
test_tool_run("gpioset", test_chip_name(0), "0=3", (char *)NULL);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_EQ(test_tool_exit_status(), 1);
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NOT_NULL(test_tool_stderr());
TEST_ASSERT_STR_CONTAINS(test_tool_stderr(), "value must be 0 or 1");
}
TEST_DEFINE(gpioset_invalid_value,
"tools: gpioset - value different than 0 or 1",
0, { 4 });
static void gpioset_invalid_offset(void)
{
test_tool_run("gpioset", test_chip_name(0),
"4000000000=1", (char *)NULL);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_EQ(test_tool_exit_status(), 1);
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NOT_NULL(test_tool_stderr());
TEST_ASSERT_STR_CONTAINS(test_tool_stderr(), "invalid offset");
}
TEST_DEFINE(gpioset_invalid_offset,
"tools: gpioset - invalid offset",
0, { 4 });
static void gpioset_daemonize_in_wrong_mode(void)
{
test_tool_run("gpioset", "--background",
test_chip_name(0), "0=1", (char *)NULL);
test_tool_wait();
TEST_ASSERT(test_tool_exited());
TEST_ASSERT_EQ(test_tool_exit_status(), 1);
TEST_ASSERT_NULL(test_tool_stdout());
TEST_ASSERT_NOT_NULL(test_tool_stderr());
TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
"can't daemonize in this mode");
}
TEST_DEFINE(gpioset_daemonize_in_wrong_mode,
"tools: gpioset - daemonize in wrong mode",
0, { 4 });