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  }