TBR veyron/runtimes/google/ipc/stream/fix: fix a bug in vif cache

Currently, vifs are cached with the actual protocol not with a
client specified protocol. E.g., vif with "wsh" are cached with
"tcp" or "ws". So we cannot find a vif with "wsh" causing unncessary
vif creation. There is also a similar problem with v4 and v6 protocols.
This CL addresses this issue.

MultiPart: 1/2
Change-Id: Id37854ff1c7b515e19bb377b1b9d1e9cc130f178
diff --git a/runtimes/google/ipc/protocols/tcp/init.go b/runtimes/google/ipc/protocols/tcp/init.go
index e1b0891..f0fe01c 100644
--- a/runtimes/google/ipc/protocols/tcp/init.go
+++ b/runtimes/google/ipc/protocols/tcp/init.go
@@ -11,9 +11,9 @@
 )
 
 func init() {
-	for _, p := range []string{"tcp", "tcp4", "tcp6"} {
-		ipc.RegisterProtocol(p, tcpDial, tcpListen)
-	}
+	ipc.RegisterProtocol("tcp", net.DialTimeout, net.Listen, "tcp4", "tcp6")
+	ipc.RegisterProtocol("tcp4", net.DialTimeout, net.Listen)
+	ipc.RegisterProtocol("tcp6", net.DialTimeout, net.Listen)
 }
 
 func tcpDial(network, address string, timeout time.Duration) (net.Conn, error) {
diff --git a/runtimes/google/ipc/protocols/ws/init.go b/runtimes/google/ipc/protocols/ws/init.go
index f218ca0..f2d9faf 100644
--- a/runtimes/google/ipc/protocols/ws/init.go
+++ b/runtimes/google/ipc/protocols/ws/init.go
@@ -8,7 +8,7 @@
 
 func init() {
 	// ws, ws4, ws6 represent websocket protocol instances.
-	for _, p := range []string{"ws", "ws4", "ws6"} {
-		ipc.RegisterProtocol(p, websocket.Dial, websocket.Listener)
-	}
+	ipc.RegisterProtocol("ws", websocket.Dial, websocket.Listener, "ws4", "ws6")
+	ipc.RegisterProtocol("ws4", websocket.Dial, websocket.Listener)
+	ipc.RegisterProtocol("ws6", websocket.Dial, websocket.Listener)
 }
diff --git a/runtimes/google/ipc/protocols/wsh/init.go b/runtimes/google/ipc/protocols/wsh/init.go
index 146a723..86e6e33 100644
--- a/runtimes/google/ipc/protocols/wsh/init.go
+++ b/runtimes/google/ipc/protocols/wsh/init.go
@@ -9,7 +9,7 @@
 )
 
 func init() {
-	for _, p := range []string{"wsh", "wsh4", "wsh6"} {
-		ipc.RegisterProtocol(p, websocket.HybridDial, websocket.HybridListener)
-	}
+	ipc.RegisterProtocol("wsh", websocket.HybridDial, websocket.HybridListener, "tcp4", "tcp6", "ws4", "ws6")
+	ipc.RegisterProtocol("wsh4", websocket.HybridDial, websocket.HybridListener, "tcp4", "ws4")
+	ipc.RegisterProtocol("wsh6", websocket.HybridDial, websocket.HybridListener, "tcp6", "ws6")
 }
diff --git a/runtimes/google/ipc/protocols/wsh_nacl/init.go b/runtimes/google/ipc/protocols/wsh_nacl/init.go
index a038a6d..426cc51 100644
--- a/runtimes/google/ipc/protocols/wsh_nacl/init.go
+++ b/runtimes/google/ipc/protocols/wsh_nacl/init.go
@@ -9,7 +9,9 @@
 )
 
 func init() {
-	for _, p := range []string{"wsh", "wsh4", "wsh6"} {
-		ipc.RegisterProtocol(p, websocket.Dial, websocket.Listener)
-	}
+	// We limit wsh to ws since in general nacl does not allow direct access
+	// to TCP/UDP networking.
+	ipc.RegisterProtocol("wsh", websocket.Dial, websocket.Listener, "ws4", "ws6")
+	ipc.RegisterProtocol("wsh4", websocket.Dial, websocket.Listener, "ws4")
+	ipc.RegisterProtocol("wsh6", websocket.Dial, websocket.Listener, "ws6")
 }
