// SPDX-License-Identifier: LGPL-2.1-or-later /* * This file is part of libgpiod. * * Copyright (C) 2017-2018 Bartosz Golaszewski */ /* GPIO line test cases. */ #include "gpiod-test.h" #include static void line_request_output(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line *line_0; struct gpiod_line *line_1; int status; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line_0 = gpiod_chip_get_line(chip, 2); line_1 = gpiod_chip_get_line(chip, 5); TEST_ASSERT_NOT_NULL(line_0); TEST_ASSERT_NOT_NULL(line_1); status = gpiod_line_request_output(line_0, TEST_CONSUMER, 0); TEST_ASSERT_RET_OK(status); status = gpiod_line_request_output(line_1, TEST_CONSUMER, 1); TEST_ASSERT_RET_OK(status); TEST_ASSERT_EQ(gpiod_line_get_value(line_0), 0); TEST_ASSERT_EQ(gpiod_line_get_value(line_1), 1); } TEST_DEFINE(line_request_output, "gpiod_line_request_output() - good", 0, { 8 }); static void line_request_already_requested(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line *line; int status; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line = gpiod_chip_get_line(chip, 0); TEST_ASSERT_NOT_NULL(line); status = gpiod_line_request_input(line, TEST_CONSUMER); TEST_ASSERT_RET_OK(status); status = gpiod_line_request_input(line, TEST_CONSUMER); TEST_ASSERT_NOTEQ(status, 0); TEST_ASSERT_ERRNO_IS(EBUSY); } TEST_DEFINE(line_request_already_requested, "gpiod_line_request() - already requested", 0, { 8 }); static void line_consumer(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line *line; int status; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line = gpiod_chip_get_line(chip, 0); TEST_ASSERT_NOT_NULL(line); TEST_ASSERT_NULL(gpiod_line_consumer(line)); status = gpiod_line_request_input(line, TEST_CONSUMER); TEST_ASSERT_RET_OK(status); TEST_ASSERT(!gpiod_line_needs_update(line)); TEST_ASSERT_STR_EQ(gpiod_line_consumer(line), TEST_CONSUMER); } TEST_DEFINE(line_consumer, "gpiod_line_consumer() - good", 0, { 8 }); static void line_consumer_long_string(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line *line; int status; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line = gpiod_chip_get_line(chip, 0); TEST_ASSERT_NOT_NULL(line); TEST_ASSERT_NULL(gpiod_line_consumer(line)); status = gpiod_line_request_input(line, "consumer string over 32 characters long"); TEST_ASSERT_RET_OK(status); TEST_ASSERT(!gpiod_line_needs_update(line)); TEST_ASSERT_STR_EQ(gpiod_line_consumer(line), "consumer string over 32 charact"); TEST_ASSERT_EQ(strlen(gpiod_line_consumer(line)), 31); } TEST_DEFINE(line_consumer_long_string, "gpiod_line_consumer() - long consumer string", 0, { 8 }); static void line_request_bulk_output(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chipA = NULL; TEST_CLEANUP_CHIP struct gpiod_chip *chipB = NULL; struct gpiod_line_bulk bulkB = GPIOD_LINE_BULK_INITIALIZER; struct gpiod_line_bulk bulkA; struct gpiod_line *lineA0; struct gpiod_line *lineA1; struct gpiod_line *lineA2; struct gpiod_line *lineA3; struct gpiod_line *lineB0; struct gpiod_line *lineB1; struct gpiod_line *lineB2; struct gpiod_line *lineB3; int valA[4], valB[4]; int status; chipA = gpiod_chip_open(test_chip_path(0)); chipB = gpiod_chip_open(test_chip_path(1)); TEST_ASSERT_NOT_NULL(chipA); TEST_ASSERT_NOT_NULL(chipB); gpiod_line_bulk_init(&bulkA); lineA0 = gpiod_chip_get_line(chipA, 0); lineA1 = gpiod_chip_get_line(chipA, 1); lineA2 = gpiod_chip_get_line(chipA, 2); lineA3 = gpiod_chip_get_line(chipA, 3); lineB0 = gpiod_chip_get_line(chipB, 0); lineB1 = gpiod_chip_get_line(chipB, 1); lineB2 = gpiod_chip_get_line(chipB, 2); lineB3 = gpiod_chip_get_line(chipB, 3); TEST_ASSERT_NOT_NULL(lineA0); TEST_ASSERT_NOT_NULL(lineA1); TEST_ASSERT_NOT_NULL(lineA2); TEST_ASSERT_NOT_NULL(lineA3); TEST_ASSERT_NOT_NULL(lineB0); TEST_ASSERT_NOT_NULL(lineB1); TEST_ASSERT_NOT_NULL(lineB2); TEST_ASSERT_NOT_NULL(lineB3); gpiod_line_bulk_add(&bulkA, lineA0); gpiod_line_bulk_add(&bulkA, lineA1); gpiod_line_bulk_add(&bulkA, lineA2); gpiod_line_bulk_add(&bulkA, lineA3); gpiod_line_bulk_add(&bulkB, lineB0); gpiod_line_bulk_add(&bulkB, lineB1); gpiod_line_bulk_add(&bulkB, lineB2); gpiod_line_bulk_add(&bulkB, lineB3); valA[0] = 1; valA[1] = 0; valA[2] = 0; valA[3] = 1; status = gpiod_line_request_bulk_output(&bulkA, TEST_CONSUMER, valA); TEST_ASSERT_RET_OK(status); valB[0] = 0; valB[1] = 1; valB[2] = 0; valB[3] = 1; status = gpiod_line_request_bulk_output(&bulkB, TEST_CONSUMER, valB); TEST_ASSERT_RET_OK(status); memset(valA, 0, sizeof(valA)); memset(valB, 0, sizeof(valB)); status = gpiod_line_get_value_bulk(&bulkA, valA); TEST_ASSERT_RET_OK(status); TEST_ASSERT_EQ(valA[0], 1); TEST_ASSERT_EQ(valA[1], 0); TEST_ASSERT_EQ(valA[2], 0); TEST_ASSERT_EQ(valA[3], 1); status = gpiod_line_get_value_bulk(&bulkB, valB); TEST_ASSERT_RET_OK(status); TEST_ASSERT_EQ(valB[0], 0); TEST_ASSERT_EQ(valB[1], 1); TEST_ASSERT_EQ(valB[2], 0); TEST_ASSERT_EQ(valB[3], 1); } TEST_DEFINE(line_request_bulk_output, "gpiod_line_request_bulk_output() - good", 0, { 8, 8 }); static void line_request_bulk_different_chips(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chipA = NULL; TEST_CLEANUP_CHIP struct gpiod_chip *chipB = NULL; struct gpiod_line_request_config req; struct gpiod_line_bulk bulk; struct gpiod_line *lineA0; struct gpiod_line *lineA1; struct gpiod_line *lineB0; struct gpiod_line *lineB1; int status; chipA = gpiod_chip_open(test_chip_path(0)); chipB = gpiod_chip_open(test_chip_path(1)); TEST_ASSERT_NOT_NULL(chipA); TEST_ASSERT_NOT_NULL(chipB); lineA0 = gpiod_chip_get_line(chipA, 0); lineA1 = gpiod_chip_get_line(chipA, 1); lineB0 = gpiod_chip_get_line(chipB, 0); lineB1 = gpiod_chip_get_line(chipB, 1); TEST_ASSERT_NOT_NULL(lineA0); TEST_ASSERT_NOT_NULL(lineA1); TEST_ASSERT_NOT_NULL(lineB0); TEST_ASSERT_NOT_NULL(lineB1); gpiod_line_bulk_init(&bulk); gpiod_line_bulk_add(&bulk, lineA0); gpiod_line_bulk_add(&bulk, lineA1); gpiod_line_bulk_add(&bulk, lineB0); gpiod_line_bulk_add(&bulk, lineB1); req.consumer = TEST_CONSUMER; req.request_type = GPIOD_LINE_REQUEST_DIRECTION_INPUT; req.flags = GPIOD_LINE_ACTIVE_STATE_HIGH; status = gpiod_line_request_bulk(&bulk, &req, NULL); TEST_ASSERT_NOTEQ(status, 0); TEST_ASSERT_ERRNO_IS(EINVAL); } TEST_DEFINE(line_request_bulk_different_chips, "gpiod_line_request_bulk() - different chips", 0, { 8, 8 }); static void line_request_null_default_vals_for_output(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line_bulk bulk = GPIOD_LINE_BULK_INITIALIZER; struct gpiod_line *line; int rv, vals[3]; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line = gpiod_chip_get_line(chip, 0); gpiod_line_bulk_add(&bulk, line); line = gpiod_chip_get_line(chip, 1); gpiod_line_bulk_add(&bulk, line); line = gpiod_chip_get_line(chip, 2); gpiod_line_bulk_add(&bulk, line); rv = gpiod_line_request_bulk_output(&bulk, TEST_CONSUMER, NULL); TEST_ASSERT_RET_OK(rv); gpiod_line_release_bulk(&bulk); rv = gpiod_line_request_bulk_input(&bulk, TEST_CONSUMER); TEST_ASSERT_RET_OK(rv); memset(vals, 0, sizeof(vals)); rv = gpiod_line_get_value_bulk(&bulk, vals); TEST_ASSERT_RET_OK(rv); TEST_ASSERT_EQ(vals[0], 0); TEST_ASSERT_EQ(vals[1], 0); TEST_ASSERT_EQ(vals[2], 0); } TEST_DEFINE(line_request_null_default_vals_for_output, "gpiod_line_request_bulk() - null default vals for output", 0, { 8 }); static void line_set_value(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line *line; int status; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line = gpiod_chip_get_line(chip, 2); TEST_ASSERT_NOT_NULL(line); status = gpiod_line_request_output(line, TEST_CONSUMER, 0); TEST_ASSERT_RET_OK(status); TEST_ASSERT_RET_OK(gpiod_line_set_value(line, 1)); TEST_ASSERT_EQ(gpiod_line_get_value(line), 1); TEST_ASSERT_RET_OK(gpiod_line_set_value(line, 0)); TEST_ASSERT_EQ(gpiod_line_get_value(line), 0); } TEST_DEFINE(line_set_value, "gpiod_line_set_value() - good", 0, { 8 }); static void line_get_value_different_chips(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chipA = NULL; TEST_CLEANUP_CHIP struct gpiod_chip *chipB = NULL; struct gpiod_line *lineA1, *lineA2, *lineB1, *lineB2; struct gpiod_line_bulk bulkA, bulkB, bulk; int rv, vals[4]; chipA = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chipA); chipB = gpiod_chip_open(test_chip_path(1)); TEST_ASSERT_NOT_NULL(chipB); lineA1 = gpiod_chip_get_line(chipA, 3); lineA2 = gpiod_chip_get_line(chipA, 4); lineB1 = gpiod_chip_get_line(chipB, 5); lineB2 = gpiod_chip_get_line(chipB, 6); TEST_ASSERT_NOT_NULL(lineA1); TEST_ASSERT_NOT_NULL(lineA2); TEST_ASSERT_NOT_NULL(lineB1); TEST_ASSERT_NOT_NULL(lineB2); gpiod_line_bulk_init(&bulkA); gpiod_line_bulk_init(&bulkB); gpiod_line_bulk_init(&bulk); gpiod_line_bulk_add(&bulk, lineA1); gpiod_line_bulk_add(&bulk, lineA2); gpiod_line_bulk_add(&bulk, lineB1); gpiod_line_bulk_add(&bulk, lineB2); gpiod_line_bulk_add(&bulkA, lineA1); gpiod_line_bulk_add(&bulkA, lineA2); gpiod_line_bulk_add(&bulkB, lineB1); gpiod_line_bulk_add(&bulkB, lineB2); gpiod_line_bulk_add(&bulk, lineA1); gpiod_line_bulk_add(&bulk, lineA2); gpiod_line_bulk_add(&bulk, lineB1); gpiod_line_bulk_add(&bulk, lineB2); rv = gpiod_line_request_bulk_input(&bulkA, TEST_CONSUMER); TEST_ASSERT_RET_OK(rv); rv = gpiod_line_request_bulk_input(&bulkB, TEST_CONSUMER); TEST_ASSERT_RET_OK(rv); rv = gpiod_line_get_value_bulk(&bulk, vals); TEST_ASSERT_EQ(rv, -1); TEST_ASSERT_ERRNO_IS(EINVAL); } TEST_DEFINE(line_get_value_different_chips, "gpiod_line_get_value_bulk() - different chips", 0, { 8, 8 }); static void line_get_good(void) { TEST_CLEANUP(test_line_close_chip) struct gpiod_line *line = NULL; line = gpiod_line_get(test_chip_name(2), 18); TEST_ASSERT_NOT_NULL(line); TEST_ASSERT_EQ(gpiod_line_offset(line), 18); } TEST_DEFINE(line_get_good, "gpiod_line_get() - good", TEST_FLAG_NAMED_LINES, { 16, 16, 32, 16 }); static void line_get_invalid_offset(void) { TEST_CLEANUP(test_line_close_chip) struct gpiod_line *line = NULL; line = gpiod_line_get(test_chip_name(3), 18); TEST_ASSERT_NULL(line); TEST_ASSERT_ERRNO_IS(EINVAL); } TEST_DEFINE(line_get_invalid_offset, "gpiod_line_get() - invalid offset", TEST_FLAG_NAMED_LINES, { 16, 16, 32, 16 }); static void line_find_good(void) { TEST_CLEANUP(test_line_close_chip) struct gpiod_line *line = NULL; line = gpiod_line_find("gpio-mockup-C-12"); TEST_ASSERT_NOT_NULL(line); TEST_ASSERT_EQ(gpiod_line_offset(line), 12); } TEST_DEFINE(line_find_good, "gpiod_line_find() - good", TEST_FLAG_NAMED_LINES, { 16, 16, 32, 16 }); static void line_find_not_found(void) { TEST_CLEANUP(test_line_close_chip) struct gpiod_line *line = NULL; line = gpiod_line_find("nonexistent"); TEST_ASSERT_NULL(line); TEST_ASSERT_ERRNO_IS(ENOENT); } TEST_DEFINE(line_find_not_found, "gpiod_line_find() - not found", TEST_FLAG_NAMED_LINES, { 16, 16, 32, 16 }); static void line_find_unnamed_lines(void) { TEST_CLEANUP(test_line_close_chip) struct gpiod_line *line = NULL; line = gpiod_line_find("gpio-mockup-C-12"); TEST_ASSERT_NULL(line); TEST_ASSERT_ERRNO_IS(ENOENT); } TEST_DEFINE(line_find_unnamed_lines, "gpiod_line_find() - unnamed lines", 0, { 16, 16, 32, 16 }); static void line_direction(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line *line; int status; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line = gpiod_chip_get_line(chip, 5); TEST_ASSERT_NOT_NULL(line); status = gpiod_line_request_output(line, TEST_CONSUMER, 0); TEST_ASSERT_RET_OK(status); TEST_ASSERT_EQ(gpiod_line_direction(line), GPIOD_LINE_DIRECTION_OUTPUT); gpiod_line_release(line); status = gpiod_line_request_input(line, TEST_CONSUMER); TEST_ASSERT_RET_OK(status); TEST_ASSERT_EQ(gpiod_line_direction(line), GPIOD_LINE_DIRECTION_INPUT); } TEST_DEFINE(line_direction, "gpiod_line_direction() - set & get", 0, { 8 }); static void line_active_state(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line *line; int status; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line = gpiod_chip_get_line(chip, 5); TEST_ASSERT_NOT_NULL(line); status = gpiod_line_request_input(line, TEST_CONSUMER); TEST_ASSERT_RET_OK(status); TEST_ASSERT_EQ(gpiod_line_active_state(line), GPIOD_LINE_ACTIVE_STATE_HIGH); gpiod_line_release(line); status = gpiod_line_request_input_flags(line, TEST_CONSUMER, GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW); TEST_ASSERT_RET_OK(status); TEST_ASSERT_EQ(gpiod_line_direction(line), GPIOD_LINE_DIRECTION_INPUT); } TEST_DEFINE(line_active_state, "gpiod_line_active_state() - set & get", 0, { 8 }); static void line_misc_flags(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line_request_config config; struct gpiod_line *line; int status; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line = gpiod_chip_get_line(chip, 2); TEST_ASSERT_NOT_NULL(line); TEST_ASSERT_FALSE(gpiod_line_is_used(line)); TEST_ASSERT_FALSE(gpiod_line_is_open_drain(line)); TEST_ASSERT_FALSE(gpiod_line_is_open_source(line)); config.request_type = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT; config.consumer = TEST_CONSUMER; config.flags = GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN; status = gpiod_line_request(line, &config, 0); TEST_ASSERT_RET_OK(status); TEST_ASSERT(gpiod_line_is_used(line)); TEST_ASSERT(gpiod_line_is_open_drain(line)); TEST_ASSERT_FALSE(gpiod_line_is_open_source(line)); gpiod_line_release(line); config.flags = GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE; status = gpiod_line_request(line, &config, 0); TEST_ASSERT_RET_OK(status); TEST_ASSERT(gpiod_line_is_used(line)); TEST_ASSERT_FALSE(gpiod_line_is_open_drain(line)); TEST_ASSERT(gpiod_line_is_open_source(line)); } TEST_DEFINE(line_misc_flags, "gpiod_line - misc flags", 0, { 8 }); static void line_open_source_open_drain_input_invalid(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line *line; int rv; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line = gpiod_chip_get_line(chip, 2); TEST_ASSERT_NOT_NULL(line); rv = gpiod_line_request_input_flags(line, TEST_CONSUMER, GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN); TEST_ASSERT_EQ(rv, -1); TEST_ASSERT_ERRNO_IS(EINVAL); rv = gpiod_line_request_input_flags(line, TEST_CONSUMER, GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE); TEST_ASSERT_EQ(rv, -1); TEST_ASSERT_ERRNO_IS(EINVAL); } TEST_DEFINE(line_open_source_open_drain_input_invalid, "gpiod_line - open-source & open-drain for input mode (invalid)", 0, { 8 }); static void line_open_source_open_drain_simultaneously(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line *line; int rv; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line = gpiod_chip_get_line(chip, 2); TEST_ASSERT_NOT_NULL(line); rv = gpiod_line_request_output_flags(line, TEST_CONSUMER, GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE | GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN, 1); TEST_ASSERT_EQ(rv, -1); TEST_ASSERT_ERRNO_IS(EINVAL); } TEST_DEFINE(line_open_source_open_drain_simultaneously, "gpiod_line - open-source & open-drain flags simultaneously", 0, { 8 }); /* Verify that the reference counting of the line fd handle works correctly. */ static void line_release_one_use_another(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line_bulk bulk; struct gpiod_line *line1; struct gpiod_line *line2; int rv, vals[2]; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line1 = gpiod_chip_get_line(chip, 2); TEST_ASSERT_NOT_NULL(line1); line2 = gpiod_chip_get_line(chip, 3); TEST_ASSERT_NOT_NULL(line2); gpiod_line_bulk_init(&bulk); gpiod_line_bulk_add(&bulk, line1); gpiod_line_bulk_add(&bulk, line2); vals[0] = vals[1] = 1; rv = gpiod_line_request_bulk_output(&bulk, TEST_CONSUMER, vals); TEST_ASSERT_RET_OK(rv); gpiod_line_release(line1); rv = gpiod_line_get_value(line1); TEST_ASSERT_EQ(rv, -1); TEST_ASSERT_ERRNO_IS(EPERM); rv = gpiod_line_get_value(line2); TEST_ASSERT_EQ(rv, 1); } TEST_DEFINE(line_release_one_use_another, "gpiod_line - request two, release one, use the other one", 0, { 8 }); static void line_null_consumer(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line_request_config config; struct gpiod_line *line; int rv; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line = gpiod_chip_get_line(chip, 2); TEST_ASSERT_NOT_NULL(line); config.request_type = GPIOD_LINE_REQUEST_DIRECTION_INPUT; config.consumer = NULL; config.flags = 0; rv = gpiod_line_request(line, &config, 0); TEST_ASSERT_RET_OK(rv); TEST_ASSERT_STR_EQ(gpiod_line_consumer(line), "?"); gpiod_line_release(line); /* * Internally we use different structures for event requests, so we * need to test that explicitly too. */ config.request_type = GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES; rv = gpiod_line_request(line, &config, 0); TEST_ASSERT_RET_OK(rv); TEST_ASSERT_STR_EQ(gpiod_line_consumer(line), "?"); } TEST_DEFINE(line_null_consumer, "line request - NULL consumer string", 0, { 8 }); static void line_empty_consumer(void) { TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line_request_config config; struct gpiod_line *line; int rv; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); line = gpiod_chip_get_line(chip, 2); TEST_ASSERT_NOT_NULL(line); config.request_type = GPIOD_LINE_REQUEST_DIRECTION_INPUT; config.consumer = ""; config.flags = 0; rv = gpiod_line_request(line, &config, 0); TEST_ASSERT_RET_OK(rv); TEST_ASSERT_STR_EQ(gpiod_line_consumer(line), "?"); gpiod_line_release(line); /* * Internally we use different structures for event requests, so we * need to test that explicitly too. */ config.request_type = GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES; rv = gpiod_line_request(line, &config, 0); TEST_ASSERT_RET_OK(rv); TEST_ASSERT_STR_EQ(gpiod_line_consumer(line), "?"); } TEST_DEFINE(line_empty_consumer, "line request - empty consumer string", 0, { 8 }); static void line_bulk_foreach(void) { static const char *const line_names[] = { "gpio-mockup-A-0", "gpio-mockup-A-1", "gpio-mockup-A-2", "gpio-mockup-A-3" }; TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL; struct gpiod_line_bulk bulk = GPIOD_LINE_BULK_INITIALIZER; struct gpiod_line *line, **lineptr; int i; chip = gpiod_chip_open(test_chip_path(0)); TEST_ASSERT_NOT_NULL(chip); for (i = 0; i < 4; i++) { line = gpiod_chip_get_line(chip, i); TEST_ASSERT_NOT_NULL(line); gpiod_line_bulk_add(&bulk, line); } i = 0; gpiod_line_bulk_foreach_line(&bulk, line, lineptr) TEST_ASSERT_STR_EQ(gpiod_line_name(line), line_names[i++]); i = 0; gpiod_line_bulk_foreach_line(&bulk, line, lineptr) { TEST_ASSERT_STR_EQ(gpiod_line_name(line), line_names[i++]); if (i == 2) break; } } TEST_DEFINE(line_bulk_foreach, "line bulk - iterate over all lines", TEST_FLAG_NAMED_LINES, { 8 });