1
0
mirror of https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git synced 2026-10-24 00:48:53 +03:00
Files
libgpiod/tests/tests-line-config.c
Bartosz Golaszewski a62c5fbc63 tests: move the test case for duplicate configured offsets
This test case lives in tests-line-request.c but it doesn't really test
request functionality but rather only the behavior of line-config. Limit
it to only testing struct gpiod_line_config and move it to
tests-line-config.c.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
2023-04-27 15:28:18 +02:00

471 lines
14 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@gmail.com>
#include <errno.h>
#include <glib.h>
#include <gpiod.h>
#include "gpiod-test.h"
#include "gpiod-test-helpers.h"
#include "gpiod-test-sim.h"
#define GPIOD_TEST_GROUP "line-config"
GPIOD_TEST_CASE(too_many_lines)
{
g_autoptr(struct_gpiod_line_settings) settings = NULL;
g_autoptr(struct_gpiod_line_config) config = NULL;
guint offsets[65], i;
gint ret;
settings = gpiod_test_create_line_settings_or_fail();
config = gpiod_test_create_line_config_or_fail();
for (i = 0; i < 65; i++)
offsets[i] = i;
ret = gpiod_line_config_add_line_settings(config, offsets, 65,
settings);
g_assert_cmpint(ret, <, 0);
g_assert_cmpint(errno, ==, E2BIG);
}
GPIOD_TEST_CASE(get_line_settings)
{
static const guint offsets[] = { 0, 1, 2, 3 };
g_autoptr(struct_gpiod_line_settings) settings = NULL;
g_autoptr(struct_gpiod_line_settings) retrieved = NULL;
g_autoptr(struct_gpiod_line_config) config = NULL;
settings = gpiod_test_create_line_settings_or_fail();
config = gpiod_test_create_line_config_or_fail();
gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT);
gpiod_line_settings_set_bias(settings, GPIOD_LINE_BIAS_PULL_DOWN);
gpiod_test_line_config_add_line_settings_or_fail(config, offsets, 4,
settings);
retrieved = gpiod_test_line_config_get_line_settings_or_fail(config, 2);
g_assert_cmpint(gpiod_line_settings_get_direction(retrieved), ==,
GPIOD_LINE_DIRECTION_INPUT);
g_assert_cmpint(gpiod_line_settings_get_bias(retrieved), ==,
GPIOD_LINE_BIAS_PULL_DOWN);
}
GPIOD_TEST_CASE(too_many_attrs)
{
g_autoptr(GPIOSimChip) sim = g_gpiosim_chip_new("num-lines", 8, NULL);
g_autoptr(struct_gpiod_chip) chip = NULL;
g_autoptr(struct_gpiod_line_config) line_cfg = NULL;
g_autoptr(struct_gpiod_line_settings) settings = NULL;
g_autoptr(struct_gpiod_line_request) request = NULL;
guint offset;
chip = gpiod_test_open_chip_or_fail(g_gpiosim_chip_get_dev_path(sim));
settings = gpiod_test_create_line_settings_or_fail();
line_cfg = gpiod_test_create_line_config_or_fail();
gpiod_line_settings_set_direction(settings,
GPIOD_LINE_DIRECTION_OUTPUT);
gpiod_line_settings_set_output_value(settings, GPIOD_LINE_VALUE_ACTIVE);
offset = 0;
gpiod_test_line_config_add_line_settings_or_fail(line_cfg, &offset, 1,
settings);
gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT);
gpiod_line_settings_set_debounce_period_us(settings, 1000);
gpiod_line_settings_set_edge_detection(settings, GPIOD_LINE_EDGE_BOTH);
offset = 1;
gpiod_test_line_config_add_line_settings_or_fail(line_cfg, &offset, 1,
settings);
gpiod_line_settings_set_bias(settings, GPIOD_LINE_BIAS_PULL_UP);
offset = 2;
gpiod_test_line_config_add_line_settings_or_fail(line_cfg, &offset, 1,
settings);
gpiod_line_settings_set_bias(settings, GPIOD_LINE_BIAS_PULL_DOWN);
offset = 3;
gpiod_test_line_config_add_line_settings_or_fail(line_cfg, &offset, 1,
settings);
gpiod_line_settings_set_bias(settings, GPIOD_LINE_BIAS_DISABLED);
offset = 4;
gpiod_test_line_config_add_line_settings_or_fail(line_cfg, &offset, 1,
settings);
gpiod_line_settings_set_active_low(settings, true);
offset = 5;
gpiod_test_line_config_add_line_settings_or_fail(line_cfg, &offset, 1,
settings);
gpiod_line_settings_set_edge_detection(settings,
GPIOD_LINE_EDGE_FALLING);
offset = 6;
gpiod_test_line_config_add_line_settings_or_fail(line_cfg, &offset, 1,
settings);
gpiod_line_settings_set_event_clock(settings,
GPIOD_LINE_CLOCK_REALTIME);
offset = 7;
gpiod_test_line_config_add_line_settings_or_fail(line_cfg, &offset, 1,
settings);
gpiod_line_settings_reset(settings);
gpiod_line_settings_set_direction(settings,
GPIOD_LINE_DIRECTION_OUTPUT);
gpiod_line_settings_set_drive(settings, GPIOD_LINE_DRIVE_OPEN_DRAIN);
offset = 8;
gpiod_test_line_config_add_line_settings_or_fail(line_cfg, &offset, 1,
settings);
gpiod_line_settings_set_drive(settings, GPIOD_LINE_DRIVE_OPEN_SOURCE);
offset = 9;
gpiod_test_line_config_add_line_settings_or_fail(line_cfg, &offset, 1,
settings);
request = gpiod_chip_request_lines(chip, NULL, line_cfg);
g_assert_null(request);
g_assert_cmpint(errno, ==, E2BIG);
}
GPIOD_TEST_CASE(null_settings)
{
static const guint offsets[] = { 0, 1, 2, 3 };
g_autoptr(struct_gpiod_line_config) config = NULL;
g_autoptr(struct_gpiod_line_settings) settings = NULL;
config = gpiod_test_create_line_config_or_fail();
gpiod_test_line_config_add_line_settings_or_fail(config, offsets, 4,
NULL);
settings = gpiod_test_line_config_get_line_settings_or_fail(config, 2);
g_assert_cmpint(gpiod_line_settings_get_drive(settings), ==,
GPIOD_LINE_DIRECTION_AS_IS);
}
GPIOD_TEST_CASE(null_and_0_offsets)
{
static const guint offsets[] = { 0, 1, 2, 3 };
g_autoptr(struct_gpiod_line_config) config = NULL;
g_autoptr(struct_gpiod_line_settings) settings = NULL;
gint ret;
config = gpiod_test_create_line_config_or_fail();
settings = gpiod_test_create_line_settings_or_fail();
ret = gpiod_line_config_add_line_settings(config, NULL, 4, settings);
g_assert_cmpint(ret, ==, -1);
gpiod_test_expect_errno(EINVAL);
ret = gpiod_line_config_add_line_settings(config, offsets, 0, settings);
g_assert_cmpint(ret, ==, -1);
gpiod_test_expect_errno(EINVAL);
}
GPIOD_TEST_CASE(reset_config)
{
static const guint offsets[] = { 0, 1, 2, 3 };
g_autoptr(struct_gpiod_line_settings) settings = NULL;
g_autoptr(struct_gpiod_line_settings) retrieved0 = NULL;
g_autoptr(struct_gpiod_line_settings) retrieved1 = NULL;
g_autoptr(struct_gpiod_line_config) config = NULL;
settings = gpiod_test_create_line_settings_or_fail();
config = gpiod_test_create_line_config_or_fail();
gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT);
gpiod_line_settings_set_bias(settings, GPIOD_LINE_BIAS_PULL_DOWN);
gpiod_test_line_config_add_line_settings_or_fail(config, offsets, 4,
settings);
retrieved0 = gpiod_test_line_config_get_line_settings_or_fail(config,
2);
g_assert_cmpint(gpiod_line_settings_get_direction(retrieved0), ==,
GPIOD_LINE_DIRECTION_INPUT);
g_assert_cmpint(gpiod_line_settings_get_bias(retrieved0), ==,
GPIOD_LINE_BIAS_PULL_DOWN);
gpiod_line_config_reset(config);
retrieved1 = gpiod_line_config_get_line_settings(config, 2);
g_assert_null(retrieved1);
}
GPIOD_TEST_CASE(get_offsets)
{
g_autoptr(struct_gpiod_line_settings) settings = NULL;
g_autoptr(struct_gpiod_line_config) config = NULL;
guint offsets[8], offsets_in[4];
size_t num_offsets;
settings = gpiod_test_create_line_settings_or_fail();
config = gpiod_test_create_line_config_or_fail();
gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT);
gpiod_line_settings_set_bias(settings, GPIOD_LINE_BIAS_PULL_DOWN);
offsets[0] = 2;
offsets[1] = 4;
gpiod_test_line_config_add_line_settings_or_fail(config, offsets, 2,
settings);
gpiod_line_settings_set_edge_detection(settings, GPIOD_LINE_EDGE_BOTH);
offsets[0] = 6;
offsets[1] = 7;
gpiod_test_line_config_add_line_settings_or_fail(config, offsets, 2,
settings);
num_offsets = gpiod_line_config_get_configured_offsets(config,
offsets_in, 4);
g_assert_cmpuint(num_offsets, ==, 4);
g_assert_cmpuint(offsets_in[0], ==, 2);
g_assert_cmpuint(offsets_in[1], ==, 4);
g_assert_cmpuint(offsets_in[2], ==, 6);
g_assert_cmpuint(offsets_in[3], ==, 7);
}
GPIOD_TEST_CASE(get_0_offsets)
{
g_autoptr(struct_gpiod_line_config) config = NULL;
size_t num_offsets;
guint offsets[3];
config = gpiod_test_create_line_config_or_fail();
num_offsets = gpiod_line_config_get_configured_offsets(config,
offsets, 0);
g_assert_cmpuint(num_offsets, ==, 0);
}
GPIOD_TEST_CASE(get_null_offsets)
{
g_autoptr(struct_gpiod_line_config) config = NULL;
size_t num_offsets;
config = gpiod_test_create_line_config_or_fail();
num_offsets = gpiod_line_config_get_configured_offsets(config,
NULL, 10);
g_assert_cmpuint(num_offsets, ==, 0);
}
GPIOD_TEST_CASE(get_less_offsets_than_configured)
{
static const guint offsets[] = { 0, 1, 2, 3 };
g_autoptr(struct_gpiod_line_config) config = NULL;
size_t num_retrieved;
guint retrieved[3];
config = gpiod_test_create_line_config_or_fail();
gpiod_test_line_config_add_line_settings_or_fail(config, offsets, 4,
NULL);
num_retrieved = gpiod_line_config_get_configured_offsets(config,
retrieved, 3);
g_assert_cmpuint(num_retrieved, ==, 3);
g_assert_cmpuint(retrieved[0], ==, 0);
g_assert_cmpuint(retrieved[1], ==, 1);
g_assert_cmpuint(retrieved[2], ==, 2);
}
GPIOD_TEST_CASE(get_more_offsets_than_configured)
{
static const guint offsets[] = { 0, 1, 2, 3 };
g_autoptr(struct_gpiod_line_config) config = NULL;
size_t num_retrieved;
guint retrieved[8];
config = gpiod_test_create_line_config_or_fail();
gpiod_test_line_config_add_line_settings_or_fail(config, offsets, 4,
NULL);
num_retrieved = gpiod_line_config_get_configured_offsets(config,
retrieved, 8);
g_assert_cmpuint(num_retrieved, ==, 4);
g_assert_cmpuint(retrieved[0], ==, 0);
g_assert_cmpuint(retrieved[1], ==, 1);
g_assert_cmpuint(retrieved[2], ==, 2);
g_assert_cmpuint(retrieved[3], ==, 3);
}
GPIOD_TEST_CASE(set_global_output_values)
{
static const guint offsets[] = { 0, 1, 2, 3 };
static const enum gpiod_line_value values[] = {
GPIOD_LINE_VALUE_ACTIVE,
GPIOD_LINE_VALUE_INACTIVE,
GPIOD_LINE_VALUE_ACTIVE,
GPIOD_LINE_VALUE_INACTIVE,
};
g_autoptr(GPIOSimChip) sim = g_gpiosim_chip_new("num-lines", 4, NULL);
g_autoptr(struct_gpiod_line_settings) settings = NULL;
g_autoptr(struct_gpiod_line_config) config = NULL;
g_autoptr(struct_gpiod_line_request) request = NULL;
g_autoptr(struct_gpiod_chip) chip = NULL;
chip = gpiod_test_open_chip_or_fail(g_gpiosim_chip_get_dev_path(sim));
settings = gpiod_test_create_line_settings_or_fail();
config = gpiod_test_create_line_config_or_fail();
gpiod_line_settings_set_direction(settings,
GPIOD_LINE_DIRECTION_OUTPUT);
gpiod_test_line_config_add_line_settings_or_fail(config, offsets, 4,
settings);
gpiod_test_line_config_set_output_values_or_fail(config, values, 4);
request = gpiod_test_chip_request_lines_or_fail(chip, NULL, config);
g_assert_cmpint(g_gpiosim_chip_get_value(sim, 0), ==,
G_GPIOSIM_VALUE_ACTIVE);
g_assert_cmpint(g_gpiosim_chip_get_value(sim, 1), ==,
G_GPIOSIM_VALUE_INACTIVE);
g_assert_cmpint(g_gpiosim_chip_get_value(sim, 2), ==,
G_GPIOSIM_VALUE_ACTIVE);
g_assert_cmpint(g_gpiosim_chip_get_value(sim, 3), ==,
G_GPIOSIM_VALUE_INACTIVE);
}
GPIOD_TEST_CASE(read_back_global_output_values)
{
static const guint offsets[] = { 0, 1, 2, 3 };
static const enum gpiod_line_value values[] = {
GPIOD_LINE_VALUE_ACTIVE,
GPIOD_LINE_VALUE_INACTIVE,
GPIOD_LINE_VALUE_ACTIVE,
GPIOD_LINE_VALUE_INACTIVE,
};
g_autoptr(struct_gpiod_line_settings) settings = NULL;
g_autoptr(struct_gpiod_line_settings) retrieved = NULL;
g_autoptr(struct_gpiod_line_config) config = NULL;
settings = gpiod_test_create_line_settings_or_fail();
config = gpiod_test_create_line_config_or_fail();
gpiod_line_settings_set_direction(settings,
GPIOD_LINE_DIRECTION_OUTPUT);
gpiod_line_settings_set_output_value(settings, GPIOD_LINE_VALUE_ACTIVE);
gpiod_test_line_config_add_line_settings_or_fail(config, offsets, 4,
settings);
gpiod_test_line_config_set_output_values_or_fail(config, values, 4);
retrieved = gpiod_test_line_config_get_line_settings_or_fail(config, 1);
g_assert_cmpint(gpiod_line_settings_get_output_value(retrieved), ==,
GPIOD_LINE_VALUE_INACTIVE);
}
GPIOD_TEST_CASE(set_output_values_invalid_value)
{
static const enum gpiod_line_value values[] = {
GPIOD_LINE_VALUE_ACTIVE,
GPIOD_LINE_VALUE_INACTIVE,
999,
GPIOD_LINE_VALUE_INACTIVE,
};
g_autoptr(struct_gpiod_line_config) config = NULL;
config = gpiod_test_create_line_config_or_fail();
g_assert_cmpint(gpiod_line_config_set_output_values(config, values, 4),
==, -1);
gpiod_test_expect_errno(EINVAL);
}
GPIOD_TEST_CASE(set_output_values_bad_args)
{
static const enum gpiod_line_value values[] = {
GPIOD_LINE_VALUE_ACTIVE,
GPIOD_LINE_VALUE_INACTIVE,
GPIOD_LINE_VALUE_ACTIVE,
GPIOD_LINE_VALUE_INACTIVE,
};
g_autoptr(struct_gpiod_line_config) config = NULL;
gint ret;
config = gpiod_test_create_line_config_or_fail();
ret = gpiod_line_config_set_output_values(config, NULL, 4);
g_assert_cmpint(ret, ==, -1);
gpiod_test_expect_errno(EINVAL);
ret = gpiod_line_config_set_output_values(config, values, 0);
g_assert_cmpint(ret, ==, -1);
gpiod_test_expect_errno(EINVAL);
}
GPIOD_TEST_CASE(set_output_values_too_many_values)
{
static const gsize num_values = 65;
g_autoptr(struct_gpiod_line_config) config = NULL;
g_autofree enum gpiod_line_value *values = NULL;
gint ret;
gsize i;
config = gpiod_test_create_line_config_or_fail();
values = g_malloc0(sizeof(*values) * num_values);
for (i = 0; i < num_values; i++)
values[i] = GPIOD_LINE_VALUE_ACTIVE;
ret = gpiod_line_config_set_output_values(config, values, num_values);
g_assert_cmpint(ret, ==, -1);
gpiod_test_expect_errno(EINVAL);
}
GPIOD_TEST_CASE(get_num_configured_offsets)
{
static const guint offsets[] = { 0, 1, 2, 3 };
g_autoptr(struct_gpiod_line_config) config = NULL;
g_autoptr(struct_gpiod_line_settings) settings = NULL;
settings = gpiod_test_create_line_settings_or_fail();
config = gpiod_test_create_line_config_or_fail();
gpiod_test_line_config_add_line_settings_or_fail(config, offsets, 4,
settings);
g_assert_cmpuint(gpiod_line_config_get_num_configured_offsets(config),
==, 4);
}
GPIOD_TEST_CASE(handle_duplicate_offsets)
{
static const guint offsets[] = { 0, 2, 2, 3 };
g_autoptr(struct_gpiod_line_config) config = NULL;
size_t num_retrieved;
guint retrieved[3];
config = gpiod_test_create_line_config_or_fail();
gpiod_test_line_config_add_line_settings_or_fail(config, offsets, 4,
NULL);
g_assert_cmpuint(gpiod_line_config_get_num_configured_offsets(config),
==, 3);
num_retrieved = gpiod_line_config_get_configured_offsets(config,
retrieved, 3);
g_assert_cmpuint(num_retrieved, ==, 3);
g_assert_cmpuint(retrieved[0], ==, 0);
g_assert_cmpuint(retrieved[1], ==, 2);
g_assert_cmpuint(retrieved[2], ==, 3);
}