diff --git a/runtimes/google/ipc/sort_endpoints.go b/runtimes/google/ipc/sort_endpoints.go
index 29d738f..9df1f8c 100644
--- a/runtimes/google/ipc/sort_endpoints.go
+++ b/runtimes/google/ipc/sort_endpoints.go
@@ -156,6 +156,9 @@
 	}
 	// Special case: if "wsh" has a rank but "wsh4"/"wsh6" don't,
 	// then they get the same rank as "wsh". Similar for "tcp" and "ws".
+	//
+	// TODO(jhahn): We have similar protocol equivalency checks at a few places.
+	// Figure out a way for this mapping to be shared.
 	if p := protocol; p == "wsh4" || p == "wsh6" || p == "tcp4" || p == "tcp6" || p == "ws4" || p == "ws6" {
 		if r, ok := ranks[p[:len(p)-1]]; ok {
 			return r, nil
diff --git a/runtimes/google/ipc/stream/manager/manager.go b/runtimes/google/ipc/stream/manager/manager.go
index ca08ba1..33f0c58 100644
--- a/runtimes/google/ipc/stream/manager/manager.go
+++ b/runtimes/google/ipc/stream/manager/manager.go
@@ -62,7 +62,7 @@
 func (DialTimeout) IPCClientOpt()   {}
 
 func dial(network, address string, timeout time.Duration) (net.Conn, error) {
-	if d, _ := ipc.RegisteredProtocol(network); d != nil {
+	if d, _, _ := ipc.RegisteredProtocol(network); d != nil {
 		return d(network, address, timeout)
 	}
 	return nil, fmt.Errorf("unknown network %s", network)
@@ -147,7 +147,7 @@
 }
 
 func listen(protocol, address string) (net.Listener, error) {
-	if _, l := ipc.RegisteredProtocol(protocol); l != nil {
+	if _, l, _ := ipc.RegisteredProtocol(protocol); l != nil {
 		return l(protocol, address)
 	}
 	return nil, fmt.Errorf("unknown network %s", protocol)
diff --git a/runtimes/google/ipc/stream/proxy/proxy.go b/runtimes/google/ipc/stream/proxy/proxy.go
index e7fe36e..0260e2c 100644
--- a/runtimes/google/ipc/stream/proxy/proxy.go
+++ b/runtimes/google/ipc/stream/proxy/proxy.go
@@ -148,7 +148,7 @@
 // New creates a new Proxy that listens for network connections on the provided
 // (network, address) pair and routes VC traffic between accepted connections.
 func New(rid naming.RoutingID, principal security.Principal, network, address, pubAddress string) (*Proxy, error) {
-	_, listenFn := ipc.RegisteredProtocol(network)
+	_, listenFn, _ := ipc.RegisteredProtocol(network)
 	if listenFn == nil {
 		return nil, fmt.Errorf("unknown network %s", network)
 	}
diff --git a/runtimes/google/ipc/stream/vif/set.go b/runtimes/google/ipc/stream/vif/set.go
index e8caa2e..0ff5c95 100644
--- a/runtimes/google/ipc/stream/vif/set.go
+++ b/runtimes/google/ipc/stream/vif/set.go
@@ -2,8 +2,11 @@
 
 import (
 	"math/rand"
+	"net"
 	"runtime"
 	"sync"
+
+	"v.io/v23/ipc"
 )
 
 // Set implements a set of VIFs keyed by (network, address) of the underlying
@@ -29,35 +32,42 @@
 	if len(address) == 0 ||
 		(network == "pipe" && address == "pipe") ||
 		(runtime.GOOS == "linux" && network == "unix" && address == "@") { // autobind
-		// Some network connections (like those created with net.Pipe
-		// or Unix sockets) do not end up with distinct conn.RemoteAddrs
-		// on distinct net.Conns. For those cases, avoid the cache collisions
-		// by disabling cache lookups for them.
+		// Some network connections (like those created with net.Pipe or Unix sockets)
+		// do not end up with distinct net.Addrs on distinct net.Conns. For those cases,
+		// avoid the cache collisions by disabling cache lookups for them.
 		return nil
 	}
 
+	var keys []string
+	_, _, p := ipc.RegisteredProtocol(network)
+	for _, n := range p {
+		keys = append(keys, key(n, address))
+	}
+
 	s.mu.RLock()
 	defer s.mu.RUnlock()
-	l, ok := s.set[s.key(network, address)]
-	if !ok || len(l) == 0 {
-		return nil
+	for _, k := range keys {
+		vifs := s.set[k]
+		if len(vifs) > 0 {
+			return vifs[rand.Intn(len(vifs))]
+		}
 	}
-	return l[rand.Intn(len(l))]
+	return nil
 }
 
 // Insert adds a VIF to the set
 func (s *Set) Insert(vif *VIF) {
 	addr := vif.conn.RemoteAddr()
-	key := s.key(addr.Network(), addr.String())
+	k := key(addr.Network(), addr.String())
 	s.mu.Lock()
 	defer s.mu.Unlock()
-	l, _ := s.set[key]
-	for _, v := range l {
+	vifs := s.set[k]
+	for _, v := range vifs {
 		if v == vif {
 			return
 		}
 	}
-	s.set[key] = append(l, vif)
+	s.set[k] = append(vifs, vif)
 	vif.addSet(s)
 }
 
@@ -65,16 +75,16 @@
 func (s *Set) Delete(vif *VIF) {
 	vif.removeSet(s)
 	addr := vif.conn.RemoteAddr()
-	key := s.key(addr.Network(), addr.String())
+	k := key(addr.Network(), addr.String())
 	s.mu.Lock()
 	defer s.mu.Unlock()
-	l, _ := s.set[key]
-	for ix, v := range l {
+	vifs := s.set[k]
+	for i, v := range vifs {
 		if v == vif {
-			if len(l) == 1 {
-				delete(s.set, key)
+			if len(vifs) == 1 {
+				delete(s.set, k)
 			} else {
-				s.set[key] = append(l[:ix], l[ix+1:]...)
+				s.set[k] = append(vifs[:i], vifs[i+1:]...)
 			}
 			return
 		}
@@ -92,6 +102,18 @@
 	return l
 }
 
-func (s *Set) key(network, address string) string {
+func key(network, address string) string {
+	if network == "tcp" || network == "ws" {
+		host, _, _ := net.SplitHostPort(address)
+		switch ip := net.ParseIP(host); {
+		case ip == nil:
+			// This may happen when address is a hostname. But we do not care
+			// about it, since vif cannot be found with a hostname anyway.
+		case ip.To4() != nil:
+			network += "4"
+		default:
+			network += "6"
+		}
+	}
 	return network + ":" + address
 }
diff --git a/runtimes/google/ipc/stream/vif/set_test.go b/runtimes/google/ipc/stream/vif/set_test.go
index 274f8c7..bea5190 100644
--- a/runtimes/google/ipc/stream/vif/set_test.go
+++ b/runtimes/google/ipc/stream/vif/set_test.go
@@ -7,142 +7,309 @@
 	"os"
 	"path"
 	"testing"
+	"time"
 
-	"v.io/core/veyron/runtimes/google/ipc/stream/vif"
+	"v.io/v23/ipc"
 	"v.io/v23/naming"
+
+	_ "v.io/core/veyron/profiles"
+	"v.io/core/veyron/runtimes/google/ipc/stream/vif"
 )
 
-func TestSetWithPipes(t *testing.T) {
-	var (
-		conn1, conn1s = net.Pipe()
-		conn2, _      = net.Pipe()
-		addr1         = conn1.RemoteAddr()
-		addr2         = conn2.RemoteAddr()
+var supportsIPv6 bool
 
-		set = vif.NewSet()
-	)
-	// The server is needed to negotiate with the dialed VIF.  Otherwise, the
-	// InternalNewDialedVIF below will block.
+func init() {
+	ipc.RegisterProtocol("unix", net.DialTimeout, net.Listen)
+
+	// Check whether the platform supports IPv6.
+	ln, err := net.Listen("tcp6", "[::1]:0")
+	defer ln.Close()
+	if err == nil {
+		supportsIPv6 = true
+	}
+}
+
+func newConn(network, address string) (net.Conn, net.Conn, error) {
+	dfunc, lfunc, _ := ipc.RegisteredProtocol(network)
+	ln, err := lfunc(network, address)
+	if err != nil {
+		return nil, nil, err
+	}
+	defer ln.Close()
+
+	done := make(chan net.Conn)
 	go func() {
-		_, err := vif.InternalNewAcceptedVIF(conn1s, naming.FixedRoutingID(2), nil)
+		conn, err := ln.Accept()
 		if err != nil {
-			panic(fmt.Sprintf("failed to create server: %s", err))
+			panic(err)
 		}
+		conn.Read(make([]byte, 1)) // Read a dummy byte.
+		done <- conn
 	}()
-	vf, err := vif.InternalNewDialedVIF(conn1, naming.FixedRoutingID(1), nil, nil, nil)
+
+	conn, err := dfunc(ln.Addr().Network(), ln.Addr().String(), 1*time.Second)
+	if err != nil {
+		return nil, nil, err
+	}
+	// Write a dummy byte since wsh listener waits for the magic bytes for ws.
+	conn.Write([]byte("."))
+	return conn, <-done, nil
+}
+
+func newVIF(c, s net.Conn) (*vif.VIF, *vif.VIF, error) {
+	done := make(chan *vif.VIF)
+	go func() {
+		vf, err := vif.InternalNewAcceptedVIF(s, naming.FixedRoutingID(0x5), nil)
+		if err != nil {
+			panic(err)
+		}
+		done <- vf
+	}()
+
+	vf, err := vif.InternalNewDialedVIF(c, naming.FixedRoutingID(0xc), nil, nil, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	return vf, <-done, nil
+}
+
+func diff(a, b []string) []string {
+	m := make(map[string]struct{})
+	for _, x := range b {
+		m[x] = struct{}{}
+	}
+	d := make([]string, 0, len(a))
+	for _, x := range a {
+		if _, ok := m[x]; !ok {
+			d = append(d, x)
+		}
+	}
+	return d
+}
+
+func TestSetBasic(t *testing.T) {
+	sockdir, err := ioutil.TempDir("", "TestSetBasic")
 	if err != nil {
 		t.Fatal(err)
 	}
-	if addr1.Network() != addr2.Network() || addr1.String() != addr2.String() {
+	defer os.RemoveAll(sockdir)
+
+	all := ipc.RegisteredProtocols()
+	unknown := naming.UnknownProtocol
+	tests := []struct {
+		network, address string
+		compatibles      []string
+	}{
+		{"tcp", "127.0.0.1:0", []string{"tcp", "tcp4", "wsh", "wsh4", unknown}},
+		{"tcp4", "127.0.0.1:0", []string{"tcp", "tcp4", "wsh", "wsh4", unknown}},
+		{"tcp", "[::1]:0", []string{"tcp", "tcp6", "wsh", "wsh6", unknown}},
+		{"tcp6", "[::1]:0", []string{"tcp", "tcp6", "wsh", "wsh6", unknown}},
+		{"ws", "127.0.0.1:0", []string{"ws", "ws4", "wsh", "wsh4", unknown}},
+		{"ws4", "127.0.0.1:0", []string{"ws", "ws4", "wsh", "wsh4", unknown}},
+		{"ws", "[::1]:0", []string{"ws", "ws6", "wsh", "wsh6", unknown}},
+		{"ws6", "[::1]:0", []string{"ws", "ws6", "wsh", "wsh6", unknown}},
+		// wsh dial always uses tcp.
+		{"wsh", "127.0.0.1:0", []string{"tcp", "tcp4", "wsh", "wsh4", unknown}},
+		{"wsh4", "127.0.0.1:0", []string{"tcp", "tcp4", "wsh", "wsh4", unknown}},
+		{"wsh", "[::1]:0", []string{"tcp", "tcp6", "wsh", "wsh6", unknown}},
+		{"wsh6", "[::1]:0", []string{"tcp", "tcp6", "wsh", "wsh6", unknown}},
+		{unknown, "127.0.0.1:0", []string{"tcp", "tcp4", "wsh", "wsh4", unknown}},
+		{unknown, "[::1]:0", []string{"tcp", "tcp6", "wsh", "wsh6", unknown}},
+		{"unix", path.Join(sockdir, "socket"), []string{"unix"}},
+	}
+
+	set := vif.NewSet()
+	for _, test := range tests {
+		if test.address == "[::1]:0" && !supportsIPv6 {
+			continue
+		}
+
+		name := fmt.Sprintf("(%q, %q)", test.network, test.address)
+
+		c, s, err := newConn(test.network, test.address)
+		if err != nil {
+			t.Fatal(err)
+		}
+		vf, _, err := newVIF(c, s)
+		if err != nil {
+			t.Fatal(err)
+		}
+		a := c.RemoteAddr()
+
+		set.Insert(vf)
+		for _, n := range test.compatibles {
+			if found := set.Find(n, a.String()); found == nil {
+				t.Fatalf("%s: Got nil, but want [%v] on Find(%q, %q))", name, vf, n, a)
+			}
+		}
+
+		for _, n := range diff(all, test.compatibles) {
+			if v := set.Find(n, a.String()); v != nil {
+				t.Fatalf("%s: Got [%v], but want nil on Find(%q, %q))", name, v, n, a)
+			}
+		}
+
+		set.Delete(vf)
+		for _, n := range all {
+			if v := set.Find(n, a.String()); v != nil {
+				t.Fatalf("%s: Got [%v], but want nil on Find(%q, %q))", name, v, n, a)
+			}
+		}
+	}
+}
+
+func TestSetWithPipes(t *testing.T) {
+	c1, s1 := net.Pipe()
+	c2, s2 := net.Pipe()
+	a1 := c1.RemoteAddr()
+	a2 := c2.RemoteAddr()
+	if a1.Network() != a2.Network() || a1.String() != a2.String() {
 		t.Fatalf("This test was intended for distinct connections that have duplicate RemoteAddrs. "+
 			"That does not seem to be the case with (%q, %q) and (%q, %q)",
-			addr1.Network(), addr1, addr2.Network(), addr2)
+			a1.Network(), a1, a2.Network(), a2)
 	}
-	set.Insert(vf)
-	if found := set.Find(addr2.Network(), addr2.String()); found != nil {
-		t.Fatalf("Got [%v] want nil on Find(%q, %q))", found, addr2.Network(), addr2)
+
+	vf1, _, err := newVIF(c1, s1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	vf2, _, err := newVIF(c2, s2)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	set := vif.NewSet()
+	set.Insert(vf1)
+	if v := set.Find(a1.Network(), a1.String()); v != nil {
+		t.Fatalf("Got [%v], but want nil on Find(%q, %q))", v, a1.Network(), a1)
+	}
+	if l := set.List(); len(l) != 1 || l[0] != vf1 {
+		t.Errorf("Unexpected list of VIFs: %v", l)
+	}
+
+	set.Insert(vf2)
+	if v := set.Find(a2.Network(), a2.String()); v != nil {
+		t.Fatalf("Got [%v], but want nil on Find(%q, %q))", v, a2.Network(), a2)
+	}
+	if l := set.List(); len(l) != 2 || l[0] != vf1 || l[1] != vf2 {
+		t.Errorf("Unexpected list of VIFs: %v", l)
+	}
+
+	set.Delete(vf1)
+	if l := set.List(); len(l) != 1 || l[0] != vf2 {
+		t.Errorf("Unexpected list of VIFs: %v", l)
+	}
+	set.Delete(vf2)
+	if l := set.List(); len(l) != 0 {
+		t.Errorf("Unexpected list of VIFs: %v", l)
 	}
 }
 
 func TestSetWithUnixSocket(t *testing.T) {
-	dir, err := ioutil.TempDir("", "TestSetWithFileConn")
+	dir, err := ioutil.TempDir("", "TestSetWithUnixSocket")
 	if err != nil {
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(dir)
-	sockname := path.Join(dir, "socket")
-	ln, err := net.Listen("unix", sockname)
-	if err != nil {
-		t.Fatal(err)
-	}
-	// Setup the creation of two separate connections.
-	// At the listener, they will end up with two distinct connections
-	// with the same "address" (empty string).
-	go func() {
-		for i := 0; i < 2; i++ {
-			conn, err := net.Dial("unix", sockname)
-			if err != nil {
-				ln.Close()
-				panic(fmt.Sprintf("dial failure: %s", err))
-			}
-			go func() {
-				if _, err := vif.InternalNewDialedVIF(conn, naming.FixedRoutingID(1), nil, nil, nil); err != nil {
-					panic(fmt.Sprintf("failed to dial VIF: %s", err))
-				}
-			}()
-		}
-	}()
 
-	conn1, err := ln.Accept()
+	c1, s1, err := newConn("unix", path.Join(dir, "socket1"))
 	if err != nil {
 		t.Fatal(err)
 	}
-	conn2, err := ln.Accept()
+	c2, s2, err := newConn("unix", path.Join(dir, "socket2"))
 	if err != nil {
 		t.Fatal(err)
 	}
-	addr1 := conn1.RemoteAddr()
-	addr2 := conn2.RemoteAddr()
-	if addr1.Network() != addr2.Network() || addr1.String() != addr2.String() {
+
+	// The client side address is always unix:@ regardless of socket name.
+	a1 := s1.RemoteAddr()
+	a2 := s2.RemoteAddr()
+	if a1.Network() != a2.Network() || a1.String() != a2.String() {
 		t.Fatalf("This test was intended for distinct connections that have duplicate RemoteAddrs. "+
 			"That does not seem to be the case with (%q, %q) and (%q, %q)",
-			addr1.Network(), addr1, addr2.Network(), addr2)
+			a1.Network(), a1, a2.Network(), a2)
 	}
-	vif1, err := vif.InternalNewAcceptedVIF(conn1, naming.FixedRoutingID(1), nil)
+
+	_, vf1, err := newVIF(c1, s1)
 	if err != nil {
 		t.Fatal(err)
 	}
-	if _, err := vif.InternalNewAcceptedVIF(conn2, naming.FixedRoutingID(1), nil); err != nil {
+	_, vf2, err := newVIF(c2, s2)
+	if err != nil {
 		t.Fatal(err)
 	}
+
 	set := vif.NewSet()
-	set.Insert(vif1)
-	if found := set.Find(addr2.Network(), addr2.String()); found != nil {
-		t.Errorf("Got [%v] want nil on Find(%q, %q)", found, addr2.Network(), addr2)
+	set.Insert(vf1)
+	if v := set.Find(a1.Network(), a1.String()); v != nil {
+		t.Fatalf("Got [%v], but want nil on Find(%q, %q))", v, a1.Network(), a1)
+	}
+	if l := set.List(); len(l) != 1 || l[0] != vf1 {
+		t.Errorf("Unexpected list of VIFs: %v", l)
+	}
+
+	set.Insert(vf2)
+	if v := set.Find(a2.Network(), a2.String()); v != nil {
+		t.Fatalf("Got [%v], but want nil on Find(%q, %q))", v, a2.Network(), a2)
+	}
+	if l := set.List(); len(l) != 2 || l[0] != vf1 || l[1] != vf2 {
+		t.Errorf("Unexpected list of VIFs: %v", l)
+	}
+
+	set.Delete(vf1)
+	if l := set.List(); len(l) != 1 || l[0] != vf2 {
+		t.Errorf("Unexpected list of VIFs: %v", l)
+	}
+	set.Delete(vf2)
+	if l := set.List(); len(l) != 0 {
+		t.Errorf("Unexpected list of VIFs: %v", l)
 	}
 }
 
-func newVIF(t *testing.T) *vif.VIF {
-	_, conn := net.Pipe()
-	vif, err := vif.InternalNewAcceptedVIF(conn, naming.FixedRoutingID(2), nil)
+func TestSetInsertDelete(t *testing.T) {
+	c1, s1 := net.Pipe()
+	c2, s2 := net.Pipe()
+	vf1, _, err := newVIF(c1, s1)
 	if err != nil {
-		t.Errorf("vif.InternalNewAcceptedVIF failed: %v", err)
+		t.Fatal(err)
 	}
-	return vif
-}
+	vf2, _, err := newVIF(c2, s2)
+	if err != nil {
+		t.Fatal(err)
+	}
 
-func TestAddRemoveVIF(t *testing.T) {
 	set1 := vif.NewSet()
 	set2 := vif.NewSet()
-	vif1 := newVIF(t)
-	vif2 := newVIF(t)
 
-	set1.Insert(vif1)
-	if l := set1.List(); len(l) != 1 || l[0] != vif1 {
+	set1.Insert(vf1)
+	if l := set1.List(); len(l) != 1 || l[0] != vf1 {
 		t.Errorf("Unexpected list of VIFs: %v", l)
 	}
-	set1.Insert(vif2)
-	if l := set1.List(); len(l) != 2 || l[0] != vif1 || l[1] != vif2 {
+	set1.Insert(vf2)
+	if l := set1.List(); len(l) != 2 || l[0] != vf1 || l[1] != vf2 {
 		t.Errorf("Unexpected list of VIFs: %v", l)
 	}
 
-	set2.Insert(vif1)
-	set2.Insert(vif2)
+	set2.Insert(vf1)
+	set2.Insert(vf2)
 
-	set1.Delete(vif1)
-	if l := set1.List(); len(l) != 1 || l[0] != vif2 {
+	set1.Delete(vf1)
+	if l := set1.List(); len(l) != 1 || l[0] != vf2 {
+		t.Errorf("Unexpected list of VIFs: %v", l)
+	}
+	if l := set2.List(); len(l) != 2 || l[0] != vf1 || l[1] != vf2 {
 		t.Errorf("Unexpected list of VIFs: %v", l)
 	}
 
-	vif1.Close()
-	if l := set1.List(); len(l) != 1 || l[0] != vif2 {
+	vf1.Close()
+	if l := set1.List(); len(l) != 1 || l[0] != vf2 {
 		t.Errorf("Unexpected list of VIFs: %v", l)
 	}
-	if l := set2.List(); len(l) != 1 || l[0] != vif2 {
+	if l := set2.List(); len(l) != 1 || l[0] != vf2 {
 		t.Errorf("Unexpected list of VIFs: %v", l)
 	}
 
-	vif2.Close()
+	vf2.Close()
 	if l := set1.List(); len(l) != 0 {
 		t.Errorf("Unexpected list of VIFs: %v", l)
 	}