diff --git a/pkg/app2/network/mock_networker.go b/pkg/app2/network/mock_networker.go new file mode 100644 index 0000000000..560de13d97 --- /dev/null +++ b/pkg/app2/network/mock_networker.go @@ -0,0 +1,107 @@ +// Code generated by mockery v1.0.0. DO NOT EDIT. + +package network + +import ( + context "context" + net "net" + + mock "github.com/stretchr/testify/mock" +) + +// MockNetworker is an autogenerated mock type for the Networker type +type MockNetworker struct { + mock.Mock +} + +// Dial provides a mock function with given fields: addr +func (_m *MockNetworker) Dial(addr Addr) (net.Conn, error) { + ret := _m.Called(addr) + + var r0 net.Conn + if rf, ok := ret.Get(0).(func(Addr) net.Conn); ok { + r0 = rf(addr) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(net.Conn) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(Addr) error); ok { + r1 = rf(addr) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DialContext provides a mock function with given fields: ctx, addr +func (_m *MockNetworker) DialContext(ctx context.Context, addr Addr) (net.Conn, error) { + ret := _m.Called(ctx, addr) + + var r0 net.Conn + if rf, ok := ret.Get(0).(func(context.Context, Addr) net.Conn); ok { + r0 = rf(ctx, addr) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(net.Conn) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, Addr) error); ok { + r1 = rf(ctx, addr) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Listen provides a mock function with given fields: addr +func (_m *MockNetworker) Listen(addr Addr) (net.Listener, error) { + ret := _m.Called(addr) + + var r0 net.Listener + if rf, ok := ret.Get(0).(func(Addr) net.Listener); ok { + r0 = rf(addr) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(net.Listener) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(Addr) error); ok { + r1 = rf(addr) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListenContext provides a mock function with given fields: ctx, addr +func (_m *MockNetworker) ListenContext(ctx context.Context, addr Addr) (net.Listener, error) { + ret := _m.Called(ctx, addr) + + var r0 net.Listener + if rf, ok := ret.Get(0).(func(context.Context, Addr) net.Listener); ok { + r0 = rf(ctx, addr) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(net.Listener) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, Addr) error); ok { + r1 = rf(ctx, addr) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} diff --git a/pkg/app2/network/networker.go b/pkg/app2/network/networker.go index 708b707e78..e25c05b137 100644 --- a/pkg/app2/network/networker.go +++ b/pkg/app2/network/networker.go @@ -7,6 +7,8 @@ import ( "sync" ) +//go:generate mockery -name Networker -case underscore -inpkg + var ( // ErrNoSuchNetworker is being returned when there's no suitable networker. ErrNoSuchNetworker = errors.New("no such networker") @@ -15,11 +17,11 @@ var ( ) var ( - networkers = map[Type]Networker{} + networkers = make(map[Type]Networker) networkersMx sync.RWMutex ) -// AddNetworker associated Networker with the `network`. +// AddNetworker associates Networker with the `network`. func AddNetworker(t Type, n Networker) error { networkersMx.Lock() defer networkersMx.Unlock() diff --git a/pkg/app2/network/networker_test.go b/pkg/app2/network/networker_test.go new file mode 100644 index 0000000000..526801daf9 --- /dev/null +++ b/pkg/app2/network/networker_test.go @@ -0,0 +1,123 @@ +package network + +import ( + "context" + "net" + "testing" + + "github.com/skycoin/skywire/pkg/routing" + + "github.com/skycoin/dmsg/cipher" + + "github.com/stretchr/testify/require" +) + +func TestAddNetworker(t *testing.T) { + clearNetworkers() + + nType := Type(TypeDMSG) + var n Networker + + err := AddNetworker(nType, n) + require.NoError(t, err) + + err = AddNetworker(nType, n) + require.Equal(t, err, ErrNetworkerAlreadyExists) +} + +func TestResolveNetworker(t *testing.T) { + clearNetworkers() + + nType := Type(TypeDMSG) + var n Networker + + n, err := ResolveNetworker(nType) + require.Equal(t, err, ErrNoSuchNetworker) + + err = AddNetworker(nType, n) + require.NoError(t, err) + + gotN, err := ResolveNetworker(nType) + require.NoError(t, err) + require.Equal(t, gotN, n) +} + +func TestDial(t *testing.T) { + addr := prepAddr() + + t.Run("no such networker", func(t *testing.T) { + clearNetworkers() + + _, err := Dial(addr) + require.Equal(t, err, ErrNoSuchNetworker) + }) + + t.Run("ok", func(t *testing.T) { + clearNetworkers() + + dialCtx := context.Background() + var ( + dialConn net.Conn + dialErr error + ) + + n := &MockNetworker{} + n.On("DialContext", dialCtx, addr).Return(dialConn, dialErr) + + err := AddNetworker(addr.Net, n) + require.NoError(t, err) + + conn, err := Dial(addr) + require.NoError(t, err) + require.Equal(t, conn, dialConn) + }) +} + +func TestListen(t *testing.T) { + addr := prepAddr() + + t.Run("no such networker", func(t *testing.T) { + clearNetworkers() + + _, err := Listen(addr) + require.Equal(t, err, ErrNoSuchNetworker) + }) + + t.Run("ok", func(t *testing.T) { + clearNetworkers() + + listenCtx := context.Background() + var ( + listenLis net.Listener + listenErr error + ) + + n := &MockNetworker{} + n.On("ListenContext", listenCtx, addr).Return(listenLis, listenErr) + + err := AddNetworker(addr.Net, n) + require.NoError(t, err) + + lis, err := Listen(addr) + require.NoError(t, err) + require.Equal(t, lis, listenLis) + }) +} + +func prepAddr() Addr { + addrPK, _ := cipher.GenerateKeyPair() + addrPort := routing.Port(100) + + return Addr{ + Net: TypeDMSG, + PubKey: addrPK, + Port: addrPort, + } +} + +func clearNetworkers() { + networkersMx.Lock() + defer networkersMx.Unlock() + + networkers = make(map[Type]Networker) +} diff --git a/pkg/app2/network/type_test.go b/pkg/app2/network/type_test.go new file mode 100644 index 0000000000..632ade9c7d --- /dev/null +++ b/pkg/app2/network/type_test.go @@ -0,0 +1,32 @@ +package network + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestType_IsValid(t *testing.T) { + tt := []struct { + name string + t Type + want bool + }{ + { + name: "valid", + t: TypeDMSG, + want: true, + }, + { + name: "not valid", + t: "not valid", + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + valid := tc.t.IsValid() + require.Equal(t, tc.want, valid) + }) + } +}