lib/model: More connection closing (#6778)

* lib/model: More connection closing

* Revert "lib/model: More connection closing"

This reverts commit 5397c3a55c0de25fab93d4ec622530818f1b2a46.

* Add tests, fix one broken-ness

* Update lib/model/model.go

Co-authored-by: Simon Frei <freisim93@gmail.com>

* Update model.go

* Update model.go

Co-authored-by: Simon Frei <freisim93@gmail.com>
This commit is contained in:
Audrius Butkevicius 2020-06-22 21:26:26 +01:00 committed by GitHub
parent b62b7d269e
commit 5fb3992275
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 119 additions and 1 deletions

View File

@ -492,7 +492,10 @@ func (m *model) restartFolder(from, to config.FolderConfiguration) {
fset = db.NewFileSet(to.ID, to.Filesystem(), m.db)
}
m.stopFolder(from, fmt.Errorf("%v folder %v", errMsg, to.Description()))
err := fmt.Errorf("%v folder %v", errMsg, to.Description())
m.stopFolder(from, err)
// Need to send CC change to both from and to devices.
m.closeConns(to.DeviceIDs(), err)
m.fmut.Lock()
defer m.fmut.Unlock()

View File

@ -3806,6 +3806,121 @@ func TestBlockListMap(t *testing.T) {
}
}
func TestConnectionTerminationOnFolderAdd(t *testing.T) {
testConfigChangeClosesConnections(t, false, true, nil, func(cfg config.Wrapper) {
fcfg := testFolderConfigTmp()
fcfg.ID = "second"
fcfg.Label = "second"
fcfg.Devices = []config.FolderDeviceConfiguration{{device2, protocol.EmptyDeviceID}}
if w, err := cfg.SetFolder(fcfg); err != nil {
t.Fatal(err)
} else {
w.Wait()
}
})
}
func TestConnectionTerminationOnFolderShare(t *testing.T) {
testConfigChangeClosesConnections(t, true, true, nil, func(cfg config.Wrapper) {
fcfg := cfg.FolderList()[0]
fcfg.Devices = []config.FolderDeviceConfiguration{{device2, protocol.EmptyDeviceID}}
if w, err := cfg.SetFolder(fcfg); err != nil {
t.Fatal(err)
} else {
w.Wait()
}
})
}
func TestConnectionTerminationOnFolderUnshare(t *testing.T) {
testConfigChangeClosesConnections(t, true, false, nil, func(cfg config.Wrapper) {
fcfg := cfg.FolderList()[0]
fcfg.Devices = nil
if w, err := cfg.SetFolder(fcfg); err != nil {
t.Fatal(err)
} else {
w.Wait()
}
})
}
func TestConnectionTerminationOnFolderRemove(t *testing.T) {
testConfigChangeClosesConnections(t, true, false, nil, func(cfg config.Wrapper) {
rcfg := cfg.RawCopy()
rcfg.Folders = nil
if w, err := cfg.Replace(rcfg); err != nil {
t.Fatal(err)
} else {
w.Wait()
}
})
}
func TestConnectionTerminationOnFolderPause(t *testing.T) {
testConfigChangeClosesConnections(t, true, false, nil, func(cfg config.Wrapper) {
fcfg := cfg.FolderList()[0]
fcfg.Paused = true
if w, err := cfg.SetFolder(fcfg); err != nil {
t.Fatal(err)
} else {
w.Wait()
}
})
}
func TestConnectionTerminationOnFolderUnpause(t *testing.T) {
testConfigChangeClosesConnections(t, true, false, func(cfg config.Wrapper) {
fcfg := cfg.FolderList()[0]
fcfg.Paused = true
if w, err := cfg.SetFolder(fcfg); err != nil {
t.Fatal(err)
} else {
w.Wait()
}
}, func(cfg config.Wrapper) {
fcfg := cfg.FolderList()[0]
fcfg.Paused = false
if w, err := cfg.SetFolder(fcfg); err != nil {
t.Fatal(err)
} else {
w.Wait()
}
})
}
func testConfigChangeClosesConnections(t *testing.T, expectFirstClosed, expectSecondClosed bool, pre func(config.Wrapper), fn func(config.Wrapper)) {
t.Helper()
wcfg, _ := tmpDefaultWrapper()
m := setupModel(wcfg)
defer cleanupModel(m)
_, err := wcfg.SetDevice(config.NewDeviceConfiguration(device2, "device2"))
if err != nil {
t.Fatal(err)
}
if pre != nil {
pre(wcfg)
}
fc1 := &fakeConnection{id: device1, model: m}
fc2 := &fakeConnection{id: device2, model: m}
m.AddConnection(fc1, protocol.HelloResult{})
m.AddConnection(fc2, protocol.HelloResult{})
t.Log("Applying config change")
fn(wcfg)
if expectFirstClosed != fc1.closed {
t.Errorf("first connection state mismatch: %t (expected) != %t", expectFirstClosed, fc1.closed)
}
if expectSecondClosed != fc2.closed {
t.Errorf("second connection state mismatch: %t (expected) != %t", expectSecondClosed, fc2.closed)
}
}
func equalStringsInAnyOrder(a, b []string) bool {
if len(a) != len(b) {
return false