// SPDX-License-Identifier: LGPL-2.1-or-later /* * This file is part of libgpiod. * * Copyright (C) 2017-2018 Bartosz Golaszewski */ /* Test cases for the gpioset program. */ #include "gpiod-test.h" #include #include 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 });