func reflector(t *testing.T, s *zmq.Socket, n int, wg *sync.WaitGroup) chan bool {
	s.SetRcvtimeo(time.Second)
	s.SetSndtimeo(time.Second)
	svcrouter.Barrier()
	wg.Add(1)
	c := make(chan bool)
	go func() {
		/* this is a nasty hack but is OK for a test program I guess */
		for {
			if msg, err := s.RecvMessageBytes(0); err == nil {
				svcrouter.DumpMsg(fmt.Sprintf("reflector %d", n), msg)
				if _, err := s.SendMessage(msg); err != nil {
					wg.Done()
					t.Fatal(err)
					return
				}
			}
			select {
			case <-c:
				wg.Done()
				return
			default:
			}
		}
	}()
	return c
}
Beispiel #2
0
func TestServiceRouter(t *testing.T) {

	numPeers := 50
	numServices := 100

	var c *zmq.Context
	var m *Mirror
	var socks []*zmq.Socket = make([]*zmq.Socket, numPeers)
	var addr []string = make([]string, numPeers)
	var err error

	defer func() {
		for _, s := range socks {
			if s != nil {
				s.Close()
			}
		}
		if m != nil {
			m.Close()
		}
		if c != nil {
			c.Term()
		}
	}()

	if c, err = zmq.NewContext(); err != nil {
		t.Fatalf("Failed to create ZMQ context: %v", err)
	}

	if m, err = NewMirror(t, c, 1); err != nil {
		t.Fatalf("Failed to create a new mirror: %v", err)
	}

	for np := 0; np < numPeers; np++ {
		if socks[np], addr[np], err = svcrouter.NewHalfPair(c, true); err != nil {
			t.Fatalf("Failed to create half pair A: %v", err)
		}

		if err = m.AddPeer(svcrouter.PeerDefinition{
			Name:     dummyPeerName(np),
			ZmqType:  zmq.PAIR,
			Address:  addr[np],
			Bind:     false,
			PeerImpl: &MirrorPeerImpl{},
		}); err != nil {
			t.Fatalf("Could not add peer %d: %v", np, err)
		}
	}

	svcrouter.Barrier()

	r := svcrouter.NewServiceRouter()

	t.Log("Adding by Peer/Service")

	for np := 0; np < numPeers; np++ {
		peerName := dummyPeerName(np)
		for ns := 0; ns < numServices; ns++ {
			serviceType, serviceId := dummyServiceName(ns)
			e := svcrouter.NewEndpointEnvelope(serviceType, serviceId, "")
			if err := r.AddService(m.RouterElement, peerName, e); err != nil {
				t.Fatalf("Could not add service %d to peer %d: %v", ns, np, err)
			}
		}
	}
	if err := r.Validate(); err != nil {
		t.Fatalf("Failed validation 1: %v", err)
	}

	for np := 0; np < numPeers; np++ {
		peerName := dummyPeerName(np)
		if l := r.LenPeerEntries(m.RouterElement, peerName); l != numServices {
			t.Fatalf("Peer %d has service element mismatch: %d != %d", l, numServices)
		}
	}

	t.Log("Removing by Service/Peer")

	for ns := 0; ns < numServices; ns++ {
		serviceType, serviceId := dummyServiceName(ns)
		for np := 0; np < numPeers; np++ {
			peerName := dummyPeerName(np)
			e := svcrouter.NewEndpointEnvelope(serviceType, serviceId, "")
			if err := r.DeleteService(m.RouterElement, peerName, e); err != nil {
				t.Fatalf("Could not delete service %d to peer %d: %v", ns, np, err)
			}
		}

		if ns%(numServices/10) == 0 {
			if err := r.Validate(); err != nil {
				t.Fatalf("Failed validation 2: %v", err)
			}
		}

	}

	for np := 0; np < numPeers; np++ {
		peerName := dummyPeerName(np)
		if l := r.LenPeerEntries(m.RouterElement, peerName); l != 0 {
			t.Fatalf("Peer %d has service element mismatch: %d != 0", l)
		}
	}

	if err := r.Validate(); err != nil {
		t.Fatalf("Failed validation 3: %v", err)
	}

	t.Log("Adding by Service/Peer")

	for ns := 0; ns < numServices; ns++ {
		serviceType, serviceId := dummyServiceName(ns)
		for np := 0; np < numPeers; np++ {
			peerName := dummyPeerName(np)
			e := svcrouter.NewEndpointEnvelope(serviceType, serviceId, "")
			if err := r.AddService(m.RouterElement, peerName, e); err != nil {
				t.Fatalf("Could not add service %d to peer %d: %v", ns, np, err)
			}
		}
	}

	if err := r.Validate(); err != nil {
		t.Fatalf("Failed validation 4: %v", err)
	}

	for np := 0; np < numPeers; np++ {
		peerName := dummyPeerName(np)
		if l := r.LenPeerEntries(m.RouterElement, peerName); l != numServices {
			t.Fatalf("Peer %d has service element mismatch: %d != %d", l, numServices)
		}
	}

	t.Log("Removing by Peer/Service")

	for np := 0; np < numPeers; np++ {
		peerName := dummyPeerName(np)
		for ns := 0; ns < numServices; ns++ {
			serviceType, serviceId := dummyServiceName(ns)
			e := svcrouter.NewEndpointEnvelope(serviceType, serviceId, "")
			if err := r.DeleteService(m.RouterElement, peerName, e); err != nil {
				t.Fatalf("Could not delete service %d to peer %d: %v", ns, np, err)
			}
		}
		if np%10 == 0 {
			if err := r.Validate(); err != nil {
				t.Fatalf("Failed validation 5: %v", err)
			}
		}
	}

	if err := r.Validate(); err != nil {
		t.Fatalf("Failed validation 6: %v", err)
	}

	for np := 0; np < numPeers; np++ {
		peerName := dummyPeerName(np)
		if l := r.LenPeerEntries(m.RouterElement, peerName); l != 0 {
			t.Fatalf("Peer %d has service element mismatch: %d != 0", l)
		}
	}

	t.Log("Adding by Service/Peer")

	for ns := 0; ns < numServices; ns++ {
		serviceType, serviceId := dummyServiceName(ns)
		for np := 0; np < numPeers; np++ {
			peerName := dummyPeerName(np)
			e := svcrouter.NewEndpointEnvelope(serviceType, serviceId, "")
			if err := r.AddService(m.RouterElement, peerName, e); err != nil {
				t.Fatalf("Could not add service %d to peer %d: %v", ns, np, err)
			}
		}
	}

	if err := r.Validate(); err != nil {
		t.Fatalf("Failed validation 7: %v", err)
	}

	for it := 0; it < 10; it++ {
		// How exciting. Let's try some routing!
		serviceType, serviceId := dummyServiceName(0)
		d := make(map[string]int, numPeers)
		for np := 0; np < numPeers; np++ {
			se := r.GetServerEntry(serviceType, serviceId, "")
			d[se.Peer.Name] += 1
		}
		if len(d) != numPeers {
			t.Fatalf("Failed load balance test 1")
		}
		for np := 0; np < numPeers; np++ {
			se := r.GetServerEntry(serviceType, serviceId, "")
			if d[se.Peer.Name] != 1 {
				t.Fatalf("Failed load balance test 2")
			}
			d[se.Peer.Name] += 1
		}
		if len(d) != numPeers {
			t.Fatalf("Failed load balance test 3")
		}
	}

	for np := 0; np < numPeers; np++ {
		peerName := dummyPeerName(np)
		if l := r.LenPeerEntries(m.RouterElement, peerName); l != numServices {
			t.Fatalf("Peer %d has service element mismatch: %d != %d", l, numServices)
		}
	}

	t.Log("Removing by Peer (all entries)")

	for np := 0; np < numPeers; np++ {
		peerName := dummyPeerName(np)
		if err := r.DeleteAllPeerEntries(m.RouterElement, peerName); err != nil {
			t.Fatalf("Could not add delete all services from peer %d: %v", np, err)
		}
	}

	for np := 0; np < numPeers; np++ {
		peerName := dummyPeerName(np)
		if l := r.LenPeerEntries(m.RouterElement, peerName); l != 0 {
			t.Fatalf("Peer %d has service element mismatch: %d != 0", l)
		}
	}

	if err := r.Validate(); err != nil {
		t.Fatalf("Failed validation final: %v", err)
	}

}
Beispiel #3
0
func TestRouterElement(t *testing.T) {
	var c *zmq.Context
	var m *Mirror
	var sa, sb *zmq.Socket
	var err error
	var addra string
	var addrb string

	defer func() {
		if sa != nil {
			sa.Close()
		}
		if sb != nil {
			sb.Close()
		}
		if m != nil {
			m.Close()
		}
		if c != nil {
			c.Term()
		}
	}()

	if c, err = zmq.NewContext(); err != nil {
		t.Fatalf("Failed to create ZMQ context: %v", err)
	}

	if m, err = NewMirror(t, c, 1); err != nil {
		t.Fatalf("Failed to create a new mirror: %v", err)
	}

	if sa, addra, err = svcrouter.NewHalfPair(c, true); err != nil {
		t.Fatalf("Failed to create half pair A: %v", err)
	}

	if sb, addrb, err = svcrouter.NewHalfPair(c, true); err != nil {
		t.Fatalf("Failed to create half pair B: %v", err)
	}

	if err = m.AddPeer(svcrouter.PeerDefinition{
		Name:     "ab",
		ZmqType:  zmq.PAIR,
		Address:  addra,
		Bind:     false,
		PeerImpl: &MirrorPeerImpl{},
	}); err != nil {
		t.Fatalf("Could not add peer A: %v", err)
	}

	if err = m.AddPeer(svcrouter.PeerDefinition{
		Name:     "ba",
		ZmqType:  zmq.PAIR,
		Address:  addrb,
		Bind:     false,
		PeerImpl: &MirrorPeerImpl{},
	}); err != nil {
		t.Fatalf("Could not add peer B: %v", err)
	}

	svcrouter.Barrier()

	num := 100
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()
		for i := 0; i < num; i++ {
			if _, err := sb.RecvMessage(0); err != nil {
				t.Fatalf("sb receive error: %v", err)
			}
		}
	}()

	msg := [][]byte{[]byte("Hello"), []byte("World")}

	for i := 0; i < num; i++ {
		if _, err := sa.SendMessage(msg); err != nil {
			t.Fatalf("sa send error: %v", err)
		}
	}
	wg.Wait()
}
func TestServiceDispatcher(t *testing.T) {
	numPeers := 10
	numServices := 10

	var c *zmq.Context
	var sd *svcrouter.ServiceDispatcher
	var socks []*zmq.Socket = make([]*zmq.Socket, numPeers)
	var addr []string = make([]string, numPeers)
	var killReflectors []chan bool = make([]chan bool, numPeers)
	var err error
	var wg sync.WaitGroup

	defer func() {
		for _, s := range socks {
			if s != nil {
				s.Close()
			}
		}
		if sd != nil {
			sd.Close()
		}
		if c != nil {
			c.Term()
		}
	}()

	if c, err = zmq.NewContext(); err != nil {
		t.Fatalf("Failed to create ZMQ context: %v", err)
	}

	if sd, err = svcrouter.NewServiceDispatcher(c, 1); err != nil {
		t.Fatalf("Failed to create a new service dispatcher: %v", err)
	}

	sd.NoEnvRouterPeer = dummyPeerName(0)
	sd.EnvRouterPeer = dummyPeerName(2)

	for np := 0; np < numPeers; np++ {
		if np%2 == 0 {
			name := fmt.Sprintf("C%04d st=ST%d si=x", np, (np/2)%2)
			if socks[np], addr[np], err = svcrouter.NewSocketAndAddress(c, true, zmq.REQ, name); err != nil {
				t.Fatalf("Failed to create half pair A: %v", err)
			}
			if err = sd.AddPeer(svcrouter.PeerDefinition{
				Name:    dummyPeerName(np),
				ZmqType: zmq.ROUTER,
				Address: addr[np],
				Bind:    false,
			}, svcrouter.PT_CLIENTSNOENV); err != nil {
				t.Fatalf("Could not add peer %d: %v", np, err)
			}
		} else {
			name := fmt.Sprintf("C%04d st=ST%d si=x", np, ((np-1)/2)%2)
			if socks[np], addr[np], err = svcrouter.NewSocketAndAddress(c, true, zmq.REP, name); err != nil {
				t.Fatalf("Failed to create half pair A: %v", err)
			}
			if err = sd.AddPeer(svcrouter.PeerDefinition{
				Name:    dummyPeerName(np),
				ZmqType: zmq.DEALER,
				Address: addr[np],
				Bind:    false,
			}, svcrouter.PT_DOWNSTREAMENVREP); err != nil {
				t.Fatalf("Could not add peer %d: %v", np, err)
			}
			killReflectors[np] = reflector(t, socks[np], np, &wg)
		}
	}

	svcrouter.Barrier()

	for np := 1; np < numPeers; np += 2 {
		for ns := 0; ns < numServices; ns++ {
			serviceType := fmt.Sprintf("ST%d", ns)
			serviceId := "x"
			e := svcrouter.NewEndpointEnvelope(serviceType, serviceId, "")
			if err := sd.AddService(sd.RouterElement, dummyPeerName(np), e); err != nil {
				t.Fatalf("Could not add service %d to peer %d: %v", ns, np, err)
			}
		}
	}

	msg := [][]byte{[]byte("Hello"), []byte("World")}

	for it := 0; it < 2; it++ {
		if _, err := socks[0].SendMessage(msg); err != nil {
			t.Fatalf("socks send error: %v", err)
		}
		if msg2, err := socks[0].RecvMessageBytes(0); err != nil {
			t.Fatalf("socks receive error: %v", err)
		} else {
			svcrouter.DumpMsg("FINAL", msg2)
			if !msgEqual(msg, msg2) {
				t.Fatalf("socks messages differ")
			}
		}
	}

	for _, v := range killReflectors {
		if v != nil {
			close(v)
		}
	}
	wg.Wait()

}