Skip to content

Commit

Permalink
test: skip tests when having no private netns
Browse files Browse the repository at this point in the history
Under valgrind in github CI we (currently) seem unable to create the
netns. This worked previously, now it no longer does.

Handle that by skipping the tests that require a netns.
  • Loading branch information
thom311 committed Jan 12, 2025
1 parent 5da4c1e commit 56c77a9
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 3 deletions.
13 changes: 12 additions & 1 deletion tests/cksuite-all-netns.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ START_TEST(cache_and_clone)
size_t i;
int r;

if (_nltst_skip_no_netns())
return;

for (i = 0; i < _NL_N_ELEMENTS(links); i++) {
if (links[i].add)
_nltst_add_link(NULL, links[i].ifname, links[i].kind,
Expand Down Expand Up @@ -132,11 +135,16 @@ START_TEST(test_create_iface)
_nl_auto_rtnl_link struct rtnl_link *link2 = NULL;
_nl_auto_rtnl_link struct rtnl_link *peer = NULL;
_nltst_auto_delete_link const char *IFNAME_DUMMY = NULL;
_nltst_auto_delete_link const char *IFNAME = "ifname";
_nltst_auto_delete_link const char *IFNAME = NULL;
int ifindex_dummy;
uint32_t u32;
int r;

if (_nltst_skip_no_netns())
return;

IFNAME = "ifname";

switch (TEST_IDX) {
case 0:
link = _nltst_assert(rtnl_link_bridge_alloc());
Expand Down Expand Up @@ -317,6 +325,9 @@ START_TEST(route_1)
_nl_auto_nl_socket struct nl_sock *sk = NULL;
_nl_auto_nl_cache struct nl_cache *cache = NULL;

if (_nltst_skip_no_netns())
return;

if (_nltst_skip_no_iproute2("route_1"))
return;

Expand Down
47 changes: 45 additions & 2 deletions tests/nl-test-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ uint32_t _nltst_rand_u32(void)

struct nltst_netns {
int canary;
bool is_unshared;
};

/*****************************************************************************/
Expand Down Expand Up @@ -114,6 +115,20 @@ void nltst_netns_fixture_teardown(void)
_nl_clear_pointer(&_netns_fixture_global.nsdata, nltst_netns_leave);
}

bool nltst_netns_fixture_is_unshared(void)
{
_assert_nltst_netns(_netns_fixture_global.nsdata);
return _netns_fixture_global.nsdata->is_unshared;
}

bool _nltst_skip_no_netns(void)
{
if (nltst_netns_fixture_is_unshared())
return false;
printf("skip test due to having no private netns\n");
return true;
}

/*****************************************************************************/

static void unshare_user(void)
Expand All @@ -125,6 +140,10 @@ static void unshare_user(void)

/* Become a root in new user NS. */
r = unshare(CLONE_NEWUSER);
if (r != 0 && errno == EPERM) {
/* No permissions? Ignore. Will be handled later. */
return;
}
_nltst_assert_errno(r == 0);

/* Since Linux 3.19 we have to disable setgroups() in order to map users.
Expand All @@ -149,14 +168,28 @@ static void unshare_user(void)
}
r = fprintf(f, "0 %d 1", uid);
_nltst_assert_errno(r > 0);
_nltst_fclose(f);
r = fclose(f);
if (r != 0 && errno == EPERM) {
/* Oddly, it seems close() can fail at this point. Ignore it,
* but we probably will be unable to unshare (which we handle
* later).
*/
} else
_nltst_assert_errno(r == 0);

/* Map current GID to root in NS to be created. */
f = fopen("/proc/self/gid_map", "we");
_nltst_assert_errno(f);
r = fprintf(f, "0 %d 1", gid);
_nltst_assert_errno(r > 0);
_nltst_fclose(f);
r = fclose(f);
if (r != 0 && errno == EPERM) {
/* Oddly, it seems close() can fail at this point. Ignore it, but
* we probably will be unable to unshare (which we handle
* later).
*/
} else
_nltst_assert_errno(r == 0);
}

struct nltst_netns *nltst_netns_enter(void)
Expand All @@ -172,13 +205,23 @@ struct nltst_netns *nltst_netns_enter(void)
unshare_user();

r = unshare(CLONE_NEWNET | CLONE_NEWNS);
if (r != 0 && errno == EPERM) {
/* The system is probably sandboxed somehow and we are unable
* to create a private netns. That seems questionable, because
* a point of a private netns is to sandbox an application.
* Not having permissions to sandbox sounds bad.
*
* Anyway. We accept this and will later skip some tests. */
return nsdata;
}
_nltst_assert_errno(r == 0);

/* We need a read-only /sys so that the platform knows there's no udev. */
mount(NULL, "/sys", "sysfs", MS_SLAVE, NULL);
r = mount("sys", "/sys", "sysfs", MS_RDONLY, NULL);
_nltst_assert_errno(r == 0);

nsdata->is_unshared = true;
return nsdata;
}

Expand Down
3 changes: 3 additions & 0 deletions tests/nl-test-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,9 @@ char **_nltst_strtokv(const char *str);

void nltst_netns_fixture_setup(void);
void nltst_netns_fixture_teardown(void);
bool nltst_netns_fixture_is_unshared(void);

bool _nltst_skip_no_netns(void);

struct nltst_netns;

Expand Down

0 comments on commit 56c77a9

Please sign in to comment.