Esempio n. 1
0
// Tests an n-node system
func TestPropagate(t *testing.T) {
	for _, nbrNodes := range []int{3, 10, 14} {
		local := sda.NewLocalTest()
		_, el, _ := local.GenTree(nbrNodes, false, true, true)
		o := local.Overlays[el.List[0].ID]

		i := 0
		msg := &PropagateMsg{[]byte("propagate")}

		tree := el.GenerateNaryTreeWithRoot(8, o.ServerIdentity())
		log.Lvl2("Starting to propagate", reflect.TypeOf(msg))
		pi, err := o.CreateProtocolSDA(tree, "Propagate")
		log.ErrFatal(err)
		nodes, err := propagateStartAndWait(pi, msg, 1000,
			func(m network.Body) {
				if bytes.Equal(msg.Data, m.(*PropagateMsg).Data) {
					i++
				} else {
					t.Error("Didn't receive correct data")
				}
			})
		log.ErrFatal(err)
		if i != 1 {
			t.Fatal("Didn't get data-request")
		}
		if nodes != nbrNodes {
			t.Fatal("Not all nodes replied")
		}
		local.CloseAll()
	}
}
Esempio n. 2
0
func (s *simpleService) ProcessClientRequest(e *network.ServerIdentity, r *sda.ClientRequest) {
	msgT, pm, err := network.UnmarshalRegisteredType(r.Data, network.DefaultConstructors(network.Suite))
	log.ErrFatal(err)
	if msgT != simpleRequestType {
		return
	}
	req := pm.(simpleRequest)
	tree := req.ServerIdentities.GenerateBinaryTree()
	tni := s.ctx.NewTreeNodeInstance(tree, tree.Root, "BackForth")
	proto, err := newBackForthProtocolRoot(tni, req.Val, func(n int) {
		if err := s.ctx.SendRaw(e, &simpleResponse{
			Val: n,
		}); err != nil {
			log.Error(err)
		}
	})
	if err != nil {
		log.Error(err)
		return
	}
	if err := s.ctx.RegisterProtocolInstance(proto); err != nil {
		log.Error(err)
	}
	go proto.Start()
}
Esempio n. 3
0
func TestClient_Send(t *testing.T) {
	local := sda.NewLocalTest()
	defer local.CloseAll()

	// register service
	sda.RegisterNewService("BackForth", func(c *sda.Context, path string) sda.Service {
		return &simpleService{
			ctx: c,
		}
	})
	// create hosts
	hosts, el, _ := local.GenTree(4, true, true, false)
	client := sda.NewClient("BackForth")

	r := &simpleRequest{
		ServerIdentities: el,
		Val:              10,
	}
	nm, err := client.Send(hosts[0].ServerIdentity, r)
	log.ErrFatal(err)

	assert.Equal(t, nm.MsgType, simpleResponseType)
	resp := nm.Msg.(simpleResponse)
	assert.Equal(t, resp.Val, 10)
}
Esempio n. 4
0
func TestProcessor_GetReply(t *testing.T) {
	defer log.AfterTest(t)
	p := NewServiceProcessor(nil)
	log.ErrFatal(p.RegisterMessage(procMsg))

	pair := config.NewKeyPair(network.Suite)
	e := network.NewServerIdentity(pair.Public, "")

	rep := p.GetReply(e, mkClientRequest(&testMsg{11}))
	val, ok := rep.(*testMsg)
	if !ok {
		t.Fatalf("Couldn't cast reply to testMsg: %+v", rep)
	}
	if val.I != 11 {
		t.Fatal("Value got lost - should be 11")
	}

	rep = p.GetReply(e, mkClientRequest(&testMsg{42}))
	errMsg, ok := rep.(*StatusRet)
	if !ok {
		t.Fatal("42 should return an error")
	}
	if errMsg.Status == "" {
		t.Fatal("The error should be non-empty")
	}
}
Esempio n. 5
0
func TestProcessor_AddMessage(t *testing.T) {
	defer log.AfterTest(t)
	p := NewServiceProcessor(nil)
	log.ErrFatal(p.RegisterMessage(procMsg))
	if len(p.functions) != 1 {
		t.Fatal("Should have registered one function")
	}
	mt := network.TypeFromData(&testMsg{})
	if mt == network.ErrorType {
		t.Fatal("Didn't register message-type correctly")
	}
	var wrongFunctions = []interface{}{
		procMsgWrong1,
		procMsgWrong2,
		procMsgWrong3,
		procMsgWrong4,
		procMsgWrong5,
		procMsgWrong6,
	}
	for _, f := range wrongFunctions {
		log.Lvl2("Checking function", reflect.TypeOf(f).String())
		err := p.RegisterMessage(f)
		if err == nil {
			t.Fatalf("Shouldn't accept function %+s", reflect.TypeOf(f).String())
		}
	}
}
Esempio n. 6
0
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)
}
Esempio n. 7
0
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))
}
Esempio n. 8
0
func TestReadGroupDescToml(t *testing.T) {
	group, err := ReadGroupDescToml(strings.NewReader(serverGroup))
	log.ErrFatal(err)

	if len(group.Roster.List) != 2 {
		t.Fatal("Should have 2 ServerIdentities")
	}
	if len(group.description) != 2 {
		t.Fatal("Should have 2 descriptions")
	}
	if group.description[group.Roster.List[1]] != "Ismail's server" {
		t.Fatal("This should be Ismail's server")
	}
}
Esempio n. 9
0
// 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)
}
Esempio n. 10
0
func TestLoadSave(t *testing.T) {
	defer log.AfterTest(t)
	log.TestOutput(testing.Verbose(), 4)
	sc, _, err := createBFTree(7, 2)
	if err != nil {
		t.Fatal(err)
	}
	dir, err := ioutil.TempDir("", "example")
	log.ErrFatal(err)
	defer os.RemoveAll(dir)
	sc.Save(dir)
	sc2, err := sda.LoadSimulationConfig(dir, "local1:2000")
	if err != nil {
		t.Fatal(err)
	}
	if sc2[0].Tree.ID != sc.Tree.ID {
		t.Fatal("Tree-id is not correct")
	}
}
Esempio n. 11
0
func TestMultipleInstances(t *testing.T) {
	defer log.AfterTest(t)

	log.TestOutput(testing.Verbose(), 4)
	sc, _, err := createBFTree(7, 2)
	if err != nil {
		t.Fatal(err)
	}
	dir, err := ioutil.TempDir("", "example")
	log.ErrFatal(err)
	defer os.RemoveAll(dir)
	sc.Save(dir)
	sc2, err := sda.LoadSimulationConfig(dir, "local1")
	if err != nil {
		t.Fatal(err)
	}
	if len(sc2) != 4 {
		t.Fatal("We should have 4 local1-hosts but have", len(sc2))
	}
	if sc2[0].Host.ServerIdentity.ID == sc2[1].Host.ServerIdentity.ID {
		t.Fatal("Hosts are not copies")
	}
}
Esempio n. 12
0
func TestClient_Parallel(t *testing.T) {
	nbrNodes := 2
	nbrParallel := 2
	local := sda.NewLocalTest()
	defer local.CloseAll()

	// register service
	sda.RegisterNewService("BackForth", func(c *sda.Context, path string) sda.Service {
		return &simpleService{
			ctx: c,
		}
	})
	// create hosts
	hosts, el, _ := local.GenTree(nbrNodes, true, true, false)

	wg := sync.WaitGroup{}
	wg.Add(nbrParallel)
	for i := 0; i < nbrParallel; i++ {
		go func(i int) {
			log.Lvl1("Starting message", i)
			r := &simpleRequest{
				ServerIdentities: el,
				Val:              10 * i,
			}
			client := sda.NewClient("BackForth")
			nm, err := client.Send(hosts[0].ServerIdentity, r)
			log.ErrFatal(err)

			assert.Equal(t, nm.MsgType, simpleResponseType)
			resp := nm.Msg.(simpleResponse)
			assert.Equal(t, resp.Val, 10*i)
			log.Lvl1("Done with message", i)
			wg.Done()
		}(i)
	}
	wg.Wait()
}
Esempio n. 13
0
// 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)
}
Esempio n. 14
0
func mkClientRequest(msg network.Body) []byte {
	b, err := network.MarshalRegisteredType(msg)
	log.ErrFatal(err)
	return b
}