mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
afa41b16ea
testutils.SetupTestOSContext() sets the calling thread's network namespace but neglected to restore it on teardown. This was not a problem in practice as it called runtime.LockOSThread() twice but runtime.UnlockOSThread() only once, so the tampered threads would be terminated by the runtime when the test case returned and replaced with a clean thread. Correct the utility so it restores the thread's network namespace during teardown and unlocks the goroutine from the thread on success. Remove unnecessary runtime.LockOSThread() calls peppering test cases which leverage testutils.SetupTestOSContext(). Signed-off-by: Cory Snider <csnider@mirantis.com>
57 lines
1.2 KiB
Go
57 lines
1.2 KiB
Go
//go:build linux || freebsd
|
|
// +build linux freebsd
|
|
|
|
package testutils
|
|
|
|
import (
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/docker/docker/libnetwork/ns"
|
|
"github.com/vishvananda/netns"
|
|
)
|
|
|
|
// SetupTestOSContext joins a new network namespace, and returns its associated
|
|
// teardown function.
|
|
//
|
|
// Example usage:
|
|
//
|
|
// defer SetupTestOSContext(t)()
|
|
func SetupTestOSContext(t *testing.T) func() {
|
|
origNS, err := netns.Get()
|
|
if err != nil {
|
|
t.Fatalf("Failed to open initial netns: %v", err)
|
|
}
|
|
restore := func() {
|
|
if err := netns.Set(origNS); err != nil {
|
|
t.Logf("Warning: failed to restore thread netns (%v)", err)
|
|
} else {
|
|
runtime.UnlockOSThread()
|
|
}
|
|
|
|
if err := origNS.Close(); err != nil {
|
|
t.Logf("Warning: netns closing failed (%v)", err)
|
|
}
|
|
}
|
|
|
|
runtime.LockOSThread()
|
|
newNS, err := netns.New()
|
|
if err != nil {
|
|
// netns.New() is not atomic: it could have encountered an error
|
|
// after unsharing the current thread's network namespace.
|
|
restore()
|
|
t.Fatalf("Failed to enter netns: %v", err)
|
|
}
|
|
|
|
// Since we are switching to a new test namespace make
|
|
// sure to re-initialize initNs context
|
|
ns.Init()
|
|
|
|
return func() {
|
|
if err := newNS.Close(); err != nil {
|
|
t.Logf("Warning: netns closing failed (%v)", err)
|
|
}
|
|
restore()
|
|
ns.Init()
|
|
}
|
|
}
|