-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor netns handling, fix flakes, namespace some tests (#227)
* netns: remove iproute2 dependency This commit introduces a breaking change to rtnetlink.NetNS. The existing netns implementation had a few problems. It assumed that network namespaces have names, that they would always be pinned to /var/run/netns, and that numeric/integer references are pid references. This made the NetNS type unusable for referring to existing netns by fd, such as ones created by other libraries, or by opening procfs entries directly as demonstrated in the new testutils.NetNS() function. The forced dependency on the `ip` CLI tool also wasn't reasonable for a pure-Go library. Using the old implementation in a scratch/distroless container would quickly run into roadblocks. This commit also removes the functionality of creating and pinning new netns. There are plenty of options out in the Go ecosystem for that, and providing your own is only a few lines of code. Signed-off-by: Timo Beckers <[email protected]> * test: remove calls to unix.Setrlimit() in favor of rlimit.RemoveMemlock() ebpf-go provides this out of the box and skips setting the rlimit on kernels that support bpf memory cgroup accounting. Signed-off-by: Timo Beckers <[email protected]> * neigh: fix flaky tests, add State field to Neigh entry The flaky tests that were documented in the code are expected. Use the State field to discard entries that can't reasonably be considered in tests. Signed-off-by: Timo Beckers <[email protected]> * neigh: fix race in Conn.Neighbours When running tests locally, I would frequently hit "too many/little matches, expected 1, actual 0" due to other tests creating and deleting interfaces in the common host netns used by all tests. Neigh entries that fail the interface lookup can't have their Interface fields populated and should be dropped from the result since the interface is no longer there to begin with. Signed-off-by: Timo Beckers <[email protected]> * xdp: refactor test suite to use test helpers and netns-driven tests While running the test suite for testing netns-related changes, I noticed some of the xdp tests started failing because they wanted to create a dummy interface in the host network namespace. Avoid the complexity of managing dummy interfaces altogether by running all tests within their own netns and use the existing lo device that's present by default. Signed-off-by: Timo Beckers <[email protected]> * xdp,netkit: remove duplicate kernelMinReq in favor of testutils.SkipOnOldKernel There were two implementations of this, so move them to common testutils. Signed-off-by: Timo Beckers <[email protected]> --------- Signed-off-by: Timo Beckers <[email protected]>
- Loading branch information
Showing
13 changed files
with
248 additions
and
324 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package testutils | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"runtime" | ||
"testing" | ||
|
||
"github.com/jsimonetti/rtnetlink/v2/internal/unix" | ||
"golang.org/x/sync/errgroup" | ||
) | ||
|
||
// NetNS returns a file descriptor to a new network namespace. | ||
// The netns handle is automatically closed as part of test cleanup. | ||
func NetNS(tb testing.TB) int { | ||
tb.Helper() | ||
|
||
var ns *os.File | ||
var eg errgroup.Group | ||
eg.Go(func() error { | ||
// Lock the new goroutine to its OS thread. Never unlock the goroutine so | ||
// the thread dies when the goroutine ends to avoid having to restore the | ||
// thread's netns. | ||
runtime.LockOSThread() | ||
|
||
// Move the current thread to a new network namespace. | ||
if err := unix.Unshare(unix.CLONE_NEWNET); err != nil { | ||
return fmt.Errorf("unsharing netns: %w", err) | ||
} | ||
|
||
f, err := os.OpenFile(fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), unix.Gettid()), | ||
unix.O_RDONLY|unix.O_CLOEXEC, 0) | ||
if err != nil { | ||
return fmt.Errorf("opening netns handle: %w", err) | ||
} | ||
|
||
// Store a namespace reference in the outer scope. | ||
ns = f | ||
|
||
return nil | ||
}) | ||
|
||
if err := eg.Wait(); err != nil { | ||
tb.Fatal(err) | ||
} | ||
|
||
tb.Cleanup(func() { | ||
// Maintain a reference to the namespace until the end of the test, where | ||
// the handle will close automatically and the namespace potentially | ||
// disappears if there are no other references (veth/netkit peers, ..) to it. | ||
ns.Close() | ||
}) | ||
|
||
return int(ns.Fd()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package testutils | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"testing" | ||
|
||
"golang.org/x/sys/unix" | ||
) | ||
|
||
func getKernelVersion(tb testing.TB) (maj, min, patch uint32) { | ||
tb.Helper() | ||
|
||
var uname unix.Utsname | ||
if err := unix.Uname(&uname); err != nil { | ||
tb.Fatalf("getting uname: %s", err) | ||
} | ||
|
||
end := bytes.IndexByte(uname.Release[:], 0) | ||
versionStr := uname.Release[:end] | ||
|
||
if count, _ := fmt.Sscanf(string(versionStr), "%d.%d.%d", &maj, &min, &patch); count < 2 { | ||
tb.Fatalf("failed to parse kernel version from %s", string(versionStr)) | ||
} | ||
return | ||
} | ||
|
||
// SkipOnOldKernel skips the test if the host's kernel is lower than the given | ||
// x.y target version. | ||
func SkipOnOldKernel(tb testing.TB, target, reason string) { | ||
maj, min, _ := getKernelVersion(tb) | ||
|
||
var maj_t, min_t, patch_t uint32 | ||
if count, _ := fmt.Sscanf(target, "%d.%d.%d", &maj_t, &min_t, &patch_t); count < 2 { | ||
tb.Fatalf("failed to parse target version from %s", target) | ||
} | ||
|
||
if maj < maj_t || maj == maj_t && min < min_t { | ||
tb.Skipf("host kernel (%d.%d) too old (minimum %d.%d): %s", maj, min, maj_t, min_t, reason) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.