From nobody Sun Feb 8 16:31:00 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C34E330E82B; Wed, 14 Jan 2026 08:59:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768381184; cv=none; b=WovMNrvKT/lzLlQSayXKiGbgF1Lo/lMhlDckhm79iTClD6cQhgKArnVTCHCxnHAVxdOzAbb2MGz/w8x2MonBi7eh3OVUWZzbsQFFHTgBijkxEATbETlUwkwVutLVIeCaESR16swRlnjUCncvPcQ/BKyXpMJP5NZVJkZjEhQ/XEk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768381184; c=relaxed/simple; bh=AXcncB8cVGGHhldgQyoX8ZrEQuko2sGpm2O0f9IUnOA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=n2W6ugfB/Fjj82Q7ruBeGWMPECCfc93onxXlL41x1rwghyA1FFTgtNSPs698MRu1thk6uarwWHtZ8S0uVMUI8w8lXpnYcHYVM1cbyqYTk+8nLhhRsJMeFryL+05dWhK5zEQaQ4UwneMyzIUKM1S+MN7yIdIIxjG5DC0X8kp74d4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=SOX5GWwr; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="SOX5GWwr" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 537F54E420CF; Wed, 14 Jan 2026 08:59:36 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 2A4876074A; Wed, 14 Jan 2026 08:59:36 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id ED12F103C8396; Wed, 14 Jan 2026 09:59:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1768381175; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=NcEoWUb5aJwsVAuuDv3WRH6UAsZs2JrlSDjQHU9FbrI=; b=SOX5GWwrY+UGf2RNQEqIdd7Uzqc3R+5gGFaB+sM1Vitseb08i2V0goabiyvkt8BANxPmff kUwfxTnEXckoqIel3NtTvQf/Z9ry5+W8QjhH5F9f5mWnGPMqhiLHjPFHDPE8FjZDfaP7x4 LvmeSGZ4SQjhbLQCALKHxiFz2hgVfWlF5cjDCywfkFrlBA4WeVP675JSB5wk3DQSZCaqBD bU6HuKx8XFUsri9EUbOME2B7QK7AExv9hPqcM+H1LXUDGJXctYyZ92G4j9tTdBFSKI4pSd kAGV01sLIvd1EkVZris3FAkhnUQAB0g9ncKIBBIMPnnHVMFwmMy2rDXkmkTtwQ== From: =?utf-8?q?Alexis_Lothor=C3=A9_=28eBPF_Foundation=29?= Date: Wed, 14 Jan 2026 09:59:12 +0100 Subject: [PATCH bpf-next 1/4] bpf/selftests: move assert macros into a dedicated header Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260114-bpftool-tests-v1-1-cfab1cc9beaf@bootlin.com> References: <20260114-bpftool-tests-v1-0-cfab1cc9beaf@bootlin.com> In-Reply-To: <20260114-bpftool-tests-v1-0-cfab1cc9beaf@bootlin.com> To: Andrii Nakryiko , Eduard Zingerman , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan Cc: ebpf@linuxfoundation.org, Bastien Curutchet , Thomas Petazzoni , linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?Alexis_Lothor=C3=A9_=28eBPF_Foundation=29?= X-Mailer: b4 0.14.3 X-Last-TLS-Session-Version: TLSv1.3 The test_progs runner defines a large set of convenient assert macros to perform all the tests. Writing a new runner involves rewriting some macros if we want some basic testing features like standardized failure log. Export those assert macros from test_progs into a dedicated header so that we can use those in any test_runner. The sole requirement to be able to use those macros is to define a test__fail function in the runner that will be called whenever an assert fails. Signed-off-by: Alexis Lothor=C3=A9 (eBPF Foundation) Acked-by: Quentin Monnet --- tools/testing/selftests/bpf/assert_helpers.h | 231 +++++++++++++++++++++++= ++++ tools/testing/selftests/bpf/test_progs.h | 226 +----------------------= --- 2 files changed, 232 insertions(+), 225 deletions(-) diff --git a/tools/testing/selftests/bpf/assert_helpers.h b/tools/testing/s= elftests/bpf/assert_helpers.h new file mode 100644 index 000000000000..93ab5bf39431 --- /dev/null +++ b/tools/testing/selftests/bpf/assert_helpers.h @@ -0,0 +1,231 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#pragma once +#include +#include +#include + +#define _CHECK(condition, tag, duration, format...) ({ \ + int __ret =3D !!(condition); \ + int __save_errno =3D errno; \ + if (__ret) { \ + test__fail(); \ + fprintf(stdout, "%s:FAIL:%s ", __func__, tag); \ + fprintf(stdout, ##format); \ + } else { \ + fprintf(stdout, "%s:PASS:%s %d nsec\n", \ + __func__, tag, duration); \ + } \ + errno =3D __save_errno; \ + __ret; \ +}) + +#define CHECK_FAIL(condition) ({ \ + int __ret =3D !!(condition); \ + int __save_errno =3D errno; \ + if (__ret) { \ + test__fail(); \ + fprintf(stdout, "%s:FAIL:%d\n", __func__, __LINE__); \ + } \ + errno =3D __save_errno; \ + __ret; \ +}) + +#define CHECK(condition, tag, format...) \ + _CHECK(condition, tag, duration, format) +#define CHECK_ATTR(condition, tag, format...) \ + _CHECK(condition, tag, tattr.duration, format) + +#define ASSERT_FAIL(fmt, args...) ({ \ + static int duration; \ + CHECK(false, "", fmt"\n", ##args); \ + false; \ +}) + +#define ASSERT_TRUE(actual, name) ({ \ + static int duration; \ + bool ___ok =3D (actual); \ + CHECK(!___ok, (name), "unexpected %s: got FALSE\n", (name)); \ + ___ok; \ +}) + +#define ASSERT_FALSE(actual, name) ({ \ + static int duration; \ + bool ___ok =3D !(actual); \ + CHECK(!___ok, (name), "unexpected %s: got TRUE\n", (name)); \ + ___ok; \ +}) + +#define ASSERT_EQ(actual, expected, name) ({ \ + static int duration; \ + typeof(actual) ___act =3D (actual); \ + typeof(expected) ___exp =3D (expected); \ + bool ___ok =3D ___act =3D=3D ___exp; \ + CHECK(!___ok, (name), \ + "unexpected %s: actual %lld !=3D expected %lld\n", \ + (name), (long long)(___act), (long long)(___exp)); \ + ___ok; \ +}) + +#define ASSERT_NEQ(actual, expected, name) ({ \ + static int duration; \ + typeof(actual) ___act =3D (actual); \ + typeof(expected) ___exp =3D (expected); \ + bool ___ok =3D ___act !=3D ___exp; \ + CHECK(!___ok, (name), \ + "unexpected %s: actual %lld =3D=3D expected %lld\n", \ + (name), (long long)(___act), (long long)(___exp)); \ + ___ok; \ +}) + +#define ASSERT_LT(actual, expected, name) ({ \ + static int duration; \ + typeof(actual) ___act =3D (actual); \ + typeof(expected) ___exp =3D (expected); \ + bool ___ok =3D ___act < ___exp; \ + CHECK(!___ok, (name), \ + "unexpected %s: actual %lld >=3D expected %lld\n", \ + (name), (long long)(___act), (long long)(___exp)); \ + ___ok; \ +}) + +#define ASSERT_LE(actual, expected, name) ({ \ + static int duration; \ + typeof(actual) ___act =3D (actual); \ + typeof(expected) ___exp =3D (expected); \ + bool ___ok =3D ___act <=3D ___exp; \ + CHECK(!___ok, (name), \ + "unexpected %s: actual %lld > expected %lld\n", \ + (name), (long long)(___act), (long long)(___exp)); \ + ___ok; \ +}) + +#define ASSERT_GT(actual, expected, name) ({ \ + static int duration; \ + typeof(actual) ___act =3D (actual); \ + typeof(expected) ___exp =3D (expected); \ + bool ___ok =3D ___act > ___exp; \ + CHECK(!___ok, (name), \ + "unexpected %s: actual %lld <=3D expected %lld\n", \ + (name), (long long)(___act), (long long)(___exp)); \ + ___ok; \ +}) + +#define ASSERT_GE(actual, expected, name) ({ \ + static int duration; \ + typeof(actual) ___act =3D (actual); \ + typeof(expected) ___exp =3D (expected); \ + bool ___ok =3D ___act >=3D ___exp; \ + CHECK(!___ok, (name), \ + "unexpected %s: actual %lld < expected %lld\n", \ + (name), (long long)(___act), (long long)(___exp)); \ + ___ok; \ +}) + +#define ASSERT_STREQ(actual, expected, name) ({ \ + static int duration; \ + const char *___act =3D actual; \ + const char *___exp =3D expected; \ + bool ___ok =3D strcmp(___act, ___exp) =3D=3D 0; \ + CHECK(!___ok, (name), \ + "unexpected %s: actual '%s' !=3D expected '%s'\n", \ + (name), ___act, ___exp); \ + ___ok; \ +}) + +#define ASSERT_STRNEQ(actual, expected, len, name) ({ \ + static int duration; \ + const char *___act =3D actual; \ + const char *___exp =3D expected; \ + int ___len =3D len; \ + bool ___ok =3D strncmp(___act, ___exp, ___len) =3D=3D 0; \ + CHECK(!___ok, (name), \ + "unexpected %s: actual '%.*s' !=3D expected '%.*s'\n", \ + (name), ___len, ___act, ___len, ___exp); \ + ___ok; \ +}) + +#define ASSERT_HAS_SUBSTR(str, substr, name) ({ \ + static int duration; \ + const char *___str =3D str; \ + const char *___substr =3D substr; \ + bool ___ok =3D strstr(___str, ___substr) !=3D NULL; \ + CHECK(!___ok, (name), \ + "unexpected %s: '%s' is not a substring of '%s'\n", \ + (name), ___substr, ___str); \ + ___ok; \ +}) + +#define ASSERT_MEMEQ(actual, expected, len, name) ({ \ + static int duration; \ + const void *__act =3D actual; \ + const void *__exp =3D expected; \ + int __len =3D len; \ + bool ___ok =3D memcmp(__act, __exp, __len) =3D=3D 0; \ + CHECK(!___ok, (name), "unexpected memory mismatch\n"); \ + fprintf(stdout, "actual:\n"); \ + hexdump("\t", __act, __len); \ + fprintf(stdout, "expected:\n"); \ + hexdump("\t", __exp, __len); \ + ___ok; \ +}) + +#define ASSERT_OK(res, name) ({ \ + static int duration; \ + long long ___res =3D (res); \ + bool ___ok =3D ___res =3D=3D 0; \ + CHECK(!___ok, (name), "unexpected error: %lld (errno %d)\n", \ + ___res, errno); \ + ___ok; \ +}) + +#define ASSERT_ERR(res, name) ({ \ + static int duration; \ + long long ___res =3D (res); \ + bool ___ok =3D ___res < 0; \ + CHECK(!___ok, (name), "unexpected success: %lld\n", ___res); \ + ___ok; \ +}) + +#define ASSERT_NULL(ptr, name) ({ \ + static int duration; \ + const void *___res =3D (ptr); \ + bool ___ok =3D !___res; \ + CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res); \ + ___ok; \ +}) + +#define ASSERT_OK_PTR(ptr, name) ({ \ + static int duration; \ + const void *___res =3D (ptr); \ + int ___err =3D libbpf_get_error(___res); \ + bool ___ok =3D ___err =3D=3D 0; \ + CHECK(!___ok, (name), "unexpected error: %d\n", ___err); \ + ___ok; \ +}) + +#define ASSERT_ERR_PTR(ptr, name) ({ \ + static int duration; \ + const void *___res =3D (ptr); \ + int ___err =3D libbpf_get_error(___res); \ + bool ___ok =3D ___err !=3D 0; \ + CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res); \ + ___ok; \ +}) + +#define ASSERT_OK_FD(fd, name) ({ \ + static int duration; \ + int ___fd =3D (fd); \ + bool ___ok =3D ___fd >=3D 0; \ + CHECK(!___ok, (name), "unexpected fd: %d (errno %d)\n", \ + ___fd, errno); \ + ___ok; \ +}) + +#define ASSERT_ERR_FD(fd, name) ({ \ + static int duration; \ + int ___fd =3D (fd); \ + bool ___ok =3D ___fd < 0; \ + CHECK(!___ok, (name), "unexpected fd: %d\n", ___fd); \ + ___ok; \ +}) + diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selft= ests/bpf/test_progs.h index eebfc18cdcd2..bb876d8f6bcc 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h @@ -42,6 +42,7 @@ typedef __u16 __sum16; #include #include "trace_helpers.h" #include "testing_helpers.h" +#include "assert_helpers.h" =20 enum verbosity { VERBOSE_NONE, @@ -195,231 +196,6 @@ void hexdump(const char *prefix, const void *buf, siz= e_t len); fprintf(stdout, ##format); \ }) =20 -#define _CHECK(condition, tag, duration, format...) ({ \ - int __ret =3D !!(condition); \ - int __save_errno =3D errno; \ - if (__ret) { \ - test__fail(); \ - fprintf(stdout, "%s:FAIL:%s ", __func__, tag); \ - fprintf(stdout, ##format); \ - } else { \ - fprintf(stdout, "%s:PASS:%s %d nsec\n", \ - __func__, tag, duration); \ - } \ - errno =3D __save_errno; \ - __ret; \ -}) - -#define CHECK_FAIL(condition) ({ \ - int __ret =3D !!(condition); \ - int __save_errno =3D errno; \ - if (__ret) { \ - test__fail(); \ - fprintf(stdout, "%s:FAIL:%d\n", __func__, __LINE__); \ - } \ - errno =3D __save_errno; \ - __ret; \ -}) - -#define CHECK(condition, tag, format...) \ - _CHECK(condition, tag, duration, format) -#define CHECK_ATTR(condition, tag, format...) \ - _CHECK(condition, tag, tattr.duration, format) - -#define ASSERT_FAIL(fmt, args...) ({ \ - static int duration =3D 0; \ - CHECK(false, "", fmt"\n", ##args); \ - false; \ -}) - -#define ASSERT_TRUE(actual, name) ({ \ - static int duration =3D 0; \ - bool ___ok =3D (actual); \ - CHECK(!___ok, (name), "unexpected %s: got FALSE\n", (name)); \ - ___ok; \ -}) - -#define ASSERT_FALSE(actual, name) ({ \ - static int duration =3D 0; \ - bool ___ok =3D !(actual); \ - CHECK(!___ok, (name), "unexpected %s: got TRUE\n", (name)); \ - ___ok; \ -}) - -#define ASSERT_EQ(actual, expected, name) ({ \ - static int duration =3D 0; \ - typeof(actual) ___act =3D (actual); \ - typeof(expected) ___exp =3D (expected); \ - bool ___ok =3D ___act =3D=3D ___exp; \ - CHECK(!___ok, (name), \ - "unexpected %s: actual %lld !=3D expected %lld\n", \ - (name), (long long)(___act), (long long)(___exp)); \ - ___ok; \ -}) - -#define ASSERT_NEQ(actual, expected, name) ({ \ - static int duration =3D 0; \ - typeof(actual) ___act =3D (actual); \ - typeof(expected) ___exp =3D (expected); \ - bool ___ok =3D ___act !=3D ___exp; \ - CHECK(!___ok, (name), \ - "unexpected %s: actual %lld =3D=3D expected %lld\n", \ - (name), (long long)(___act), (long long)(___exp)); \ - ___ok; \ -}) - -#define ASSERT_LT(actual, expected, name) ({ \ - static int duration =3D 0; \ - typeof(actual) ___act =3D (actual); \ - typeof(expected) ___exp =3D (expected); \ - bool ___ok =3D ___act < ___exp; \ - CHECK(!___ok, (name), \ - "unexpected %s: actual %lld >=3D expected %lld\n", \ - (name), (long long)(___act), (long long)(___exp)); \ - ___ok; \ -}) - -#define ASSERT_LE(actual, expected, name) ({ \ - static int duration =3D 0; \ - typeof(actual) ___act =3D (actual); \ - typeof(expected) ___exp =3D (expected); \ - bool ___ok =3D ___act <=3D ___exp; \ - CHECK(!___ok, (name), \ - "unexpected %s: actual %lld > expected %lld\n", \ - (name), (long long)(___act), (long long)(___exp)); \ - ___ok; \ -}) - -#define ASSERT_GT(actual, expected, name) ({ \ - static int duration =3D 0; \ - typeof(actual) ___act =3D (actual); \ - typeof(expected) ___exp =3D (expected); \ - bool ___ok =3D ___act > ___exp; \ - CHECK(!___ok, (name), \ - "unexpected %s: actual %lld <=3D expected %lld\n", \ - (name), (long long)(___act), (long long)(___exp)); \ - ___ok; \ -}) - -#define ASSERT_GE(actual, expected, name) ({ \ - static int duration =3D 0; \ - typeof(actual) ___act =3D (actual); \ - typeof(expected) ___exp =3D (expected); \ - bool ___ok =3D ___act >=3D ___exp; \ - CHECK(!___ok, (name), \ - "unexpected %s: actual %lld < expected %lld\n", \ - (name), (long long)(___act), (long long)(___exp)); \ - ___ok; \ -}) - -#define ASSERT_STREQ(actual, expected, name) ({ \ - static int duration =3D 0; \ - const char *___act =3D actual; \ - const char *___exp =3D expected; \ - bool ___ok =3D strcmp(___act, ___exp) =3D=3D 0; \ - CHECK(!___ok, (name), \ - "unexpected %s: actual '%s' !=3D expected '%s'\n", \ - (name), ___act, ___exp); \ - ___ok; \ -}) - -#define ASSERT_STRNEQ(actual, expected, len, name) ({ \ - static int duration =3D 0; \ - const char *___act =3D actual; \ - const char *___exp =3D expected; \ - int ___len =3D len; \ - bool ___ok =3D strncmp(___act, ___exp, ___len) =3D=3D 0; \ - CHECK(!___ok, (name), \ - "unexpected %s: actual '%.*s' !=3D expected '%.*s'\n", \ - (name), ___len, ___act, ___len, ___exp); \ - ___ok; \ -}) - -#define ASSERT_HAS_SUBSTR(str, substr, name) ({ \ - static int duration =3D 0; \ - const char *___str =3D str; \ - const char *___substr =3D substr; \ - bool ___ok =3D strstr(___str, ___substr) !=3D NULL; \ - CHECK(!___ok, (name), \ - "unexpected %s: '%s' is not a substring of '%s'\n", \ - (name), ___substr, ___str); \ - ___ok; \ -}) - -#define ASSERT_MEMEQ(actual, expected, len, name) ({ \ - static int duration =3D 0; \ - const void *__act =3D actual; \ - const void *__exp =3D expected; \ - int __len =3D len; \ - bool ___ok =3D memcmp(__act, __exp, __len) =3D=3D 0; \ - CHECK(!___ok, (name), "unexpected memory mismatch\n"); \ - fprintf(stdout, "actual:\n"); \ - hexdump("\t", __act, __len); \ - fprintf(stdout, "expected:\n"); \ - hexdump("\t", __exp, __len); \ - ___ok; \ -}) - -#define ASSERT_OK(res, name) ({ \ - static int duration =3D 0; \ - long long ___res =3D (res); \ - bool ___ok =3D ___res =3D=3D 0; \ - CHECK(!___ok, (name), "unexpected error: %lld (errno %d)\n", \ - ___res, errno); \ - ___ok; \ -}) - -#define ASSERT_ERR(res, name) ({ \ - static int duration =3D 0; \ - long long ___res =3D (res); \ - bool ___ok =3D ___res < 0; \ - CHECK(!___ok, (name), "unexpected success: %lld\n", ___res); \ - ___ok; \ -}) - -#define ASSERT_NULL(ptr, name) ({ \ - static int duration =3D 0; \ - const void *___res =3D (ptr); \ - bool ___ok =3D !___res; \ - CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res); \ - ___ok; \ -}) - -#define ASSERT_OK_PTR(ptr, name) ({ \ - static int duration =3D 0; \ - const void *___res =3D (ptr); \ - int ___err =3D libbpf_get_error(___res); \ - bool ___ok =3D ___err =3D=3D 0; \ - CHECK(!___ok, (name), "unexpected error: %d\n", ___err); \ - ___ok; \ -}) - -#define ASSERT_ERR_PTR(ptr, name) ({ \ - static int duration =3D 0; \ - const void *___res =3D (ptr); \ - int ___err =3D libbpf_get_error(___res); \ - bool ___ok =3D ___err !=3D 0; \ - CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res); \ - ___ok; \ -}) - -#define ASSERT_OK_FD(fd, name) ({ \ - static int duration =3D 0; \ - int ___fd =3D (fd); \ - bool ___ok =3D ___fd >=3D 0; \ - CHECK(!___ok, (name), "unexpected fd: %d (errno %d)\n", \ - ___fd, errno); \ - ___ok; \ -}) - -#define ASSERT_ERR_FD(fd, name) ({ \ - static int duration =3D 0; \ - int ___fd =3D (fd); \ - bool ___ok =3D ___fd < 0; \ - CHECK(!___ok, (name), "unexpected fd: %d\n", ___fd); \ - ___ok; \ -}) - #define SYS(goto_label, fmt, ...) \ ({ \ char cmd[1024]; \ --=20 2.52.0