syncthing/lib/protocol/common_test.go
Jakob Borg be0508cf26
lib/model, lib/protocol: Use error handling to avoid panic on non-started folder (fixes #6174) (#6212)
This adds error returns to model methods called by the protocol layer.
Returning an error will cause the connection to be torn down as the
message couldn't be handled. Using this to signal that a folder isn't
currently available will then cause a reconnection a few moments later,
when it'll hopefully work better.

Tested manually by running with STRECHECKDBEVERY=0 on a nontrivially
sized setup. This panics reliably before this patch, but just causes a
disconnect/reconnect now.
2019-12-04 10:46:55 +01:00

88 lines
1.9 KiB
Go

// Copyright (C) 2014 The Protocol Authors.
package protocol
import "time"
type TestModel struct {
data []byte
folder string
name string
offset int64
size int32
hash []byte
weakHash uint32
fromTemporary bool
indexFn func(DeviceID, string, []FileInfo)
ccFn func(DeviceID, ClusterConfig)
closedCh chan struct{}
closedErr error
}
func newTestModel() *TestModel {
return &TestModel{
closedCh: make(chan struct{}),
}
}
func (t *TestModel) Index(deviceID DeviceID, folder string, files []FileInfo) error {
if t.indexFn != nil {
t.indexFn(deviceID, folder, files)
}
return nil
}
func (t *TestModel) IndexUpdate(deviceID DeviceID, folder string, files []FileInfo) error {
return nil
}
func (t *TestModel) Request(deviceID DeviceID, folder, name string, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (RequestResponse, error) {
t.folder = folder
t.name = name
t.offset = offset
t.size = size
t.hash = hash
t.weakHash = weakHash
t.fromTemporary = fromTemporary
buf := make([]byte, len(t.data))
copy(buf, t.data)
return &fakeRequestResponse{buf}, nil
}
func (t *TestModel) Closed(conn Connection, err error) {
t.closedErr = err
close(t.closedCh)
}
func (t *TestModel) ClusterConfig(deviceID DeviceID, config ClusterConfig) error {
if t.ccFn != nil {
t.ccFn(deviceID, config)
}
return nil
}
func (t *TestModel) DownloadProgress(DeviceID, string, []FileDownloadProgressUpdate) error {
return nil
}
func (t *TestModel) closedError() error {
select {
case <-t.closedCh:
return t.closedErr
case <-time.After(1 * time.Second):
return nil // Timeout
}
}
type fakeRequestResponse struct {
data []byte
}
func (r *fakeRequestResponse) Data() []byte {
return r.data
}
func (r *fakeRequestResponse) Close() {}
func (r *fakeRequestResponse) Wait() {}