lib: Use counterfeiter to mock interfaces in tests (#7375)
This commit is contained in:
+24
-84
@@ -13,8 +13,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
protocolmocks "github.com/syncthing/syncthing/lib/protocol/mocks"
|
||||
"github.com/syncthing/syncthing/lib/scanner"
|
||||
"github.com/syncthing/syncthing/lib/testutils"
|
||||
)
|
||||
|
||||
type downloadProgressMessage struct {
|
||||
@@ -22,97 +22,37 @@ type downloadProgressMessage struct {
|
||||
updates []protocol.FileDownloadProgressUpdate
|
||||
}
|
||||
|
||||
func newFakeConnection(id protocol.DeviceID, model Model) *fakeConnection {
|
||||
f := &fakeConnection{
|
||||
Connection: new(protocolmocks.Connection),
|
||||
id: id,
|
||||
model: model,
|
||||
}
|
||||
f.RequestCalls(func(ctx context.Context, folder, name string, blockNo int, offset int64, size int, hash []byte, weakHash uint32, fromTemporary bool) ([]byte, error) {
|
||||
return f.fileData[name], nil
|
||||
})
|
||||
f.IDReturns(id)
|
||||
f.CloseCalls(func(err error) {
|
||||
model.Closed(f, err)
|
||||
f.ClosedReturns(true)
|
||||
})
|
||||
return f
|
||||
}
|
||||
|
||||
type fakeConnection struct {
|
||||
testutils.FakeConnectionInfo
|
||||
*protocolmocks.Connection
|
||||
id protocol.DeviceID
|
||||
downloadProgressMessages []downloadProgressMessage
|
||||
closed bool
|
||||
files []protocol.FileInfo
|
||||
fileData map[string][]byte
|
||||
folder string
|
||||
model *testModel
|
||||
indexFn func(context.Context, string, []protocol.FileInfo)
|
||||
requestFn func(ctx context.Context, folder, name string, offset int64, size int, hash []byte, fromTemporary bool) ([]byte, error)
|
||||
closeFn func(error)
|
||||
clusterConfigFn func(protocol.ClusterConfig)
|
||||
model Model
|
||||
mut sync.Mutex
|
||||
}
|
||||
|
||||
func (f *fakeConnection) Close(err error) {
|
||||
f.mut.Lock()
|
||||
defer f.mut.Unlock()
|
||||
if f.closeFn != nil {
|
||||
f.closeFn(err)
|
||||
return
|
||||
}
|
||||
f.closed = true
|
||||
f.model.Closed(f, err)
|
||||
}
|
||||
|
||||
func (f *fakeConnection) Start() {
|
||||
}
|
||||
|
||||
func (f *fakeConnection) ID() protocol.DeviceID {
|
||||
return f.id
|
||||
}
|
||||
|
||||
func (f *fakeConnection) Name() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (f *fakeConnection) Option(string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (f *fakeConnection) Index(ctx context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
f.mut.Lock()
|
||||
defer f.mut.Unlock()
|
||||
if f.indexFn != nil {
|
||||
f.indexFn(ctx, folder, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeConnection) IndexUpdate(ctx context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
f.mut.Lock()
|
||||
defer f.mut.Unlock()
|
||||
if f.indexFn != nil {
|
||||
f.indexFn(ctx, folder, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeConnection) Request(ctx context.Context, folder, name string, blockNo int, offset int64, size int, hash []byte, weakHash uint32, fromTemporary bool) ([]byte, error) {
|
||||
f.mut.Lock()
|
||||
defer f.mut.Unlock()
|
||||
if f.requestFn != nil {
|
||||
return f.requestFn(ctx, folder, name, offset, size, hash, fromTemporary)
|
||||
}
|
||||
return f.fileData[name], nil
|
||||
}
|
||||
|
||||
func (f *fakeConnection) ClusterConfig(cc protocol.ClusterConfig) {
|
||||
f.mut.Lock()
|
||||
defer f.mut.Unlock()
|
||||
if f.clusterConfigFn != nil {
|
||||
f.clusterConfigFn(cc)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *fakeConnection) Ping() bool {
|
||||
f.mut.Lock()
|
||||
defer f.mut.Unlock()
|
||||
return f.closed
|
||||
}
|
||||
|
||||
func (f *fakeConnection) Closed() bool {
|
||||
f.mut.Lock()
|
||||
defer f.mut.Unlock()
|
||||
return f.closed
|
||||
}
|
||||
|
||||
func (f *fakeConnection) Statistics() protocol.Statistics {
|
||||
return protocol.Statistics{}
|
||||
func (f *fakeConnection) setIndexFn(fn func(_ context.Context, folder string, fs []protocol.FileInfo) error) {
|
||||
f.IndexCalls(fn)
|
||||
f.IndexUpdateCalls(fn)
|
||||
}
|
||||
|
||||
func (f *fakeConnection) DownloadProgress(_ context.Context, folder string, updates []protocol.FileDownloadProgressUpdate) {
|
||||
@@ -201,7 +141,7 @@ func (f *fakeConnection) sendIndexUpdate() {
|
||||
}
|
||||
|
||||
func addFakeConn(m *testModel, dev protocol.DeviceID) *fakeConnection {
|
||||
fc := &fakeConnection{id: dev, model: m}
|
||||
fc := newFakeConnection(dev, m)
|
||||
m.AddConnection(fc, protocol.Hello{})
|
||||
|
||||
m.ClusterConfig(dev, protocol.ClusterConfig{
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:generate counterfeiter -o mocks/folderSummaryService.go --fake-name FolderSummaryService . FolderSummaryService
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
// Code generated by counterfeiter. DO NOT EDIT.
|
||||
package mocks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/model"
|
||||
)
|
||||
|
||||
type FolderSummaryService struct {
|
||||
OnEventRequestStub func()
|
||||
onEventRequestMutex sync.RWMutex
|
||||
onEventRequestArgsForCall []struct {
|
||||
}
|
||||
ServeStub func(context.Context) error
|
||||
serveMutex sync.RWMutex
|
||||
serveArgsForCall []struct {
|
||||
arg1 context.Context
|
||||
}
|
||||
serveReturns struct {
|
||||
result1 error
|
||||
}
|
||||
serveReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
SummaryStub func(string) (map[string]interface{}, error)
|
||||
summaryMutex sync.RWMutex
|
||||
summaryArgsForCall []struct {
|
||||
arg1 string
|
||||
}
|
||||
summaryReturns struct {
|
||||
result1 map[string]interface{}
|
||||
result2 error
|
||||
}
|
||||
summaryReturnsOnCall map[int]struct {
|
||||
result1 map[string]interface{}
|
||||
result2 error
|
||||
}
|
||||
invocations map[string][][]interface{}
|
||||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) OnEventRequest() {
|
||||
fake.onEventRequestMutex.Lock()
|
||||
fake.onEventRequestArgsForCall = append(fake.onEventRequestArgsForCall, struct {
|
||||
}{})
|
||||
stub := fake.OnEventRequestStub
|
||||
fake.recordInvocation("OnEventRequest", []interface{}{})
|
||||
fake.onEventRequestMutex.Unlock()
|
||||
if stub != nil {
|
||||
fake.OnEventRequestStub()
|
||||
}
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) OnEventRequestCallCount() int {
|
||||
fake.onEventRequestMutex.RLock()
|
||||
defer fake.onEventRequestMutex.RUnlock()
|
||||
return len(fake.onEventRequestArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) OnEventRequestCalls(stub func()) {
|
||||
fake.onEventRequestMutex.Lock()
|
||||
defer fake.onEventRequestMutex.Unlock()
|
||||
fake.OnEventRequestStub = stub
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) Serve(arg1 context.Context) error {
|
||||
fake.serveMutex.Lock()
|
||||
ret, specificReturn := fake.serveReturnsOnCall[len(fake.serveArgsForCall)]
|
||||
fake.serveArgsForCall = append(fake.serveArgsForCall, struct {
|
||||
arg1 context.Context
|
||||
}{arg1})
|
||||
stub := fake.ServeStub
|
||||
fakeReturns := fake.serveReturns
|
||||
fake.recordInvocation("Serve", []interface{}{arg1})
|
||||
fake.serveMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) ServeCallCount() int {
|
||||
fake.serveMutex.RLock()
|
||||
defer fake.serveMutex.RUnlock()
|
||||
return len(fake.serveArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) ServeCalls(stub func(context.Context) error) {
|
||||
fake.serveMutex.Lock()
|
||||
defer fake.serveMutex.Unlock()
|
||||
fake.ServeStub = stub
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) ServeArgsForCall(i int) context.Context {
|
||||
fake.serveMutex.RLock()
|
||||
defer fake.serveMutex.RUnlock()
|
||||
argsForCall := fake.serveArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) ServeReturns(result1 error) {
|
||||
fake.serveMutex.Lock()
|
||||
defer fake.serveMutex.Unlock()
|
||||
fake.ServeStub = nil
|
||||
fake.serveReturns = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) ServeReturnsOnCall(i int, result1 error) {
|
||||
fake.serveMutex.Lock()
|
||||
defer fake.serveMutex.Unlock()
|
||||
fake.ServeStub = nil
|
||||
if fake.serveReturnsOnCall == nil {
|
||||
fake.serveReturnsOnCall = make(map[int]struct {
|
||||
result1 error
|
||||
})
|
||||
}
|
||||
fake.serveReturnsOnCall[i] = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) Summary(arg1 string) (map[string]interface{}, error) {
|
||||
fake.summaryMutex.Lock()
|
||||
ret, specificReturn := fake.summaryReturnsOnCall[len(fake.summaryArgsForCall)]
|
||||
fake.summaryArgsForCall = append(fake.summaryArgsForCall, struct {
|
||||
arg1 string
|
||||
}{arg1})
|
||||
stub := fake.SummaryStub
|
||||
fakeReturns := fake.summaryReturns
|
||||
fake.recordInvocation("Summary", []interface{}{arg1})
|
||||
fake.summaryMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) SummaryCallCount() int {
|
||||
fake.summaryMutex.RLock()
|
||||
defer fake.summaryMutex.RUnlock()
|
||||
return len(fake.summaryArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) SummaryCalls(stub func(string) (map[string]interface{}, error)) {
|
||||
fake.summaryMutex.Lock()
|
||||
defer fake.summaryMutex.Unlock()
|
||||
fake.SummaryStub = stub
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) SummaryArgsForCall(i int) string {
|
||||
fake.summaryMutex.RLock()
|
||||
defer fake.summaryMutex.RUnlock()
|
||||
argsForCall := fake.summaryArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) SummaryReturns(result1 map[string]interface{}, result2 error) {
|
||||
fake.summaryMutex.Lock()
|
||||
defer fake.summaryMutex.Unlock()
|
||||
fake.SummaryStub = nil
|
||||
fake.summaryReturns = struct {
|
||||
result1 map[string]interface{}
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) SummaryReturnsOnCall(i int, result1 map[string]interface{}, result2 error) {
|
||||
fake.summaryMutex.Lock()
|
||||
defer fake.summaryMutex.Unlock()
|
||||
fake.SummaryStub = nil
|
||||
if fake.summaryReturnsOnCall == nil {
|
||||
fake.summaryReturnsOnCall = make(map[int]struct {
|
||||
result1 map[string]interface{}
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.summaryReturnsOnCall[i] = struct {
|
||||
result1 map[string]interface{}
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) Invocations() map[string][][]interface{} {
|
||||
fake.invocationsMutex.RLock()
|
||||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.onEventRequestMutex.RLock()
|
||||
defer fake.onEventRequestMutex.RUnlock()
|
||||
fake.serveMutex.RLock()
|
||||
defer fake.serveMutex.RUnlock()
|
||||
fake.summaryMutex.RLock()
|
||||
defer fake.summaryMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
for key, value := range fake.invocations {
|
||||
copiedInvocations[key] = value
|
||||
}
|
||||
return copiedInvocations
|
||||
}
|
||||
|
||||
func (fake *FolderSummaryService) recordInvocation(key string, args []interface{}) {
|
||||
fake.invocationsMutex.Lock()
|
||||
defer fake.invocationsMutex.Unlock()
|
||||
if fake.invocations == nil {
|
||||
fake.invocations = map[string][][]interface{}{}
|
||||
}
|
||||
if fake.invocations[key] == nil {
|
||||
fake.invocations[key] = [][]interface{}{}
|
||||
}
|
||||
fake.invocations[key] = append(fake.invocations[key], args)
|
||||
}
|
||||
|
||||
var _ model.FolderSummaryService = new(FolderSummaryService)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,8 @@
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:generate counterfeiter -o mocks/model.go --fake-name Model . Model
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
|
||||
+19
-26
@@ -35,6 +35,7 @@ import (
|
||||
"github.com/syncthing/syncthing/lib/ignore"
|
||||
"github.com/syncthing/syncthing/lib/osutil"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
protocolmocks "github.com/syncthing/syncthing/lib/protocol/mocks"
|
||||
srand "github.com/syncthing/syncthing/lib/rand"
|
||||
"github.com/syncthing/syncthing/lib/testutils"
|
||||
"github.com/syncthing/syncthing/lib/versioner"
|
||||
@@ -116,7 +117,7 @@ func newState(t testing.TB, cfg config.Configuration) (*testModel, context.Cance
|
||||
m := setupModel(t, wcfg)
|
||||
|
||||
for _, dev := range cfg.Devices {
|
||||
m.AddConnection(&fakeConnection{id: dev.DeviceID, model: m}, protocol.Hello{})
|
||||
m.AddConnection(newFakeConnection(dev.DeviceID, m), protocol.Hello{})
|
||||
}
|
||||
|
||||
return m, cancel
|
||||
@@ -267,7 +268,7 @@ func BenchmarkRequestOut(b *testing.B) {
|
||||
const n = 1000
|
||||
files := genFiles(n)
|
||||
|
||||
fc := &fakeConnection{id: device1, model: m}
|
||||
fc := newFakeConnection(device1, m)
|
||||
for _, f := range files {
|
||||
fc.addFile(f.Name, 0644, protocol.FileInfoTypeFile, []byte("some data to return"))
|
||||
}
|
||||
@@ -329,7 +330,7 @@ func TestDeviceRename(t *testing.T) {
|
||||
t.Errorf("Device already has a name")
|
||||
}
|
||||
|
||||
conn := &fakeConnection{id: device1, model: m}
|
||||
conn := newFakeConnection(device1, m)
|
||||
|
||||
m.AddConnection(conn, hello)
|
||||
|
||||
@@ -871,9 +872,7 @@ func TestIssue5063(t *testing.T) {
|
||||
m.pmut.Lock()
|
||||
for _, c := range m.conn {
|
||||
conn := c.(*fakeConnection)
|
||||
conn.mut.Lock()
|
||||
conn.closeFn = func(_ error) {}
|
||||
conn.mut.Unlock()
|
||||
conn.CloseCalls(func(_ error) {})
|
||||
defer m.Closed(c, errStopped) // to unblock deferred m.Stop()
|
||||
}
|
||||
m.pmut.Unlock()
|
||||
@@ -1324,7 +1323,7 @@ func TestAutoAcceptEnc(t *testing.T) {
|
||||
// Earlier tests might cause the connection to get closed, thus ClusterConfig
|
||||
// would panic.
|
||||
clusterConfig := func(deviceID protocol.DeviceID, cm protocol.ClusterConfig) {
|
||||
m.AddConnection(&fakeConnection{id: deviceID, model: m}, protocol.Hello{})
|
||||
m.AddConnection(newFakeConnection(deviceID, m), protocol.Hello{})
|
||||
m.ClusterConfig(deviceID, cm)
|
||||
}
|
||||
|
||||
@@ -2196,9 +2195,9 @@ func TestSharedWithClearedOnDisconnect(t *testing.T) {
|
||||
m := setupModel(t, wcfg)
|
||||
defer cleanupModel(m)
|
||||
|
||||
conn1 := &fakeConnection{id: device1, model: m}
|
||||
conn1 := newFakeConnection(device1, m)
|
||||
m.AddConnection(conn1, protocol.Hello{})
|
||||
conn2 := &fakeConnection{id: device2, model: m}
|
||||
conn2 := newFakeConnection(device2, m)
|
||||
m.AddConnection(conn2, protocol.Hello{})
|
||||
|
||||
m.ClusterConfig(device1, protocol.ClusterConfig{
|
||||
@@ -2429,8 +2428,8 @@ func TestNoRequestsFromPausedDevices(t *testing.T) {
|
||||
t.Errorf("should have two available")
|
||||
}
|
||||
|
||||
m.Closed(&fakeConnection{id: device1, model: m}, errDeviceUnknown)
|
||||
m.Closed(&fakeConnection{id: device2, model: m}, errDeviceUnknown)
|
||||
m.Closed(newFakeConnection(device1, m), errDeviceUnknown)
|
||||
m.Closed(newFakeConnection(device2, m), errDeviceUnknown)
|
||||
|
||||
avail = m.Availability("default", file, file.Blocks[0])
|
||||
if len(avail) != 0 {
|
||||
@@ -3172,7 +3171,7 @@ func TestConnCloseOnRestart(t *testing.T) {
|
||||
|
||||
br := &testutils.BlockingRW{}
|
||||
nw := &testutils.NoopRW{}
|
||||
m.AddConnection(protocol.NewConnection(device1, br, nw, testutils.NoopCloser{}, m, &testutils.FakeConnectionInfo{"fc"}, protocol.CompressionNever), protocol.Hello{})
|
||||
m.AddConnection(protocol.NewConnection(device1, br, nw, testutils.NoopCloser{}, m, new(protocolmocks.ConnectionInfo), protocol.CompressionNever), protocol.Hello{})
|
||||
m.pmut.RLock()
|
||||
if len(m.closed) != 1 {
|
||||
t.Fatalf("Expected just one conn (len(m.conn) == %v)", len(m.conn))
|
||||
@@ -3819,20 +3818,14 @@ func testConfigChangeTriggersClusterConfigs(t *testing.T, expectFirst, expectSec
|
||||
|
||||
cc1 := make(chan struct{}, 1)
|
||||
cc2 := make(chan struct{}, 1)
|
||||
fc1 := &fakeConnection{
|
||||
id: device1,
|
||||
model: m,
|
||||
clusterConfigFn: func(_ protocol.ClusterConfig) {
|
||||
cc1 <- struct{}{}
|
||||
},
|
||||
}
|
||||
fc2 := &fakeConnection{
|
||||
id: device2,
|
||||
model: m,
|
||||
clusterConfigFn: func(_ protocol.ClusterConfig) {
|
||||
cc2 <- struct{}{}
|
||||
},
|
||||
}
|
||||
fc1 := newFakeConnection(device1, m)
|
||||
fc1.ClusterConfigCalls(func(_ protocol.ClusterConfig) {
|
||||
cc1 <- struct{}{}
|
||||
})
|
||||
fc2 := newFakeConnection(device2, m)
|
||||
fc2.ClusterConfigCalls(func(_ protocol.ClusterConfig) {
|
||||
cc2 <- struct{}{}
|
||||
})
|
||||
m.AddConnection(fc1, protocol.Hello{})
|
||||
m.AddConnection(fc2, protocol.Hello{})
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ func TestSendDownloadProgressMessages(t *testing.T) {
|
||||
}
|
||||
waiter.Wait()
|
||||
|
||||
fc := &fakeConnection{}
|
||||
fc := newFakeConnection(protocol.DeviceID{}, nil)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
evLogger := events.NewLogger()
|
||||
|
||||
+87
-114
@@ -38,8 +38,7 @@ func TestRequestSimple(t *testing.T) {
|
||||
// We listen for incoming index updates and trigger when we see one for
|
||||
// the expected test file.
|
||||
done := make(chan struct{})
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
select {
|
||||
case <-done:
|
||||
t.Error("More than one index update sent")
|
||||
@@ -48,11 +47,11 @@ func TestRequestSimple(t *testing.T) {
|
||||
for _, f := range fs {
|
||||
if f.Name == "testfile" {
|
||||
close(done)
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
// Send an update for the test file, wait for it to sync and be reported back.
|
||||
contents := []byte("test file contents\n")
|
||||
@@ -81,8 +80,7 @@ func TestSymlinkTraversalRead(t *testing.T) {
|
||||
// We listen for incoming index updates and trigger when we see one for
|
||||
// the expected test file.
|
||||
done := make(chan struct{})
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
select {
|
||||
case <-done:
|
||||
t.Error("More than one index update sent")
|
||||
@@ -91,11 +89,11 @@ func TestSymlinkTraversalRead(t *testing.T) {
|
||||
for _, f := range fs {
|
||||
if f.Name == "symlink" {
|
||||
close(done)
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
// Send an update for the symlink, wait for it to sync and be reported back.
|
||||
contents := []byte("..")
|
||||
@@ -127,26 +125,25 @@ func TestSymlinkTraversalWrite(t *testing.T) {
|
||||
done := make(chan struct{}, 1)
|
||||
badReq := make(chan string, 1)
|
||||
badIdx := make(chan string, 1)
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
for _, f := range fs {
|
||||
if f.Name == "symlink" {
|
||||
done <- struct{}{}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
if strings.HasPrefix(f.Name, "symlink") {
|
||||
badIdx <- f.Name
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
fc.requestFn = func(_ context.Context, folder, name string, offset int64, size int, hash []byte, fromTemporary bool) ([]byte, error) {
|
||||
return nil
|
||||
})
|
||||
fc.RequestCalls(func(ctx context.Context, folder, name string, blockNo int, offset int64, size int, hash []byte, weakHash uint32, fromTemporary bool) ([]byte, error) {
|
||||
if name != "symlink" && strings.HasPrefix(name, "symlink") {
|
||||
badReq <- name
|
||||
}
|
||||
return fc.fileData[name], nil
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
})
|
||||
|
||||
// Send an update for the symlink, wait for it to sync and be reported back.
|
||||
contents := []byte("..")
|
||||
@@ -186,8 +183,7 @@ func TestRequestCreateTmpSymlink(t *testing.T) {
|
||||
// the expected test file.
|
||||
goodIdx := make(chan struct{})
|
||||
name := fs.TempName("testlink")
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
for _, f := range fs {
|
||||
if f.Name == name {
|
||||
if f.IsInvalid() {
|
||||
@@ -196,11 +192,11 @@ func TestRequestCreateTmpSymlink(t *testing.T) {
|
||||
t.Error("Received index with non-invalid temporary file")
|
||||
close(goodIdx)
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
// Send an update for the test file, wait for it to sync and be reported back.
|
||||
fc.addFile(name, 0644, protocol.FileInfoTypeSymlink, []byte(".."))
|
||||
@@ -244,11 +240,10 @@ func TestRequestVersioningSymlinkAttack(t *testing.T) {
|
||||
// We listen for incoming index updates and trigger when we see one for
|
||||
// the expected test file.
|
||||
idx := make(chan int)
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
idx <- len(fs)
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
waitForIdx := func() {
|
||||
select {
|
||||
@@ -335,8 +330,7 @@ func pullInvalidIgnored(t *testing.T, ft config.FolderType) {
|
||||
}
|
||||
|
||||
done := make(chan struct{})
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
expected := map[string]struct{}{invIgn: {}, ign: {}, ignExisting: {}}
|
||||
for _, f := range fs {
|
||||
if _, ok := expected[f.Name]; !ok {
|
||||
@@ -351,8 +345,8 @@ func pullInvalidIgnored(t *testing.T, ft config.FolderType) {
|
||||
t.Errorf("File %v wasn't added to index", name)
|
||||
}
|
||||
close(done)
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
sub := m.evLogger.Subscribe(events.FolderErrors)
|
||||
defer sub.Unsubscribe()
|
||||
@@ -372,8 +366,7 @@ func pullInvalidIgnored(t *testing.T, ft config.FolderType) {
|
||||
var expectedMut sync.Mutex
|
||||
// The indexes will normally arrive in one update, but it is possible
|
||||
// that they arrive in separate ones.
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
expectedMut.Lock()
|
||||
for _, f := range fs {
|
||||
_, ok := expected[f.Name]
|
||||
@@ -411,13 +404,13 @@ func pullInvalidIgnored(t *testing.T, ft config.FolderType) {
|
||||
close(done)
|
||||
}
|
||||
expectedMut.Unlock()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
// Make sure pulling doesn't interfere, as index updates are racy and
|
||||
// thus we cannot distinguish between scan and pull results.
|
||||
fc.requestFn = func(_ context.Context, folder, name string, offset int64, size int, hash []byte, fromTemporary bool) ([]byte, error) {
|
||||
fc.RequestCalls(func(ctx context.Context, folder, name string, blockNo int, offset int64, size int, hash []byte, weakHash uint32, fromTemporary bool) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
})
|
||||
|
||||
if err := m.SetIgnores("default", []string{"*:ignored*"}); err != nil {
|
||||
panic(err)
|
||||
@@ -438,11 +431,10 @@ func TestIssue4841(t *testing.T) {
|
||||
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI())
|
||||
|
||||
received := make(chan []protocol.FileInfo)
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, _ string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, _ string, fs []protocol.FileInfo) error {
|
||||
received <- fs
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
checkReceived := func(fs []protocol.FileInfo) protocol.FileInfo {
|
||||
t.Helper()
|
||||
if len(fs) != 1 {
|
||||
@@ -492,11 +484,10 @@ func TestRescanIfHaveInvalidContent(t *testing.T) {
|
||||
must(t, writeFile(tfs, "foo", payload, 0777))
|
||||
|
||||
received := make(chan []protocol.FileInfo)
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, _ string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, _ string, fs []protocol.FileInfo) error {
|
||||
received <- fs
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
checkReceived := func(fs []protocol.FileInfo) protocol.FileInfo {
|
||||
t.Helper()
|
||||
if len(fs) != 1 {
|
||||
@@ -560,11 +551,10 @@ func TestParentDeletion(t *testing.T) {
|
||||
received := make(chan []protocol.FileInfo)
|
||||
fc.addFile(parent, 0777, protocol.FileInfoTypeDirectory, nil)
|
||||
fc.addFile(child, 0777, protocol.FileInfoTypeDirectory, nil)
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
received <- fs
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
fc.sendIndexUpdate()
|
||||
|
||||
// Get back index from initial setup
|
||||
@@ -634,16 +624,15 @@ func TestRequestSymlinkWindows(t *testing.T) {
|
||||
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI())
|
||||
|
||||
received := make(chan []protocol.FileInfo)
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
select {
|
||||
case <-received:
|
||||
t.Error("More than one index update sent")
|
||||
default:
|
||||
}
|
||||
received <- fs
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
fc.addFile("link", 0644, protocol.FileInfoTypeSymlink, nil)
|
||||
fc.sendIndexUpdate()
|
||||
@@ -705,16 +694,15 @@ func TestRequestRemoteRenameChanged(t *testing.T) {
|
||||
defer cleanupModelAndRemoveDir(m, tfs.URI())
|
||||
|
||||
received := make(chan []protocol.FileInfo)
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
select {
|
||||
case <-received:
|
||||
t.Error("More than one index update sent")
|
||||
default:
|
||||
}
|
||||
received <- fs
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
// setup
|
||||
a := "a"
|
||||
@@ -743,12 +731,11 @@ func TestRequestRemoteRenameChanged(t *testing.T) {
|
||||
|
||||
var gotA, gotB, gotConfl bool
|
||||
done := make(chan struct{})
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
select {
|
||||
case <-done:
|
||||
t.Error("Received more index updates than expected")
|
||||
return
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
for _, f := range fs {
|
||||
@@ -780,8 +767,8 @@ func TestRequestRemoteRenameChanged(t *testing.T) {
|
||||
if gotA && gotB && gotConfl {
|
||||
close(done)
|
||||
}
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
fd, err := tfs.OpenFile(b, fs.OptReadWrite, 0644)
|
||||
if err != nil {
|
||||
@@ -841,11 +828,10 @@ func TestRequestRemoteRenameConflict(t *testing.T) {
|
||||
defer cleanupModelAndRemoveDir(m, tmpDir)
|
||||
|
||||
recv := make(chan int)
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
recv <- len(fs)
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
// setup
|
||||
a := "a"
|
||||
@@ -932,16 +918,15 @@ func TestRequestDeleteChanged(t *testing.T) {
|
||||
defer cleanupModelAndRemoveDir(m, tfs.URI())
|
||||
|
||||
done := make(chan struct{})
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
select {
|
||||
case <-done:
|
||||
t.Error("More than one index update sent")
|
||||
default:
|
||||
}
|
||||
close(done)
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
// setup
|
||||
a := "a"
|
||||
@@ -955,16 +940,15 @@ func TestRequestDeleteChanged(t *testing.T) {
|
||||
t.Fatal("timed out")
|
||||
}
|
||||
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
select {
|
||||
case <-done:
|
||||
t.Error("More than one index update sent")
|
||||
default:
|
||||
}
|
||||
close(done)
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
fd, err := tfs.OpenFile(a, fs.OptReadWrite, 0644)
|
||||
if err != nil {
|
||||
@@ -1006,11 +990,9 @@ func TestNeedFolderFiles(t *testing.T) {
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
errPreventSync := errors.New("you aren't getting any of this")
|
||||
fc.mut.Lock()
|
||||
fc.requestFn = func(context.Context, string, string, int64, int, []byte, bool) ([]byte, error) {
|
||||
fc.RequestCalls(func(ctx context.Context, folder, name string, blockNo int, offset int64, size int, hash []byte, weakHash uint32, fromTemporary bool) ([]byte, error) {
|
||||
return nil, errPreventSync
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
})
|
||||
|
||||
data := []byte("foo")
|
||||
num := 20
|
||||
@@ -1073,12 +1055,11 @@ func TestIgnoreDeleteUnignore(t *testing.T) {
|
||||
}
|
||||
|
||||
done := make(chan struct{})
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
basicCheck(fs)
|
||||
close(done)
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := writeFile(fss, file, contents, 0644); err != nil {
|
||||
panic(err)
|
||||
@@ -1092,16 +1073,15 @@ func TestIgnoreDeleteUnignore(t *testing.T) {
|
||||
}
|
||||
|
||||
done = make(chan struct{})
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
basicCheck(fs)
|
||||
f := fs[0]
|
||||
if !f.IsInvalid() {
|
||||
t.Errorf("Received non-invalid index update")
|
||||
}
|
||||
close(done)
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := m.SetIgnores("default", []string{"foobar"}); err != nil {
|
||||
panic(err)
|
||||
@@ -1114,8 +1094,7 @@ func TestIgnoreDeleteUnignore(t *testing.T) {
|
||||
}
|
||||
|
||||
done = make(chan struct{})
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
basicCheck(fs)
|
||||
f := fs[0]
|
||||
if f.IsInvalid() {
|
||||
@@ -1126,8 +1105,8 @@ func TestIgnoreDeleteUnignore(t *testing.T) {
|
||||
}
|
||||
l.Infoln(f)
|
||||
close(done)
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := fss.Remove(file); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -1153,8 +1132,7 @@ func TestRequestLastFileProgress(t *testing.T) {
|
||||
|
||||
done := make(chan struct{})
|
||||
|
||||
fc.mut.Lock()
|
||||
fc.requestFn = func(_ context.Context, folder, name string, _ int64, _ int, _ []byte, _ bool) ([]byte, error) {
|
||||
fc.RequestCalls(func(ctx context.Context, folder, name string, blockNo int, offset int64, size int, hash []byte, weakHash uint32, fromTemporary bool) ([]byte, error) {
|
||||
defer close(done)
|
||||
progress, queued, rest, err := m.NeedFolderFiles(folder, 1, 10)
|
||||
must(t, err)
|
||||
@@ -1165,8 +1143,7 @@ func TestRequestLastFileProgress(t *testing.T) {
|
||||
t.Error("Expected exactly one item in progress.")
|
||||
}
|
||||
return fc.fileData[name], nil
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
})
|
||||
|
||||
contents := []byte("test file contents\n")
|
||||
fc.addFile("testfile", 0644, protocol.FileInfoTypeFile, contents)
|
||||
@@ -1189,15 +1166,14 @@ func TestRequestIndexSenderPause(t *testing.T) {
|
||||
defer cleanupModelAndRemoveDir(m, tfs.URI())
|
||||
|
||||
indexChan := make(chan []protocol.FileInfo)
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(ctx context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(ctx context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
select {
|
||||
case indexChan <- fs:
|
||||
case <-done:
|
||||
case <-ctx.Done():
|
||||
}
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
return nil
|
||||
})
|
||||
|
||||
var seq int64 = 1
|
||||
files := []protocol.FileInfo{{Name: "foo", Size: 10, Version: protocol.Vector{}.Update(myID.Short()), Sequence: seq}}
|
||||
@@ -1324,20 +1300,19 @@ func TestRequestIndexSenderClusterConfigBeforeStart(t *testing.T) {
|
||||
defer close(done) // Must be the last thing to be deferred, thus first to run.
|
||||
indexChan := make(chan []protocol.FileInfo, 1)
|
||||
ccChan := make(chan protocol.ClusterConfig, 1)
|
||||
fc.mut.Lock()
|
||||
fc.indexFn = func(_ context.Context, folder string, fs []protocol.FileInfo) {
|
||||
fc.setIndexFn(func(_ context.Context, folder string, fs []protocol.FileInfo) error {
|
||||
select {
|
||||
case indexChan <- fs:
|
||||
case <-done:
|
||||
}
|
||||
}
|
||||
fc.clusterConfigFn = func(cc protocol.ClusterConfig) {
|
||||
return nil
|
||||
})
|
||||
fc.ClusterConfigCalls(func(cc protocol.ClusterConfig) {
|
||||
select {
|
||||
case ccChan <- cc:
|
||||
case <-done:
|
||||
}
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
})
|
||||
|
||||
m.ServeBackground()
|
||||
|
||||
@@ -1388,16 +1363,14 @@ func TestRequestReceiveEncryptedLocalNoSend(t *testing.T) {
|
||||
indexChan := make(chan []protocol.FileInfo, 1)
|
||||
done := make(chan struct{})
|
||||
defer close(done)
|
||||
fc := &fakeConnection{
|
||||
id: device1,
|
||||
model: m,
|
||||
indexFn: func(_ context.Context, _ string, fs []protocol.FileInfo) {
|
||||
select {
|
||||
case indexChan <- fs:
|
||||
case <-done:
|
||||
}
|
||||
},
|
||||
}
|
||||
fc := newFakeConnection(device1, m)
|
||||
fc.setIndexFn(func(_ context.Context, _ string, fs []protocol.FileInfo) error {
|
||||
select {
|
||||
case indexChan <- fs:
|
||||
case <-done:
|
||||
}
|
||||
return nil
|
||||
})
|
||||
m.AddConnection(fc, protocol.Hello{})
|
||||
m.ClusterConfig(device1, protocol.ClusterConfig{
|
||||
Folders: []protocol.Folder{
|
||||
|
||||
Reference in New Issue
Block a user