diff --git a/mock/network_entity.go b/mock/network_entity.go new file mode 100644 index 00000000..23e2d3de --- /dev/null +++ b/mock/network_entity.go @@ -0,0 +1,116 @@ +// Copyright (c) nano Author. All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +package mock + +import ( + "fmt" + "net" +) + +// fakeAddr mock the net.Addr interface +type fakeAddr struct { +} + +// Network implements the net.Addr interface +func (a fakeAddr) Network() string { return "mock" } + +// String implements the net.Addr interface +func (a fakeAddr) String() string { return "mock-addr" } + +type message struct { + route string + data interface{} +} + +// NetworkEntity represents an network entity which can be used to construct the +// session object. +type NetworkEntity struct { + messages []message + responses []interface{} + msgmap map[uint64]interface{} +} + +// NewNetworkEntity returns an mock network entity +func NewNetworkEntity() *NetworkEntity { + return &NetworkEntity{ + msgmap: map[uint64]interface{}{}, + } +} + +// Push implements the session.NetworkEntity interface +func (n *NetworkEntity) Push(route string, v interface{}) error { + n.messages = append(n.messages, message{route: route, data: v}) + return nil +} + +// MID implements the session.NetworkEntity interface +func (n *NetworkEntity) MID() uint64 { + return 1 +} + +// Response implements the session.NetworkEntity interface +func (n *NetworkEntity) Response(v interface{}) error { + n.responses = append(n.responses, v) + return nil +} + +// ResponseMID implements the session.NetworkEntity interface +func (n *NetworkEntity) ResponseMID(mid uint64, v interface{}) error { + _, found := n.msgmap[mid] + if found { + return fmt.Errorf("duplicated message id: %v", mid) + } + n.msgmap[mid] = v + return nil +} + +// Close implements the session.NetworkEntity interface +func (n *NetworkEntity) Close() error { + return nil +} + +// RemoteAddr implements the session.NetworkEntity interface +func (n *NetworkEntity) RemoteAddr() net.Addr { + return fakeAddr{} +} + +// LastResponse returns the last respond message +func (n *NetworkEntity) LastResponse() interface{} { + if len(n.responses) < 1 { + return nil + } + return n.responses[len(n.responses)-1] +} + +// FindResponseByMID returns the response respective the message id +func (n *NetworkEntity) FindResponseByMID(mid uint64) interface{} { + return n.msgmap[mid] +} + +// FindResponseByRoute returns the response respective the route +func (n *NetworkEntity) FindResponseByRoute(route string) interface{} { + for i := range n.messages { + if n.messages[i].route == route { + return n.messages[i].data + } + } + return nil +} diff --git a/mock/network_entity_test.go b/mock/network_entity_test.go new file mode 100644 index 00000000..7c480f95 --- /dev/null +++ b/mock/network_entity_test.go @@ -0,0 +1,56 @@ +// Copyright (c) nano Author. All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +package mock_test + +import ( + "testing" + + "github.com/lonng/nano/mock" + . "github.com/pingcap/check" +) + +type networkEntitySuite struct{} + +func TestNetworkEntity(t *testing.T) { + TestingT(t) +} + +var _ = Suite(&networkEntitySuite{}) + +func (s *networkEntitySuite) TestNetworkEntity(c *C) { + entity := mock.NewNetworkEntity() + + c.Assert(entity.LastResponse(), IsNil) + c.Assert(entity.MID(), Equals, uint64(1)) + c.Assert(entity.Response("hello"), IsNil) + c.Assert(entity.LastResponse().(string), Equals, "hello") + + c.Assert(entity.FindResponseByMID(1), IsNil) + c.Assert(entity.ResponseMID(1, "test"), IsNil) + c.Assert(entity.FindResponseByMID(1).(string), Equals, "test") + + c.Assert(entity.FindResponseByRoute("t.tt"), IsNil) + c.Assert(entity.Push("t.tt", "test"), IsNil) + c.Assert(entity.FindResponseByRoute("t.tt").(string), Equals, "test") + + c.Assert(entity.RemoteAddr().String(), Equals, "mock-addr") + c.Assert(entity.Close(), IsNil) +}