1
0
Эх сурвалжийг харах

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 <[email protected]>

* Update model.go

* Update model.go

Co-authored-by: Simon Frei <[email protected]>
Audrius Butkevicius 5 жил өмнө
parent
commit
5fb3992275

+ 4 - 1
lib/model/model.go

@@ -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()

+ 115 - 0
lib/model/model_test.go

@@ -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