mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-19 19:45:12 +00:00
parent
b806026990
commit
9d21b91124
@ -58,7 +58,7 @@ var (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
dev1, _ = protocol.DeviceIDFromString("AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR")
|
dev1, _ = protocol.DeviceIDFromString("AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR")
|
||||||
apiCfg.GUIReturns(config.GUIConfiguration{APIKey: testAPIKey})
|
apiCfg.GUIReturns(config.GUIConfiguration{APIKey: testAPIKey, RawAddress: "127.0.0.1:0"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
@ -496,7 +496,9 @@ func TestAPIServiceRequests(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
|
tc := tc
|
||||||
t.Run(cases[0].URL, func(t *testing.T) {
|
t.Run(cases[0].URL, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
testHTTPRequest(t, baseURL, tc, testAPIKey)
|
testHTTPRequest(t, baseURL, tc, testAPIKey)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -559,6 +561,7 @@ func TestHTTPLogin(t *testing.T) {
|
|||||||
cfg.GUIReturns(config.GUIConfiguration{
|
cfg.GUIReturns(config.GUIConfiguration{
|
||||||
User: "üser",
|
User: "üser",
|
||||||
Password: "$2a$10$IdIZTxTg/dCNuNEGlmLynOjqg4B1FvDKuIV5e0BB3pnWVHNb8.GSq", // bcrypt of "räksmörgås" in UTF-8
|
Password: "$2a$10$IdIZTxTg/dCNuNEGlmLynOjqg4B1FvDKuIV5e0BB3pnWVHNb8.GSq", // bcrypt of "räksmörgås" in UTF-8
|
||||||
|
RawAddress: "127.0.0.1:0",
|
||||||
APIKey: testAPIKey,
|
APIKey: testAPIKey,
|
||||||
})
|
})
|
||||||
baseURL, cancel, err := startHTTP(cfg)
|
baseURL, cancel, err := startHTTP(cfg)
|
||||||
@ -1050,12 +1053,12 @@ func TestHostCheck(t *testing.T) {
|
|||||||
t.Error("Incorrect host header, check disabled: expected 200 OK, not", resp.Status)
|
t.Error("Incorrect host header, check disabled: expected 200 OK, not", resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !testing.Short() {
|
||||||
// A server bound to a wildcard address also doesn't do the check
|
// A server bound to a wildcard address also doesn't do the check
|
||||||
|
|
||||||
cfg = newMockedConfig()
|
cfg = newMockedConfig()
|
||||||
cfg.GUIReturns(config.GUIConfiguration{
|
cfg.GUIReturns(config.GUIConfiguration{
|
||||||
RawAddress: "0.0.0.0:0",
|
RawAddress: "0.0.0.0:0",
|
||||||
InsecureSkipHostCheck: true,
|
|
||||||
})
|
})
|
||||||
baseURL, cancel, err = startHTTP(cfg)
|
baseURL, cancel, err = startHTTP(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1075,6 +1078,7 @@ func TestHostCheck(t *testing.T) {
|
|||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
t.Error("Incorrect host header, wildcard bound: expected 200 OK, not", resp.Status)
|
t.Error("Incorrect host header, wildcard bound: expected 200 OK, not", resp.Status)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This should all work over IPv6 as well
|
// This should all work over IPv6 as well
|
||||||
|
|
||||||
|
@ -32,12 +32,12 @@ func newFakeConnection(id protocol.DeviceID, model Model) *fakeConnection {
|
|||||||
f.RequestCalls(func(ctx context.Context, folder, name string, blockNo int, offset int64, size int, hash []byte, weakHash uint32, fromTemporary bool) ([]byte, error) {
|
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
|
return f.fileData[name], nil
|
||||||
})
|
})
|
||||||
f.IDReturns(id)
|
f.DeviceIDReturns(id)
|
||||||
f.CloseCalls(func(err error) {
|
f.CloseCalls(func(err error) {
|
||||||
f.closeOnce.Do(func() {
|
f.closeOnce.Do(func() {
|
||||||
close(f.closed)
|
close(f.closed)
|
||||||
})
|
})
|
||||||
model.Closed(id, err)
|
model.Closed(f, err)
|
||||||
f.ClosedReturns(f.closed)
|
f.ClosedReturns(f.closed)
|
||||||
})
|
})
|
||||||
return f
|
return f
|
||||||
@ -157,7 +157,7 @@ func (f *fakeConnection) sendIndexUpdate() {
|
|||||||
for i := range f.files {
|
for i := range f.files {
|
||||||
toSend[i] = prepareFileInfoForIndex(f.files[i])
|
toSend[i] = prepareFileInfoForIndex(f.files[i])
|
||||||
}
|
}
|
||||||
f.model.IndexUpdate(f.id, f.folder, toSend)
|
f.model.IndexUpdate(f, f.folder, toSend)
|
||||||
}
|
}
|
||||||
|
|
||||||
func addFakeConn(m *testModel, dev protocol.DeviceID, folderID string) *fakeConnection {
|
func addFakeConn(m *testModel, dev protocol.DeviceID, folderID string) *fakeConnection {
|
||||||
@ -165,7 +165,7 @@ func addFakeConn(m *testModel, dev protocol.DeviceID, folderID string) *fakeConn
|
|||||||
fc.folder = folderID
|
fc.folder = folderID
|
||||||
m.AddConnection(fc, protocol.Hello{})
|
m.AddConnection(fc, protocol.Hello{})
|
||||||
|
|
||||||
m.ClusterConfig(dev, protocol.ClusterConfig{
|
m.ClusterConfig(fc, protocol.ClusterConfig{
|
||||||
Folders: []protocol.Folder{
|
Folders: []protocol.Folder{
|
||||||
{
|
{
|
||||||
ID: folderID,
|
ID: folderID,
|
||||||
|
@ -30,7 +30,7 @@ func TestRecvOnlyRevertDeletes(t *testing.T) {
|
|||||||
defer wcfgCancel()
|
defer wcfgCancel()
|
||||||
ffs := f.Filesystem(nil)
|
ffs := f.Filesystem(nil)
|
||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
addFakeConn(m, device1, f.ID)
|
conn := addFakeConn(m, device1, f.ID)
|
||||||
|
|
||||||
// Create some test data
|
// Create some test data
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ func TestRecvOnlyRevertDeletes(t *testing.T) {
|
|||||||
|
|
||||||
// Send and index update for the known stuff
|
// Send and index update for the known stuff
|
||||||
|
|
||||||
must(t, m.Index(device1, "ro", knownFiles))
|
must(t, m.Index(conn, "ro", knownFiles))
|
||||||
f.updateLocalsFromScanning(knownFiles)
|
f.updateLocalsFromScanning(knownFiles)
|
||||||
|
|
||||||
size := globalSize(t, m, "ro")
|
size := globalSize(t, m, "ro")
|
||||||
@ -112,7 +112,7 @@ func TestRecvOnlyRevertNeeds(t *testing.T) {
|
|||||||
defer wcfgCancel()
|
defer wcfgCancel()
|
||||||
ffs := f.Filesystem(nil)
|
ffs := f.Filesystem(nil)
|
||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
addFakeConn(m, device1, f.ID)
|
conn := addFakeConn(m, device1, f.ID)
|
||||||
|
|
||||||
// Create some test data
|
// Create some test data
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ func TestRecvOnlyRevertNeeds(t *testing.T) {
|
|||||||
|
|
||||||
// Send and index update for the known stuff
|
// Send and index update for the known stuff
|
||||||
|
|
||||||
must(t, m.Index(device1, "ro", knownFiles))
|
must(t, m.Index(conn, "ro", knownFiles))
|
||||||
f.updateLocalsFromScanning(knownFiles)
|
f.updateLocalsFromScanning(knownFiles)
|
||||||
|
|
||||||
// Scan the folder.
|
// Scan the folder.
|
||||||
@ -202,7 +202,7 @@ func TestRecvOnlyUndoChanges(t *testing.T) {
|
|||||||
defer wcfgCancel()
|
defer wcfgCancel()
|
||||||
ffs := f.Filesystem(nil)
|
ffs := f.Filesystem(nil)
|
||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
addFakeConn(m, device1, f.ID)
|
conn := addFakeConn(m, device1, f.ID)
|
||||||
|
|
||||||
// Create some test data
|
// Create some test data
|
||||||
|
|
||||||
@ -212,7 +212,7 @@ func TestRecvOnlyUndoChanges(t *testing.T) {
|
|||||||
|
|
||||||
// Send an index update for the known stuff
|
// Send an index update for the known stuff
|
||||||
|
|
||||||
must(t, m.Index(device1, "ro", knownFiles))
|
must(t, m.Index(conn, "ro", knownFiles))
|
||||||
f.updateLocalsFromScanning(knownFiles)
|
f.updateLocalsFromScanning(knownFiles)
|
||||||
|
|
||||||
// Scan the folder.
|
// Scan the folder.
|
||||||
@ -272,7 +272,7 @@ func TestRecvOnlyDeletedRemoteDrop(t *testing.T) {
|
|||||||
defer wcfgCancel()
|
defer wcfgCancel()
|
||||||
ffs := f.Filesystem(nil)
|
ffs := f.Filesystem(nil)
|
||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
addFakeConn(m, device1, f.ID)
|
conn := addFakeConn(m, device1, f.ID)
|
||||||
|
|
||||||
// Create some test data
|
// Create some test data
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ func TestRecvOnlyDeletedRemoteDrop(t *testing.T) {
|
|||||||
|
|
||||||
// Send an index update for the known stuff
|
// Send an index update for the known stuff
|
||||||
|
|
||||||
must(t, m.Index(device1, "ro", knownFiles))
|
must(t, m.Index(conn, "ro", knownFiles))
|
||||||
f.updateLocalsFromScanning(knownFiles)
|
f.updateLocalsFromScanning(knownFiles)
|
||||||
|
|
||||||
// Scan the folder.
|
// Scan the folder.
|
||||||
@ -337,7 +337,7 @@ func TestRecvOnlyRemoteUndoChanges(t *testing.T) {
|
|||||||
defer wcfgCancel()
|
defer wcfgCancel()
|
||||||
ffs := f.Filesystem(nil)
|
ffs := f.Filesystem(nil)
|
||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
addFakeConn(m, device1, f.ID)
|
conn := addFakeConn(m, device1, f.ID)
|
||||||
|
|
||||||
// Create some test data
|
// Create some test data
|
||||||
|
|
||||||
@ -347,7 +347,7 @@ func TestRecvOnlyRemoteUndoChanges(t *testing.T) {
|
|||||||
|
|
||||||
// Send an index update for the known stuff
|
// Send an index update for the known stuff
|
||||||
|
|
||||||
must(t, m.Index(device1, "ro", knownFiles))
|
must(t, m.Index(conn, "ro", knownFiles))
|
||||||
f.updateLocalsFromScanning(knownFiles)
|
f.updateLocalsFromScanning(knownFiles)
|
||||||
|
|
||||||
// Scan the folder.
|
// Scan the folder.
|
||||||
@ -402,7 +402,7 @@ func TestRecvOnlyRemoteUndoChanges(t *testing.T) {
|
|||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
snap.Release()
|
snap.Release()
|
||||||
must(t, m.IndexUpdate(device1, "ro", files))
|
must(t, m.IndexUpdate(conn, "ro", files))
|
||||||
|
|
||||||
// Ensure the pull to resolve conflicts (content identical) happened
|
// Ensure the pull to resolve conflicts (content identical) happened
|
||||||
must(t, f.doInSync(func() error {
|
must(t, f.doInSync(func() error {
|
||||||
@ -427,7 +427,7 @@ func TestRecvOnlyRevertOwnID(t *testing.T) {
|
|||||||
defer wcfgCancel()
|
defer wcfgCancel()
|
||||||
ffs := f.Filesystem(nil)
|
ffs := f.Filesystem(nil)
|
||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
addFakeConn(m, device1, f.ID)
|
conn := addFakeConn(m, device1, f.ID)
|
||||||
|
|
||||||
// Create some test data
|
// Create some test data
|
||||||
|
|
||||||
@ -470,7 +470,7 @@ func TestRecvOnlyRevertOwnID(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// Receive an index update with an older version, but valid and then revert
|
// Receive an index update with an older version, but valid and then revert
|
||||||
must(t, m.Index(device1, f.ID, []protocol.FileInfo{fi}))
|
must(t, m.Index(conn, f.ID, []protocol.FileInfo{fi}))
|
||||||
f.Revert()
|
f.Revert()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
|
@ -1278,7 +1278,7 @@ func TestPullSymlinkOverExistingWindows(t *testing.T) {
|
|||||||
|
|
||||||
m, f, wcfgCancel := setupSendReceiveFolder(t)
|
m, f, wcfgCancel := setupSendReceiveFolder(t)
|
||||||
defer wcfgCancel()
|
defer wcfgCancel()
|
||||||
addFakeConn(m, device1, f.ID)
|
conn := addFakeConn(m, device1, f.ID)
|
||||||
|
|
||||||
name := "foo"
|
name := "foo"
|
||||||
if fd, err := f.mtimefs.Create(name); err != nil {
|
if fd, err := f.mtimefs.Create(name); err != nil {
|
||||||
@ -1296,7 +1296,7 @@ func TestPullSymlinkOverExistingWindows(t *testing.T) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
t.Fatal("file missing")
|
t.Fatal("file missing")
|
||||||
}
|
}
|
||||||
must(t, m.Index(device1, f.ID, []protocol.FileInfo{{Name: name, Type: protocol.FileInfoTypeSymlink, Version: file.Version.Update(device1.Short())}}))
|
must(t, m.Index(conn, f.ID, []protocol.FileInfo{{Name: name, Type: protocol.FileInfoTypeSymlink, Version: file.Version.Update(device1.Short())}}))
|
||||||
|
|
||||||
scanChan := make(chan string)
|
scanChan := make(chan string)
|
||||||
|
|
||||||
|
@ -56,10 +56,10 @@ func newIndexHandler(conn protocol.Connection, downloads *deviceDownloadState, f
|
|||||||
// the IndexID, or something else weird has
|
// the IndexID, or something else weird has
|
||||||
// happened. We send a full index to reset the
|
// happened. We send a full index to reset the
|
||||||
// situation.
|
// situation.
|
||||||
l.Infof("Device %v folder %s is delta index compatible, but seems out of sync with reality", conn.ID().Short(), folder.Description())
|
l.Infof("Device %v folder %s is delta index compatible, but seems out of sync with reality", conn.DeviceID().Short(), folder.Description())
|
||||||
startSequence = 0
|
startSequence = 0
|
||||||
} else {
|
} else {
|
||||||
l.Debugf("Device %v folder %s is delta index compatible (mlv=%d)", conn.ID().Short(), folder.Description(), startInfo.local.MaxSequence)
|
l.Debugf("Device %v folder %s is delta index compatible (mlv=%d)", conn.DeviceID().Short(), folder.Description(), startInfo.local.MaxSequence)
|
||||||
startSequence = startInfo.local.MaxSequence
|
startSequence = startInfo.local.MaxSequence
|
||||||
}
|
}
|
||||||
} else if startInfo.local.IndexID != 0 {
|
} else if startInfo.local.IndexID != 0 {
|
||||||
@ -67,10 +67,10 @@ func newIndexHandler(conn protocol.Connection, downloads *deviceDownloadState, f
|
|||||||
// not the right one. Either they are confused or we
|
// not the right one. Either they are confused or we
|
||||||
// must have reset our database since last talking to
|
// must have reset our database since last talking to
|
||||||
// them. We'll start with a full index transfer.
|
// them. We'll start with a full index transfer.
|
||||||
l.Infof("Device %v folder %s has mismatching index ID for us (%v != %v)", conn.ID().Short(), folder.Description(), startInfo.local.IndexID, myIndexID)
|
l.Infof("Device %v folder %s has mismatching index ID for us (%v != %v)", conn.DeviceID().Short(), folder.Description(), startInfo.local.IndexID, myIndexID)
|
||||||
startSequence = 0
|
startSequence = 0
|
||||||
} else {
|
} else {
|
||||||
l.Debugf("Device %v folder %s has no index ID for us", conn.ID().Short(), folder.Description())
|
l.Debugf("Device %v folder %s has no index ID for us", conn.DeviceID().Short(), folder.Description())
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the other side's description of themselves. We
|
// This is the other side's description of themselves. We
|
||||||
@ -78,23 +78,23 @@ func newIndexHandler(conn protocol.Connection, downloads *deviceDownloadState, f
|
|||||||
// otherwise we drop our old index data and expect to get a
|
// otherwise we drop our old index data and expect to get a
|
||||||
// completely new set.
|
// completely new set.
|
||||||
|
|
||||||
theirIndexID := fset.IndexID(conn.ID())
|
theirIndexID := fset.IndexID(conn.DeviceID())
|
||||||
if startInfo.remote.IndexID == 0 {
|
if startInfo.remote.IndexID == 0 {
|
||||||
// They're not announcing an index ID. This means they
|
// They're not announcing an index ID. This means they
|
||||||
// do not support delta indexes and we should clear any
|
// do not support delta indexes and we should clear any
|
||||||
// information we have from them before accepting their
|
// information we have from them before accepting their
|
||||||
// index, which will presumably be a full index.
|
// index, which will presumably be a full index.
|
||||||
l.Debugf("Device %v folder %s does not announce an index ID", conn.ID().Short(), folder.Description())
|
l.Debugf("Device %v folder %s does not announce an index ID", conn.DeviceID().Short(), folder.Description())
|
||||||
fset.Drop(conn.ID())
|
fset.Drop(conn.DeviceID())
|
||||||
} else if startInfo.remote.IndexID != theirIndexID {
|
} else if startInfo.remote.IndexID != theirIndexID {
|
||||||
// The index ID we have on file is not what they're
|
// The index ID we have on file is not what they're
|
||||||
// announcing. They must have reset their database and
|
// announcing. They must have reset their database and
|
||||||
// will probably send us a full index. We drop any
|
// will probably send us a full index. We drop any
|
||||||
// information we have and remember this new index ID
|
// information we have and remember this new index ID
|
||||||
// instead.
|
// instead.
|
||||||
l.Infof("Device %v folder %s has a new index ID (%v)", conn.ID().Short(), folder.Description(), startInfo.remote.IndexID)
|
l.Infof("Device %v folder %s has a new index ID (%v)", conn.DeviceID().Short(), folder.Description(), startInfo.remote.IndexID)
|
||||||
fset.Drop(conn.ID())
|
fset.Drop(conn.DeviceID())
|
||||||
fset.SetIndexID(conn.ID(), startInfo.remote.IndexID)
|
fset.SetIndexID(conn.DeviceID(), startInfo.remote.IndexID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &indexHandler{
|
return &indexHandler{
|
||||||
@ -129,12 +129,12 @@ func (s *indexHandler) waitForFileset(ctx context.Context) (*db.FileSet, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *indexHandler) Serve(ctx context.Context) (err error) {
|
func (s *indexHandler) Serve(ctx context.Context) (err error) {
|
||||||
l.Debugf("Starting index handler for %s to %s at %s (slv=%d)", s.folder, s.conn.ID(), s.conn, s.prevSequence)
|
l.Debugf("Starting index handler for %s to %s at %s (slv=%d)", s.folder, s.conn.DeviceID().Short(), s.conn, s.prevSequence)
|
||||||
stop := make(chan struct{})
|
stop := make(chan struct{})
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
err = svcutil.NoRestartErr(err)
|
err = svcutil.NoRestartErr(err)
|
||||||
l.Debugf("Exiting index handler for %s to %s at %s: %v", s.folder, s.conn.ID(), s.conn, err)
|
l.Debugf("Exiting index handler for %s to %s at %s: %v", s.folder, s.conn.DeviceID().Short(), s.conn, err)
|
||||||
close(stop)
|
close(stop)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -308,7 +308,7 @@ func (s *indexHandler) sendIndexTo(ctx context.Context, fset *db.FileSet) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *indexHandler) receive(fs []protocol.FileInfo, update bool, op string) error {
|
func (s *indexHandler) receive(fs []protocol.FileInfo, update bool, op string) error {
|
||||||
deviceID := s.conn.ID()
|
deviceID := s.conn.DeviceID()
|
||||||
|
|
||||||
s.cond.L.Lock()
|
s.cond.L.Lock()
|
||||||
paused := s.paused
|
paused := s.paused
|
||||||
@ -369,7 +369,7 @@ func prepareFileInfoForIndex(f protocol.FileInfo) protocol.FileInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *indexHandler) String() string {
|
func (s *indexHandler) String() string {
|
||||||
return fmt.Sprintf("indexHandler@%p for %s to %s at %s", s, s.folder, s.conn.ID().Short(), s.conn)
|
return fmt.Sprintf("indexHandler@%p for %s to %s at %s", s, s.folder, s.conn.DeviceID().Short(), s.conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
type indexHandlerRegistry struct {
|
type indexHandlerRegistry struct {
|
||||||
@ -414,7 +414,7 @@ func newIndexHandlerRegistry(conn protocol.Connection, downloads *deviceDownload
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *indexHandlerRegistry) String() string {
|
func (r *indexHandlerRegistry) String() string {
|
||||||
return fmt.Sprintf("indexHandlerRegistry/%v", r.conn.ID().Short())
|
return fmt.Sprintf("indexHandlerRegistry/%v", r.conn.DeviceID().Short())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *indexHandlerRegistry) GetSupervisor() *suture.Supervisor {
|
func (r *indexHandlerRegistry) GetSupervisor() *suture.Supervisor {
|
||||||
@ -447,11 +447,11 @@ func (r *indexHandlerRegistry) AddIndexInfo(folder string, startInfo *clusterCon
|
|||||||
if is, ok := r.indexHandlers[folder]; ok {
|
if is, ok := r.indexHandlers[folder]; ok {
|
||||||
r.sup.RemoveAndWait(is.token, 0)
|
r.sup.RemoveAndWait(is.token, 0)
|
||||||
delete(r.indexHandlers, folder)
|
delete(r.indexHandlers, folder)
|
||||||
l.Debugf("Removed index sender for device %v and folder %v due to added pending", r.conn.ID().Short(), folder)
|
l.Debugf("Removed index sender for device %v and folder %v due to added pending", r.conn.DeviceID().Short(), folder)
|
||||||
}
|
}
|
||||||
folderState, ok := r.folderStates[folder]
|
folderState, ok := r.folderStates[folder]
|
||||||
if !ok {
|
if !ok {
|
||||||
l.Debugf("Pending index handler for device %v and folder %v", r.conn.ID().Short(), folder)
|
l.Debugf("Pending index handler for device %v and folder %v", r.conn.DeviceID().Short(), folder)
|
||||||
r.startInfos[folder] = startInfo
|
r.startInfos[folder] = startInfo
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -464,13 +464,13 @@ func (r *indexHandlerRegistry) Remove(folder string) {
|
|||||||
r.mut.Lock()
|
r.mut.Lock()
|
||||||
defer r.mut.Unlock()
|
defer r.mut.Unlock()
|
||||||
|
|
||||||
l.Debugf("Removing index handler for device %v and folder %v", r.conn.ID().Short(), folder)
|
l.Debugf("Removing index handler for device %v and folder %v", r.conn.DeviceID().Short(), folder)
|
||||||
if is, ok := r.indexHandlers[folder]; ok {
|
if is, ok := r.indexHandlers[folder]; ok {
|
||||||
r.sup.RemoveAndWait(is.token, 0)
|
r.sup.RemoveAndWait(is.token, 0)
|
||||||
delete(r.indexHandlers, folder)
|
delete(r.indexHandlers, folder)
|
||||||
}
|
}
|
||||||
delete(r.startInfos, folder)
|
delete(r.startInfos, folder)
|
||||||
l.Debugf("Removed index handler for device %v and folder %v", r.conn.ID().Short(), folder)
|
l.Debugf("Removed index handler for device %v and folder %v", r.conn.DeviceID().Short(), folder)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveAllExcept stops all running index handlers and removes those pending to be started,
|
// RemoveAllExcept stops all running index handlers and removes those pending to be started,
|
||||||
@ -484,13 +484,13 @@ func (r *indexHandlerRegistry) RemoveAllExcept(except map[string]remoteFolderSta
|
|||||||
if _, ok := except[folder]; !ok {
|
if _, ok := except[folder]; !ok {
|
||||||
r.sup.RemoveAndWait(is.token, 0)
|
r.sup.RemoveAndWait(is.token, 0)
|
||||||
delete(r.indexHandlers, folder)
|
delete(r.indexHandlers, folder)
|
||||||
l.Debugf("Removed index handler for device %v and folder %v (removeAllExcept)", r.conn.ID().Short(), folder)
|
l.Debugf("Removed index handler for device %v and folder %v (removeAllExcept)", r.conn.DeviceID().Short(), folder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for folder := range r.startInfos {
|
for folder := range r.startInfos {
|
||||||
if _, ok := except[folder]; !ok {
|
if _, ok := except[folder]; !ok {
|
||||||
delete(r.startInfos, folder)
|
delete(r.startInfos, folder)
|
||||||
l.Debugf("Removed pending index handler for device %v and folder %v (removeAllExcept)", r.conn.ID().Short(), folder)
|
l.Debugf("Removed pending index handler for device %v and folder %v (removeAllExcept)", r.conn.DeviceID().Short(), folder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -499,7 +499,7 @@ func (r *indexHandlerRegistry) RemoveAllExcept(except map[string]remoteFolderSta
|
|||||||
// changes. The exception being if the folder is removed entirely, then call
|
// changes. The exception being if the folder is removed entirely, then call
|
||||||
// Remove. The fset and runner arguments may be nil, if given folder is paused.
|
// Remove. The fset and runner arguments may be nil, if given folder is paused.
|
||||||
func (r *indexHandlerRegistry) RegisterFolderState(folder config.FolderConfiguration, fset *db.FileSet, runner service) {
|
func (r *indexHandlerRegistry) RegisterFolderState(folder config.FolderConfiguration, fset *db.FileSet, runner service) {
|
||||||
if !folder.SharedWith(r.conn.ID()) {
|
if !folder.SharedWith(r.conn.DeviceID()) {
|
||||||
r.Remove(folder.ID)
|
r.Remove(folder.ID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -516,13 +516,13 @@ func (r *indexHandlerRegistry) RegisterFolderState(folder config.FolderConfigura
|
|||||||
// folderPausedLocked stops a running index handler.
|
// folderPausedLocked stops a running index handler.
|
||||||
// It is a noop if the folder isn't known or has not been started yet.
|
// It is a noop if the folder isn't known or has not been started yet.
|
||||||
func (r *indexHandlerRegistry) folderPausedLocked(folder string) {
|
func (r *indexHandlerRegistry) folderPausedLocked(folder string) {
|
||||||
l.Debugf("Pausing index handler for device %v and folder %v", r.conn.ID().Short(), folder)
|
l.Debugf("Pausing index handler for device %v and folder %v", r.conn.DeviceID().Short(), folder)
|
||||||
delete(r.folderStates, folder)
|
delete(r.folderStates, folder)
|
||||||
if is, ok := r.indexHandlers[folder]; ok {
|
if is, ok := r.indexHandlers[folder]; ok {
|
||||||
is.pause()
|
is.pause()
|
||||||
l.Debugf("Paused index handler for device %v and folder %v", r.conn.ID().Short(), folder)
|
l.Debugf("Paused index handler for device %v and folder %v", r.conn.DeviceID().Short(), folder)
|
||||||
} else {
|
} else {
|
||||||
l.Debugf("No index handler for device %v and folder %v to pause", r.conn.ID().Short(), folder)
|
l.Debugf("No index handler for device %v and folder %v to pause", r.conn.DeviceID().Short(), folder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,16 +541,16 @@ func (r *indexHandlerRegistry) folderRunningLocked(folder config.FolderConfigura
|
|||||||
if isOk {
|
if isOk {
|
||||||
r.sup.RemoveAndWait(is.token, 0)
|
r.sup.RemoveAndWait(is.token, 0)
|
||||||
delete(r.indexHandlers, folder.ID)
|
delete(r.indexHandlers, folder.ID)
|
||||||
l.Debugf("Removed index handler for device %v and folder %v in resume", r.conn.ID().Short(), folder.ID)
|
l.Debugf("Removed index handler for device %v and folder %v in resume", r.conn.DeviceID().Short(), folder.ID)
|
||||||
}
|
}
|
||||||
r.startLocked(folder, fset, runner, info)
|
r.startLocked(folder, fset, runner, info)
|
||||||
delete(r.startInfos, folder.ID)
|
delete(r.startInfos, folder.ID)
|
||||||
l.Debugf("Started index handler for device %v and folder %v in resume", r.conn.ID().Short(), folder.ID)
|
l.Debugf("Started index handler for device %v and folder %v in resume", r.conn.DeviceID().Short(), folder.ID)
|
||||||
} else if isOk {
|
} else if isOk {
|
||||||
l.Debugf("Resuming index handler for device %v and folder %v", r.conn.ID().Short(), folder)
|
l.Debugf("Resuming index handler for device %v and folder %v", r.conn.DeviceID().Short(), folder)
|
||||||
is.resume(fset, runner)
|
is.resume(fset, runner)
|
||||||
} else {
|
} else {
|
||||||
l.Debugf("Not resuming index handler for device %v and folder %v as none is paused and there is no start info", r.conn.ID().Short(), folder.ID)
|
l.Debugf("Not resuming index handler for device %v and folder %v as none is paused and there is no start info", r.conn.DeviceID().Short(), folder.ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,7 +560,7 @@ func (r *indexHandlerRegistry) ReceiveIndex(folder string, fs []protocol.FileInf
|
|||||||
is, isOk := r.indexHandlers[folder]
|
is, isOk := r.indexHandlers[folder]
|
||||||
if !isOk {
|
if !isOk {
|
||||||
l.Infof("%v for nonexistent or paused folder %q", op, folder)
|
l.Infof("%v for nonexistent or paused folder %q", op, folder)
|
||||||
return ErrFolderMissing
|
return fmt.Errorf("%s: %w", folder, ErrFolderMissing)
|
||||||
}
|
}
|
||||||
return is.receive(fs, update, op)
|
return is.receive(fs, update, op)
|
||||||
}
|
}
|
||||||
|
@ -44,16 +44,16 @@ type Model struct {
|
|||||||
arg1 string
|
arg1 string
|
||||||
arg2 string
|
arg2 string
|
||||||
}
|
}
|
||||||
ClosedStub func(protocol.DeviceID, error)
|
ClosedStub func(protocol.Connection, error)
|
||||||
closedMutex sync.RWMutex
|
closedMutex sync.RWMutex
|
||||||
closedArgsForCall []struct {
|
closedArgsForCall []struct {
|
||||||
arg1 protocol.DeviceID
|
arg1 protocol.Connection
|
||||||
arg2 error
|
arg2 error
|
||||||
}
|
}
|
||||||
ClusterConfigStub func(protocol.DeviceID, protocol.ClusterConfig) error
|
ClusterConfigStub func(protocol.Connection, protocol.ClusterConfig) error
|
||||||
clusterConfigMutex sync.RWMutex
|
clusterConfigMutex sync.RWMutex
|
||||||
clusterConfigArgsForCall []struct {
|
clusterConfigArgsForCall []struct {
|
||||||
arg1 protocol.DeviceID
|
arg1 protocol.Connection
|
||||||
arg2 protocol.ClusterConfig
|
arg2 protocol.ClusterConfig
|
||||||
}
|
}
|
||||||
clusterConfigReturns struct {
|
clusterConfigReturns struct {
|
||||||
@ -200,10 +200,10 @@ type Model struct {
|
|||||||
dismissPendingFolderReturnsOnCall map[int]struct {
|
dismissPendingFolderReturnsOnCall map[int]struct {
|
||||||
result1 error
|
result1 error
|
||||||
}
|
}
|
||||||
DownloadProgressStub func(protocol.DeviceID, string, []protocol.FileDownloadProgressUpdate) error
|
DownloadProgressStub func(protocol.Connection, string, []protocol.FileDownloadProgressUpdate) error
|
||||||
downloadProgressMutex sync.RWMutex
|
downloadProgressMutex sync.RWMutex
|
||||||
downloadProgressArgsForCall []struct {
|
downloadProgressArgsForCall []struct {
|
||||||
arg1 protocol.DeviceID
|
arg1 protocol.Connection
|
||||||
arg2 string
|
arg2 string
|
||||||
arg3 []protocol.FileDownloadProgressUpdate
|
arg3 []protocol.FileDownloadProgressUpdate
|
||||||
}
|
}
|
||||||
@ -303,10 +303,10 @@ type Model struct {
|
|||||||
result1 []*model.TreeEntry
|
result1 []*model.TreeEntry
|
||||||
result2 error
|
result2 error
|
||||||
}
|
}
|
||||||
IndexStub func(protocol.DeviceID, string, []protocol.FileInfo) error
|
IndexStub func(protocol.Connection, string, []protocol.FileInfo) error
|
||||||
indexMutex sync.RWMutex
|
indexMutex sync.RWMutex
|
||||||
indexArgsForCall []struct {
|
indexArgsForCall []struct {
|
||||||
arg1 protocol.DeviceID
|
arg1 protocol.Connection
|
||||||
arg2 string
|
arg2 string
|
||||||
arg3 []protocol.FileInfo
|
arg3 []protocol.FileInfo
|
||||||
}
|
}
|
||||||
@ -316,10 +316,10 @@ type Model struct {
|
|||||||
indexReturnsOnCall map[int]struct {
|
indexReturnsOnCall map[int]struct {
|
||||||
result1 error
|
result1 error
|
||||||
}
|
}
|
||||||
IndexUpdateStub func(protocol.DeviceID, string, []protocol.FileInfo) error
|
IndexUpdateStub func(protocol.Connection, string, []protocol.FileInfo) error
|
||||||
indexUpdateMutex sync.RWMutex
|
indexUpdateMutex sync.RWMutex
|
||||||
indexUpdateArgsForCall []struct {
|
indexUpdateArgsForCall []struct {
|
||||||
arg1 protocol.DeviceID
|
arg1 protocol.Connection
|
||||||
arg2 string
|
arg2 string
|
||||||
arg3 []protocol.FileInfo
|
arg3 []protocol.FileInfo
|
||||||
}
|
}
|
||||||
@ -447,10 +447,10 @@ type Model struct {
|
|||||||
result1 []db.FileInfoTruncated
|
result1 []db.FileInfoTruncated
|
||||||
result2 error
|
result2 error
|
||||||
}
|
}
|
||||||
RequestStub func(protocol.DeviceID, string, string, int32, int32, int64, []byte, uint32, bool) (protocol.RequestResponse, error)
|
RequestStub func(protocol.Connection, string, string, int32, int32, int64, []byte, uint32, bool) (protocol.RequestResponse, error)
|
||||||
requestMutex sync.RWMutex
|
requestMutex sync.RWMutex
|
||||||
requestArgsForCall []struct {
|
requestArgsForCall []struct {
|
||||||
arg1 protocol.DeviceID
|
arg1 protocol.Connection
|
||||||
arg2 string
|
arg2 string
|
||||||
arg3 string
|
arg3 string
|
||||||
arg4 int32
|
arg4 int32
|
||||||
@ -728,10 +728,10 @@ func (fake *Model) BringToFrontArgsForCall(i int) (string, string) {
|
|||||||
return argsForCall.arg1, argsForCall.arg2
|
return argsForCall.arg1, argsForCall.arg2
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) Closed(arg1 protocol.DeviceID, arg2 error) {
|
func (fake *Model) Closed(arg1 protocol.Connection, arg2 error) {
|
||||||
fake.closedMutex.Lock()
|
fake.closedMutex.Lock()
|
||||||
fake.closedArgsForCall = append(fake.closedArgsForCall, struct {
|
fake.closedArgsForCall = append(fake.closedArgsForCall, struct {
|
||||||
arg1 protocol.DeviceID
|
arg1 protocol.Connection
|
||||||
arg2 error
|
arg2 error
|
||||||
}{arg1, arg2})
|
}{arg1, arg2})
|
||||||
stub := fake.ClosedStub
|
stub := fake.ClosedStub
|
||||||
@ -748,24 +748,24 @@ func (fake *Model) ClosedCallCount() int {
|
|||||||
return len(fake.closedArgsForCall)
|
return len(fake.closedArgsForCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) ClosedCalls(stub func(protocol.DeviceID, error)) {
|
func (fake *Model) ClosedCalls(stub func(protocol.Connection, error)) {
|
||||||
fake.closedMutex.Lock()
|
fake.closedMutex.Lock()
|
||||||
defer fake.closedMutex.Unlock()
|
defer fake.closedMutex.Unlock()
|
||||||
fake.ClosedStub = stub
|
fake.ClosedStub = stub
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) ClosedArgsForCall(i int) (protocol.DeviceID, error) {
|
func (fake *Model) ClosedArgsForCall(i int) (protocol.Connection, error) {
|
||||||
fake.closedMutex.RLock()
|
fake.closedMutex.RLock()
|
||||||
defer fake.closedMutex.RUnlock()
|
defer fake.closedMutex.RUnlock()
|
||||||
argsForCall := fake.closedArgsForCall[i]
|
argsForCall := fake.closedArgsForCall[i]
|
||||||
return argsForCall.arg1, argsForCall.arg2
|
return argsForCall.arg1, argsForCall.arg2
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) ClusterConfig(arg1 protocol.DeviceID, arg2 protocol.ClusterConfig) error {
|
func (fake *Model) ClusterConfig(arg1 protocol.Connection, arg2 protocol.ClusterConfig) error {
|
||||||
fake.clusterConfigMutex.Lock()
|
fake.clusterConfigMutex.Lock()
|
||||||
ret, specificReturn := fake.clusterConfigReturnsOnCall[len(fake.clusterConfigArgsForCall)]
|
ret, specificReturn := fake.clusterConfigReturnsOnCall[len(fake.clusterConfigArgsForCall)]
|
||||||
fake.clusterConfigArgsForCall = append(fake.clusterConfigArgsForCall, struct {
|
fake.clusterConfigArgsForCall = append(fake.clusterConfigArgsForCall, struct {
|
||||||
arg1 protocol.DeviceID
|
arg1 protocol.Connection
|
||||||
arg2 protocol.ClusterConfig
|
arg2 protocol.ClusterConfig
|
||||||
}{arg1, arg2})
|
}{arg1, arg2})
|
||||||
stub := fake.ClusterConfigStub
|
stub := fake.ClusterConfigStub
|
||||||
@ -787,13 +787,13 @@ func (fake *Model) ClusterConfigCallCount() int {
|
|||||||
return len(fake.clusterConfigArgsForCall)
|
return len(fake.clusterConfigArgsForCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) ClusterConfigCalls(stub func(protocol.DeviceID, protocol.ClusterConfig) error) {
|
func (fake *Model) ClusterConfigCalls(stub func(protocol.Connection, protocol.ClusterConfig) error) {
|
||||||
fake.clusterConfigMutex.Lock()
|
fake.clusterConfigMutex.Lock()
|
||||||
defer fake.clusterConfigMutex.Unlock()
|
defer fake.clusterConfigMutex.Unlock()
|
||||||
fake.ClusterConfigStub = stub
|
fake.ClusterConfigStub = stub
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) ClusterConfigArgsForCall(i int) (protocol.DeviceID, protocol.ClusterConfig) {
|
func (fake *Model) ClusterConfigArgsForCall(i int) (protocol.Connection, protocol.ClusterConfig) {
|
||||||
fake.clusterConfigMutex.RLock()
|
fake.clusterConfigMutex.RLock()
|
||||||
defer fake.clusterConfigMutex.RUnlock()
|
defer fake.clusterConfigMutex.RUnlock()
|
||||||
argsForCall := fake.clusterConfigArgsForCall[i]
|
argsForCall := fake.clusterConfigArgsForCall[i]
|
||||||
@ -1484,7 +1484,7 @@ func (fake *Model) DismissPendingFolderReturnsOnCall(i int, result1 error) {
|
|||||||
}{result1}
|
}{result1}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) DownloadProgress(arg1 protocol.DeviceID, arg2 string, arg3 []protocol.FileDownloadProgressUpdate) error {
|
func (fake *Model) DownloadProgress(arg1 protocol.Connection, arg2 string, arg3 []protocol.FileDownloadProgressUpdate) error {
|
||||||
var arg3Copy []protocol.FileDownloadProgressUpdate
|
var arg3Copy []protocol.FileDownloadProgressUpdate
|
||||||
if arg3 != nil {
|
if arg3 != nil {
|
||||||
arg3Copy = make([]protocol.FileDownloadProgressUpdate, len(arg3))
|
arg3Copy = make([]protocol.FileDownloadProgressUpdate, len(arg3))
|
||||||
@ -1493,7 +1493,7 @@ func (fake *Model) DownloadProgress(arg1 protocol.DeviceID, arg2 string, arg3 []
|
|||||||
fake.downloadProgressMutex.Lock()
|
fake.downloadProgressMutex.Lock()
|
||||||
ret, specificReturn := fake.downloadProgressReturnsOnCall[len(fake.downloadProgressArgsForCall)]
|
ret, specificReturn := fake.downloadProgressReturnsOnCall[len(fake.downloadProgressArgsForCall)]
|
||||||
fake.downloadProgressArgsForCall = append(fake.downloadProgressArgsForCall, struct {
|
fake.downloadProgressArgsForCall = append(fake.downloadProgressArgsForCall, struct {
|
||||||
arg1 protocol.DeviceID
|
arg1 protocol.Connection
|
||||||
arg2 string
|
arg2 string
|
||||||
arg3 []protocol.FileDownloadProgressUpdate
|
arg3 []protocol.FileDownloadProgressUpdate
|
||||||
}{arg1, arg2, arg3Copy})
|
}{arg1, arg2, arg3Copy})
|
||||||
@ -1516,13 +1516,13 @@ func (fake *Model) DownloadProgressCallCount() int {
|
|||||||
return len(fake.downloadProgressArgsForCall)
|
return len(fake.downloadProgressArgsForCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) DownloadProgressCalls(stub func(protocol.DeviceID, string, []protocol.FileDownloadProgressUpdate) error) {
|
func (fake *Model) DownloadProgressCalls(stub func(protocol.Connection, string, []protocol.FileDownloadProgressUpdate) error) {
|
||||||
fake.downloadProgressMutex.Lock()
|
fake.downloadProgressMutex.Lock()
|
||||||
defer fake.downloadProgressMutex.Unlock()
|
defer fake.downloadProgressMutex.Unlock()
|
||||||
fake.DownloadProgressStub = stub
|
fake.DownloadProgressStub = stub
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) DownloadProgressArgsForCall(i int) (protocol.DeviceID, string, []protocol.FileDownloadProgressUpdate) {
|
func (fake *Model) DownloadProgressArgsForCall(i int) (protocol.Connection, string, []protocol.FileDownloadProgressUpdate) {
|
||||||
fake.downloadProgressMutex.RLock()
|
fake.downloadProgressMutex.RLock()
|
||||||
defer fake.downloadProgressMutex.RUnlock()
|
defer fake.downloadProgressMutex.RUnlock()
|
||||||
argsForCall := fake.downloadProgressArgsForCall[i]
|
argsForCall := fake.downloadProgressArgsForCall[i]
|
||||||
@ -1990,7 +1990,7 @@ func (fake *Model) GlobalDirectoryTreeReturnsOnCall(i int, result1 []*model.Tree
|
|||||||
}{result1, result2}
|
}{result1, result2}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) Index(arg1 protocol.DeviceID, arg2 string, arg3 []protocol.FileInfo) error {
|
func (fake *Model) Index(arg1 protocol.Connection, arg2 string, arg3 []protocol.FileInfo) error {
|
||||||
var arg3Copy []protocol.FileInfo
|
var arg3Copy []protocol.FileInfo
|
||||||
if arg3 != nil {
|
if arg3 != nil {
|
||||||
arg3Copy = make([]protocol.FileInfo, len(arg3))
|
arg3Copy = make([]protocol.FileInfo, len(arg3))
|
||||||
@ -1999,7 +1999,7 @@ func (fake *Model) Index(arg1 protocol.DeviceID, arg2 string, arg3 []protocol.Fi
|
|||||||
fake.indexMutex.Lock()
|
fake.indexMutex.Lock()
|
||||||
ret, specificReturn := fake.indexReturnsOnCall[len(fake.indexArgsForCall)]
|
ret, specificReturn := fake.indexReturnsOnCall[len(fake.indexArgsForCall)]
|
||||||
fake.indexArgsForCall = append(fake.indexArgsForCall, struct {
|
fake.indexArgsForCall = append(fake.indexArgsForCall, struct {
|
||||||
arg1 protocol.DeviceID
|
arg1 protocol.Connection
|
||||||
arg2 string
|
arg2 string
|
||||||
arg3 []protocol.FileInfo
|
arg3 []protocol.FileInfo
|
||||||
}{arg1, arg2, arg3Copy})
|
}{arg1, arg2, arg3Copy})
|
||||||
@ -2022,13 +2022,13 @@ func (fake *Model) IndexCallCount() int {
|
|||||||
return len(fake.indexArgsForCall)
|
return len(fake.indexArgsForCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) IndexCalls(stub func(protocol.DeviceID, string, []protocol.FileInfo) error) {
|
func (fake *Model) IndexCalls(stub func(protocol.Connection, string, []protocol.FileInfo) error) {
|
||||||
fake.indexMutex.Lock()
|
fake.indexMutex.Lock()
|
||||||
defer fake.indexMutex.Unlock()
|
defer fake.indexMutex.Unlock()
|
||||||
fake.IndexStub = stub
|
fake.IndexStub = stub
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) IndexArgsForCall(i int) (protocol.DeviceID, string, []protocol.FileInfo) {
|
func (fake *Model) IndexArgsForCall(i int) (protocol.Connection, string, []protocol.FileInfo) {
|
||||||
fake.indexMutex.RLock()
|
fake.indexMutex.RLock()
|
||||||
defer fake.indexMutex.RUnlock()
|
defer fake.indexMutex.RUnlock()
|
||||||
argsForCall := fake.indexArgsForCall[i]
|
argsForCall := fake.indexArgsForCall[i]
|
||||||
@ -2058,7 +2058,7 @@ func (fake *Model) IndexReturnsOnCall(i int, result1 error) {
|
|||||||
}{result1}
|
}{result1}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) IndexUpdate(arg1 protocol.DeviceID, arg2 string, arg3 []protocol.FileInfo) error {
|
func (fake *Model) IndexUpdate(arg1 protocol.Connection, arg2 string, arg3 []protocol.FileInfo) error {
|
||||||
var arg3Copy []protocol.FileInfo
|
var arg3Copy []protocol.FileInfo
|
||||||
if arg3 != nil {
|
if arg3 != nil {
|
||||||
arg3Copy = make([]protocol.FileInfo, len(arg3))
|
arg3Copy = make([]protocol.FileInfo, len(arg3))
|
||||||
@ -2067,7 +2067,7 @@ func (fake *Model) IndexUpdate(arg1 protocol.DeviceID, arg2 string, arg3 []proto
|
|||||||
fake.indexUpdateMutex.Lock()
|
fake.indexUpdateMutex.Lock()
|
||||||
ret, specificReturn := fake.indexUpdateReturnsOnCall[len(fake.indexUpdateArgsForCall)]
|
ret, specificReturn := fake.indexUpdateReturnsOnCall[len(fake.indexUpdateArgsForCall)]
|
||||||
fake.indexUpdateArgsForCall = append(fake.indexUpdateArgsForCall, struct {
|
fake.indexUpdateArgsForCall = append(fake.indexUpdateArgsForCall, struct {
|
||||||
arg1 protocol.DeviceID
|
arg1 protocol.Connection
|
||||||
arg2 string
|
arg2 string
|
||||||
arg3 []protocol.FileInfo
|
arg3 []protocol.FileInfo
|
||||||
}{arg1, arg2, arg3Copy})
|
}{arg1, arg2, arg3Copy})
|
||||||
@ -2090,13 +2090,13 @@ func (fake *Model) IndexUpdateCallCount() int {
|
|||||||
return len(fake.indexUpdateArgsForCall)
|
return len(fake.indexUpdateArgsForCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) IndexUpdateCalls(stub func(protocol.DeviceID, string, []protocol.FileInfo) error) {
|
func (fake *Model) IndexUpdateCalls(stub func(protocol.Connection, string, []protocol.FileInfo) error) {
|
||||||
fake.indexUpdateMutex.Lock()
|
fake.indexUpdateMutex.Lock()
|
||||||
defer fake.indexUpdateMutex.Unlock()
|
defer fake.indexUpdateMutex.Unlock()
|
||||||
fake.IndexUpdateStub = stub
|
fake.IndexUpdateStub = stub
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) IndexUpdateArgsForCall(i int) (protocol.DeviceID, string, []protocol.FileInfo) {
|
func (fake *Model) IndexUpdateArgsForCall(i int) (protocol.Connection, string, []protocol.FileInfo) {
|
||||||
fake.indexUpdateMutex.RLock()
|
fake.indexUpdateMutex.RLock()
|
||||||
defer fake.indexUpdateMutex.RUnlock()
|
defer fake.indexUpdateMutex.RUnlock()
|
||||||
argsForCall := fake.indexUpdateArgsForCall[i]
|
argsForCall := fake.indexUpdateArgsForCall[i]
|
||||||
@ -2666,7 +2666,7 @@ func (fake *Model) RemoteNeedFolderFilesReturnsOnCall(i int, result1 []db.FileIn
|
|||||||
}{result1, result2}
|
}{result1, result2}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) Request(arg1 protocol.DeviceID, arg2 string, arg3 string, arg4 int32, arg5 int32, arg6 int64, arg7 []byte, arg8 uint32, arg9 bool) (protocol.RequestResponse, error) {
|
func (fake *Model) Request(arg1 protocol.Connection, arg2 string, arg3 string, arg4 int32, arg5 int32, arg6 int64, arg7 []byte, arg8 uint32, arg9 bool) (protocol.RequestResponse, error) {
|
||||||
var arg7Copy []byte
|
var arg7Copy []byte
|
||||||
if arg7 != nil {
|
if arg7 != nil {
|
||||||
arg7Copy = make([]byte, len(arg7))
|
arg7Copy = make([]byte, len(arg7))
|
||||||
@ -2675,7 +2675,7 @@ func (fake *Model) Request(arg1 protocol.DeviceID, arg2 string, arg3 string, arg
|
|||||||
fake.requestMutex.Lock()
|
fake.requestMutex.Lock()
|
||||||
ret, specificReturn := fake.requestReturnsOnCall[len(fake.requestArgsForCall)]
|
ret, specificReturn := fake.requestReturnsOnCall[len(fake.requestArgsForCall)]
|
||||||
fake.requestArgsForCall = append(fake.requestArgsForCall, struct {
|
fake.requestArgsForCall = append(fake.requestArgsForCall, struct {
|
||||||
arg1 protocol.DeviceID
|
arg1 protocol.Connection
|
||||||
arg2 string
|
arg2 string
|
||||||
arg3 string
|
arg3 string
|
||||||
arg4 int32
|
arg4 int32
|
||||||
@ -2704,13 +2704,13 @@ func (fake *Model) RequestCallCount() int {
|
|||||||
return len(fake.requestArgsForCall)
|
return len(fake.requestArgsForCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) RequestCalls(stub func(protocol.DeviceID, string, string, int32, int32, int64, []byte, uint32, bool) (protocol.RequestResponse, error)) {
|
func (fake *Model) RequestCalls(stub func(protocol.Connection, string, string, int32, int32, int64, []byte, uint32, bool) (protocol.RequestResponse, error)) {
|
||||||
fake.requestMutex.Lock()
|
fake.requestMutex.Lock()
|
||||||
defer fake.requestMutex.Unlock()
|
defer fake.requestMutex.Unlock()
|
||||||
fake.RequestStub = stub
|
fake.RequestStub = stub
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Model) RequestArgsForCall(i int) (protocol.DeviceID, string, string, int32, int32, int64, []byte, uint32, bool) {
|
func (fake *Model) RequestArgsForCall(i int) (protocol.Connection, string, string, int32, int32, int64, []byte, uint32, bool) {
|
||||||
fake.requestMutex.RLock()
|
fake.requestMutex.RLock()
|
||||||
defer fake.requestMutex.RUnlock()
|
defer fake.requestMutex.RUnlock()
|
||||||
argsForCall := fake.requestArgsForCall[i]
|
argsForCall := fake.requestArgsForCall[i]
|
||||||
|
@ -847,7 +847,7 @@ func (comp *FolderCompletion) setComplectionPct() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Map returns the members as a map, e.g. used in api to serialize as JSON.
|
// Map returns the members as a map, e.g. used in api to serialize as JSON.
|
||||||
func (comp FolderCompletion) Map() map[string]interface{} {
|
func (comp *FolderCompletion) Map() map[string]interface{} {
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"completion": comp.CompletionPct,
|
"completion": comp.CompletionPct,
|
||||||
"globalBytes": comp.GlobalBytes,
|
"globalBytes": comp.GlobalBytes,
|
||||||
@ -1110,22 +1110,23 @@ func (p *pager) done() bool {
|
|||||||
|
|
||||||
// Index is called when a new device is connected and we receive their full index.
|
// Index is called when a new device is connected and we receive their full index.
|
||||||
// Implements the protocol.Model interface.
|
// Implements the protocol.Model interface.
|
||||||
func (m *model) Index(deviceID protocol.DeviceID, folder string, fs []protocol.FileInfo) error {
|
func (m *model) Index(conn protocol.Connection, folder string, fs []protocol.FileInfo) error {
|
||||||
return m.handleIndex(deviceID, folder, fs, false)
|
return m.handleIndex(conn, folder, fs, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexUpdate is called for incremental updates to connected devices' indexes.
|
// IndexUpdate is called for incremental updates to connected devices' indexes.
|
||||||
// Implements the protocol.Model interface.
|
// Implements the protocol.Model interface.
|
||||||
func (m *model) IndexUpdate(deviceID protocol.DeviceID, folder string, fs []protocol.FileInfo) error {
|
func (m *model) IndexUpdate(conn protocol.Connection, folder string, fs []protocol.FileInfo) error {
|
||||||
return m.handleIndex(deviceID, folder, fs, true)
|
return m.handleIndex(conn, folder, fs, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *model) handleIndex(deviceID protocol.DeviceID, folder string, fs []protocol.FileInfo, update bool) error {
|
func (m *model) handleIndex(conn protocol.Connection, folder string, fs []protocol.FileInfo, update bool) error {
|
||||||
op := "Index"
|
op := "Index"
|
||||||
if update {
|
if update {
|
||||||
op += " update"
|
op += " update"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deviceID := conn.DeviceID()
|
||||||
l.Debugf("%v (in): %s / %q: %d files", op, deviceID, folder, len(fs))
|
l.Debugf("%v (in): %s / %q: %d files", op, deviceID, folder, len(fs))
|
||||||
|
|
||||||
if cfg, ok := m.cfg.Folder(folder); !ok || !cfg.SharedWith(deviceID) {
|
if cfg, ok := m.cfg.Folder(folder); !ok || !cfg.SharedWith(deviceID) {
|
||||||
@ -1159,12 +1160,13 @@ type ClusterConfigReceivedEventData struct {
|
|||||||
Device protocol.DeviceID `json:"device"`
|
Device protocol.DeviceID `json:"device"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterConfig) error {
|
func (m *model) ClusterConfig(conn protocol.Connection, cm protocol.ClusterConfig) error {
|
||||||
// Check the peer device's announced folders against our own. Emits events
|
// Check the peer device's announced folders against our own. Emits events
|
||||||
// for folders that we don't expect (unknown or not shared).
|
// for folders that we don't expect (unknown or not shared).
|
||||||
// Also, collect a list of folders we do share, and if he's interested in
|
// Also, collect a list of folders we do share, and if he's interested in
|
||||||
// temporary indexes, subscribe the connection.
|
// temporary indexes, subscribe the connection.
|
||||||
|
|
||||||
|
deviceID := conn.DeviceID()
|
||||||
l.Debugf("Handling ClusterConfig from %v", deviceID.Short())
|
l.Debugf("Handling ClusterConfig from %v", deviceID.Short())
|
||||||
|
|
||||||
m.pmut.RLock()
|
m.pmut.RLock()
|
||||||
@ -1544,7 +1546,7 @@ func (m *model) sendClusterConfig(ids []protocol.DeviceID) {
|
|||||||
m.pmut.RUnlock()
|
m.pmut.RUnlock()
|
||||||
// Generating cluster-configs acquires fmut -> must happen outside of pmut.
|
// Generating cluster-configs acquires fmut -> must happen outside of pmut.
|
||||||
for _, conn := range ccConns {
|
for _, conn := range ccConns {
|
||||||
cm, passwords := m.generateClusterConfig(conn.ID())
|
cm, passwords := m.generateClusterConfig(conn.DeviceID())
|
||||||
conn.SetFolderPasswords(passwords)
|
conn.SetFolderPasswords(passwords)
|
||||||
go conn.ClusterConfig(cm)
|
go conn.ClusterConfig(cm)
|
||||||
}
|
}
|
||||||
@ -1774,7 +1776,8 @@ func (m *model) introduceDevice(device protocol.Device, introducerCfg config.Dev
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Closed is called when a connection has been closed
|
// Closed is called when a connection has been closed
|
||||||
func (m *model) Closed(device protocol.DeviceID, err error) {
|
func (m *model) Closed(conn protocol.Connection, err error) {
|
||||||
|
device := conn.DeviceID()
|
||||||
m.pmut.Lock()
|
m.pmut.Lock()
|
||||||
conn, ok := m.conn[device]
|
conn, ok := m.conn[device]
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -1834,11 +1837,13 @@ func (r *requestResponse) Wait() {
|
|||||||
|
|
||||||
// Request returns the specified data segment by reading it from local disk.
|
// Request returns the specified data segment by reading it from local disk.
|
||||||
// Implements the protocol.Model interface.
|
// Implements the protocol.Model interface.
|
||||||
func (m *model) Request(deviceID protocol.DeviceID, folder, name string, _, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (out protocol.RequestResponse, err error) {
|
func (m *model) Request(conn protocol.Connection, folder, name string, _, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (out protocol.RequestResponse, err error) {
|
||||||
if size < 0 || offset < 0 {
|
if size < 0 || offset < 0 {
|
||||||
return nil, protocol.ErrInvalid
|
return nil, protocol.ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deviceID := conn.DeviceID()
|
||||||
|
|
||||||
m.fmut.RLock()
|
m.fmut.RLock()
|
||||||
folderCfg, ok := m.folderCfgs[folder]
|
folderCfg, ok := m.folderCfgs[folder]
|
||||||
folderIgnores := m.folderIgnores[folder]
|
folderIgnores := m.folderIgnores[folder]
|
||||||
@ -2214,7 +2219,7 @@ func (m *model) GetHello(id protocol.DeviceID) protocol.HelloIntf {
|
|||||||
// be sent to the connected peer, thereafter index updates whenever the local
|
// be sent to the connected peer, thereafter index updates whenever the local
|
||||||
// folder changes.
|
// folder changes.
|
||||||
func (m *model) AddConnection(conn protocol.Connection, hello protocol.Hello) {
|
func (m *model) AddConnection(conn protocol.Connection, hello protocol.Hello) {
|
||||||
deviceID := conn.ID()
|
deviceID := conn.DeviceID()
|
||||||
device, ok := m.cfg.Device(deviceID)
|
device, ok := m.cfg.Device(deviceID)
|
||||||
if !ok {
|
if !ok {
|
||||||
l.Infoln("Trying to add connection to unknown device")
|
l.Infoln("Trying to add connection to unknown device")
|
||||||
@ -2303,11 +2308,12 @@ func (m *model) AddConnection(conn protocol.Connection, hello protocol.Hello) {
|
|||||||
m.deviceWasSeen(deviceID)
|
m.deviceWasSeen(deviceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *model) DownloadProgress(device protocol.DeviceID, folder string, updates []protocol.FileDownloadProgressUpdate) error {
|
func (m *model) DownloadProgress(conn protocol.Connection, folder string, updates []protocol.FileDownloadProgressUpdate) error {
|
||||||
m.fmut.RLock()
|
m.fmut.RLock()
|
||||||
cfg, ok := m.folderCfgs[folder]
|
cfg, ok := m.folderCfgs[folder]
|
||||||
m.fmut.RUnlock()
|
m.fmut.RUnlock()
|
||||||
|
|
||||||
|
device := conn.DeviceID()
|
||||||
if !ok || cfg.DisableTempIndexes || !cfg.SharedWith(device) {
|
if !ok || cfg.DisableTempIndexes || !cfg.SharedWith(device) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ func TestRequest(t *testing.T) {
|
|||||||
m.ScanFolder("default")
|
m.ScanFolder("default")
|
||||||
|
|
||||||
// Existing, shared file
|
// Existing, shared file
|
||||||
res, err := m.Request(device1, "default", "foo", 0, 6, 0, nil, 0, false)
|
res, err := m.Request(device1Conn, "default", "foo", 0, 6, 0, nil, 0, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -104,35 +104,35 @@ func TestRequest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Existing, nonshared file
|
// Existing, nonshared file
|
||||||
_, err = m.Request(device2, "default", "foo", 0, 6, 0, nil, 0, false)
|
_, err = m.Request(device2Conn, "default", "foo", 0, 6, 0, nil, 0, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Unexpected nil error on insecure file read")
|
t.Error("Unexpected nil error on insecure file read")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nonexistent file
|
// Nonexistent file
|
||||||
_, err = m.Request(device1, "default", "nonexistent", 0, 6, 0, nil, 0, false)
|
_, err = m.Request(device1Conn, "default", "nonexistent", 0, 6, 0, nil, 0, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Unexpected nil error on insecure file read")
|
t.Error("Unexpected nil error on insecure file read")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shared folder, but disallowed file name
|
// Shared folder, but disallowed file name
|
||||||
_, err = m.Request(device1, "default", "../walk.go", 0, 6, 0, nil, 0, false)
|
_, err = m.Request(device1Conn, "default", "../walk.go", 0, 6, 0, nil, 0, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Unexpected nil error on insecure file read")
|
t.Error("Unexpected nil error on insecure file read")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Negative offset
|
// Negative offset
|
||||||
_, err = m.Request(device1, "default", "foo", 0, -4, 0, nil, 0, false)
|
_, err = m.Request(device1Conn, "default", "foo", 0, -4, 0, nil, 0, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Unexpected nil error on insecure file read")
|
t.Error("Unexpected nil error on insecure file read")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Larger block than available
|
// Larger block than available
|
||||||
_, err = m.Request(device1, "default", "foo", 0, 42, 0, []byte("hash necessary but not checked"), 0, false)
|
_, err = m.Request(device1Conn, "default", "foo", 0, 42, 0, []byte("hash necessary but not checked"), 0, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Unexpected nil error on read past end of file")
|
t.Error("Unexpected nil error on read past end of file")
|
||||||
}
|
}
|
||||||
_, err = m.Request(device1, "default", "foo", 0, 42, 0, nil, 0, false)
|
_, err = m.Request(device1Conn, "default", "foo", 0, 42, 0, nil, 0, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("Unexpected error when large read should be permitted")
|
t.Error("Unexpected error when large read should be permitted")
|
||||||
}
|
}
|
||||||
@ -168,11 +168,11 @@ func benchmarkIndex(b *testing.B, nfiles int) {
|
|||||||
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
|
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
|
||||||
|
|
||||||
files := genFiles(nfiles)
|
files := genFiles(nfiles)
|
||||||
must(b, m.Index(device1, fcfg.ID, files))
|
must(b, m.Index(device1Conn, fcfg.ID, files))
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
must(b, m.Index(device1, fcfg.ID, files))
|
must(b, m.Index(device1Conn, fcfg.ID, files))
|
||||||
}
|
}
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
}
|
}
|
||||||
@ -197,11 +197,11 @@ func benchmarkIndexUpdate(b *testing.B, nfiles, nufiles int) {
|
|||||||
files := genFiles(nfiles)
|
files := genFiles(nfiles)
|
||||||
ufiles := genFiles(nufiles)
|
ufiles := genFiles(nufiles)
|
||||||
|
|
||||||
must(b, m.Index(device1, fcfg.ID, files))
|
must(b, m.Index(device1Conn, fcfg.ID, files))
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
must(b, m.IndexUpdate(device1, fcfg.ID, ufiles))
|
must(b, m.IndexUpdate(device1Conn, fcfg.ID, ufiles))
|
||||||
}
|
}
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
}
|
}
|
||||||
@ -218,7 +218,7 @@ func BenchmarkRequestOut(b *testing.B) {
|
|||||||
fc.addFile(f.Name, 0o644, protocol.FileInfoTypeFile, []byte("some data to return"))
|
fc.addFile(f.Name, 0o644, protocol.FileInfoTypeFile, []byte("some data to return"))
|
||||||
}
|
}
|
||||||
m.AddConnection(fc, protocol.Hello{})
|
m.AddConnection(fc, protocol.Hello{})
|
||||||
must(b, m.Index(device1, "default", files))
|
must(b, m.Index(device1Conn, "default", files))
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
@ -247,7 +247,7 @@ func BenchmarkRequestInSingleFile(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
if _, err := m.Request(device1, "default", "request/for/a/file/in/a/couple/of/dirs/128k", 0, 128<<10, 0, nil, 0, false); err != nil {
|
if _, err := m.Request(device1Conn, "default", "request/for/a/file/in/a/couple/of/dirs/128k", 0, 128<<10, 0, nil, 0, false); err != nil {
|
||||||
b.Error(err)
|
b.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -287,7 +287,7 @@ func TestDeviceRename(t *testing.T) {
|
|||||||
t.Errorf("Device already has a name")
|
t.Errorf("Device already has a name")
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Closed(conn.ID(), protocol.ErrTimeout)
|
m.Closed(conn, protocol.ErrTimeout)
|
||||||
hello.DeviceName = "tester"
|
hello.DeviceName = "tester"
|
||||||
m.AddConnection(conn, hello)
|
m.AddConnection(conn, hello)
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ func TestDeviceRename(t *testing.T) {
|
|||||||
t.Errorf("Device did not get a name")
|
t.Errorf("Device did not get a name")
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Closed(conn.ID(), protocol.ErrTimeout)
|
m.Closed(conn, protocol.ErrTimeout)
|
||||||
hello.DeviceName = "tester2"
|
hello.DeviceName = "tester2"
|
||||||
m.AddConnection(conn, hello)
|
m.AddConnection(conn, hello)
|
||||||
|
|
||||||
@ -317,7 +317,7 @@ func TestDeviceRename(t *testing.T) {
|
|||||||
t.Errorf("Device name not saved in config")
|
t.Errorf("Device name not saved in config")
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Closed(conn.ID(), protocol.ErrTimeout)
|
m.Closed(conn, protocol.ErrTimeout)
|
||||||
|
|
||||||
waiter, err := cfg.Modify(func(cfg *config.Configuration) {
|
waiter, err := cfg.Modify(func(cfg *config.Configuration) {
|
||||||
cfg.Options.OverwriteRemoteDevNames = true
|
cfg.Options.OverwriteRemoteDevNames = true
|
||||||
@ -528,7 +528,7 @@ func TestIntroducer(t *testing.T) {
|
|||||||
SkipIntroductionRemovals: true,
|
SkipIntroductionRemovals: true,
|
||||||
EncryptionPasswordToken: []byte("faketoken"),
|
EncryptionPasswordToken: []byte("faketoken"),
|
||||||
})
|
})
|
||||||
m.ClusterConfig(device1, cc)
|
m.ClusterConfig(device1Conn, cc)
|
||||||
|
|
||||||
if newDev, ok := m.cfg.Device(device2); !ok || !newDev.Introducer || !newDev.SkipIntroductionRemovals {
|
if newDev, ok := m.cfg.Device(device2); !ok || !newDev.Introducer || !newDev.SkipIntroductionRemovals {
|
||||||
t.Error("device 2 missing or wrong flags")
|
t.Error("device 2 missing or wrong flags")
|
||||||
@ -584,7 +584,7 @@ func TestIntroducer(t *testing.T) {
|
|||||||
Introducer: true,
|
Introducer: true,
|
||||||
SkipIntroductionRemovals: true,
|
SkipIntroductionRemovals: true,
|
||||||
})
|
})
|
||||||
m.ClusterConfig(device1, cc)
|
m.ClusterConfig(device1Conn, cc)
|
||||||
|
|
||||||
// Should not get introducer, as it's already unset, and it's an existing device.
|
// Should not get introducer, as it's already unset, and it's an existing device.
|
||||||
if newDev, ok := m.cfg.Device(device2); !ok || newDev.Introducer || newDev.SkipIntroductionRemovals {
|
if newDev, ok := m.cfg.Device(device2); !ok || newDev.Introducer || newDev.SkipIntroductionRemovals {
|
||||||
@ -634,7 +634,7 @@ func TestIntroducer(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
m.ClusterConfig(device1, protocol.ClusterConfig{})
|
m.ClusterConfig(device1Conn, protocol.ClusterConfig{})
|
||||||
|
|
||||||
if _, ok := m.cfg.Device(device2); ok {
|
if _, ok := m.cfg.Device(device2); ok {
|
||||||
t.Error("device 2 should have been removed")
|
t.Error("device 2 should have been removed")
|
||||||
@ -686,7 +686,7 @@ func TestIntroducer(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
m.ClusterConfig(device1, protocol.ClusterConfig{})
|
m.ClusterConfig(device1Conn, protocol.ClusterConfig{})
|
||||||
|
|
||||||
if _, ok := m.cfg.Device(device2); !ok {
|
if _, ok := m.cfg.Device(device2); !ok {
|
||||||
t.Error("device 2 should not have been removed")
|
t.Error("device 2 should not have been removed")
|
||||||
@ -743,7 +743,7 @@ func TestIntroducer(t *testing.T) {
|
|||||||
Introducer: true,
|
Introducer: true,
|
||||||
SkipIntroductionRemovals: true,
|
SkipIntroductionRemovals: true,
|
||||||
})
|
})
|
||||||
m.ClusterConfig(device1, cc)
|
m.ClusterConfig(device1Conn, cc)
|
||||||
|
|
||||||
if _, ok := m.cfg.Device(device2); !ok {
|
if _, ok := m.cfg.Device(device2); !ok {
|
||||||
t.Error("device 2 should not have been removed")
|
t.Error("device 2 should not have been removed")
|
||||||
@ -794,7 +794,7 @@ func TestIntroducer(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
m.ClusterConfig(device1, protocol.ClusterConfig{})
|
m.ClusterConfig(device1Conn, protocol.ClusterConfig{})
|
||||||
|
|
||||||
if _, ok := m.cfg.Device(device2); !ok {
|
if _, ok := m.cfg.Device(device2); !ok {
|
||||||
t.Error("device 2 should not have been removed")
|
t.Error("device 2 should not have been removed")
|
||||||
@ -847,7 +847,7 @@ func TestIntroducer(t *testing.T) {
|
|||||||
})
|
})
|
||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
m.ClusterConfig(device1, protocol.ClusterConfig{})
|
m.ClusterConfig(device1Conn, protocol.ClusterConfig{})
|
||||||
|
|
||||||
if _, ok := m.cfg.Device(device2); !ok {
|
if _, ok := m.cfg.Device(device2); !ok {
|
||||||
t.Error("device 2 should not have been removed")
|
t.Error("device 2 should not have been removed")
|
||||||
@ -906,14 +906,14 @@ func TestIssue5063(t *testing.T) {
|
|||||||
for _, c := range m.conn {
|
for _, c := range m.conn {
|
||||||
conn := c.(*fakeConnection)
|
conn := c.(*fakeConnection)
|
||||||
conn.CloseCalls(func(_ error) {})
|
conn.CloseCalls(func(_ error) {})
|
||||||
defer m.Closed(c.ID(), errStopped) // to unblock deferred m.Stop()
|
defer m.Closed(c, errStopped) // to unblock deferred m.Stop()
|
||||||
}
|
}
|
||||||
m.pmut.Unlock()
|
m.pmut.Unlock()
|
||||||
|
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
|
|
||||||
addAndVerify := func(id string) {
|
addAndVerify := func(id string) {
|
||||||
m.ClusterConfig(device1, createClusterConfig(device1, id))
|
m.ClusterConfig(device1Conn, createClusterConfig(device1, id))
|
||||||
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
||||||
t.Error("expected shared", id)
|
t.Error("expected shared", id)
|
||||||
}
|
}
|
||||||
@ -951,7 +951,7 @@ func TestAutoAcceptRejected(t *testing.T) {
|
|||||||
// defer cleanupModel(m)
|
// defer cleanupModel(m)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
id := srand.String(8)
|
id := srand.String(8)
|
||||||
m.ClusterConfig(device1, createClusterConfig(device1, id))
|
m.ClusterConfig(device1Conn, createClusterConfig(device1, id))
|
||||||
|
|
||||||
if cfg, ok := m.cfg.Folder(id); ok && cfg.SharedWith(device1) {
|
if cfg, ok := m.cfg.Folder(id); ok && cfg.SharedWith(device1) {
|
||||||
t.Error("unexpected shared", id)
|
t.Error("unexpected shared", id)
|
||||||
@ -964,7 +964,7 @@ func TestAutoAcceptNewFolder(t *testing.T) {
|
|||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
id := srand.String(8)
|
id := srand.String(8)
|
||||||
m.ClusterConfig(device1, createClusterConfig(device1, id))
|
m.ClusterConfig(device1Conn, createClusterConfig(device1, id))
|
||||||
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
||||||
t.Error("expected shared", id)
|
t.Error("expected shared", id)
|
||||||
}
|
}
|
||||||
@ -976,14 +976,14 @@ func TestAutoAcceptNewFolderFromTwoDevices(t *testing.T) {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
id := srand.String(8)
|
id := srand.String(8)
|
||||||
defer os.RemoveAll(id)
|
defer os.RemoveAll(id)
|
||||||
m.ClusterConfig(device1, createClusterConfig(device1, id))
|
m.ClusterConfig(device1Conn, createClusterConfig(device1, id))
|
||||||
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
||||||
t.Error("expected shared", id)
|
t.Error("expected shared", id)
|
||||||
}
|
}
|
||||||
if fcfg, ok := m.cfg.Folder(id); !ok || fcfg.SharedWith(device2) {
|
if fcfg, ok := m.cfg.Folder(id); !ok || fcfg.SharedWith(device2) {
|
||||||
t.Error("unexpected expected shared", id)
|
t.Error("unexpected expected shared", id)
|
||||||
}
|
}
|
||||||
m.ClusterConfig(device2, createClusterConfig(device2, id))
|
m.ClusterConfig(device2Conn, createClusterConfig(device2, id))
|
||||||
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device2) {
|
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device2) {
|
||||||
t.Error("expected shared", id)
|
t.Error("expected shared", id)
|
||||||
}
|
}
|
||||||
@ -997,14 +997,14 @@ func TestAutoAcceptNewFolderFromOnlyOneDevice(t *testing.T) {
|
|||||||
defer os.RemoveAll(id)
|
defer os.RemoveAll(id)
|
||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
m.ClusterConfig(device1, createClusterConfig(device1, id))
|
m.ClusterConfig(device1Conn, createClusterConfig(device1, id))
|
||||||
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
||||||
t.Error("expected shared", id)
|
t.Error("expected shared", id)
|
||||||
}
|
}
|
||||||
if fcfg, ok := m.cfg.Folder(id); !ok || fcfg.SharedWith(device2) {
|
if fcfg, ok := m.cfg.Folder(id); !ok || fcfg.SharedWith(device2) {
|
||||||
t.Error("unexpected expected shared", id)
|
t.Error("unexpected expected shared", id)
|
||||||
}
|
}
|
||||||
m.ClusterConfig(device2, createClusterConfig(device2, id))
|
m.ClusterConfig(device2Conn, createClusterConfig(device2, id))
|
||||||
if fcfg, ok := m.cfg.Folder(id); !ok || fcfg.SharedWith(device2) {
|
if fcfg, ok := m.cfg.Folder(id); !ok || fcfg.SharedWith(device2) {
|
||||||
t.Error("unexpected shared", id)
|
t.Error("unexpected shared", id)
|
||||||
}
|
}
|
||||||
@ -1035,10 +1035,10 @@ func TestAutoAcceptNewFolderPremutationsNoPanic(t *testing.T) {
|
|||||||
cfg.Folders = append(cfg.Folders, fcfg)
|
cfg.Folders = append(cfg.Folders, fcfg)
|
||||||
}
|
}
|
||||||
m, cancel := newState(t, cfg)
|
m, cancel := newState(t, cfg)
|
||||||
m.ClusterConfig(device1, protocol.ClusterConfig{
|
m.ClusterConfig(device1Conn, protocol.ClusterConfig{
|
||||||
Folders: []protocol.Folder{dev1folder},
|
Folders: []protocol.Folder{dev1folder},
|
||||||
})
|
})
|
||||||
m.ClusterConfig(device2, protocol.ClusterConfig{
|
m.ClusterConfig(device2Conn, protocol.ClusterConfig{
|
||||||
Folders: []protocol.Folder{dev2folder},
|
Folders: []protocol.Folder{dev2folder},
|
||||||
})
|
})
|
||||||
cleanupModel(m)
|
cleanupModel(m)
|
||||||
@ -1058,7 +1058,7 @@ func TestAutoAcceptMultipleFolders(t *testing.T) {
|
|||||||
m, cancel := newState(t, defaultAutoAcceptCfg)
|
m, cancel := newState(t, defaultAutoAcceptCfg)
|
||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
m.ClusterConfig(device1, createClusterConfig(device1, id1, id2))
|
m.ClusterConfig(device1Conn, createClusterConfig(device1, id1, id2))
|
||||||
if fcfg, ok := m.cfg.Folder(id1); !ok || !fcfg.SharedWith(device1) {
|
if fcfg, ok := m.cfg.Folder(id1); !ok || !fcfg.SharedWith(device1) {
|
||||||
t.Error("expected shared", id1)
|
t.Error("expected shared", id1)
|
||||||
}
|
}
|
||||||
@ -1086,7 +1086,7 @@ func TestAutoAcceptExistingFolder(t *testing.T) {
|
|||||||
if fcfg, ok := m.cfg.Folder(id); !ok || fcfg.SharedWith(device1) {
|
if fcfg, ok := m.cfg.Folder(id); !ok || fcfg.SharedWith(device1) {
|
||||||
t.Error("missing folder, or shared", id)
|
t.Error("missing folder, or shared", id)
|
||||||
}
|
}
|
||||||
m.ClusterConfig(device1, createClusterConfig(device1, id))
|
m.ClusterConfig(device1Conn, createClusterConfig(device1, id))
|
||||||
|
|
||||||
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) || fcfg.Path != idOther {
|
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) || fcfg.Path != idOther {
|
||||||
t.Error("missing folder, or unshared, or path changed", id)
|
t.Error("missing folder, or unshared, or path changed", id)
|
||||||
@ -1112,7 +1112,7 @@ func TestAutoAcceptNewAndExistingFolder(t *testing.T) {
|
|||||||
if fcfg, ok := m.cfg.Folder(id1); !ok || fcfg.SharedWith(device1) {
|
if fcfg, ok := m.cfg.Folder(id1); !ok || fcfg.SharedWith(device1) {
|
||||||
t.Error("missing folder, or shared", id1)
|
t.Error("missing folder, or shared", id1)
|
||||||
}
|
}
|
||||||
m.ClusterConfig(device1, createClusterConfig(device1, id1, id2))
|
m.ClusterConfig(device1Conn, createClusterConfig(device1, id1, id2))
|
||||||
|
|
||||||
for i, id := range []string{id1, id2} {
|
for i, id := range []string{id1, id2} {
|
||||||
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
||||||
@ -1143,7 +1143,7 @@ func TestAutoAcceptAlreadyShared(t *testing.T) {
|
|||||||
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
||||||
t.Error("missing folder, or not shared", id)
|
t.Error("missing folder, or not shared", id)
|
||||||
}
|
}
|
||||||
m.ClusterConfig(device1, createClusterConfig(device1, id))
|
m.ClusterConfig(device1Conn, createClusterConfig(device1, id))
|
||||||
|
|
||||||
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
if fcfg, ok := m.cfg.Folder(id); !ok || !fcfg.SharedWith(device1) {
|
||||||
t.Error("missing folder, or not shared", id)
|
t.Error("missing folder, or not shared", id)
|
||||||
@ -1159,7 +1159,7 @@ func TestAutoAcceptNameConflict(t *testing.T) {
|
|||||||
m, cancel := newState(t, defaultAutoAcceptCfg)
|
m, cancel := newState(t, defaultAutoAcceptCfg)
|
||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
m.ClusterConfig(device1, protocol.ClusterConfig{
|
m.ClusterConfig(device1Conn, protocol.ClusterConfig{
|
||||||
Folders: []protocol.Folder{
|
Folders: []protocol.Folder{
|
||||||
{
|
{
|
||||||
ID: id,
|
ID: id,
|
||||||
@ -1179,7 +1179,7 @@ func TestAutoAcceptPrefersLabel(t *testing.T) {
|
|||||||
label := srand.String(8)
|
label := srand.String(8)
|
||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
m.ClusterConfig(device1, addFolderDevicesToClusterConfig(protocol.ClusterConfig{
|
m.ClusterConfig(device1Conn, addFolderDevicesToClusterConfig(protocol.ClusterConfig{
|
||||||
Folders: []protocol.Folder{
|
Folders: []protocol.Folder{
|
||||||
{
|
{
|
||||||
ID: id,
|
ID: id,
|
||||||
@ -1203,7 +1203,7 @@ func TestAutoAcceptFallsBackToID(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
m.ClusterConfig(device1, addFolderDevicesToClusterConfig(protocol.ClusterConfig{
|
m.ClusterConfig(device1Conn, addFolderDevicesToClusterConfig(protocol.ClusterConfig{
|
||||||
Folders: []protocol.Folder{
|
Folders: []protocol.Folder{
|
||||||
{
|
{
|
||||||
ID: id,
|
ID: id,
|
||||||
@ -1245,7 +1245,7 @@ func TestAutoAcceptPausedWhenFolderConfigChanged(t *testing.T) {
|
|||||||
t.Fatal("folder running?")
|
t.Fatal("folder running?")
|
||||||
}
|
}
|
||||||
|
|
||||||
m.ClusterConfig(device1, createClusterConfig(device1, id))
|
m.ClusterConfig(device1Conn, createClusterConfig(device1, id))
|
||||||
m.generateClusterConfig(device1)
|
m.generateClusterConfig(device1)
|
||||||
|
|
||||||
if fcfg, ok := m.cfg.Folder(id); !ok {
|
if fcfg, ok := m.cfg.Folder(id); !ok {
|
||||||
@ -1294,7 +1294,7 @@ func TestAutoAcceptPausedWhenFolderConfigNotChanged(t *testing.T) {
|
|||||||
t.Fatal("folder running?")
|
t.Fatal("folder running?")
|
||||||
}
|
}
|
||||||
|
|
||||||
m.ClusterConfig(device1, createClusterConfig(device1, id))
|
m.ClusterConfig(device1Conn, createClusterConfig(device1, id))
|
||||||
m.generateClusterConfig(device1)
|
m.generateClusterConfig(device1)
|
||||||
|
|
||||||
if fcfg, ok := m.cfg.Folder(id); !ok {
|
if fcfg, ok := m.cfg.Folder(id); !ok {
|
||||||
@ -1338,7 +1338,7 @@ func TestAutoAcceptEnc(t *testing.T) {
|
|||||||
// would panic.
|
// would panic.
|
||||||
clusterConfig := func(deviceID protocol.DeviceID, cm protocol.ClusterConfig) {
|
clusterConfig := func(deviceID protocol.DeviceID, cm protocol.ClusterConfig) {
|
||||||
m.AddConnection(newFakeConnection(deviceID, m), protocol.Hello{})
|
m.AddConnection(newFakeConnection(deviceID, m), protocol.Hello{})
|
||||||
m.ClusterConfig(deviceID, cm)
|
m.ClusterConfig(&protocolmocks.Connection{DeviceIDStub: func() protocol.DeviceID { return deviceID }}, cm)
|
||||||
}
|
}
|
||||||
|
|
||||||
clusterConfig(device1, basicCC())
|
clusterConfig(device1, basicCC())
|
||||||
@ -1703,7 +1703,7 @@ func TestRWScanRecovery(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGlobalDirectoryTree(t *testing.T) {
|
func TestGlobalDirectoryTree(t *testing.T) {
|
||||||
m, _, fcfg, wCancel := setupModelWithConnection(t)
|
m, conn, fcfg, wCancel := setupModelWithConnection(t)
|
||||||
defer wCancel()
|
defer wCancel()
|
||||||
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
|
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
|
||||||
|
|
||||||
@ -1807,7 +1807,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
|
|||||||
return string(bytes)
|
return string(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
must(t, m.Index(device1, "default", testdata))
|
must(t, m.Index(conn, "default", testdata))
|
||||||
|
|
||||||
result, _ := m.GlobalDirectoryTree("default", "", -1, false)
|
result, _ := m.GlobalDirectoryTree("default", "", -1, false)
|
||||||
|
|
||||||
@ -2014,7 +2014,7 @@ func benchmarkTree(b *testing.B, n1, n2 int) {
|
|||||||
m.ScanFolder(fcfg.ID)
|
m.ScanFolder(fcfg.ID)
|
||||||
files := genDeepFiles(n1, n2)
|
files := genDeepFiles(n1, n2)
|
||||||
|
|
||||||
must(b, m.Index(device1, fcfg.ID, files))
|
must(b, m.Index(device1Conn, fcfg.ID, files))
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
@ -2160,7 +2160,7 @@ func TestSharedWithClearedOnDisconnect(t *testing.T) {
|
|||||||
conn2 := newFakeConnection(device2, m)
|
conn2 := newFakeConnection(device2, m)
|
||||||
m.AddConnection(conn2, protocol.Hello{})
|
m.AddConnection(conn2, protocol.Hello{})
|
||||||
|
|
||||||
m.ClusterConfig(device1, protocol.ClusterConfig{
|
m.ClusterConfig(conn1, protocol.ClusterConfig{
|
||||||
Folders: []protocol.Folder{
|
Folders: []protocol.Folder{
|
||||||
{
|
{
|
||||||
ID: "default",
|
ID: "default",
|
||||||
@ -2172,7 +2172,7 @@ func TestSharedWithClearedOnDisconnect(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
m.ClusterConfig(device2, protocol.ClusterConfig{
|
m.ClusterConfig(conn2, protocol.ClusterConfig{
|
||||||
Folders: []protocol.Folder{
|
Folders: []protocol.Folder{
|
||||||
{
|
{
|
||||||
ID: "default",
|
ID: "default",
|
||||||
@ -2398,7 +2398,7 @@ func TestCustomMarkerName(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoveDirWithContent(t *testing.T) {
|
func TestRemoveDirWithContent(t *testing.T) {
|
||||||
m, _, fcfg, wcfgCancel := setupModelWithConnection(t)
|
m, conn, fcfg, wcfgCancel := setupModelWithConnection(t)
|
||||||
defer wcfgCancel()
|
defer wcfgCancel()
|
||||||
tfs := fcfg.Filesystem(nil)
|
tfs := fcfg.Filesystem(nil)
|
||||||
defer cleanupModelAndRemoveDir(m, tfs.URI())
|
defer cleanupModelAndRemoveDir(m, tfs.URI())
|
||||||
@ -2425,7 +2425,7 @@ func TestRemoveDirWithContent(t *testing.T) {
|
|||||||
file.Deleted = true
|
file.Deleted = true
|
||||||
file.Version = file.Version.Update(device1.Short()).Update(device1.Short())
|
file.Version = file.Version.Update(device1.Short()).Update(device1.Short())
|
||||||
|
|
||||||
must(t, m.IndexUpdate(device1, fcfg.ID, []protocol.FileInfo{dir, file}))
|
must(t, m.IndexUpdate(conn, fcfg.ID, []protocol.FileInfo{dir, file}))
|
||||||
|
|
||||||
// Is there something we could trigger on instead of just waiting?
|
// Is there something we could trigger on instead of just waiting?
|
||||||
timeout := time.NewTimer(5 * time.Second)
|
timeout := time.NewTimer(5 * time.Second)
|
||||||
@ -2919,19 +2919,19 @@ func TestRequestLimit(t *testing.T) {
|
|||||||
})
|
})
|
||||||
must(t, err)
|
must(t, err)
|
||||||
waiter.Wait()
|
waiter.Wait()
|
||||||
m, _ := setupModelWithConnectionFromWrapper(t, wrapper)
|
m, conn := setupModelWithConnectionFromWrapper(t, wrapper)
|
||||||
defer cleanupModel(m)
|
defer cleanupModel(m)
|
||||||
m.ScanFolder("default")
|
m.ScanFolder("default")
|
||||||
|
|
||||||
befReq := time.Now()
|
befReq := time.Now()
|
||||||
first, err := m.Request(device1, "default", file, 0, 2000, 0, nil, 0, false)
|
first, err := m.Request(conn, "default", file, 0, 2000, 0, nil, 0, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("First request failed: %v", err)
|
t.Fatalf("First request failed: %v", err)
|
||||||
}
|
}
|
||||||
reqDur := time.Since(befReq)
|
reqDur := time.Since(befReq)
|
||||||
returned := make(chan struct{})
|
returned := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
second, err := m.Request(device1, "default", file, 0, 2000, 0, nil, 0, false)
|
second, err := m.Request(conn, "default", file, 0, 2000, 0, nil, 0, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Second request failed: %v", err)
|
t.Errorf("Second request failed: %v", err)
|
||||||
}
|
}
|
||||||
@ -2969,12 +2969,16 @@ func TestConnCloseOnRestart(t *testing.T) {
|
|||||||
|
|
||||||
br := &testutils.BlockingRW{}
|
br := &testutils.BlockingRW{}
|
||||||
nw := &testutils.NoopRW{}
|
nw := &testutils.NoopRW{}
|
||||||
m.AddConnection(protocol.NewConnection(device1, br, nw, testutils.NoopCloser{}, m, new(protocolmocks.ConnectionInfo), protocol.CompressionNever, nil, m.keyGen), protocol.Hello{})
|
ci := &protocolmocks.ConnectionInfo{}
|
||||||
|
m.AddConnection(protocol.NewConnection(device1, br, nw, testutils.NoopCloser{}, m, ci, protocol.CompressionNever, nil, m.keyGen), protocol.Hello{})
|
||||||
m.pmut.RLock()
|
m.pmut.RLock()
|
||||||
if len(m.closed) != 1 {
|
if len(m.closed) != 1 {
|
||||||
t.Fatalf("Expected just one conn (len(m.conn) == %v)", len(m.conn))
|
t.Fatalf("Expected just one conn (len(m.closed) == %v)", len(m.closed))
|
||||||
|
}
|
||||||
|
var closed chan struct{}
|
||||||
|
for _, c := range m.closed {
|
||||||
|
closed = c
|
||||||
}
|
}
|
||||||
closed := m.closed[device1]
|
|
||||||
m.pmut.RUnlock()
|
m.pmut.RUnlock()
|
||||||
|
|
||||||
waiter, err := w.RemoveDevice(device1)
|
waiter, err := w.RemoveDevice(device1)
|
||||||
@ -3069,7 +3073,10 @@ func TestDevicePause(t *testing.T) {
|
|||||||
defer sub.Unsubscribe()
|
defer sub.Unsubscribe()
|
||||||
|
|
||||||
m.pmut.RLock()
|
m.pmut.RLock()
|
||||||
closed := m.closed[device1]
|
var closed chan struct{}
|
||||||
|
for _, c := range m.closed {
|
||||||
|
closed = c
|
||||||
|
}
|
||||||
m.pmut.RUnlock()
|
m.pmut.RUnlock()
|
||||||
|
|
||||||
pauseDevice(t, m.cfg, device1, true)
|
pauseDevice(t, m.cfg, device1, true)
|
||||||
@ -3567,7 +3574,7 @@ func TestAddFolderCompletion(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestScanDeletedROChangedOnSR(t *testing.T) {
|
func TestScanDeletedROChangedOnSR(t *testing.T) {
|
||||||
m, _, fcfg, wCancel := setupModelWithConnection(t)
|
m, conn, fcfg, wCancel := setupModelWithConnection(t)
|
||||||
ffs := fcfg.Filesystem(nil)
|
ffs := fcfg.Filesystem(nil)
|
||||||
defer wCancel()
|
defer wCancel()
|
||||||
defer cleanupModelAndRemoveDir(m, ffs.URI())
|
defer cleanupModelAndRemoveDir(m, ffs.URI())
|
||||||
@ -3585,7 +3592,7 @@ func TestScanDeletedROChangedOnSR(t *testing.T) {
|
|||||||
}
|
}
|
||||||
// A remote must have the file, otherwise the deletion below is
|
// A remote must have the file, otherwise the deletion below is
|
||||||
// automatically resolved as not a ro-changed item.
|
// automatically resolved as not a ro-changed item.
|
||||||
must(t, m.IndexUpdate(device1, fcfg.ID, []protocol.FileInfo{file}))
|
must(t, m.IndexUpdate(conn, fcfg.ID, []protocol.FileInfo{file}))
|
||||||
|
|
||||||
must(t, ffs.Remove(name))
|
must(t, ffs.Remove(name))
|
||||||
m.ScanFolders()
|
m.ScanFolders()
|
||||||
@ -3690,17 +3697,17 @@ func TestIssue6961(t *testing.T) {
|
|||||||
}
|
}
|
||||||
m.ServeBackground()
|
m.ServeBackground()
|
||||||
defer cleanupModelAndRemoveDir(m, tfs.URI())
|
defer cleanupModelAndRemoveDir(m, tfs.URI())
|
||||||
addFakeConn(m, device1, fcfg.ID)
|
conn1 := addFakeConn(m, device1, fcfg.ID)
|
||||||
addFakeConn(m, device2, fcfg.ID)
|
conn2 := addFakeConn(m, device2, fcfg.ID)
|
||||||
m.ScanFolders()
|
m.ScanFolders()
|
||||||
|
|
||||||
name := "foo"
|
name := "foo"
|
||||||
version := protocol.Vector{}.Update(device1.Short())
|
version := protocol.Vector{}.Update(device1.Short())
|
||||||
|
|
||||||
// Remote, valid and existing file
|
// Remote, valid and existing file
|
||||||
must(t, m.Index(device1, fcfg.ID, []protocol.FileInfo{{Name: name, Version: version, Sequence: 1}}))
|
must(t, m.Index(conn1, fcfg.ID, []protocol.FileInfo{{Name: name, Version: version, Sequence: 1}}))
|
||||||
// Remote, invalid (receive-only) and existing file
|
// Remote, invalid (receive-only) and existing file
|
||||||
must(t, m.Index(device2, fcfg.ID, []protocol.FileInfo{{Name: name, RawInvalid: true, Sequence: 1}}))
|
must(t, m.Index(conn2, fcfg.ID, []protocol.FileInfo{{Name: name, RawInvalid: true, Sequence: 1}}))
|
||||||
// Create a local file
|
// Create a local file
|
||||||
if fd, err := tfs.OpenFile(name, fs.OptCreate, 0o666); err != nil {
|
if fd, err := tfs.OpenFile(name, fs.OptCreate, 0o666); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -3726,7 +3733,7 @@ func TestIssue6961(t *testing.T) {
|
|||||||
m.ScanFolders()
|
m.ScanFolders()
|
||||||
|
|
||||||
// Drop the remote index, add some other file.
|
// Drop the remote index, add some other file.
|
||||||
must(t, m.Index(device2, fcfg.ID, []protocol.FileInfo{{Name: "bar", RawInvalid: true, Sequence: 1}}))
|
must(t, m.Index(conn2, fcfg.ID, []protocol.FileInfo{{Name: "bar", RawInvalid: true, Sequence: 1}}))
|
||||||
|
|
||||||
// Pause and unpause folder to create new db.FileSet and thus recalculate everything
|
// Pause and unpause folder to create new db.FileSet and thus recalculate everything
|
||||||
pauseFolder(t, wcfg, fcfg.ID, true)
|
pauseFolder(t, wcfg, fcfg.ID, true)
|
||||||
@ -3740,7 +3747,7 @@ func TestIssue6961(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCompletionEmptyGlobal(t *testing.T) {
|
func TestCompletionEmptyGlobal(t *testing.T) {
|
||||||
m, _, fcfg, wcfgCancel := setupModelWithConnection(t)
|
m, conn, fcfg, wcfgCancel := setupModelWithConnection(t)
|
||||||
defer wcfgCancel()
|
defer wcfgCancel()
|
||||||
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
|
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem(nil).URI())
|
||||||
files := []protocol.FileInfo{{Name: "foo", Version: protocol.Vector{}.Update(myID.Short()), Sequence: 1}}
|
files := []protocol.FileInfo{{Name: "foo", Version: protocol.Vector{}.Update(myID.Short()), Sequence: 1}}
|
||||||
@ -3749,7 +3756,7 @@ func TestCompletionEmptyGlobal(t *testing.T) {
|
|||||||
m.fmut.Unlock()
|
m.fmut.Unlock()
|
||||||
files[0].Deleted = true
|
files[0].Deleted = true
|
||||||
files[0].Version = files[0].Version.Update(device1.Short())
|
files[0].Version = files[0].Version.Update(device1.Short())
|
||||||
must(t, m.IndexUpdate(device1, fcfg.ID, files))
|
must(t, m.IndexUpdate(conn, fcfg.ID, files))
|
||||||
comp := m.testCompletion(protocol.LocalDeviceID, fcfg.ID)
|
comp := m.testCompletion(protocol.LocalDeviceID, fcfg.ID)
|
||||||
if comp.CompletionPct != 95 {
|
if comp.CompletionPct != 95 {
|
||||||
t.Error("Expected completion of 95%, got", comp.CompletionPct)
|
t.Error("Expected completion of 95%, got", comp.CompletionPct)
|
||||||
@ -3762,34 +3769,34 @@ func TestNeedMetaAfterIndexReset(t *testing.T) {
|
|||||||
addDevice2(t, w, fcfg)
|
addDevice2(t, w, fcfg)
|
||||||
m := setupModel(t, w)
|
m := setupModel(t, w)
|
||||||
defer cleanupModelAndRemoveDir(m, fcfg.Path)
|
defer cleanupModelAndRemoveDir(m, fcfg.Path)
|
||||||
addFakeConn(m, device1, fcfg.ID)
|
conn1 := addFakeConn(m, device1, fcfg.ID)
|
||||||
addFakeConn(m, device2, fcfg.ID)
|
conn2 := addFakeConn(m, device2, fcfg.ID)
|
||||||
|
|
||||||
var seq int64 = 1
|
var seq int64 = 1
|
||||||
files := []protocol.FileInfo{{Name: "foo", Size: 10, Version: protocol.Vector{}.Update(device1.Short()), Sequence: seq}}
|
files := []protocol.FileInfo{{Name: "foo", Size: 10, Version: protocol.Vector{}.Update(device1.Short()), Sequence: seq}}
|
||||||
|
|
||||||
// Start with two remotes having one file, then both deleting it, then
|
// Start with two remotes having one file, then both deleting it, then
|
||||||
// only one adding it again.
|
// only one adding it again.
|
||||||
must(t, m.Index(device1, fcfg.ID, files))
|
must(t, m.Index(conn1, fcfg.ID, files))
|
||||||
must(t, m.Index(device2, fcfg.ID, files))
|
must(t, m.Index(conn2, fcfg.ID, files))
|
||||||
seq++
|
seq++
|
||||||
files[0].SetDeleted(device2.Short())
|
files[0].SetDeleted(device2.Short())
|
||||||
files[0].Sequence = seq
|
files[0].Sequence = seq
|
||||||
must(t, m.IndexUpdate(device2, fcfg.ID, files))
|
must(t, m.IndexUpdate(conn1, fcfg.ID, files))
|
||||||
must(t, m.IndexUpdate(device1, fcfg.ID, files))
|
must(t, m.IndexUpdate(conn2, fcfg.ID, files))
|
||||||
seq++
|
seq++
|
||||||
files[0].Deleted = false
|
files[0].Deleted = false
|
||||||
files[0].Size = 20
|
files[0].Size = 20
|
||||||
files[0].Version = files[0].Version.Update(device1.Short())
|
files[0].Version = files[0].Version.Update(device1.Short())
|
||||||
files[0].Sequence = seq
|
files[0].Sequence = seq
|
||||||
must(t, m.IndexUpdate(device1, fcfg.ID, files))
|
must(t, m.IndexUpdate(conn1, fcfg.ID, files))
|
||||||
|
|
||||||
if comp := m.testCompletion(device2, fcfg.ID); comp.NeedItems != 1 {
|
if comp := m.testCompletion(device2, fcfg.ID); comp.NeedItems != 1 {
|
||||||
t.Error("Expected one needed item for device2, got", comp.NeedItems)
|
t.Error("Expected one needed item for device2, got", comp.NeedItems)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pretend we had an index reset on device 1
|
// Pretend we had an index reset on device 1
|
||||||
must(t, m.Index(device1, fcfg.ID, files))
|
must(t, m.Index(conn1, fcfg.ID, files))
|
||||||
if comp := m.testCompletion(device2, fcfg.ID); comp.NeedItems != 1 {
|
if comp := m.testCompletion(device2, fcfg.ID); comp.NeedItems != 1 {
|
||||||
t.Error("Expected one needed item for device2, got", comp.NeedItems)
|
t.Error("Expected one needed item for device2, got", comp.NeedItems)
|
||||||
}
|
}
|
||||||
|
@ -315,15 +315,15 @@ func (t *ProgressEmitter) emptyLocked() bool {
|
|||||||
func (t *ProgressEmitter) temporaryIndexSubscribe(conn protocol.Connection, folders []string) {
|
func (t *ProgressEmitter) temporaryIndexSubscribe(conn protocol.Connection, folders []string) {
|
||||||
t.mut.Lock()
|
t.mut.Lock()
|
||||||
defer t.mut.Unlock()
|
defer t.mut.Unlock()
|
||||||
t.connections[conn.ID()] = conn
|
t.connections[conn.DeviceID()] = conn
|
||||||
t.foldersByConns[conn.ID()] = folders
|
t.foldersByConns[conn.DeviceID()] = folders
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ProgressEmitter) temporaryIndexUnsubscribe(conn protocol.Connection) {
|
func (t *ProgressEmitter) temporaryIndexUnsubscribe(conn protocol.Connection) {
|
||||||
t.mut.Lock()
|
t.mut.Lock()
|
||||||
defer t.mut.Unlock()
|
defer t.mut.Unlock()
|
||||||
delete(t.connections, conn.ID())
|
delete(t.connections, conn.DeviceID())
|
||||||
delete(t.foldersByConns, conn.ID())
|
delete(t.foldersByConns, conn.DeviceID())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ProgressEmitter) clearLocked() {
|
func (t *ProgressEmitter) clearLocked() {
|
||||||
|
@ -463,7 +463,7 @@ func TestSendDownloadProgressMessages(t *testing.T) {
|
|||||||
p.temporaryIndexUnsubscribe(fc)
|
p.temporaryIndexUnsubscribe(fc)
|
||||||
|
|
||||||
sendMsgs(p)
|
sendMsgs(p)
|
||||||
_, ok := p.sentDownloadStates[fc.ID()]
|
_, ok := p.sentDownloadStates[fc.DeviceID()]
|
||||||
if ok {
|
if ok {
|
||||||
t.Error("Should not be there")
|
t.Error("Should not be there")
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ func TestSymlinkTraversalRead(t *testing.T) {
|
|||||||
<-done
|
<-done
|
||||||
|
|
||||||
// Request a file by traversing the symlink
|
// Request a file by traversing the symlink
|
||||||
res, err := m.Request(device1, "default", "symlink/requests_test.go", 0, 10, 0, nil, 0, false)
|
res, err := m.Request(device1Conn, "default", "symlink/requests_test.go", 0, 10, 0, nil, 0, false)
|
||||||
if err == nil || res != nil {
|
if err == nil || res != nil {
|
||||||
t.Error("Managed to traverse symlink")
|
t.Error("Managed to traverse symlink")
|
||||||
}
|
}
|
||||||
@ -439,7 +439,7 @@ func TestRescanIfHaveInvalidContent(t *testing.T) {
|
|||||||
t.Fatalf("unexpected weak hash: %d != 103547413", f.Blocks[0].WeakHash)
|
t.Fatalf("unexpected weak hash: %d != 103547413", f.Blocks[0].WeakHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := m.Request(device1, "default", "foo", 0, int32(len(payload)), 0, f.Blocks[0].Hash, f.Blocks[0].WeakHash, false)
|
res, err := m.Request(device1Conn, "default", "foo", 0, int32(len(payload)), 0, f.Blocks[0].Hash, f.Blocks[0].WeakHash, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -453,7 +453,7 @@ func TestRescanIfHaveInvalidContent(t *testing.T) {
|
|||||||
|
|
||||||
writeFile(t, tfs, "foo", payload)
|
writeFile(t, tfs, "foo", payload)
|
||||||
|
|
||||||
_, err = m.Request(device1, "default", "foo", 0, int32(len(payload)), 0, f.Blocks[0].Hash, f.Blocks[0].WeakHash, false)
|
_, err = m.Request(device1Conn, "default", "foo", 0, int32(len(payload)), 0, f.Blocks[0].Hash, f.Blocks[0].WeakHash, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expected failure")
|
t.Fatalf("expected failure")
|
||||||
}
|
}
|
||||||
@ -1122,7 +1122,7 @@ func TestRequestIndexSenderPause(t *testing.T) {
|
|||||||
|
|
||||||
cc := basicClusterConfig(device1, myID, fcfg.ID)
|
cc := basicClusterConfig(device1, myID, fcfg.ID)
|
||||||
cc.Folders[0].Paused = true
|
cc.Folders[0].Paused = true
|
||||||
m.ClusterConfig(device1, cc)
|
m.ClusterConfig(fc, cc)
|
||||||
|
|
||||||
seq++
|
seq++
|
||||||
files[0].Sequence = seq
|
files[0].Sequence = seq
|
||||||
@ -1143,7 +1143,7 @@ func TestRequestIndexSenderPause(t *testing.T) {
|
|||||||
// Remote unpaused
|
// Remote unpaused
|
||||||
|
|
||||||
cc.Folders[0].Paused = false
|
cc.Folders[0].Paused = false
|
||||||
m.ClusterConfig(device1, cc)
|
m.ClusterConfig(fc, cc)
|
||||||
select {
|
select {
|
||||||
case <-time.After(5 * time.Second):
|
case <-time.After(5 * time.Second):
|
||||||
t.Fatal("timed out before receiving index")
|
t.Fatal("timed out before receiving index")
|
||||||
@ -1168,12 +1168,12 @@ func TestRequestIndexSenderPause(t *testing.T) {
|
|||||||
// Local and remote paused, then first resume remote, then local
|
// Local and remote paused, then first resume remote, then local
|
||||||
|
|
||||||
cc.Folders[0].Paused = true
|
cc.Folders[0].Paused = true
|
||||||
m.ClusterConfig(device1, cc)
|
m.ClusterConfig(fc, cc)
|
||||||
|
|
||||||
pauseFolder(t, m.cfg, fcfg.ID, true)
|
pauseFolder(t, m.cfg, fcfg.ID, true)
|
||||||
|
|
||||||
cc.Folders[0].Paused = false
|
cc.Folders[0].Paused = false
|
||||||
m.ClusterConfig(device1, cc)
|
m.ClusterConfig(fc, cc)
|
||||||
|
|
||||||
pauseFolder(t, m.cfg, fcfg.ID, false)
|
pauseFolder(t, m.cfg, fcfg.ID, false)
|
||||||
|
|
||||||
@ -1190,7 +1190,7 @@ func TestRequestIndexSenderPause(t *testing.T) {
|
|||||||
// Folder removed on remote
|
// Folder removed on remote
|
||||||
|
|
||||||
cc = protocol.ClusterConfig{}
|
cc = protocol.ClusterConfig{}
|
||||||
m.ClusterConfig(device1, cc)
|
m.ClusterConfig(fc, cc)
|
||||||
|
|
||||||
seq++
|
seq++
|
||||||
files[0].Sequence = seq
|
files[0].Sequence = seq
|
||||||
@ -1304,7 +1304,7 @@ func TestRequestReceiveEncrypted(t *testing.T) {
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
m.AddConnection(fc, protocol.Hello{})
|
m.AddConnection(fc, protocol.Hello{})
|
||||||
m.ClusterConfig(device1, protocol.ClusterConfig{
|
m.ClusterConfig(fc, protocol.ClusterConfig{
|
||||||
Folders: []protocol.Folder{
|
Folders: []protocol.Folder{
|
||||||
{
|
{
|
||||||
ID: "default",
|
ID: "default",
|
||||||
@ -1354,7 +1354,7 @@ func TestRequestReceiveEncrypted(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Simulate request from device that is untrusted too, i.e. with non-empty, but garbage hash
|
// Simulate request from device that is untrusted too, i.e. with non-empty, but garbage hash
|
||||||
_, err := m.Request(device1, fcfg.ID, name, 0, 1064, 0, []byte("garbage"), 0, false)
|
_, err := m.Request(fc, fcfg.ID, name, 0, 1064, 0, []byte("garbage"), 0, false)
|
||||||
must(t, err)
|
must(t, err)
|
||||||
|
|
||||||
changed, err := m.LocalChangedFolderFiles(fcfg.ID, 1, 10)
|
changed, err := m.LocalChangedFolderFiles(fcfg.ID, 1, 10)
|
||||||
@ -1380,7 +1380,7 @@ func TestRequestGlobalInvalidToValid(t *testing.T) {
|
|||||||
})
|
})
|
||||||
must(t, err)
|
must(t, err)
|
||||||
waiter.Wait()
|
waiter.Wait()
|
||||||
addFakeConn(m, device2, fcfg.ID)
|
conn := addFakeConn(m, device2, fcfg.ID)
|
||||||
tfs := fcfg.Filesystem(nil)
|
tfs := fcfg.Filesystem(nil)
|
||||||
defer cleanupModelAndRemoveDir(m, tfs.URI())
|
defer cleanupModelAndRemoveDir(m, tfs.URI())
|
||||||
|
|
||||||
@ -1405,7 +1405,7 @@ func TestRequestGlobalInvalidToValid(t *testing.T) {
|
|||||||
file := fc.files[0]
|
file := fc.files[0]
|
||||||
fc.mut.Unlock()
|
fc.mut.Unlock()
|
||||||
file.SetIgnored()
|
file.SetIgnored()
|
||||||
m.IndexUpdate(device2, fcfg.ID, []protocol.FileInfo{prepareFileInfoForIndex(file)})
|
m.IndexUpdate(conn, fcfg.ID, []protocol.FileInfo{prepareFileInfoForIndex(file)})
|
||||||
|
|
||||||
// Wait for the ignored file to be received and possible pulled
|
// Wait for the ignored file to be received and possible pulled
|
||||||
timeout := time.After(10 * time.Second)
|
timeout := time.After(10 * time.Second)
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/fs"
|
"github.com/syncthing/syncthing/lib/fs"
|
||||||
"github.com/syncthing/syncthing/lib/ignore"
|
"github.com/syncthing/syncthing/lib/ignore"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
|
"github.com/syncthing/syncthing/lib/protocol/mocks"
|
||||||
"github.com/syncthing/syncthing/lib/rand"
|
"github.com/syncthing/syncthing/lib/rand"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,12 +30,16 @@ var (
|
|||||||
defaultFolderConfig config.FolderConfiguration
|
defaultFolderConfig config.FolderConfiguration
|
||||||
defaultCfg config.Configuration
|
defaultCfg config.Configuration
|
||||||
defaultAutoAcceptCfg config.Configuration
|
defaultAutoAcceptCfg config.Configuration
|
||||||
|
device1Conn = &mocks.Connection{}
|
||||||
|
device2Conn = &mocks.Connection{}
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
myID, _ = protocol.DeviceIDFromString("ZNWFSWE-RWRV2BD-45BLMCV-LTDE2UR-4LJDW6J-R5BPWEB-TXD27XJ-IZF5RA4")
|
myID, _ = protocol.DeviceIDFromString("ZNWFSWE-RWRV2BD-45BLMCV-LTDE2UR-4LJDW6J-R5BPWEB-TXD27XJ-IZF5RA4")
|
||||||
device1, _ = protocol.DeviceIDFromString("AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR")
|
device1, _ = protocol.DeviceIDFromString("AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR")
|
||||||
device2, _ = protocol.DeviceIDFromString("GYRZZQB-IRNPV4Z-T7TC52W-EQYJ3TT-FDQW6MW-DFLMU42-SSSU6EM-FBK2VAY")
|
device2, _ = protocol.DeviceIDFromString("GYRZZQB-IRNPV4Z-T7TC52W-EQYJ3TT-FDQW6MW-DFLMU42-SSSU6EM-FBK2VAY")
|
||||||
|
device1Conn.DeviceIDReturns(device1)
|
||||||
|
device2Conn.DeviceIDReturns(device2)
|
||||||
|
|
||||||
cfg := config.New(myID)
|
cfg := config.New(myID)
|
||||||
cfg.Options.MinHomeDiskFree.Value = 0 // avoids unnecessary free space checks
|
cfg.Options.MinHomeDiskFree.Value = 0 // avoids unnecessary free space checks
|
||||||
|
@ -167,15 +167,15 @@ func negotiateTLS(cert tls.Certificate, conn0, conn1 net.Conn) (net.Conn, net.Co
|
|||||||
|
|
||||||
type fakeModel struct{}
|
type fakeModel struct{}
|
||||||
|
|
||||||
func (*fakeModel) Index(_ DeviceID, _ string, _ []FileInfo) error {
|
func (*fakeModel) Index(Connection, string, []FileInfo) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*fakeModel) IndexUpdate(_ DeviceID, _ string, _ []FileInfo) error {
|
func (*fakeModel) IndexUpdate(Connection, string, []FileInfo) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*fakeModel) Request(_ DeviceID, _, _ string, _, size int32, offset int64, _ []byte, _ uint32, _ bool) (RequestResponse, error) {
|
func (*fakeModel) Request(_ Connection, _, _ string, _, size int32, offset int64, _ []byte, _ uint32, _ bool) (RequestResponse, error) {
|
||||||
// We write the offset to the end of the buffer, so the receiver
|
// We write the offset to the end of the buffer, so the receiver
|
||||||
// can verify that it did in fact get some data back over the
|
// can verify that it did in fact get some data back over the
|
||||||
// connection.
|
// connection.
|
||||||
@ -184,13 +184,13 @@ func (*fakeModel) Request(_ DeviceID, _, _ string, _, size int32, offset int64,
|
|||||||
return &fakeRequestResponse{buf}, nil
|
return &fakeRequestResponse{buf}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*fakeModel) ClusterConfig(_ DeviceID, _ ClusterConfig) error {
|
func (*fakeModel) ClusterConfig(Connection, ClusterConfig) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*fakeModel) Closed(DeviceID, error) {
|
func (*fakeModel) Closed(Connection, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*fakeModel) DownloadProgress(_ DeviceID, _ string, _ []FileDownloadProgressUpdate) error {
|
func (*fakeModel) DownloadProgress(Connection, string, []FileDownloadProgressUpdate) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ type TestModel struct {
|
|||||||
hash []byte
|
hash []byte
|
||||||
weakHash uint32
|
weakHash uint32
|
||||||
fromTemporary bool
|
fromTemporary bool
|
||||||
indexFn func(DeviceID, string, []FileInfo)
|
indexFn func(string, []FileInfo)
|
||||||
ccFn func(DeviceID, ClusterConfig)
|
ccFn func(ClusterConfig)
|
||||||
closedCh chan struct{}
|
closedCh chan struct{}
|
||||||
closedErr error
|
closedErr error
|
||||||
}
|
}
|
||||||
@ -25,18 +25,18 @@ func newTestModel() *TestModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestModel) Index(deviceID DeviceID, folder string, files []FileInfo) error {
|
func (t *TestModel) Index(_ Connection, folder string, files []FileInfo) error {
|
||||||
if t.indexFn != nil {
|
if t.indexFn != nil {
|
||||||
t.indexFn(deviceID, folder, files)
|
t.indexFn(folder, files)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*TestModel) IndexUpdate(_ DeviceID, _ string, _ []FileInfo) error {
|
func (*TestModel) IndexUpdate(Connection, string, []FileInfo) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestModel) Request(_ DeviceID, folder, name string, _, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (RequestResponse, error) {
|
func (t *TestModel) Request(_ Connection, folder, name string, _, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (RequestResponse, error) {
|
||||||
t.folder = folder
|
t.folder = folder
|
||||||
t.name = name
|
t.name = name
|
||||||
t.offset = offset
|
t.offset = offset
|
||||||
@ -49,19 +49,19 @@ func (t *TestModel) Request(_ DeviceID, folder, name string, _, size int32, offs
|
|||||||
return &fakeRequestResponse{buf}, nil
|
return &fakeRequestResponse{buf}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestModel) Closed(_ DeviceID, err error) {
|
func (t *TestModel) Closed(_ Connection, err error) {
|
||||||
t.closedErr = err
|
t.closedErr = err
|
||||||
close(t.closedCh)
|
close(t.closedCh)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestModel) ClusterConfig(deviceID DeviceID, config ClusterConfig) error {
|
func (t *TestModel) ClusterConfig(_ Connection, config ClusterConfig) error {
|
||||||
if t.ccFn != nil {
|
if t.ccFn != nil {
|
||||||
t.ccFn(deviceID, config)
|
t.ccFn(config)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*TestModel) DownloadProgress(DeviceID, string, []FileDownloadProgressUpdate) error {
|
func (*TestModel) DownloadProgress(Connection, string, []FileDownloadProgressUpdate) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,12 +43,12 @@ const (
|
|||||||
// receives encrypted metadata and requests from the untrusted device, so it
|
// receives encrypted metadata and requests from the untrusted device, so it
|
||||||
// must decrypt those and answer requests by encrypting the data.
|
// must decrypt those and answer requests by encrypting the data.
|
||||||
type encryptedModel struct {
|
type encryptedModel struct {
|
||||||
model Model
|
model contextLessModel
|
||||||
folderKeys *folderKeyRegistry
|
folderKeys *folderKeyRegistry
|
||||||
keyGen *KeyGenerator
|
keyGen *KeyGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
func newEncryptedModel(model Model, folderKeys *folderKeyRegistry, keyGen *KeyGenerator) encryptedModel {
|
func newEncryptedModel(model contextLessModel, folderKeys *folderKeyRegistry, keyGen *KeyGenerator) encryptedModel {
|
||||||
return encryptedModel{
|
return encryptedModel{
|
||||||
model: model,
|
model: model,
|
||||||
folderKeys: folderKeys,
|
folderKeys: folderKeys,
|
||||||
@ -56,30 +56,30 @@ func newEncryptedModel(model Model, folderKeys *folderKeyRegistry, keyGen *KeyGe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e encryptedModel) Index(deviceID DeviceID, folder string, files []FileInfo) error {
|
func (e encryptedModel) Index(folder string, files []FileInfo) error {
|
||||||
if folderKey, ok := e.folderKeys.get(folder); ok {
|
if folderKey, ok := e.folderKeys.get(folder); ok {
|
||||||
// incoming index data to be decrypted
|
// incoming index data to be decrypted
|
||||||
if err := decryptFileInfos(e.keyGen, files, folderKey); err != nil {
|
if err := decryptFileInfos(e.keyGen, files, folderKey); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return e.model.Index(deviceID, folder, files)
|
return e.model.Index(folder, files)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e encryptedModel) IndexUpdate(deviceID DeviceID, folder string, files []FileInfo) error {
|
func (e encryptedModel) IndexUpdate(folder string, files []FileInfo) error {
|
||||||
if folderKey, ok := e.folderKeys.get(folder); ok {
|
if folderKey, ok := e.folderKeys.get(folder); ok {
|
||||||
// incoming index data to be decrypted
|
// incoming index data to be decrypted
|
||||||
if err := decryptFileInfos(e.keyGen, files, folderKey); err != nil {
|
if err := decryptFileInfos(e.keyGen, files, folderKey); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return e.model.IndexUpdate(deviceID, folder, files)
|
return e.model.IndexUpdate(folder, files)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e encryptedModel) Request(deviceID DeviceID, folder, name string, blockNo, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (RequestResponse, error) {
|
func (e encryptedModel) Request(folder, name string, blockNo, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (RequestResponse, error) {
|
||||||
folderKey, ok := e.folderKeys.get(folder)
|
folderKey, ok := e.folderKeys.get(folder)
|
||||||
if !ok {
|
if !ok {
|
||||||
return e.model.Request(deviceID, folder, name, blockNo, size, offset, hash, weakHash, fromTemporary)
|
return e.model.Request(folder, name, blockNo, size, offset, hash, weakHash, fromTemporary)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Figure out the real file name, offset and size from the encrypted /
|
// Figure out the real file name, offset and size from the encrypted /
|
||||||
@ -120,7 +120,7 @@ func (e encryptedModel) Request(deviceID DeviceID, folder, name string, blockNo,
|
|||||||
|
|
||||||
// Perform that request and grab the data.
|
// Perform that request and grab the data.
|
||||||
|
|
||||||
resp, err := e.model.Request(deviceID, folder, realName, blockNo, realSize, realOffset, realHash, 0, false)
|
resp, err := e.model.Request(folder, realName, blockNo, realSize, realOffset, realHash, 0, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -142,21 +142,21 @@ func (e encryptedModel) Request(deviceID DeviceID, folder, name string, blockNo,
|
|||||||
return rawResponse{enc}, nil
|
return rawResponse{enc}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e encryptedModel) DownloadProgress(deviceID DeviceID, folder string, updates []FileDownloadProgressUpdate) error {
|
func (e encryptedModel) DownloadProgress(folder string, updates []FileDownloadProgressUpdate) error {
|
||||||
if _, ok := e.folderKeys.get(folder); !ok {
|
if _, ok := e.folderKeys.get(folder); !ok {
|
||||||
return e.model.DownloadProgress(deviceID, folder, updates)
|
return e.model.DownloadProgress(folder, updates)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypted devices shouldn't send these - ignore them.
|
// Encrypted devices shouldn't send these - ignore them.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e encryptedModel) ClusterConfig(deviceID DeviceID, config ClusterConfig) error {
|
func (e encryptedModel) ClusterConfig(config ClusterConfig) error {
|
||||||
return e.model.ClusterConfig(deviceID, config)
|
return e.model.ClusterConfig(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e encryptedModel) Closed(device DeviceID, err error) {
|
func (e encryptedModel) Closed(err error) {
|
||||||
e.model.Closed(device, err)
|
e.model.Closed(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The encryptedConnection sits between the model and the encrypted device. It
|
// The encryptedConnection sits between the model and the encrypted device. It
|
||||||
@ -185,8 +185,8 @@ func (e encryptedConnection) SetFolderPasswords(passwords map[string]string) {
|
|||||||
e.folderKeys.setPasswords(passwords)
|
e.folderKeys.setPasswords(passwords)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e encryptedConnection) ID() DeviceID {
|
func (e encryptedConnection) DeviceID() DeviceID {
|
||||||
return e.conn.ID()
|
return e.conn.DeviceID()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e encryptedConnection) Index(ctx context.Context, folder string, files []FileInfo) error {
|
func (e encryptedConnection) Index(ctx context.Context, folder string, files []FileInfo) error {
|
||||||
|
@ -41,6 +41,16 @@ type Connection struct {
|
|||||||
cryptoReturnsOnCall map[int]struct {
|
cryptoReturnsOnCall map[int]struct {
|
||||||
result1 string
|
result1 string
|
||||||
}
|
}
|
||||||
|
DeviceIDStub func() protocol.DeviceID
|
||||||
|
deviceIDMutex sync.RWMutex
|
||||||
|
deviceIDArgsForCall []struct {
|
||||||
|
}
|
||||||
|
deviceIDReturns struct {
|
||||||
|
result1 protocol.DeviceID
|
||||||
|
}
|
||||||
|
deviceIDReturnsOnCall map[int]struct {
|
||||||
|
result1 protocol.DeviceID
|
||||||
|
}
|
||||||
DownloadProgressStub func(context.Context, string, []protocol.FileDownloadProgressUpdate)
|
DownloadProgressStub func(context.Context, string, []protocol.FileDownloadProgressUpdate)
|
||||||
downloadProgressMutex sync.RWMutex
|
downloadProgressMutex sync.RWMutex
|
||||||
downloadProgressArgsForCall []struct {
|
downloadProgressArgsForCall []struct {
|
||||||
@ -58,16 +68,6 @@ type Connection struct {
|
|||||||
establishedAtReturnsOnCall map[int]struct {
|
establishedAtReturnsOnCall map[int]struct {
|
||||||
result1 time.Time
|
result1 time.Time
|
||||||
}
|
}
|
||||||
IDStub func() protocol.DeviceID
|
|
||||||
iDMutex sync.RWMutex
|
|
||||||
iDArgsForCall []struct {
|
|
||||||
}
|
|
||||||
iDReturns struct {
|
|
||||||
result1 protocol.DeviceID
|
|
||||||
}
|
|
||||||
iDReturnsOnCall map[int]struct {
|
|
||||||
result1 protocol.DeviceID
|
|
||||||
}
|
|
||||||
IndexStub func(context.Context, string, []protocol.FileInfo) error
|
IndexStub func(context.Context, string, []protocol.FileInfo) error
|
||||||
indexMutex sync.RWMutex
|
indexMutex sync.RWMutex
|
||||||
indexArgsForCall []struct {
|
indexArgsForCall []struct {
|
||||||
@ -368,6 +368,59 @@ func (fake *Connection) CryptoReturnsOnCall(i int, result1 string) {
|
|||||||
}{result1}
|
}{result1}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fake *Connection) DeviceID() protocol.DeviceID {
|
||||||
|
fake.deviceIDMutex.Lock()
|
||||||
|
ret, specificReturn := fake.deviceIDReturnsOnCall[len(fake.deviceIDArgsForCall)]
|
||||||
|
fake.deviceIDArgsForCall = append(fake.deviceIDArgsForCall, struct {
|
||||||
|
}{})
|
||||||
|
stub := fake.DeviceIDStub
|
||||||
|
fakeReturns := fake.deviceIDReturns
|
||||||
|
fake.recordInvocation("DeviceID", []interface{}{})
|
||||||
|
fake.deviceIDMutex.Unlock()
|
||||||
|
if stub != nil {
|
||||||
|
return stub()
|
||||||
|
}
|
||||||
|
if specificReturn {
|
||||||
|
return ret.result1
|
||||||
|
}
|
||||||
|
return fakeReturns.result1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fake *Connection) DeviceIDCallCount() int {
|
||||||
|
fake.deviceIDMutex.RLock()
|
||||||
|
defer fake.deviceIDMutex.RUnlock()
|
||||||
|
return len(fake.deviceIDArgsForCall)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fake *Connection) DeviceIDCalls(stub func() protocol.DeviceID) {
|
||||||
|
fake.deviceIDMutex.Lock()
|
||||||
|
defer fake.deviceIDMutex.Unlock()
|
||||||
|
fake.DeviceIDStub = stub
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fake *Connection) DeviceIDReturns(result1 protocol.DeviceID) {
|
||||||
|
fake.deviceIDMutex.Lock()
|
||||||
|
defer fake.deviceIDMutex.Unlock()
|
||||||
|
fake.DeviceIDStub = nil
|
||||||
|
fake.deviceIDReturns = struct {
|
||||||
|
result1 protocol.DeviceID
|
||||||
|
}{result1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fake *Connection) DeviceIDReturnsOnCall(i int, result1 protocol.DeviceID) {
|
||||||
|
fake.deviceIDMutex.Lock()
|
||||||
|
defer fake.deviceIDMutex.Unlock()
|
||||||
|
fake.DeviceIDStub = nil
|
||||||
|
if fake.deviceIDReturnsOnCall == nil {
|
||||||
|
fake.deviceIDReturnsOnCall = make(map[int]struct {
|
||||||
|
result1 protocol.DeviceID
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fake.deviceIDReturnsOnCall[i] = struct {
|
||||||
|
result1 protocol.DeviceID
|
||||||
|
}{result1}
|
||||||
|
}
|
||||||
|
|
||||||
func (fake *Connection) DownloadProgress(arg1 context.Context, arg2 string, arg3 []protocol.FileDownloadProgressUpdate) {
|
func (fake *Connection) DownloadProgress(arg1 context.Context, arg2 string, arg3 []protocol.FileDownloadProgressUpdate) {
|
||||||
var arg3Copy []protocol.FileDownloadProgressUpdate
|
var arg3Copy []protocol.FileDownloadProgressUpdate
|
||||||
if arg3 != nil {
|
if arg3 != nil {
|
||||||
@ -460,59 +513,6 @@ func (fake *Connection) EstablishedAtReturnsOnCall(i int, result1 time.Time) {
|
|||||||
}{result1}
|
}{result1}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fake *Connection) ID() protocol.DeviceID {
|
|
||||||
fake.iDMutex.Lock()
|
|
||||||
ret, specificReturn := fake.iDReturnsOnCall[len(fake.iDArgsForCall)]
|
|
||||||
fake.iDArgsForCall = append(fake.iDArgsForCall, struct {
|
|
||||||
}{})
|
|
||||||
stub := fake.IDStub
|
|
||||||
fakeReturns := fake.iDReturns
|
|
||||||
fake.recordInvocation("ID", []interface{}{})
|
|
||||||
fake.iDMutex.Unlock()
|
|
||||||
if stub != nil {
|
|
||||||
return stub()
|
|
||||||
}
|
|
||||||
if specificReturn {
|
|
||||||
return ret.result1
|
|
||||||
}
|
|
||||||
return fakeReturns.result1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fake *Connection) IDCallCount() int {
|
|
||||||
fake.iDMutex.RLock()
|
|
||||||
defer fake.iDMutex.RUnlock()
|
|
||||||
return len(fake.iDArgsForCall)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fake *Connection) IDCalls(stub func() protocol.DeviceID) {
|
|
||||||
fake.iDMutex.Lock()
|
|
||||||
defer fake.iDMutex.Unlock()
|
|
||||||
fake.IDStub = stub
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fake *Connection) IDReturns(result1 protocol.DeviceID) {
|
|
||||||
fake.iDMutex.Lock()
|
|
||||||
defer fake.iDMutex.Unlock()
|
|
||||||
fake.IDStub = nil
|
|
||||||
fake.iDReturns = struct {
|
|
||||||
result1 protocol.DeviceID
|
|
||||||
}{result1}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fake *Connection) IDReturnsOnCall(i int, result1 protocol.DeviceID) {
|
|
||||||
fake.iDMutex.Lock()
|
|
||||||
defer fake.iDMutex.Unlock()
|
|
||||||
fake.IDStub = nil
|
|
||||||
if fake.iDReturnsOnCall == nil {
|
|
||||||
fake.iDReturnsOnCall = make(map[int]struct {
|
|
||||||
result1 protocol.DeviceID
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fake.iDReturnsOnCall[i] = struct {
|
|
||||||
result1 protocol.DeviceID
|
|
||||||
}{result1}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fake *Connection) Index(arg1 context.Context, arg2 string, arg3 []protocol.FileInfo) error {
|
func (fake *Connection) Index(arg1 context.Context, arg2 string, arg3 []protocol.FileInfo) error {
|
||||||
var arg3Copy []protocol.FileInfo
|
var arg3Copy []protocol.FileInfo
|
||||||
if arg3 != nil {
|
if arg3 != nil {
|
||||||
@ -1164,12 +1164,12 @@ func (fake *Connection) Invocations() map[string][][]interface{} {
|
|||||||
defer fake.clusterConfigMutex.RUnlock()
|
defer fake.clusterConfigMutex.RUnlock()
|
||||||
fake.cryptoMutex.RLock()
|
fake.cryptoMutex.RLock()
|
||||||
defer fake.cryptoMutex.RUnlock()
|
defer fake.cryptoMutex.RUnlock()
|
||||||
|
fake.deviceIDMutex.RLock()
|
||||||
|
defer fake.deviceIDMutex.RUnlock()
|
||||||
fake.downloadProgressMutex.RLock()
|
fake.downloadProgressMutex.RLock()
|
||||||
defer fake.downloadProgressMutex.RUnlock()
|
defer fake.downloadProgressMutex.RUnlock()
|
||||||
fake.establishedAtMutex.RLock()
|
fake.establishedAtMutex.RLock()
|
||||||
defer fake.establishedAtMutex.RUnlock()
|
defer fake.establishedAtMutex.RUnlock()
|
||||||
fake.iDMutex.RLock()
|
|
||||||
defer fake.iDMutex.RUnlock()
|
|
||||||
fake.indexMutex.RLock()
|
fake.indexMutex.RLock()
|
||||||
defer fake.indexMutex.RUnlock()
|
defer fake.indexMutex.RUnlock()
|
||||||
fake.indexUpdateMutex.RLock()
|
fake.indexUpdateMutex.RLock()
|
||||||
|
@ -9,27 +9,27 @@ package protocol
|
|||||||
|
|
||||||
import "golang.org/x/text/unicode/norm"
|
import "golang.org/x/text/unicode/norm"
|
||||||
|
|
||||||
func makeNative(m Model) Model { return nativeModel{m} }
|
func makeNative(m contextLessModel) contextLessModel { return nativeModel{m} }
|
||||||
|
|
||||||
type nativeModel struct {
|
type nativeModel struct {
|
||||||
Model
|
contextLessModel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m nativeModel) Index(deviceID DeviceID, folder string, files []FileInfo) error {
|
func (m nativeModel) Index(folder string, files []FileInfo) error {
|
||||||
for i := range files {
|
for i := range files {
|
||||||
files[i].Name = norm.NFD.String(files[i].Name)
|
files[i].Name = norm.NFD.String(files[i].Name)
|
||||||
}
|
}
|
||||||
return m.Model.Index(deviceID, folder, files)
|
return m.contextLessModel.Index(folder, files)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m nativeModel) IndexUpdate(deviceID DeviceID, folder string, files []FileInfo) error {
|
func (m nativeModel) IndexUpdate(folder string, files []FileInfo) error {
|
||||||
for i := range files {
|
for i := range files {
|
||||||
files[i].Name = norm.NFD.String(files[i].Name)
|
files[i].Name = norm.NFD.String(files[i].Name)
|
||||||
}
|
}
|
||||||
return m.Model.IndexUpdate(deviceID, folder, files)
|
return m.contextLessModel.IndexUpdate(folder, files)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m nativeModel) Request(deviceID DeviceID, folder, name string, blockNo, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (RequestResponse, error) {
|
func (m nativeModel) Request(folder, name string, blockNo, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (RequestResponse, error) {
|
||||||
name = norm.NFD.String(name)
|
name = norm.NFD.String(name)
|
||||||
return m.Model.Request(deviceID, folder, name, blockNo, size, offset, hash, weakHash, fromTemporary)
|
return m.contextLessModel.Request(folder, name, blockNo, size, offset, hash, weakHash, fromTemporary)
|
||||||
}
|
}
|
||||||
|
@ -7,4 +7,4 @@ package protocol
|
|||||||
|
|
||||||
// Normal Unixes uses NFC and slashes, which is the wire format.
|
// Normal Unixes uses NFC and slashes, which is the wire format.
|
||||||
|
|
||||||
func makeNative(m Model) Model { return m }
|
func makeNative(m contextLessModel) contextLessModel { return m }
|
||||||
|
@ -13,30 +13,30 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeNative(m Model) Model { return nativeModel{m} }
|
func makeNative(m contextLessModel) contextLessModel { return nativeModel{m} }
|
||||||
|
|
||||||
type nativeModel struct {
|
type nativeModel struct {
|
||||||
Model
|
contextLessModel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m nativeModel) Index(deviceID DeviceID, folder string, files []FileInfo) error {
|
func (m nativeModel) Index(folder string, files []FileInfo) error {
|
||||||
files = fixupFiles(files)
|
files = fixupFiles(files)
|
||||||
return m.Model.Index(deviceID, folder, files)
|
return m.contextLessModel.Index(folder, files)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m nativeModel) IndexUpdate(deviceID DeviceID, folder string, files []FileInfo) error {
|
func (m nativeModel) IndexUpdate(folder string, files []FileInfo) error {
|
||||||
files = fixupFiles(files)
|
files = fixupFiles(files)
|
||||||
return m.Model.IndexUpdate(deviceID, folder, files)
|
return m.contextLessModel.IndexUpdate(folder, files)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m nativeModel) Request(deviceID DeviceID, folder, name string, blockNo, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (RequestResponse, error) {
|
func (m nativeModel) Request(folder, name string, blockNo, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (RequestResponse, error) {
|
||||||
if strings.Contains(name, `\`) {
|
if strings.Contains(name, `\`) {
|
||||||
l.Warnf("Dropping request for %s, contains invalid path separator", name)
|
l.Warnf("Dropping request for %s, contains invalid path separator", name)
|
||||||
return nil, ErrNoSuchFile
|
return nil, ErrNoSuchFile
|
||||||
}
|
}
|
||||||
|
|
||||||
name = filepath.FromSlash(name)
|
name = filepath.FromSlash(name)
|
||||||
return m.Model.Request(deviceID, folder, name, blockNo, size, offset, hash, weakHash, fromTemporary)
|
return m.contextLessModel.Request(folder, name, blockNo, size, offset, hash, weakHash, fromTemporary)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fixupFiles(files []FileInfo) []FileInfo {
|
func fixupFiles(files []FileInfo) []FileInfo {
|
||||||
|
@ -123,17 +123,28 @@ var (
|
|||||||
|
|
||||||
type Model interface {
|
type Model interface {
|
||||||
// An index was received from the peer device
|
// An index was received from the peer device
|
||||||
Index(deviceID DeviceID, folder string, files []FileInfo) error
|
Index(conn Connection, folder string, files []FileInfo) error
|
||||||
// An index update was received from the peer device
|
// An index update was received from the peer device
|
||||||
IndexUpdate(deviceID DeviceID, folder string, files []FileInfo) error
|
IndexUpdate(conn Connection, folder string, files []FileInfo) error
|
||||||
// A request was made by the peer device
|
// A request was made by the peer device
|
||||||
Request(deviceID DeviceID, folder, name string, blockNo, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (RequestResponse, error)
|
Request(conn Connection, folder, name string, blockNo, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (RequestResponse, error)
|
||||||
// A cluster configuration message was received
|
// A cluster configuration message was received
|
||||||
ClusterConfig(deviceID DeviceID, config ClusterConfig) error
|
ClusterConfig(conn Connection, config ClusterConfig) error
|
||||||
// The peer device closed the connection or an error occurred
|
// The peer device closed the connection or an error occurred
|
||||||
Closed(device DeviceID, err error)
|
Closed(conn Connection, err error)
|
||||||
// The peer device sent progress updates for the files it is currently downloading
|
// The peer device sent progress updates for the files it is currently downloading
|
||||||
DownloadProgress(deviceID DeviceID, folder string, updates []FileDownloadProgressUpdate) error
|
DownloadProgress(conn Connection, folder string, updates []FileDownloadProgressUpdate) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// contextLessModel is the Model interface, but without the initial
|
||||||
|
// Connection parameter. Internal use only.
|
||||||
|
type contextLessModel interface {
|
||||||
|
Index(folder string, files []FileInfo) error
|
||||||
|
IndexUpdate(folder string, files []FileInfo) error
|
||||||
|
Request(folder, name string, blockNo, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (RequestResponse, error)
|
||||||
|
ClusterConfig(config ClusterConfig) error
|
||||||
|
Closed(err error)
|
||||||
|
DownloadProgress(folder string, updates []FileDownloadProgressUpdate) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestResponse interface {
|
type RequestResponse interface {
|
||||||
@ -146,7 +157,7 @@ type Connection interface {
|
|||||||
Start()
|
Start()
|
||||||
SetFolderPasswords(passwords map[string]string)
|
SetFolderPasswords(passwords map[string]string)
|
||||||
Close(err error)
|
Close(err error)
|
||||||
ID() DeviceID
|
DeviceID() DeviceID
|
||||||
Index(ctx context.Context, folder string, files []FileInfo) error
|
Index(ctx context.Context, folder string, files []FileInfo) error
|
||||||
IndexUpdate(ctx context.Context, folder string, files []FileInfo) error
|
IndexUpdate(ctx context.Context, folder string, files []FileInfo) error
|
||||||
Request(ctx context.Context, folder string, name string, blockNo int, offset int64, size int, hash []byte, weakHash uint32, fromTemporary bool) ([]byte, error)
|
Request(ctx context.Context, folder string, name string, blockNo int, offset int64, size int, hash []byte, weakHash uint32, fromTemporary bool) ([]byte, error)
|
||||||
@ -171,8 +182,8 @@ type ConnectionInfo interface {
|
|||||||
type rawConnection struct {
|
type rawConnection struct {
|
||||||
ConnectionInfo
|
ConnectionInfo
|
||||||
|
|
||||||
id DeviceID
|
deviceID DeviceID
|
||||||
receiver Model
|
model contextLessModel
|
||||||
startTime time.Time
|
startTime time.Time
|
||||||
|
|
||||||
cr *countingReader
|
cr *countingReader
|
||||||
@ -229,10 +240,16 @@ const (
|
|||||||
// Should not be modified in production code, just for testing.
|
// Should not be modified in production code, just for testing.
|
||||||
var CloseTimeout = 10 * time.Second
|
var CloseTimeout = 10 * time.Second
|
||||||
|
|
||||||
func NewConnection(deviceID DeviceID, reader io.Reader, writer io.Writer, closer io.Closer, receiver Model, connInfo ConnectionInfo, compress Compression, passwords map[string]string, keyGen *KeyGenerator) Connection {
|
func NewConnection(deviceID DeviceID, reader io.Reader, writer io.Writer, closer io.Closer, model Model, connInfo ConnectionInfo, compress Compression, passwords map[string]string, keyGen *KeyGenerator) Connection {
|
||||||
|
// We create the wrapper for the model first, as it needs to be passed
|
||||||
|
// in at the lowest level in the stack. At the end of construction,
|
||||||
|
// before returning, we add the connection to cwm so that it can be used
|
||||||
|
// by the model.
|
||||||
|
cwm := &connectionWrappingModel{model: model}
|
||||||
|
|
||||||
// Encryption / decryption is first (outermost) before conversion to
|
// Encryption / decryption is first (outermost) before conversion to
|
||||||
// native path formats.
|
// native path formats.
|
||||||
nm := makeNative(receiver)
|
nm := makeNative(cwm)
|
||||||
em := newEncryptedModel(nm, newFolderKeyRegistry(keyGen, passwords), keyGen)
|
em := newEncryptedModel(nm, newFolderKeyRegistry(keyGen, passwords), keyGen)
|
||||||
|
|
||||||
// We do the wire format conversion first (outermost) so that the
|
// We do the wire format conversion first (outermost) so that the
|
||||||
@ -241,17 +258,18 @@ func NewConnection(deviceID DeviceID, reader io.Reader, writer io.Writer, closer
|
|||||||
ec := newEncryptedConnection(rc, rc, em.folderKeys, keyGen)
|
ec := newEncryptedConnection(rc, rc, em.folderKeys, keyGen)
|
||||||
wc := wireFormatConnection{ec}
|
wc := wireFormatConnection{ec}
|
||||||
|
|
||||||
|
cwm.conn = wc
|
||||||
return wc
|
return wc
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRawConnection(deviceID DeviceID, reader io.Reader, writer io.Writer, closer io.Closer, receiver Model, connInfo ConnectionInfo, compress Compression) *rawConnection {
|
func newRawConnection(deviceID DeviceID, reader io.Reader, writer io.Writer, closer io.Closer, receiver contextLessModel, connInfo ConnectionInfo, compress Compression) *rawConnection {
|
||||||
cr := &countingReader{Reader: reader}
|
cr := &countingReader{Reader: reader}
|
||||||
cw := &countingWriter{Writer: writer}
|
cw := &countingWriter{Writer: writer}
|
||||||
|
|
||||||
return &rawConnection{
|
return &rawConnection{
|
||||||
ConnectionInfo: connInfo,
|
ConnectionInfo: connInfo,
|
||||||
id: deviceID,
|
deviceID: deviceID,
|
||||||
receiver: receiver,
|
model: receiver,
|
||||||
cr: cr,
|
cr: cr,
|
||||||
cw: cw,
|
cw: cw,
|
||||||
closer: closer,
|
closer: closer,
|
||||||
@ -295,8 +313,8 @@ func (c *rawConnection) Start() {
|
|||||||
c.startTime = time.Now().Truncate(time.Second)
|
c.startTime = time.Now().Truncate(time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *rawConnection) ID() DeviceID {
|
func (c *rawConnection) DeviceID() DeviceID {
|
||||||
return c.id
|
return c.deviceID
|
||||||
}
|
}
|
||||||
|
|
||||||
// Index writes the list of file information to the connected peer device
|
// Index writes the list of file information to the connected peer device
|
||||||
@ -462,7 +480,7 @@ func (c *rawConnection) dispatcherLoop() (err error) {
|
|||||||
|
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case *ClusterConfig:
|
case *ClusterConfig:
|
||||||
err = c.receiver.ClusterConfig(c.id, *msg)
|
err = c.model.ClusterConfig(*msg)
|
||||||
|
|
||||||
case *Index:
|
case *Index:
|
||||||
err = c.handleIndex(*msg)
|
err = c.handleIndex(*msg)
|
||||||
@ -477,7 +495,7 @@ func (c *rawConnection) dispatcherLoop() (err error) {
|
|||||||
c.handleResponse(*msg)
|
c.handleResponse(*msg)
|
||||||
|
|
||||||
case *DownloadProgress:
|
case *DownloadProgress:
|
||||||
err = c.receiver.DownloadProgress(c.id, msg.Folder, msg.Updates)
|
err = c.model.DownloadProgress(msg.Folder, msg.Updates)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newHandleError(err, msgContext)
|
return newHandleError(err, msgContext)
|
||||||
@ -579,13 +597,13 @@ func (c *rawConnection) readHeader(fourByteBuf []byte) (Header, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *rawConnection) handleIndex(im Index) error {
|
func (c *rawConnection) handleIndex(im Index) error {
|
||||||
l.Debugf("Index(%v, %v, %d file)", c.id, im.Folder, len(im.Files))
|
l.Debugf("Index(%v, %v, %d file)", c.deviceID, im.Folder, len(im.Files))
|
||||||
return c.receiver.Index(c.id, im.Folder, im.Files)
|
return c.model.Index(im.Folder, im.Files)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *rawConnection) handleIndexUpdate(im IndexUpdate) error {
|
func (c *rawConnection) handleIndexUpdate(im IndexUpdate) error {
|
||||||
l.Debugf("queueing IndexUpdate(%v, %v, %d files)", c.id, im.Folder, len(im.Files))
|
l.Debugf("queueing IndexUpdate(%v, %v, %d files)", c.deviceID, im.Folder, len(im.Files))
|
||||||
return c.receiver.IndexUpdate(c.id, im.Folder, im.Files)
|
return c.model.IndexUpdate(im.Folder, im.Files)
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkIndexConsistency verifies a number of invariants on FileInfos received in
|
// checkIndexConsistency verifies a number of invariants on FileInfos received in
|
||||||
@ -651,7 +669,7 @@ func checkFilename(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *rawConnection) handleRequest(req Request) {
|
func (c *rawConnection) handleRequest(req Request) {
|
||||||
res, err := c.receiver.Request(c.id, req.Folder, req.Name, int32(req.BlockNo), int32(req.Size), req.Offset, req.Hash, req.WeakHash, req.FromTemporary)
|
res, err := c.model.Request(req.Folder, req.Name, int32(req.BlockNo), int32(req.Size), req.Offset, req.Hash, req.WeakHash, req.FromTemporary)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.send(context.Background(), &Response{
|
c.send(context.Background(), &Response{
|
||||||
ID: req.ID,
|
ID: req.ID,
|
||||||
@ -925,7 +943,7 @@ func (c *rawConnection) internalClose(err error) {
|
|||||||
c.closeOnce.Do(func() {
|
c.closeOnce.Do(func() {
|
||||||
l.Debugln("close due to", err)
|
l.Debugln("close due to", err)
|
||||||
if cerr := c.closer.Close(); cerr != nil {
|
if cerr := c.closer.Close(); cerr != nil {
|
||||||
l.Debugln(c.id, "failed to close underlying conn:", cerr)
|
l.Debugln(c.deviceID, "failed to close underlying conn:", cerr)
|
||||||
}
|
}
|
||||||
close(c.closed)
|
close(c.closed)
|
||||||
|
|
||||||
@ -940,7 +958,7 @@ func (c *rawConnection) internalClose(err error) {
|
|||||||
|
|
||||||
<-c.dispatcherLoopStopped
|
<-c.dispatcherLoopStopped
|
||||||
|
|
||||||
c.receiver.Closed(c.ID(), err)
|
c.model.Closed(err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -958,11 +976,11 @@ func (c *rawConnection) pingSender() {
|
|||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
d := time.Since(c.cw.Last())
|
d := time.Since(c.cw.Last())
|
||||||
if d < PingSendInterval/2 {
|
if d < PingSendInterval/2 {
|
||||||
l.Debugln(c.id, "ping skipped after wr", d)
|
l.Debugln(c.deviceID, "ping skipped after wr", d)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Debugln(c.id, "ping -> after", d)
|
l.Debugln(c.deviceID, "ping -> after", d)
|
||||||
c.ping()
|
c.ping()
|
||||||
|
|
||||||
case <-c.closed:
|
case <-c.closed:
|
||||||
@ -983,11 +1001,11 @@ func (c *rawConnection) pingReceiver() {
|
|||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
d := time.Since(c.cr.Last())
|
d := time.Since(c.cr.Last())
|
||||||
if d > ReceiveTimeout {
|
if d > ReceiveTimeout {
|
||||||
l.Debugln(c.id, "ping timeout", d)
|
l.Debugln(c.deviceID, "ping timeout", d)
|
||||||
c.internalClose(ErrTimeout)
|
c.internalClose(ErrTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Debugln(c.id, "last read within", d)
|
l.Debugln(c.deviceID, "last read within", d)
|
||||||
|
|
||||||
case <-c.closed:
|
case <-c.closed:
|
||||||
return
|
return
|
||||||
@ -1068,3 +1086,35 @@ func messageContext(msg message) (string, error) {
|
|||||||
return "", errors.New("unknown or empty message")
|
return "", errors.New("unknown or empty message")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// connectionWrappingModel takes the Model interface from the model package,
|
||||||
|
// which expects the Connection as the first parameter in all methods, and
|
||||||
|
// wraps it to conform to the protocol.contextLessModel interface.
|
||||||
|
type connectionWrappingModel struct {
|
||||||
|
conn Connection
|
||||||
|
model Model
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *connectionWrappingModel) Index(folder string, files []FileInfo) error {
|
||||||
|
return c.model.Index(c.conn, folder, files)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *connectionWrappingModel) IndexUpdate(folder string, files []FileInfo) error {
|
||||||
|
return c.model.IndexUpdate(c.conn, folder, files)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *connectionWrappingModel) Request(folder, name string, blockNo, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (RequestResponse, error) {
|
||||||
|
return c.model.Request(c.conn, folder, name, blockNo, size, offset, hash, weakHash, fromTemporary)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *connectionWrappingModel) ClusterConfig(config ClusterConfig) error {
|
||||||
|
return c.model.ClusterConfig(c.conn, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *connectionWrappingModel) Closed(err error) {
|
||||||
|
c.model.Closed(c.conn, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *connectionWrappingModel) DownloadProgress(folder string, updates []FileDownloadProgressUpdate) error {
|
||||||
|
return c.model.DownloadProgress(c.conn, folder, updates)
|
||||||
|
}
|
||||||
|
@ -145,7 +145,7 @@ func TestCloseRace(t *testing.T) {
|
|||||||
indexReceived := make(chan struct{})
|
indexReceived := make(chan struct{})
|
||||||
unblockIndex := make(chan struct{})
|
unblockIndex := make(chan struct{})
|
||||||
m0 := newTestModel()
|
m0 := newTestModel()
|
||||||
m0.indexFn = func(_ DeviceID, _ string, _ []FileInfo) {
|
m0.indexFn = func(string, []FileInfo) {
|
||||||
close(indexReceived)
|
close(indexReceived)
|
||||||
<-unblockIndex
|
<-unblockIndex
|
||||||
}
|
}
|
||||||
@ -924,7 +924,7 @@ func TestDispatcherToCloseDeadlock(t *testing.T) {
|
|||||||
m := newTestModel()
|
m := newTestModel()
|
||||||
rw := testutils.NewBlockingRW()
|
rw := testutils.NewBlockingRW()
|
||||||
c := getRawConnection(NewConnection(c0ID, rw, &testutils.NoopRW{}, testutils.NoopCloser{}, m, new(mockedConnectionInfo), CompressionAlways, nil, testKeyGen))
|
c := getRawConnection(NewConnection(c0ID, rw, &testutils.NoopRW{}, testutils.NoopCloser{}, m, new(mockedConnectionInfo), CompressionAlways, nil, testKeyGen))
|
||||||
m.ccFn = func(devID DeviceID, cc ClusterConfig) {
|
m.ccFn = func(ClusterConfig) {
|
||||||
c.Close(errManual)
|
c.Close(errManual)
|
||||||
}
|
}
|
||||||
c.Start()
|
c.Start()
|
||||||
|
Loading…
Reference in New Issue
Block a user