From: "Laguna, Lukasz" <lukasz.laguna@intel.com>
To: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>,
<igt-dev@lists.freedesktop.org>
Cc: <adam.miszczak@linux.intel.com>, <jakub1.kolakowski@intel.com>,
<michal.wajdeczko@intel.com>,
Kamil Konieczny <kamil.konieczny@linux.intel.com>
Subject: Re: [PATCH v3 i-g-t 02/10] lib/tests/igt_sysfs_choice: Add test coverage
Date: Thu, 29 Jan 2026 09:19:28 +0100 [thread overview]
Message-ID: <066a4ec5-2440-4b2c-8f8d-4d9448fae771@intel.com> (raw)
In-Reply-To: <20260128180819.1373376-3-marcin.bernatowicz@linux.intel.com>
On 1/28/2026 19:08, Marcin Bernatowicz wrote:
> Add unit tests exercising parsing, selection rules, intersection,
> round-trip formatting, and mask conversion for igt_sysfs_choice.
>
> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
> Cc: Adam Miszczak <adam.miszczak@linux.intel.com>
> Cc: Jakub Kolakowski <jakub1.kolakowski@intel.com>
> Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> Cc: Lukasz Laguna <lukasz.laguna@intel.com>
Reviewed-by: Lukasz Laguna <lukasz.laguna@intel.com>
> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
>
> ---
> v2:
> - Align igt_simple_main() usage with upstream changes.
> - Corrected date, improved assert messages.
> - Use BIT() instead of (1u << n) for sysfs choice masks.
> - Adjust test for igt_sysfs_choice_to_string() returning error code.
> - Adjust test for igt_sysfs_choice_format_mask() returning error code.
>
> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
> ---
> lib/tests/igt_sysfs_choice.c | 388 +++++++++++++++++++++++++++++++++++
> lib/tests/meson.build | 1 +
> 2 files changed, 389 insertions(+)
> create mode 100644 lib/tests/igt_sysfs_choice.c
>
> diff --git a/lib/tests/igt_sysfs_choice.c b/lib/tests/igt_sysfs_choice.c
> new file mode 100644
> index 000000000..c573a0dff
> --- /dev/null
> +++ b/lib/tests/igt_sysfs_choice.c
> @@ -0,0 +1,388 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2026 Intel Corporation
> + */
> +#include <errno.h>
> +#include "drmtest.h"
> +#include "igt_core.h"
> +#include "intel_chipset.h"
> +#include "igt_sysfs_choice.h"
> +
> +static void assert_token(const struct igt_sysfs_choice *c,
> + size_t idx, const char *expected)
> +{
> + igt_assert_f(idx < c->num_tokens,
> + "token index %zu out of range (num_tokens=%zu)\n",
> + idx, c->num_tokens);
> + igt_assert(c->tokens[idx]);
> + igt_assert_f(!strcmp(c->tokens[idx], expected),
> + "token[%zu] mismatch: got='%s' expected='%s'\n",
> + idx, c->tokens[idx], expected);
> +}
> +
> +static void parse_ok(const char *str, struct igt_sysfs_choice *choice)
> +{
> + int ret;
> +
> + ret = igt_sysfs_choice_parse(str, choice);
> + igt_assert_f(ret == 0, "parse(\"%s\") failed: %d\n", str, ret);
> +}
> +
> +static void test_parse_basic_first_selected(void)
> +{
> + struct igt_sysfs_choice c;
> +
> + parse_ok("[low] normal high\n", &c);
> +
> + igt_assert_eq(c.num_tokens, 3);
> + assert_token(&c, 0, "low");
> + assert_token(&c, 1, "normal");
> + assert_token(&c, 2, "high");
> +
> + igt_assert_eq(c.selected, 0);
> +}
> +
> +static void test_parse_middle_selected_whitespace(void)
> +{
> + struct igt_sysfs_choice c;
> +
> + parse_ok(" low [normal] high \n", &c);
> +
> + igt_assert_eq(c.num_tokens, 3);
> + assert_token(&c, 0, "low");
> + assert_token(&c, 1, "normal");
> + assert_token(&c, 2, "high");
> +
> + igt_assert_eq(c.selected, 1);
> +}
> +
> +static void test_parse_single_token(void)
> +{
> + struct igt_sysfs_choice c;
> +
> + parse_ok("[only]\n", &c);
> +
> + igt_assert_eq(c.num_tokens, 1);
> + assert_token(&c, 0, "only");
> + igt_assert_eq(c.selected, 0);
> +}
> +
> +static void test_parse_error_missing_selected(void)
> +{
> + struct igt_sysfs_choice c;
> + int ret;
> +
> + ret = igt_sysfs_choice_parse("low normal high\n", &c);
> + igt_assert_eq(ret, -EINVAL);
> +}
> +
> +static void test_parse_error_multiple_selected(void)
> +{
> + struct igt_sysfs_choice c;
> + int ret;
> +
> + ret = igt_sysfs_choice_parse("[low] [normal] high\n", &c);
> + igt_assert_eq(ret, -EINVAL);
> +
> + ret = igt_sysfs_choice_parse("low [normal] [high]\n", &c);
> + igt_assert_eq(ret, -EINVAL);
> +}
> +
> +static void test_parse_error_unterminated_bracket(void)
> +{
> + struct igt_sysfs_choice c;
> + int ret;
> +
> + ret = igt_sysfs_choice_parse("[low normal high\n", &c);
> + igt_assert_eq(ret, -EINVAL);
> +
> + ret = igt_sysfs_choice_parse("low [normal high]\n", &c);
> + igt_assert_eq(ret, -EINVAL);
> +}
> +
> +static void test_parse_error_too_many_tokens(void)
> +{
> + struct igt_sysfs_choice c;
> + char buf[512];
> + size_t i;
> + int len = 0;
> + int ret;
> +
> + /*
> + * Build a line with (IGT_SYSFS_CHOICE_MAX_TOKENS + 1) tokens:
> + * "[t0] t1 t2 ... tN"
> + */
> + len += snprintf(buf + len, sizeof(buf) - len, "[t0]");
> + for (i = 1; i < IGT_SYSFS_CHOICE_MAX_TOKENS + 1 && len < (int)sizeof(buf); i++)
> + len += snprintf(buf + len, sizeof(buf) - len, " t%zu", i);
> + len += snprintf(buf + len, sizeof(buf) - len, "\n");
> +
> + ret = igt_sysfs_choice_parse(buf, &c);
> + igt_assert_eq(ret, -E2BIG);
> +}
> +
> +static void test_selected_basic(void)
> +{
> + struct igt_sysfs_choice c;
> + const char *sel;
> +
> + /* selected at position 0 */
> + parse_ok("[low] normal high\n", &c);
> + sel = igt_sysfs_choice_selected(&c);
> + igt_assert(sel);
> + igt_assert(!strcmp(sel, "low"));
> +
> + /* selected at position 1 */
> + parse_ok("low [normal] high\n", &c);
> + sel = igt_sysfs_choice_selected(&c);
> + igt_assert(sel);
> + igt_assert(!strcmp(sel, "normal"));
> +
> + /* selected at position 2 */
> + parse_ok("low normal [high]\n", &c);
> + sel = igt_sysfs_choice_selected(&c);
> + igt_assert(sel);
> + igt_assert(!strcmp(sel, "high"));
> +}
> +
> +static void test_selected_invalid_index(void)
> +{
> + struct igt_sysfs_choice c;
> + const char *sel;
> +
> + /* selected = -1 */
> + parse_ok("[only]\n", &c);
> + c.selected = -1;
> + sel = igt_sysfs_choice_selected(&c);
> + igt_assert(!sel);
> +
> + /* selected >= num_tokens */
> + parse_ok("[only]\n", &c);
> + c.selected = 999;
> + sel = igt_sysfs_choice_selected(&c);
> + igt_assert(!sel);
> +
> + /* empty choice */
> + memset(&c, 0, sizeof(c));
> + sel = igt_sysfs_choice_selected(&c);
> + igt_assert(!sel);
> +}
> +
> +static void test_to_string_roundtrip(void)
> +{
> + struct igt_sysfs_choice c1, c2;
> + char out[IGT_SYSFS_CHOICE_MAX_LEN];
> + int ret;
> +
> + parse_ok(" low [normal] high \n", &c1);
> +
> + ret = igt_sysfs_choice_to_string(&c1, out, sizeof(out));
> + igt_assert_eq(ret, 0);
> +
> + /*
> + * Expect canonical format: tokens separated by single spaces,
> + * one [selected], no trailing newline.
> + */
> + igt_assert_f(!strcmp(out, "low [normal] high"),
> + "choice_to_string produced '%s'\n", out);
> +
> + /* Parse again and ensure we get the same structure. */
> + parse_ok(out, &c2);
> +
> + igt_assert_eq(c2.num_tokens, 3);
> + assert_token(&c2, 0, "low");
> + assert_token(&c2, 1, "normal");
> + assert_token(&c2, 2, "high");
> + igt_assert_eq(c2.selected, 1);
> +}
> +
> +static void test_find_basic(void)
> +{
> + struct igt_sysfs_choice c;
> + int idx;
> +
> + parse_ok("[low] normal high\n", &c);
> +
> + idx = igt_sysfs_choice_find(&c, "low");
> + igt_assert_eq(idx, 0);
> +
> + idx = igt_sysfs_choice_find(&c, "normal");
> + igt_assert_eq(idx, 1);
> +
> + idx = igt_sysfs_choice_find(&c, "high");
> + igt_assert_eq(idx, 2);
> +
> + idx = igt_sysfs_choice_find(&c, "ultra");
> + igt_assert_lt(idx, 0);
> +}
> +
> +static const char *const prio_names[] = {
> + "low",
> + "normal",
> + "high",
> +};
> +
> +static void test_to_mask_basic(void)
> +{
> + struct igt_sysfs_choice c;
> + unsigned int mask = 0;
> + int selected_idx = -1;
> + int ret;
> +
> + parse_ok("[low] normal high\n", &c);
> +
> + ret = igt_sysfs_choice_to_mask(&c, prio_names, ARRAY_SIZE(prio_names),
> + &mask, &selected_idx);
> + igt_assert_eq(ret, 0);
> +
> + /* low | normal | high -> bits 0,1,2 set */
> + igt_assert_eq(mask, BIT(0) | BIT(1) | BIT(2));
> + igt_assert_eq(selected_idx, 0);
> +}
> +
> +static void test_to_mask_ignores_unknown(void)
> +{
> + struct igt_sysfs_choice c;
> + unsigned int mask = 0;
> + int selected_idx = -1;
> + int ret;
> +
> + parse_ok("[low] normal extra\n", &c);
> +
> + ret = igt_sysfs_choice_to_mask(&c, prio_names, ARRAY_SIZE(prio_names),
> + &mask, &selected_idx);
> + igt_assert_eq(ret, 0);
> +
> + /* "extra" is ignored, only low + normal mapped */
> + igt_assert_eq(mask, BIT(0) | BIT(1));
> + igt_assert_eq(selected_idx, 0);
> +}
> +
> +static void test_to_mask_selected_unknown(void)
> +{
> + struct igt_sysfs_choice c;
> + unsigned int mask = 0;
> + int selected_idx = 123;
> + int ret;
> +
> + parse_ok("low normal [extra]\n", &c);
> +
> + ret = igt_sysfs_choice_to_mask(&c, prio_names, ARRAY_SIZE(prio_names),
> + &mask, &selected_idx);
> + igt_assert_eq(ret, 0);
> +
> + igt_assert_eq(mask, BIT(0) | BIT(1)); /* low + normal */
> + igt_assert_eq(selected_idx, -1);
> +}
> +
> +static void test_format_mask_basic(void)
> +{
> + char buf[128];
> + int ret;
> +
> + /* mask for low + normal + high, selected = normal (1) */
> + ret = igt_sysfs_choice_format_mask(buf, sizeof(buf),
> + prio_names, ARRAY_SIZE(prio_names),
> + BIT(0) | BIT(1) | BIT(2),
> + 1);
> + igt_assert_eq(ret, 0);
> + igt_assert_f(!strcmp(buf, "low [normal] high"),
> + "choice_format_mask produced '%s'\n", buf);
> +}
> +
> +static void test_format_mask_empty(void)
> +{
> + char buf[128];
> + int ret;
> +
> + ret = igt_sysfs_choice_format_mask(buf, sizeof(buf),
> + prio_names, ARRAY_SIZE(prio_names),
> + 0, -1);
> + igt_assert_eq(ret, 0);
> + igt_assert_eq(buf[0], '\0');
> +}
> +
> +static void test_format_mask_unknown_bit(void)
> +{
> + char buf[128];
> + int ret;
> +
> + ret = igt_sysfs_choice_format_mask(buf, sizeof(buf),
> + prio_names, ARRAY_SIZE(prio_names),
> + BIT(0) | BIT(3),
> + 0);
> + igt_assert_eq(ret, 0);
> + igt_assert_f(!strcmp(buf, "[low]"),
> + "format_mask produced '%s'\n", buf);
> +}
> +
> +static void test_intersect_basic(void)
> +{
> + struct igt_sysfs_choice a, b;
> + int ret;
> +
> + parse_ok("[low] normal high\n", &a);
> + parse_ok("low [normal] ultra\n", &b);
> +
> + ret = igt_sysfs_choice_intersect(&a, &b);
> + igt_assert_eq(ret, 0);
> +
> + igt_assert_eq(a.num_tokens, 2);
> + assert_token(&a, 0, "low");
> + assert_token(&a, 1, "normal");
> +
> + /* semantics: selected remains the original selected token if still common */
> + igt_assert_eq(a.selected, 0);
> +}
> +
> +static void test_intersect_single_common(void)
> +{
> + struct igt_sysfs_choice a, b;
> + int ret;
> +
> + parse_ok("low [normal] high\n", &a);
> + parse_ok("[normal] ultra\n", &b);
> +
> + ret = igt_sysfs_choice_intersect(&a, &b);
> + igt_assert_eq(ret, 0);
> +
> + igt_assert_eq(a.num_tokens, 1);
> + assert_token(&a, 0, "normal");
> + igt_assert_eq(a.selected, 0);
> +}
> +
> +static void test_intersect_no_common(void)
> +{
> + struct igt_sysfs_choice a, b;
> + int ret;
> +
> + parse_ok("[low] normal\n", &a);
> + parse_ok("[high] ultra\n", &b);
> +
> + ret = igt_sysfs_choice_intersect(&a, &b);
> + igt_assert_eq(ret, -ENOENT);
> +}
> +
> +int igt_simple_main()
> +{
> + test_parse_basic_first_selected();
> + test_parse_middle_selected_whitespace();
> + test_parse_single_token();
> + test_parse_error_missing_selected();
> + test_parse_error_multiple_selected();
> + test_parse_error_unterminated_bracket();
> + test_parse_error_too_many_tokens();
> + test_selected_basic();
> + test_selected_invalid_index();
> + test_to_string_roundtrip();
> + test_find_basic();
> + test_to_mask_basic();
> + test_to_mask_ignores_unknown();
> + test_to_mask_selected_unknown();
> + test_format_mask_basic();
> + test_format_mask_empty();
> + test_format_mask_unknown_bit();
> + test_intersect_basic();
> + test_intersect_single_common();
> + test_intersect_no_common();
> +}
> diff --git a/lib/tests/meson.build b/lib/tests/meson.build
> index 1ce19f63c..124a9ecae 100644
> --- a/lib/tests/meson.build
> +++ b/lib/tests/meson.build
> @@ -23,6 +23,7 @@ lib_tests = [
> 'igt_simulation',
> 'igt_stats',
> 'igt_subtest_group',
> + 'igt_sysfs_choice',
> 'igt_thread',
> 'igt_types',
> 'i915_perf_data_alignment',
next prev parent reply other threads:[~2026-01-29 8:19 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-28 18:08 [PATCH v3 i-g-t 00/10] Xe SR-IOV admin scheduling helpers and test updates Marcin Bernatowicz
2026-01-28 18:08 ` [PATCH v3 i-g-t 01/10] lib/igt_sysfs_choice: Add helpers for sysfs enumerated choice attributes Marcin Bernatowicz
2026-01-29 8:19 ` Laguna, Lukasz
2026-01-28 18:08 ` [PATCH v3 i-g-t 02/10] lib/tests/igt_sysfs_choice: Add test coverage Marcin Bernatowicz
2026-01-29 8:19 ` Laguna, Lukasz [this message]
2026-01-28 18:08 ` [PATCH v3 i-g-t 03/10] lib/xe/xe_sriov_provisioning: Add string conversion helpers for scheduling priority Marcin Bernatowicz
2026-01-28 18:08 ` [PATCH v3 i-g-t 04/10] lib/xe/xe_sriov_provisioning: Add sched priority mask to string helper Marcin Bernatowicz
2026-01-29 8:19 ` Laguna, Lukasz
2026-01-28 18:08 ` [PATCH v3 i-g-t 05/10] lib/igt_sriov_device: Add helper for PF/VF sysfs path formatting Marcin Bernatowicz
2026-01-28 18:08 ` [PATCH v3 i-g-t 06/10] lib/xe/xe_sriov_admin: Add SR-IOV admin sysfs accessors Marcin Bernatowicz
2026-01-29 8:21 ` Laguna, Lukasz
2026-01-28 18:08 ` [PATCH v3 i-g-t 07/10] tests/intel/xe_sriov_scheduling: Avoid assert on scheduling params restore in cleanup Marcin Bernatowicz
2026-01-28 18:08 ` [PATCH v3 i-g-t 08/10] tests/intel/xe_sriov_scheduling: Prefer SR-IOV admin sysfs accessors Marcin Bernatowicz
2026-01-28 18:08 ` [PATCH v3 i-g-t 09/10] tests/intel/xe_pmu: " Marcin Bernatowicz
2026-01-28 18:08 ` [PATCH v3 i-g-t 10/10] tests/intel/xe_sriov_admin: Add SR-IOV admin sysfs scheduling attributes tests Marcin Bernatowicz
2026-01-29 8:21 ` Laguna, Lukasz
2026-01-28 20:32 ` ✓ Xe.CI.BAT: success for Xe SR-IOV admin scheduling helpers and test updates (rev3) Patchwork
2026-01-28 20:47 ` ✗ i915.CI.BAT: failure " Patchwork
2026-01-29 10:11 ` Bernatowicz, Marcin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=066a4ec5-2440-4b2c-8f8d-4d9448fae771@intel.com \
--to=lukasz.laguna@intel.com \
--cc=adam.miszczak@linux.intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=jakub1.kolakowski@intel.com \
--cc=kamil.konieczny@linux.intel.com \
--cc=marcin.bernatowicz@linux.intel.com \
--cc=michal.wajdeczko@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox