github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/libnetwork/drivers/overlay/overlay_test.go (about) 1 package overlay 2 3 import ( 4 "context" 5 "fmt" 6 "net" 7 "os" 8 "syscall" 9 "testing" 10 "time" 11 12 "golang.org/x/sys/unix" 13 14 "github.com/docker/docker/pkg/plugingetter" 15 "github.com/docker/libkv/store/consul" 16 "github.com/docker/libnetwork/datastore" 17 "github.com/docker/libnetwork/discoverapi" 18 "github.com/docker/libnetwork/driverapi" 19 "github.com/docker/libnetwork/netlabel" 20 _ "github.com/docker/libnetwork/testutils" 21 "github.com/vishvananda/netlink/nl" 22 ) 23 24 func init() { 25 consul.Register() 26 } 27 28 type driverTester struct { 29 t *testing.T 30 d *driver 31 } 32 33 const testNetworkType = "overlay" 34 35 func setupDriver(t *testing.T) *driverTester { 36 dt := &driverTester{t: t} 37 config := make(map[string]interface{}) 38 config[netlabel.GlobalKVClient] = discoverapi.DatastoreConfigData{ 39 Scope: datastore.GlobalScope, 40 Provider: "consul", 41 Address: "127.0.0.01:8500", 42 } 43 44 if err := Init(dt, config); err != nil { 45 t.Fatal(err) 46 } 47 48 iface, err := net.InterfaceByName("eth0") 49 if err != nil { 50 t.Fatal(err) 51 } 52 addrs, err := iface.Addrs() 53 if err != nil || len(addrs) == 0 { 54 t.Fatal(err) 55 } 56 data := discoverapi.NodeDiscoveryData{ 57 Address: addrs[0].String(), 58 Self: true, 59 } 60 dt.d.DiscoverNew(discoverapi.NodeDiscovery, data) 61 return dt 62 } 63 64 func cleanupDriver(t *testing.T, dt *driverTester) { 65 ch := make(chan struct{}) 66 go func() { 67 Fini(dt.d) 68 close(ch) 69 }() 70 71 select { 72 case <-ch: 73 case <-time.After(10 * time.Second): 74 t.Fatal("test timed out because Fini() did not return on time") 75 } 76 } 77 78 func (dt *driverTester) GetPluginGetter() plugingetter.PluginGetter { 79 return nil 80 } 81 82 func (dt *driverTester) RegisterDriver(name string, drv driverapi.Driver, 83 cap driverapi.Capability) error { 84 if name != testNetworkType { 85 dt.t.Fatalf("Expected driver register name to be %q. Instead got %q", 86 testNetworkType, name) 87 } 88 89 if _, ok := drv.(*driver); !ok { 90 dt.t.Fatalf("Expected driver type to be %T. Instead got %T", 91 &driver{}, drv) 92 } 93 94 dt.d = drv.(*driver) 95 return nil 96 } 97 98 func TestOverlayInit(t *testing.T) { 99 if err := Init(&driverTester{t: t}, nil); err != nil { 100 t.Fatal(err) 101 } 102 } 103 104 func TestOverlayFiniWithoutConfig(t *testing.T) { 105 dt := &driverTester{t: t} 106 if err := Init(dt, nil); err != nil { 107 t.Fatal(err) 108 } 109 110 cleanupDriver(t, dt) 111 } 112 113 func TestOverlayConfig(t *testing.T) { 114 dt := setupDriver(t) 115 116 time.Sleep(1 * time.Second) 117 118 d := dt.d 119 if d.notifyCh == nil { 120 t.Fatal("Driver notify channel wasn't initialized after Config method") 121 } 122 123 if d.exitCh == nil { 124 t.Fatal("Driver serfloop exit channel wasn't initialized after Config method") 125 } 126 127 if d.serfInstance == nil { 128 t.Fatal("Driver serfinstance hasn't been initialized after Config method") 129 } 130 131 cleanupDriver(t, dt) 132 } 133 134 func TestOverlayType(t *testing.T) { 135 dt := &driverTester{t: t} 136 if err := Init(dt, nil); err != nil { 137 t.Fatal(err) 138 } 139 140 if dt.d.Type() != testNetworkType { 141 t.Fatalf("Expected Type() to return %q. Instead got %q", testNetworkType, 142 dt.d.Type()) 143 } 144 } 145 146 // Test that the netlink socket close unblock the watchMiss to avoid deadlock 147 func TestNetlinkSocket(t *testing.T) { 148 // This is the same code used by the overlay driver to create the netlink interface 149 // for the watch miss 150 nlSock, err := nl.Subscribe(syscall.NETLINK_ROUTE, syscall.RTNLGRP_NEIGH) 151 if err != nil { 152 t.Fatal() 153 } 154 // set the receive timeout to not remain stuck on the RecvFrom if the fd gets closed 155 tv := unix.NsecToTimeval(soTimeout.Nanoseconds()) 156 err = nlSock.SetReceiveTimeout(&tv) 157 if err != nil { 158 t.Fatal() 159 } 160 n := &network{id: "testnetid"} 161 ch := make(chan error) 162 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 163 defer cancel() 164 go func() { 165 n.watchMiss(nlSock, fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), syscall.Gettid())) 166 ch <- nil 167 }() 168 time.Sleep(5 * time.Second) 169 nlSock.Close() 170 select { 171 case <-ch: 172 case <-ctx.Done(): 173 { 174 t.Fatalf("Timeout expired") 175 } 176 } 177 }