func configureNetNSWithBridgeAndSetIPAddress() error {
	if err := configureNetNSWithBridge(); err != nil {
		return err
	}
	bridge, err := netlink.LinkByName(bridgeName)
	if err != nil {
		return err
	}
	ip, ipNetAddr, err := net.ParseCIDR(expectedBridgeAddress)
	if err != nil {
		return err
	}
	return netlink.AddrAdd(bridge, &netlink.Addr{
		IPNet: &net.IPNet{
			IP:   ip,
			Mask: ipNetAddr.Mask,
		},
	})
}
configureNetNSWithBridgeAndSetIPAddress creates a bridge in the network namespace
and sets and IP address for the same
package e2eTests
import (
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"runtime"
	"strconv"
	"testing"
	"github.com/containernetworking/cni/pkg/invoke"
	"github.com/containernetworking/cni/pkg/ns"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/vishvananda/netlink"
)
const (
	bridgeName            = "ecs-test-bridge"
	ifName                = "ecs-test-eth0"
	containerID           = "contain-er"
	expectedBridgeAddress = "169.254.172.1/22"
	expectedGateway       = "169.254.172.1"
	expectedVethAddress   = "169.254.172.2/22"
	dst                   = "169.254.170.2/32"
	bridgeDst             = "169.254.172.1/32"
	netConf               = `
{
    "type":"ecs-bridge",
    "cniVersion":"0.3.0",
    "bridge":"%s",
    "ipam":{
	"type":"ecs-ipam",
	"id":"test",
	"cniVersion":"0.3.0",
	"ipv4-subnet":"169.254.172.0/22",
	"ipv4-routes":[
	    {
		"dst":"%s"
	    }
	]
    }
}`
)
func init() {
	runtime.LockOSThread()
}
type configureNetNSFunc func() error
func TestAddDel(t *testing.T) {
	testCases := map[string]configureNetNSFunc{
		"When Bridge Exists":                                configureNetNSWithBridge,
		"When Bridge Exists And Configured With IP Address": configureNetNSWithBridgeAndSetIPAddress,
		"When Bridge Does Not Exist":                        configureNetNSNop,
	}
	bridgePluginPath, err := invoke.FindInPath("ecs-bridge", []string{os.Getenv("CNI_PATH")})
	require.NoError(t, err, "Unable to find bridge plugin in path")
	testLogDir, err := ioutil.TempDir("", "ecs-bridge-e2e-test-")
	require.NoError(t, err, "Unable to create directory for storing test logs")
	os.Setenv("ECS_CNI_LOG_FILE", fmt.Sprintf("%s/bridge.log", testLogDir))
	t.Logf("Using %s for test logs", testLogDir)
	defer os.Unsetenv("ECS_CNI_LOG_FILE")
	ok, err := strconv.ParseBool(getEnvOrDefault("ECS_PRESERVE_E2E_TEST_LOGS", "false"))
	assert.NoError(t, err, "Unable to parse ECS_PRESERVE_E2E_TEST_LOGS env var")
	defer func(preserve bool) {
		if !t.Failed() && !preserve {
			os.RemoveAll(testLogDir)
		}
	}(ok)
	for tcName, configFunc := range testCases {
		t.Run(tcName, func(t *testing.T) {
			testNS, err := ns.NewNS()
			require.NoError(t, err, "Unable to create the network namespace to run the test in")
			defer testNS.Close()
			targetNS, err := ns.NewNS()
			require.NoError(t, err,
				"Unable to create the network namespace that represents the network namespace of the container")
			defer targetNS.Close()
			ipamDir, err := ioutil.TempDir("", "ecs-ipam-")
			require.NoError(t, err, "Unable to create a temp directory for the ipam db")
			os.Setenv("IPAM_DB_PATH", fmt.Sprintf("%s/ipam.db", ipamDir))
			defer os.Unsetenv("IPAM_DB_PATH")
			ok, err := strconv.ParseBool(getEnvOrDefault("ECS_BRIDGE_PRESERVE_IPAM_DB", "false"))
			assert.NoError(t, err, "Unable to parse ECS_BRIDGE_PRESERVE_IPAM_DB env var")
			if !ok {
				defer os.RemoveAll(ipamDir)
			}
			execInvokeArgs := &invoke.Args{
				ContainerID: containerID,
				NetNS:       targetNS.Path(),
				IfName:      ifName,
				Path:        os.Getenv("CNI_PATH"),
			}
			var vethTestNetNS netlink.Link
			testNS.Do(func(ns.NetNS) error {
				err = configFunc()
				require.NoError(t, err, "Unable to configure test netns before executing ADD")
				execInvokeArgs.Command = "ADD"
				_, err := invoke.ExecPluginWithResult(
					bridgePluginPath,
					[]byte(fmt.Sprintf(netConf, bridgeName, dst)),
					execInvokeArgs)
				require.NoError(t, err, "Unable to execute ADD command for ecs-bridge plugin")
				bridge := getBridgeLink(t)
				validateBridgeAddress(t, bridge)
				vethTestNetNS, ok = getVethAndVerifyLo(t)
				require.True(t, ok, "veth device not found in test netns")
				return nil
			})
			var vethTargetNetNS netlink.Link
			targetNS.Do(func(ns.NetNS) error {
				vethTargetNetNS, ok = getVethAndVerifyLo(t)
				require.True(t, ok, "veth device not found in target netns")
				validateVethAddress(t, vethTargetNetNS)
				validateRouteForVethInTargetNetNS(t, vethTargetNetNS)
				return nil
			})
			testNS.Do(func(ns.NetNS) error {
				execInvokeArgs.Command = "DEL"
				err := invoke.ExecPluginWithoutResult(
					bridgePluginPath,
					[]byte(fmt.Sprintf(netConf, bridgeName, dst)),
					execInvokeArgs)
				require.NoError(t, err, "Unable to execute DEL command for ecs-bridge plugin")
				validateLinkDoesNotExist(t, vethTestNetNS.Attrs().Name)
				bridge := getBridgeLink(t)
				validateBridgeAddress(t, bridge)
				return nil
			})
			targetNS.Do(func(ns.NetNS) error {
				validateLinkDoesNotExist(t, vethTargetNetNS.Attrs().Name)
				return nil
			})
		})
	}
}
func configureNetNSWithBridge() error {
	bridgeLinkAttributes := netlink.NewLinkAttrs()
	bridgeLinkAttributes.Name = bridgeName
	return netlink.LinkAdd(&netlink.Bridge{
		LinkAttrs: bridgeLinkAttributes,
	})
}