mirror of
https://github.com/moby/moby.git
synced 2026-08-03 22:51:03 +00:00
Add option WithSetNsHandles for testutil SetupTestOSContextEx
Allow tests to run in parallel with separate network namespaces, without modifying the global-state namespace/netlink handles in the "ns" package ... only useful for tests that don't depend on package "ns". Use the new option in iptabler/nftabler tests. Signed-off-by: Rob Murray <rob.murray@docker.com>
This commit is contained in:
@@ -149,7 +149,7 @@ func TestIptabler(t *testing.T) {
|
||||
}
|
||||
|
||||
func testIptabler(t *testing.T, tn string, config firewaller.Config, netConfig firewaller.NetworkConfig, bindLocalhost bool, resName string) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
defer netnsutils.SetupTestOSContext(t, netnsutils.WithSetNsHandles(false))()
|
||||
|
||||
stripComments := func(text string) string {
|
||||
lines := strings.Split(text, "\n")
|
||||
|
||||
@@ -91,7 +91,7 @@ func TestNftabler(t *testing.T) {
|
||||
}
|
||||
|
||||
func testNftabler(t *testing.T, tn string, config firewaller.Config, netConfig firewaller.NetworkConfig, bindLocalhost bool, resName string) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
defer netnsutils.SetupTestOSContext(t, netnsutils.WithSetNsHandles(false))()
|
||||
|
||||
checkResults := func(family, name string, en bool) {
|
||||
t.Helper()
|
||||
|
||||
@@ -25,8 +25,22 @@ var osContextLock sync.Mutex
|
||||
type OSContext struct {
|
||||
origNS, newNS netns.NsHandle
|
||||
|
||||
tid int
|
||||
caller string // The file:line where SetupTestOSContextEx was called, for interpolating into error messages.
|
||||
tid int
|
||||
caller string // The file:line where SetupTestOSContextEx was called, for interpolating into error messages.
|
||||
setNsHandles bool // See [WithSetNsHandles].
|
||||
}
|
||||
|
||||
// WithSetNsHandles is an option for [SetupTestOSContext]/[SetupTestOSContextEx],
|
||||
// value false prevents reset of the namespace and netlink handles in package ns.
|
||||
// This allows multiple OSContext instances to be active at the same time,
|
||||
// but means code that relies on package ns, including [ns.NlHandle], will
|
||||
// not work correctly. So, it's useful for tests that want clean network
|
||||
// namespaces for parallel subtests, as long as they don't use package ns.
|
||||
// The default is true.
|
||||
func WithSetNsHandles(p bool) func(*OSContext) {
|
||||
return func(c *OSContext) {
|
||||
c.setNsHandles = p
|
||||
}
|
||||
}
|
||||
|
||||
// SetupTestOSContext joins the current goroutine to a new network namespace,
|
||||
@@ -35,8 +49,8 @@ type OSContext struct {
|
||||
// Example usage:
|
||||
//
|
||||
// defer SetupTestOSContext(t)()
|
||||
func SetupTestOSContext(t *testing.T) func() {
|
||||
c := SetupTestOSContextEx(t)
|
||||
func SetupTestOSContext(t *testing.T, opts ...func(*OSContext)) func() {
|
||||
c := SetupTestOSContextEx(t, opts...)
|
||||
return func() { c.Cleanup(t) }
|
||||
}
|
||||
|
||||
@@ -50,8 +64,19 @@ func SetupTestOSContext(t *testing.T) func() {
|
||||
//
|
||||
// c := SetupTestOSContext(t)
|
||||
// defer c.Cleanup(t)
|
||||
func SetupTestOSContextEx(t *testing.T) *OSContext {
|
||||
osContextLock.Lock()
|
||||
func SetupTestOSContextEx(t *testing.T, opts ...func(*OSContext)) *OSContext {
|
||||
c := OSContext{
|
||||
setNsHandles: true,
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(&c)
|
||||
}
|
||||
// If the namespace/netlink handles in package ns are to be reset, make sure
|
||||
// only one OSContext is active at a time.
|
||||
if c.setNsHandles {
|
||||
osContextLock.Lock()
|
||||
}
|
||||
|
||||
runtime.LockOSThread()
|
||||
origNS, err := netns.Get()
|
||||
if err != nil {
|
||||
@@ -59,10 +84,8 @@ func SetupTestOSContextEx(t *testing.T) *OSContext {
|
||||
t.Fatalf("Failed to open initial netns: %v", err)
|
||||
}
|
||||
|
||||
c := OSContext{
|
||||
tid: unix.Gettid(),
|
||||
origNS: origNS,
|
||||
}
|
||||
c.tid = unix.Gettid()
|
||||
c.origNS = origNS
|
||||
c.newNS, err = netns.New()
|
||||
if err != nil {
|
||||
// netns.New() is not atomic: it could have encountered an error
|
||||
@@ -73,7 +96,9 @@ func SetupTestOSContextEx(t *testing.T) *OSContext {
|
||||
|
||||
// Since we are switching to a new test namespace make
|
||||
// sure to re-initialize initNs context
|
||||
ns.ResetHandles()
|
||||
if c.setNsHandles {
|
||||
ns.ResetHandles()
|
||||
}
|
||||
|
||||
nl := ns.NlHandle()
|
||||
lo, err := nl.LinkByName("lo")
|
||||
@@ -108,8 +133,10 @@ func (c *OSContext) Cleanup(t *testing.T) {
|
||||
t.Logf("Warning: netns closing failed (%v)", err)
|
||||
}
|
||||
c.restore(t)
|
||||
ns.ResetHandles()
|
||||
osContextLock.Unlock()
|
||||
if c.setNsHandles {
|
||||
ns.ResetHandles()
|
||||
osContextLock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *OSContext) restore(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user