mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-08 05:57:03 +09:00
propagate handshake error + NetworkCompatibilityStatus method
This commit is contained in:
parent
698507d363
commit
d04e55bc9c
12 changed files with 289 additions and 38 deletions
|
@ -177,6 +177,20 @@ func (mr *MockServiceMockRecorder) Name() *gomock.Call {
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name))
|
||||
}
|
||||
|
||||
// NetworkCompatibilityStatus mocks base method.
|
||||
func (m *MockService) NetworkCompatibilityStatus() nodeconf.NetworkCompatibilityStatus {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "NetworkCompatibilityStatus")
|
||||
ret0, _ := ret[0].(nodeconf.NetworkCompatibilityStatus)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// NetworkCompatibilityStatus indicates an expected call of NetworkCompatibilityStatus.
|
||||
func (mr *MockServiceMockRecorder) NetworkCompatibilityStatus() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkCompatibilityStatus", reflect.TypeOf((*MockService)(nil).NetworkCompatibilityStatus))
|
||||
}
|
||||
|
||||
// NodeIds mocks base method.
|
||||
func (m *MockService) NodeIds(arg0 string) []string {
|
||||
m.ctrl.T.Helper()
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
//go:generate mockgen -destination mock_nodeconf/mock_nodeconf.go github.com/anytypeio/any-sync/nodeconf Service
|
||||
package nodeconf
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:generate mockgen -destination mock_nodeconf/mock_nodeconf.go github.com/anytypeio/any-sync/nodeconf Service
|
||||
package nodeconf
|
||||
|
||||
import (
|
||||
|
@ -5,6 +6,8 @@ import (
|
|||
commonaccount "github.com/anytypeio/any-sync/accountservice"
|
||||
"github.com/anytypeio/any-sync/app"
|
||||
"github.com/anytypeio/any-sync/app/logger"
|
||||
"github.com/anytypeio/any-sync/net"
|
||||
"github.com/anytypeio/any-sync/net/secureservice/handshake"
|
||||
"github.com/anytypeio/any-sync/util/periodicsync"
|
||||
"github.com/anytypeio/go-chash"
|
||||
"go.uber.org/zap"
|
||||
|
@ -20,12 +23,22 @@ const (
|
|||
|
||||
var log = logger.NewNamed(CName)
|
||||
|
||||
type NetworkCompatibilityStatus int
|
||||
|
||||
const (
|
||||
NetworkCompatibilityStatusUnknown NetworkCompatibilityStatus = iota
|
||||
NetworkCompatibilityStatusOk
|
||||
NetworkCompatibilityStatusError
|
||||
NetworkCompatibilityStatusIncompatible
|
||||
)
|
||||
|
||||
func New() Service {
|
||||
return new(service)
|
||||
}
|
||||
|
||||
type Service interface {
|
||||
NodeConf
|
||||
NetworkCompatibilityStatus() NetworkCompatibilityStatus
|
||||
app.ComponentRunnable
|
||||
}
|
||||
|
||||
|
@ -37,6 +50,8 @@ type service struct {
|
|||
last NodeConf
|
||||
mu sync.RWMutex
|
||||
sync periodicsync.PeriodicSync
|
||||
|
||||
compatibilityStatus NetworkCompatibilityStatus
|
||||
}
|
||||
|
||||
func (s *service) Init(a *app.App) (err error) {
|
||||
|
@ -75,10 +90,19 @@ func (s *service) Run(_ context.Context) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (s *service) NetworkCompatibilityStatus() NetworkCompatibilityStatus {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return s.compatibilityStatus
|
||||
}
|
||||
|
||||
func (s *service) updateConfiguration(ctx context.Context) (err error) {
|
||||
last, err := s.source.GetLast(ctx, s.Configuration().Id)
|
||||
if err != nil {
|
||||
s.setCompatibilityStatusByErr(err)
|
||||
return
|
||||
} else {
|
||||
s.setCompatibilityStatusByErr(nil)
|
||||
}
|
||||
if err = s.store.SaveLast(ctx, last); err != nil {
|
||||
return
|
||||
|
@ -137,6 +161,21 @@ func (s *service) setLastConfiguration(c Configuration) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (s *service) setCompatibilityStatusByErr(err error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
switch err {
|
||||
case nil:
|
||||
s.compatibilityStatus = NetworkCompatibilityStatusOk
|
||||
case handshake.ErrIncompatibleVersion:
|
||||
s.compatibilityStatus = NetworkCompatibilityStatusIncompatible
|
||||
case net.ErrUnableToConnect:
|
||||
s.compatibilityStatus = NetworkCompatibilityStatusUnknown
|
||||
default:
|
||||
s.compatibilityStatus = NetworkCompatibilityStatusError
|
||||
}
|
||||
}
|
||||
|
||||
func (s *service) Id() string {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
@ -204,6 +243,8 @@ func (s *service) NodeTypes(nodeId string) []NodeType {
|
|||
}
|
||||
|
||||
func (s *service) Close(ctx context.Context) (err error) {
|
||||
s.sync.Close()
|
||||
if s.sync != nil {
|
||||
s.sync.Close()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
175
nodeconf/service_test.go
Normal file
175
nodeconf/service_test.go
Normal file
|
@ -0,0 +1,175 @@
|
|||
package nodeconf
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/anytypeio/any-sync/app"
|
||||
"github.com/anytypeio/any-sync/net"
|
||||
"github.com/anytypeio/any-sync/net/secureservice/handshake"
|
||||
"github.com/anytypeio/any-sync/testutil/accounttest"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var ctx = context.Background()
|
||||
|
||||
func TestService_NetworkCompatibilityStatus(t *testing.T) {
|
||||
t.Run("unknown", func(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.finish(t)
|
||||
fx.testSource.call = func() (c Configuration, e error) {
|
||||
e = net.ErrUnableToConnect
|
||||
return
|
||||
}
|
||||
fx.run(t)
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
assert.Equal(t, NetworkCompatibilityStatusUnknown, fx.NetworkCompatibilityStatus())
|
||||
})
|
||||
t.Run("incompatible", func(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.finish(t)
|
||||
fx.testSource.err = handshake.ErrIncompatibleVersion
|
||||
fx.run(t)
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
assert.Equal(t, NetworkCompatibilityStatusIncompatible, fx.NetworkCompatibilityStatus())
|
||||
})
|
||||
t.Run("error", func(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.finish(t)
|
||||
fx.testSource.call = func() (c Configuration, e error) {
|
||||
e = errors.New("some error")
|
||||
return
|
||||
}
|
||||
fx.run(t)
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
assert.Equal(t, NetworkCompatibilityStatusError, fx.NetworkCompatibilityStatus())
|
||||
})
|
||||
t.Run("ok", func(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.finish(t)
|
||||
fx.run(t)
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
assert.Equal(t, NetworkCompatibilityStatusOk, fx.NetworkCompatibilityStatus())
|
||||
})
|
||||
}
|
||||
|
||||
func newFixture(t *testing.T) *fixture {
|
||||
fx := &fixture{
|
||||
Service: New(),
|
||||
a: new(app.App),
|
||||
testStore: &testStore{},
|
||||
testSource: &testSource{},
|
||||
testConf: newTestConf(),
|
||||
}
|
||||
fx.a.Register(fx.testConf).Register(&accounttest.AccountTestService{}).Register(fx.Service).Register(fx.testSource).Register(fx.testStore)
|
||||
return fx
|
||||
}
|
||||
|
||||
type fixture struct {
|
||||
Service
|
||||
a *app.App
|
||||
testStore *testStore
|
||||
testSource *testSource
|
||||
testConf *testConf
|
||||
}
|
||||
|
||||
func (fx *fixture) run(t *testing.T) {
|
||||
require.NoError(t, fx.a.Start(ctx))
|
||||
}
|
||||
|
||||
func (fx *fixture) finish(t *testing.T) {
|
||||
require.NoError(t, fx.a.Close(ctx))
|
||||
}
|
||||
|
||||
type testSource struct {
|
||||
conf Configuration
|
||||
err error
|
||||
call func() (Configuration, error)
|
||||
}
|
||||
|
||||
func (t *testSource) Init(a *app.App) error { return nil }
|
||||
func (t *testSource) Name() string { return CNameSource }
|
||||
|
||||
func (t *testSource) GetLast(ctx context.Context, currentId string) (c Configuration, err error) {
|
||||
if t.call != nil {
|
||||
return t.call()
|
||||
}
|
||||
return t.conf, t.err
|
||||
}
|
||||
|
||||
type testStore struct {
|
||||
conf *Configuration
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (t *testStore) Init(a *app.App) error { return nil }
|
||||
func (t *testStore) Name() string { return CNameStore }
|
||||
|
||||
func (t *testStore) GetLast(ctx context.Context, netId string) (c Configuration, err error) {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
if t.conf != nil {
|
||||
return *t.conf, nil
|
||||
} else {
|
||||
err = ErrConfigurationNotFound
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (t *testStore) SaveLast(ctx context.Context, c Configuration) (err error) {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
t.conf = &c
|
||||
return
|
||||
}
|
||||
|
||||
type testConf struct {
|
||||
Configuration
|
||||
}
|
||||
|
||||
func (t *testConf) Init(a *app.App) error { return nil }
|
||||
func (t *testConf) Name() string { return "config" }
|
||||
|
||||
func (t *testConf) GetNodeConf() Configuration {
|
||||
return t.Configuration
|
||||
}
|
||||
|
||||
func newTestConf() *testConf {
|
||||
return &testConf{
|
||||
Configuration{
|
||||
Id: "test",
|
||||
NetworkId: "testNetwork",
|
||||
Nodes: []Node{
|
||||
{
|
||||
PeerId: "12D3KooWKLCajM89S8unbt3tgGbRLgmiWnFZT3adn9A5pQciBSLa",
|
||||
Addresses: []string{"127.0.0.1:4830"},
|
||||
Types: []NodeType{NodeTypeCoordinator},
|
||||
},
|
||||
{
|
||||
PeerId: "12D3KooWKnXTtbveMDUFfeSqR5dt9a4JW66tZQXG7C7PdDh3vqGu",
|
||||
Addresses: []string{"127.0.0.1:4730"},
|
||||
Types: []NodeType{NodeTypeTree},
|
||||
},
|
||||
{
|
||||
PeerId: "12D3KooWKgVN2kW8xw5Uvm2sLUnkeUNQYAvcWvF58maTzev7FjPi",
|
||||
Addresses: []string{"127.0.0.1:4731"},
|
||||
Types: []NodeType{NodeTypeTree},
|
||||
},
|
||||
{
|
||||
PeerId: "12D3KooWCUPYuMnQhu9yREJgQyjcz8zWY83rZGmDLwb9YR6QkbZX",
|
||||
Addresses: []string{"127.0.0.1:4732"},
|
||||
Types: []NodeType{NodeTypeTree},
|
||||
},
|
||||
{
|
||||
PeerId: "12D3KooWQxiZ5a7vcy4DTJa8Gy1eVUmwb5ojN4SrJC9Rjxzigw6C",
|
||||
Addresses: []string{"127.0.0.1:4733"},
|
||||
Types: []NodeType{NodeTypeFile},
|
||||
},
|
||||
},
|
||||
CreationTime: time.Now(),
|
||||
},
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue