// Test closing and opening of Host on same address func TestHostClose(t *testing.T) { defer log.AfterTest(t) time.Sleep(time.Second) h1 := sda.NewLocalHost(2000) h2 := sda.NewLocalHost(2001) h1.ListenAndBind() _, err := h2.Connect(h1.ServerIdentity) if err != nil { t.Fatal("Couldn't Connect()", err) } err = h1.Close() if err != nil { t.Fatal("Couldn't close:", err) } err = h2.Close() if err != nil { t.Fatal("Couldn't close:", err) } log.Lvl3("Finished first connection, starting 2nd") h3 := sda.NewLocalHost(2002) h3.ListenAndBind() c, err := h2.Connect(h3.ServerIdentity) if err != nil { t.Fatal(h2, "Couldn Connect() to", h3) } log.Lvl3("Closing h3") err = h3.Close() if err != nil { // try closing the underlying connection manually and fail c.Close() t.Fatal("Couldn't Close()", h3) } }
func TestServiceProtocolProcessMessage(t *testing.T) { ds := &DummyService{ link: make(chan bool), } var count int sda.RegisterNewService("DummyService", func(c *sda.Context, path string) sda.Service { if count == 0 { count++ // the client does not need a Service return &DummyService{link: make(chan bool)} } ds.c = c ds.path = path ds.Config = DummyConfig{ Send: true, } return ds }) // fake a client h2 := sda.NewLocalHost(2010) defer h2.Close() host := sda.NewLocalHost(2000) host.ListenAndBind() host.StartProcessMessages() log.Lvl1("Host created and listening") defer host.Close() // create the entityList and tree el := sda.NewRoster([]*network.ServerIdentity{host.ServerIdentity}) tree := el.GenerateBinaryTree() // give it to the service ds.fakeTree = tree // Send a request to the service b, err := network.MarshalRegisteredType(&DummyMsg{10}) log.ErrFatal(err) re := &sda.ClientRequest{ Service: sda.ServiceFactory.ServiceID("DummyService"), Data: b, } log.Lvl1("Client connecting to host") if _, err := h2.Connect(host.ServerIdentity); err != nil { t.Fatal(err) } log.Lvl1("Sending request to service...") if err := h2.SendRaw(host.ServerIdentity, re); err != nil { t.Fatal(err) } // wait for the link from the protocol waitOrFatalValue(ds.link, true, t) // now wait for the same link as the protocol should have sent a message to // himself ! waitOrFatalValue(ds.link, true, t) }
// Test if a request that makes the service create a new protocol works func TestServiceRequestNewProtocol(t *testing.T) { ds := &DummyService{ link: make(chan bool), } sda.RegisterNewService("DummyService", func(c *sda.Context, path string) sda.Service { ds.c = c ds.path = path return ds }) host := sda.NewLocalHost(2000) host.Listen() host.StartProcessMessages() log.Lvl1("Host created and listening") defer host.Close() // create the entityList and tree el := sda.NewRoster([]*network.ServerIdentity{host.ServerIdentity}) tree := el.GenerateBinaryTree() // give it to the service ds.fakeTree = tree // Send a request to the service b, err := network.MarshalRegisteredType(&DummyMsg{10}) log.ErrFatal(err) re := &sda.ClientRequest{ Service: sda.ServiceFactory.ServiceID("DummyService"), Data: b, } // fake a client h2 := sda.NewLocalHost(2010) defer h2.Close() log.Lvl1("Client connecting to host") if _, err := h2.Connect(host.ServerIdentity); err != nil { t.Fatal(err) } log.Lvl1("Sending request to service...") if err := h2.SendRaw(host.ServerIdentity, re); err != nil { t.Fatal(err) } // wait for the link from the waitOrFatalValue(ds.link, true, t) // Now RESEND the value so we instantiate using the SAME TREENODE log.Lvl1("Sending request AGAIN to service...") if err := h2.SendRaw(host.ServerIdentity, re); err != nil { t.Fatal(err) } // wait for the link from the // NOW expect false waitOrFatalValue(ds.link, false, t) }
func TestServiceProcessServiceMessage(t *testing.T) { ds1 := &DummyService{ link: make(chan bool), } ds2 := &DummyService{ link: make(chan bool), } var count int sda.RegisterNewService("DummyService", func(c *sda.Context, path string) sda.Service { var s *DummyService if count == 0 { s = ds1 } else { s = ds2 } s.c = c s.path = path return s }) // create two hosts h2 := sda.NewLocalHost(2010) defer h2.Close() h1 := sda.NewLocalHost(2000) h1.ListenAndBind() h1.StartProcessMessages() defer h1.Close() log.Lvl1("Host created and listening") // connect themselves log.Lvl1("Client connecting to host") if _, err := h2.Connect(h1.ServerIdentity); err != nil { t.Fatal(err) } // create request m, err := sda.CreateServiceMessage("DummyService", &DummyMsg{10}) assert.Nil(t, err) log.Lvl1("Sending request to service...") assert.Nil(t, h2.SendRaw(h1.ServerIdentity, m)) // wait for the link from the Service on host 1 waitOrFatalValue(ds1.link, true, t) }
// Test the automatic connection upon request func TestAutoConnection(t *testing.T) { defer log.AfterTest(t) h1 := sda.NewLocalHost(2000) h2 := sda.NewLocalHost(2001) h2.ListenAndBind() defer h1.Close() defer h2.Close() err := h1.SendRaw(h2.ServerIdentity, &SimpleMessage{12}) if err != nil { t.Fatal("Couldn't send message:", err) } // Receive the message msg := h2.Receive() if msg.Msg.(SimpleMessage).I != 12 { t.Fatal("Simple message got distorted") } }
// Test setting up of Host func TestHostNew(t *testing.T) { defer log.AfterTest(t) h1 := sda.NewLocalHost(2000) if h1 == nil { t.Fatal("Couldn't setup a Host") } err := h1.Close() if err != nil { t.Fatal("Couldn't close", err) } }
func TestServiceProcessRequest(t *testing.T) { ds := &DummyService{ link: make(chan bool), } sda.RegisterNewService("DummyService", func(c *sda.Context, path string) sda.Service { ds.c = c ds.path = path return ds }) host := sda.NewLocalHost(2000) host.Listen() host.StartProcessMessages() log.Lvl1("Host created and listening") defer host.Close() // Send a request to the service re := &sda.ClientRequest{ Service: sda.ServiceFactory.ServiceID("DummyService"), Data: []byte("a"), } // fake a client h2 := sda.NewLocalHost(2010) defer h2.Close() log.Lvl1("Client connecting to host") if _, err := h2.Connect(host.ServerIdentity); err != nil { t.Fatal(err) } log.Lvl1("Sending request to service...") if err := h2.SendRaw(host.ServerIdentity, re); err != nil { t.Fatal(err) } // wait for the link select { case v := <-ds.link: if v { t.Fatal("was expecting false !") } case <-time.After(100 * time.Millisecond): t.Fatal("Too late") } }
func TestReconnection(t *testing.T) { defer log.AfterTest(t) h1 := sda.NewLocalHost(2000) h2 := sda.NewLocalHost(2001) defer h1.Close() defer h2.Close() h1.ListenAndBind() h2.ListenAndBind() log.Lvl1("Sending h1->h2") log.ErrFatal(sendrcv(h1, h2)) log.Lvl1("Sending h2->h1") log.ErrFatal(sendrcv(h2, h1)) log.Lvl1("Closing h1") h1.CloseConnections() log.Lvl1("Listening again on h1") h1.ListenAndBind() log.Lvl1("Sending h2->h1") log.ErrFatal(sendrcv(h2, h1)) log.Lvl1("Sending h1->h2") log.ErrFatal(sendrcv(h1, h2)) log.Lvl1("Shutting down listener of h2") // closing h2, but simulate *hard* failure, without sending a FIN packet c2 := h1.Connection(h2.ServerIdentity) // making h2 fails h2.AbortConnections() log.Lvl1("asking h2 to listen again") // making h2 backup again h2.ListenAndBind() // and re-registering the connection to h2 from h1 h1.RegisterConnection(h2.ServerIdentity, c2) log.Lvl1("Sending h1->h2") log.ErrFatal(sendrcv(h1, h2)) }
func TestServiceNew(t *testing.T) { ds := &DummyService{ link: make(chan bool), } sda.RegisterNewService("DummyService", func(c *sda.Context, path string) sda.Service { ds.c = c ds.path = path ds.link <- true return ds }) go func() { h := sda.NewLocalHost(2000) h.Close() }() waitOrFatal(ds.link, t) }
func TestOverlayDone(t *testing.T) { defer log.AfterTest(t) log.TestOutput(testing.Verbose(), 4) // setup h1 := sda.NewLocalHost(2000) defer h1.Close() fn := func(n *sda.TreeNodeInstance) (sda.ProtocolInstance, error) { ps := ProtocolOverlay{ TreeNodeInstance: n, } return &ps, nil } el := sda.NewRoster([]*network.ServerIdentity{h1.ServerIdentity}) h1.AddRoster(el) tree := el.GenerateBinaryTree() h1.AddTree(tree) sda.ProtocolRegisterName("ProtocolOverlay", fn) p, err := h1.CreateProtocol("ProtocolOverlay", tree) if err != nil { t.Fatal("error starting new node", err) } po := p.(*ProtocolOverlay) // release the resources var count int po.OnDoneCallback(func() bool { count++ if count >= 2 { return true } return false }) po.Release() overlay := h1.Overlay() if _, ok := overlay.TokenToNode(po.Token()); !ok { t.Fatal("Node should exists after first call Done()") } po.Release() if _, ok := overlay.TokenToNode(po.Token()); ok { t.Fatal("Node should NOT exists after call Done()") } }
// test for calling the NewProtocol method on a remote Service func TestServiceNewProtocol(t *testing.T) { ds1 := &DummyService{ link: make(chan bool), Config: DummyConfig{ Send: true, }, } ds2 := &DummyService{ link: make(chan bool), } var count int sda.RegisterNewService("DummyService", func(c *sda.Context, path string) sda.Service { var localDs *DummyService switch count { case 2: // the client does not need a Service return &DummyService{link: make(chan bool)} case 1: // children localDs = ds2 case 0: // root localDs = ds1 } localDs.c = c localDs.path = path count++ return localDs }) host := sda.NewLocalHost(2000) host.ListenAndBind() host.StartProcessMessages() log.Lvl1("Host created and listening") defer host.Close() host2 := sda.NewLocalHost(2002) host2.ListenAndBind() host2.StartProcessMessages() defer host2.Close() // create the entityList and tree el := sda.NewRoster([]*network.ServerIdentity{host.ServerIdentity, host2.ServerIdentity}) tree := el.GenerateBinaryTree() // give it to the service ds1.fakeTree = tree // Send a request to the service b, err := network.MarshalRegisteredType(&DummyMsg{10}) log.ErrFatal(err) re := &sda.ClientRequest{ Service: sda.ServiceFactory.ServiceID("DummyService"), Data: b, } // fake a client client := sda.NewLocalHost(2010) defer client.Close() log.Lvl1("Client connecting to host") if _, err := client.Connect(host.ServerIdentity); err != nil { t.Fatal(err) } log.Lvl1("Sending request to service...") if err := client.SendRaw(host.ServerIdentity, re); err != nil { t.Fatal(err) } // wait for the link from the protocol that Starts waitOrFatalValue(ds1.link, true, t) // now wait for the same link as the protocol should have sent a message to // himself ! waitOrFatalValue(ds1.link, true, t) // now wait for the SECOND LINK on the SECOND HOST that the SECOND SERVICE // should have started (ds2) in ProcessRequest waitOrFatalValue(ds2.link, true, t) }