context_unix.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. //go:build linux || freebsd
  2. // +build linux freebsd
  3. package testutils
  4. import (
  5. "runtime"
  6. "testing"
  7. "github.com/docker/docker/libnetwork/ns"
  8. "github.com/vishvananda/netns"
  9. )
  10. // SetupTestOSContext joins a new network namespace, and returns its associated
  11. // teardown function.
  12. //
  13. // Example usage:
  14. //
  15. // defer SetupTestOSContext(t)()
  16. func SetupTestOSContext(t *testing.T) func() {
  17. origNS, err := netns.Get()
  18. if err != nil {
  19. t.Fatalf("Failed to open initial netns: %v", err)
  20. }
  21. restore := func() {
  22. if err := netns.Set(origNS); err != nil {
  23. t.Logf("Warning: failed to restore thread netns (%v)", err)
  24. } else {
  25. runtime.UnlockOSThread()
  26. }
  27. if err := origNS.Close(); err != nil {
  28. t.Logf("Warning: netns closing failed (%v)", err)
  29. }
  30. }
  31. runtime.LockOSThread()
  32. newNS, err := netns.New()
  33. if err != nil {
  34. // netns.New() is not atomic: it could have encountered an error
  35. // after unsharing the current thread's network namespace.
  36. restore()
  37. t.Fatalf("Failed to enter netns: %v", err)
  38. }
  39. // Since we are switching to a new test namespace make
  40. // sure to re-initialize initNs context
  41. ns.Init()
  42. return func() {
  43. if err := newNS.Close(); err != nil {
  44. t.Logf("Warning: netns closing failed (%v)", err)
  45. }
  46. restore()
  47. ns.Init()
  48. }
  49. }