// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2019 Facebook */
#include <test_progs.h>
#include <sys/mman.h>
#include <sys/utsname.h>
#include <linux/version.h>
#include "test_core_extern.skel.h"
static uint32_t get_kernel_version(void )
{
uint32_t major, minor, patch;
struct utsname info;
uname(&info);
if (sscanf(info.release, "%u.%u.%u" , &major, &minor, &patch) != 3)
return 0;
return KERNEL_VERSION(major, minor, patch);
}
#define CFG "CONFIG_BPF_SYSCALL=n\n"
static struct test_case {
const char *name;
const char *cfg;
bool fails;
struct test_core_extern__data data;
} test_cases[] = {
{ .name = "default search path" , .data = { .bpf_syscall = true } },
{
.name = "custom values" ,
.cfg = "CONFIG_BPF_SYSCALL=n\n"
"CONFIG_TRISTATE=m\n"
"CONFIG_BOOL=y\n"
"CONFIG_CHAR=100\n"
"CONFIG_USHORT=30000\n"
"CONFIG_INT=123456\n"
"CONFIG_ULONG=0xDEADBEEFC0DE\n"
"CONFIG_STR=\" abracad\"\n"
"CONFIG_MISSING=0" ,
.data = {
.unkn_virt_val = 0,
.bpf_syscall = false ,
.tristate_val = TRI_MODULE,
.bool_val = true ,
.char_val = 100,
.ushort_val = 30000,
.int_val = 123456,
.ulong_val = 0xDEADBEEFC0DE,
.str_val = "abracad" ,
},
},
/* TRISTATE */
{ .name = "tristate (y)" , .cfg = CFG"CONFIG_TRISTATE=y\n" ,
.data = { .tristate_val = TRI_YES } },
{ .name = "tristate (n)" , .cfg = CFG"CONFIG_TRISTATE=n\n" ,
.data = { .tristate_val = TRI_NO } },
{ .name = "tristate (m)" , .cfg = CFG"CONFIG_TRISTATE=m\n" ,
.data = { .tristate_val = TRI_MODULE } },
{ .name = "tristate (int)" , .fails = 1, .cfg = CFG"CONFIG_TRISTATE=1" },
{ .name = "tristate (bad)" , .fails = 1, .cfg = CFG"CONFIG_TRISTATE=M" },
/* BOOL */
{ .name = "bool (y)" , .cfg = CFG"CONFIG_BOOL=y\n" ,
.data = { .bool_val = true } },
{ .name = "bool (n)" , .cfg = CFG"CONFIG_BOOL=n\n" ,
.data = { .bool_val = false } },
{ .name = "bool (tristate)" , .fails = 1, .cfg = CFG"CONFIG_BOOL=m" },
{ .name = "bool (int)" , .fails = 1, .cfg = CFG"CONFIG_BOOL=1" },
/* CHAR */
{ .name = "char (tristate)" , .cfg = CFG"CONFIG_CHAR=m\n" ,
.data = { .char_val = 'm' } },
{ .name = "char (bad)" , .fails = 1, .cfg = CFG"CONFIG_CHAR=q\n" },
{ .name = "char (empty)" , .fails = 1, .cfg = CFG"CONFIG_CHAR=\n" },
{ .name = "char (str)" , .fails = 1, .cfg = CFG"CONFIG_CHAR=\" y\"\n" },
/* STRING */
{ .name = "str (empty)" , .cfg = CFG"CONFIG_STR=\" \"\n" ,
.data = { .str_val = "\0\0\0\0\0\0\0" } },
{ .name = "str (padded)" , .cfg = CFG"CONFIG_STR=\" abra\"\n" ,
.data = { .str_val = "abra\0\0\0" } },
{ .name = "str (too long)" , .cfg = CFG"CONFIG_STR=\" abracada\"\n" ,
.data = { .str_val = "abracad" } },
{ .name = "str (no value)" , .fails = 1, .cfg = CFG"CONFIG_STR=\n" },
{ .name = "str (bad value)" , .fails = 1, .cfg = CFG"CONFIG_STR=bla\n" },
/* INTEGERS */
{
.name = "integer forms" ,
.cfg = CFG
"CONFIG_CHAR=0xA\n"
"CONFIG_USHORT=0462\n"
"CONFIG_INT=-100\n"
"CONFIG_ULONG=+1000000000000" ,
.data = {
.char_val = 0xA,
.ushort_val = 0462,
.int_val = -100,
.ulong_val = 1000000000000,
},
},
{ .name = "int (bad)" , .fails = 1, .cfg = CFG"CONFIG_INT=abc" },
{ .name = "int (str)" , .fails = 1, .cfg = CFG"CONFIG_INT=\" abc\"" },
{ .name = "int (empty)" , .fails = 1, .cfg = CFG"CONFIG_INT=" },
{ .name = "int (mixed)" , .fails = 1, .cfg = CFG"CONFIG_INT=123abc" },
{ .name = "int (max)" , .cfg = CFG"CONFIG_INT=2147483647" ,
.data = { .int_val = 2147483647 } },
{ .name = "int (min)" , .cfg = CFG"CONFIG_INT=-2147483648" ,
.data = { .int_val = -2147483648 } },
{ .name = "int (max+1)" , .fails = 1, .cfg = CFG"CONFIG_INT=2147483648" },
{ .name = "int (min-1)" , .fails = 1, .cfg = CFG"CONFIG_INT=-2147483649" },
{ .name = "ushort (max)" , .cfg = CFG"CONFIG_USHORT=65535" ,
.data = { .ushort_val = 65535 } },
{ .name = "ushort (min)" , .cfg = CFG"CONFIG_USHORT=0" ,
.data = { .ushort_val = 0 } },
{ .name = "ushort (max+1)" , .fails = 1, .cfg = CFG"CONFIG_USHORT=65536" },
{ .name = "ushort (min-1)" , .fails = 1, .cfg = CFG"CONFIG_USHORT=-1" },
{ .name = "u64 (max)" , .cfg = CFG"CONFIG_ULONG=0xffffffffffffffff" ,
.data = { .ulong_val = 0xffffffffffffffff } },
{ .name = "u64 (min)" , .cfg = CFG"CONFIG_ULONG=0" ,
.data = { .ulong_val = 0 } },
{ .name = "u64 (max+1)" , .fails = 1, .cfg = CFG"CONFIG_ULONG=0x10000000000000000" },
};
void test_core_extern(void )
{
const uint32_t kern_ver = get_kernel_version();
int err, i, j;
struct test_core_extern *skel = NULL;
uint64_t *got, *exp;
int n = sizeof (*skel->data) / sizeof (uint64_t);
for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
struct test_case *t = &test_cases[i];
DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
.kconfig = t->cfg,
);
if (!test__start_subtest(t->name))
continue ;
skel = test_core_extern__open_opts(&opts);
if (!ASSERT_OK_PTR(skel, "skel_open" ))
goto cleanup;
err = test_core_extern__load(skel);
if (t->fails) {
ASSERT_ERR(err, "skel_load_should_fail" );
goto cleanup;
} else if (!ASSERT_OK(err, "skel_load" )) {
goto cleanup;
}
err = test_core_extern__attach(skel);
if (!ASSERT_OK(err, "attach_raw_tp" ))
goto cleanup;
usleep(1);
t->data.kern_ver = kern_ver;
t->data.missing_val = 0xDEADC0DE;
got = (uint64_t *)skel->data;
exp = (uint64_t *)&t->data;
for (j = 0; j < n; j++) {
ASSERT_EQ(got[j], exp[j], "result" );
}
cleanup:
test_core_extern__destroy(skel);
skel = NULL;
}
}
Messung V0.5 C=94 H=87 G=90
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland