Example #1
0
func TestPeer(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	type testStruct struct {
		msg                string
		pid                PeerIdentifier
		agent              transport.Agent
		appliedFunc        func(*Peer)
		expectedIdentifier string
		expectedHostPort   string
		expectedStatus     transport.PeerStatus
		expectedAgent      transport.Agent
	}
	tests := []testStruct{
		func() (s testStruct) {
			s.msg = "create"
			s.pid = PeerIdentifier("localhost:12345")
			s.agent = transporttest.NewMockAgent(mockCtrl)

			s.appliedFunc = func(p *Peer) {}

			s.expectedIdentifier = "localhost:12345"
			s.expectedHostPort = "localhost:12345"
			s.expectedAgent = s.agent
			s.expectedStatus = transport.PeerStatus{
				PendingRequestCount: 0,
				ConnectionStatus:    transport.PeerUnavailable,
			}
			return
		}(),
		func() (s testStruct) {
			s.msg = "start request"
			agent := transporttest.NewMockAgent(mockCtrl)
			agent.EXPECT().NotifyStatusChanged(gomock.Any()).Times(1)
			s.agent = agent

			s.appliedFunc = func(p *Peer) {
				p.StartRequest()
			}

			s.expectedAgent = s.agent
			s.expectedStatus = transport.PeerStatus{
				PendingRequestCount: 1,
				ConnectionStatus:    transport.PeerUnavailable,
			}
			return
		}(),
		func() (s testStruct) {
			s.msg = "start request stop request"
			agent := transporttest.NewMockAgent(mockCtrl)
			agent.EXPECT().NotifyStatusChanged(gomock.Any()).Times(2)
			s.agent = agent

			s.appliedFunc = func(p *Peer) {
				done := p.StartRequest()
				done()
			}

			s.expectedAgent = s.agent
			s.expectedStatus = transport.PeerStatus{
				PendingRequestCount: 0,
				ConnectionStatus:    transport.PeerUnavailable,
			}
			return
		}(),
		func() (s testStruct) {
			s.msg = "start 5 stop 2"
			agent := transporttest.NewMockAgent(mockCtrl)
			agent.EXPECT().NotifyStatusChanged(gomock.Any()).Times(7)
			s.agent = agent

			s.appliedFunc = func(p *Peer) {
				done1 := p.StartRequest()
				p.StartRequest()
				p.StartRequest()
				done2 := p.StartRequest()
				done1()
				p.StartRequest()
				done2()
			}

			s.expectedAgent = s.agent
			s.expectedStatus = transport.PeerStatus{
				PendingRequestCount: 3,
				ConnectionStatus:    transport.PeerUnavailable,
			}
			return
		}(),
		func() (s testStruct) {
			s.msg = "start 5 stop 5"
			agent := transporttest.NewMockAgent(mockCtrl)
			agent.EXPECT().NotifyStatusChanged(gomock.Any()).Times(10)
			s.agent = agent

			s.appliedFunc = func(p *Peer) {
				for i := 0; i < 5; i++ {
					done := p.StartRequest()
					defer done()
				}
			}

			s.expectedAgent = s.agent
			s.expectedStatus = transport.PeerStatus{
				PendingRequestCount: 0,
				ConnectionStatus:    transport.PeerUnavailable,
			}
			return
		}(),
		func() (s testStruct) {
			s.msg = "set status"

			s.appliedFunc = func(p *Peer) {
				p.SetStatus(transport.PeerAvailable)
			}

			s.expectedStatus = transport.PeerStatus{
				PendingRequestCount: 0,
				ConnectionStatus:    transport.PeerAvailable,
			}
			return
		}(),
	}

	for _, tt := range tests {
		if tt.pid == PeerIdentifier("") {
			tt.pid = PeerIdentifier("localhost:12345")
			tt.expectedIdentifier = "localhost:12345"
			tt.expectedHostPort = "localhost:12345"
		}
		if tt.agent == nil {
			tt.agent = transporttest.NewMockAgent(mockCtrl)
			tt.expectedAgent = tt.agent
		}

		peer := NewPeer(tt.pid, tt.agent)

		tt.appliedFunc(peer)

		assert.Equal(t, tt.expectedIdentifier, peer.Identifier(), tt.msg)
		assert.Equal(t, tt.expectedHostPort, peer.HostPort(), tt.msg)
		assert.Equal(t, tt.expectedAgent, peer.Agent(), tt.msg)
		assert.Equal(t, tt.expectedStatus, peer.Status(), tt.msg)
	}
}
Example #2
0
func TestSingle(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	type expectedChooseResult struct {
		peer transport.Peer
		err  error
	}

	type testStruct struct {
		msg                   string
		pid                   transport.PeerIdentifier
		agent                 *transporttest.MockAgent
		appliedFunc           func(*single) error
		expectedPeerID        transport.PeerIdentifier
		expectedPeer          transport.Peer
		expectedAgent         transport.Agent
		expectedStarted       bool
		expectedErr           error
		expectedChooseResults []expectedChooseResult
	}
	tests := []testStruct{
		func() (s testStruct) {
			s.msg = "setup"
			s.pid = transporttest.NewMockPeerIdentifier(mockCtrl)
			s.agent = transporttest.NewMockAgent(mockCtrl)

			s.appliedFunc = func(pl *single) error {
				return nil
			}

			s.expectedPeerID = s.pid
			s.expectedAgent = s.agent
			s.expectedStarted = false
			return
		}(),
		func() (s testStruct) {
			s.msg = "stop before start"
			s.pid = transporttest.NewMockPeerIdentifier(mockCtrl)
			s.agent = transporttest.NewMockAgent(mockCtrl)

			s.appliedFunc = func(pl *single) error {
				return pl.Stop()
			}

			s.expectedErr = errors.ErrPeerListNotStarted("single")
			s.expectedPeerID = s.pid
			s.expectedAgent = s.agent
			s.expectedStarted = false
			return
		}(),
		func() (s testStruct) {
			s.msg = "choose before start"
			s.pid = transporttest.NewMockPeerIdentifier(mockCtrl)
			s.agent = transporttest.NewMockAgent(mockCtrl)

			s.appliedFunc = func(pl *single) error {
				return nil
			}

			s.expectedPeerID = s.pid
			s.expectedAgent = s.agent
			s.expectedStarted = false
			s.expectedChooseResults = []expectedChooseResult{{
				peer: nil,
				err:  errors.ErrPeerListNotStarted("single"),
			}}
			return
		}(),
		func() (s testStruct) {
			s.msg = "start and choose"
			s.pid = transporttest.NewMockPeerIdentifier(mockCtrl)
			s.agent = transporttest.NewMockAgent(mockCtrl)

			s.expectedPeer = transporttest.NewMockPeer(mockCtrl)
			s.agent.EXPECT().RetainPeer(s.pid, gomock.Any()).Return(s.expectedPeer, nil)

			s.appliedFunc = func(pl *single) error {
				return pl.Start()
			}

			s.expectedPeerID = s.pid
			s.expectedAgent = s.agent
			s.expectedStarted = true
			s.expectedChooseResults = []expectedChooseResult{{
				peer: s.expectedPeer,
				err:  nil,
			}}
			return
		}(),
		func() (s testStruct) {
			s.msg = "start with agent error"
			s.pid = transporttest.NewMockPeerIdentifier(mockCtrl)
			s.agent = transporttest.NewMockAgent(mockCtrl)

			s.expectedErr = fmt.Errorf("test error")
			s.agent.EXPECT().RetainPeer(s.pid, gomock.Any()).Return(nil, s.expectedErr)

			s.appliedFunc = func(pl *single) error {
				return pl.Start()
			}

			s.expectedPeerID = s.pid
			s.expectedAgent = s.agent
			s.expectedStarted = false
			return
		}(),
		func() (s testStruct) {
			s.msg = "start twice"
			s.pid = transporttest.NewMockPeerIdentifier(mockCtrl)
			s.agent = transporttest.NewMockAgent(mockCtrl)

			s.expectedPeer = transporttest.NewMockPeer(mockCtrl)
			s.agent.EXPECT().RetainPeer(s.pid, gomock.Any()).Return(s.expectedPeer, nil)

			s.appliedFunc = func(pl *single) error {
				pl.Start()
				return pl.Start()
			}

			s.expectedErr = errors.ErrPeerListAlreadyStarted("single")
			s.expectedPeerID = s.pid
			s.expectedAgent = s.agent
			s.expectedStarted = true
			return
		}(),
		func() (s testStruct) {
			s.msg = "start stop"
			s.pid = transporttest.NewMockPeerIdentifier(mockCtrl)
			s.agent = transporttest.NewMockAgent(mockCtrl)

			peer := transporttest.NewMockPeer(mockCtrl)
			s.agent.EXPECT().RetainPeer(s.pid, gomock.Any()).Return(peer, nil)
			s.agent.EXPECT().ReleasePeer(s.pid, gomock.Any()).Return(nil)

			s.appliedFunc = func(pl *single) error {
				err := pl.Start()
				if err != nil {
					return err
				}
				return pl.Stop()
			}

			s.expectedErr = nil
			s.expectedPeerID = s.pid
			s.expectedPeer = nil
			s.expectedAgent = s.agent
			s.expectedStarted = false
			return
		}(),
		func() (s testStruct) {
			s.msg = "start stop release failure"
			s.pid = transporttest.NewMockPeerIdentifier(mockCtrl)
			s.agent = transporttest.NewMockAgent(mockCtrl)

			s.expectedPeer = transporttest.NewMockPeer(mockCtrl)
			s.agent.EXPECT().RetainPeer(s.pid, gomock.Any()).Return(s.expectedPeer, nil)

			s.expectedErr = errors.ErrAgentHasNoReferenceToPeer{}
			s.agent.EXPECT().ReleasePeer(s.pid, gomock.Any()).Return(s.expectedErr)

			s.appliedFunc = func(pl *single) error {
				err := pl.Start()
				if err != nil {
					return err
				}
				return pl.Stop()
			}

			s.expectedPeerID = s.pid
			s.expectedAgent = s.agent
			s.expectedStarted = false
			return
		}(),
	}

	for _, tt := range tests {
		pl := NewSingle(tt.pid, tt.agent).(*single)

		err := tt.appliedFunc(pl)

		assert.Equal(t, tt.expectedErr, err, tt.msg)
		assert.Equal(t, tt.expectedAgent, pl.agent, tt.msg)
		assert.Equal(t, tt.expectedPeerID, pl.initialPeerID, tt.msg)
		assert.Equal(t, tt.expectedPeer, pl.peer, tt.msg)
		assert.Equal(t, tt.expectedStarted, pl.started, tt.msg)

		for _, expectedResult := range tt.expectedChooseResults {
			peer, err := pl.ChoosePeer(context.Background(), &transport.Request{})

			assert.Equal(t, expectedResult.peer, peer, tt.msg)
			assert.True(t, expectedResult.peer == peer, tt.msg)
			assert.Equal(t, expectedResult.err, err, tt.msg)
		}
	}
}