lib/protocol: Send Close message on read error (#7141)

This commit is contained in:
Simon Frei
2020-11-27 11:31:20 +01:00
committed by GitHub
parent a9764fc16c
commit bbb22c8c80
3 changed files with 94 additions and 23 deletions
+36 -5
View File
@@ -33,8 +33,10 @@ func TestPing(t *testing.T) {
c0 := NewConnection(c0ID, ar, bw, newTestModel(), "name", CompressionAlways).(wireFormatConnection).Connection.(*rawConnection)
c0.Start()
defer closeAndWait(c0, ar, bw)
c1 := NewConnection(c1ID, br, aw, newTestModel(), "name", CompressionAlways).(wireFormatConnection).Connection.(*rawConnection)
c1.Start()
defer closeAndWait(c1, ar, bw)
c0.ClusterConfig(ClusterConfig{})
c1.ClusterConfig(ClusterConfig{})
@@ -57,8 +59,10 @@ func TestClose(t *testing.T) {
c0 := NewConnection(c0ID, ar, bw, m0, "name", CompressionAlways).(wireFormatConnection).Connection.(*rawConnection)
c0.Start()
defer closeAndWait(c0, ar, bw)
c1 := NewConnection(c1ID, br, aw, m1, "name", CompressionAlways)
c1.Start()
defer closeAndWait(c1, ar, bw)
c0.ClusterConfig(ClusterConfig{})
c1.ClusterConfig(ClusterConfig{})
@@ -97,8 +101,10 @@ func TestCloseOnBlockingSend(t *testing.T) {
m := newTestModel()
c := NewConnection(c0ID, &testutils.BlockingRW{}, &testutils.BlockingRW{}, m, "name", CompressionAlways).(wireFormatConnection).Connection.(*rawConnection)
rw := testutils.NewBlockingRW()
c := NewConnection(c0ID, rw, rw, m, "name", CompressionAlways).(wireFormatConnection).Connection.(*rawConnection)
c.Start()
defer closeAndWait(c, rw)
wg := sync.WaitGroup{}
@@ -149,8 +155,10 @@ func TestCloseRace(t *testing.T) {
c0 := NewConnection(c0ID, ar, bw, m0, "c0", CompressionNever).(wireFormatConnection).Connection.(*rawConnection)
c0.Start()
defer closeAndWait(c0, ar, bw)
c1 := NewConnection(c1ID, br, aw, m1, "c1", CompressionNever)
c1.Start()
defer closeAndWait(c1, ar, bw)
c0.ClusterConfig(ClusterConfig{})
c1.ClusterConfig(ClusterConfig{})
@@ -184,8 +192,10 @@ func TestCloseRace(t *testing.T) {
func TestClusterConfigFirst(t *testing.T) {
m := newTestModel()
c := NewConnection(c0ID, &testutils.BlockingRW{}, &testutils.NoopRW{}, m, "name", CompressionAlways).(wireFormatConnection).Connection.(*rawConnection)
rw := testutils.NewBlockingRW()
c := NewConnection(c0ID, rw, &testutils.NoopRW{}, m, "name", CompressionAlways).(wireFormatConnection).Connection.(*rawConnection)
c.Start()
defer closeAndWait(c, rw)
select {
case c.outbox <- asyncMessage{&Ping{}, nil}:
@@ -234,8 +244,10 @@ func TestCloseTimeout(t *testing.T) {
m := newTestModel()
c := NewConnection(c0ID, &testutils.BlockingRW{}, &testutils.BlockingRW{}, m, "name", CompressionAlways).(wireFormatConnection).Connection.(*rawConnection)
rw := testutils.NewBlockingRW()
c := NewConnection(c0ID, rw, rw, m, "name", CompressionAlways).(wireFormatConnection).Connection.(*rawConnection)
c.Start()
defer closeAndWait(c, rw)
done := make(chan struct{})
go func() {
@@ -852,8 +864,10 @@ func TestSha256OfEmptyBlock(t *testing.T) {
func TestClusterConfigAfterClose(t *testing.T) {
m := newTestModel()
c := NewConnection(c0ID, &testutils.BlockingRW{}, &testutils.BlockingRW{}, m, "name", CompressionAlways).(wireFormatConnection).Connection.(*rawConnection)
rw := testutils.NewBlockingRW()
c := NewConnection(c0ID, rw, rw, m, "name", CompressionAlways).(wireFormatConnection).Connection.(*rawConnection)
c.Start()
defer closeAndWait(c, rw)
c.internalClose(errManual)
@@ -874,11 +888,13 @@ func TestDispatcherToCloseDeadlock(t *testing.T) {
// Verify that we don't deadlock when calling Close() from within one of
// the model callbacks (ClusterConfig).
m := newTestModel()
c := NewConnection(c0ID, &testutils.BlockingRW{}, &testutils.NoopRW{}, m, "name", CompressionAlways).(wireFormatConnection).Connection.(*rawConnection)
rw := testutils.NewBlockingRW()
c := NewConnection(c0ID, rw, &testutils.NoopRW{}, m, "name", CompressionAlways).(wireFormatConnection).Connection.(*rawConnection)
m.ccFn = func(devID DeviceID, cc ClusterConfig) {
c.Close(errManual)
}
c.Start()
defer closeAndWait(c, rw)
c.inbox <- &ClusterConfig{}
@@ -945,3 +961,18 @@ func TestIndexIDString(t *testing.T) {
t.Error(i.String())
}
}
func closeAndWait(c Connection, closers ...io.Closer) {
for _, closer := range closers {
closer.Close()
}
var raw *rawConnection
switch i := c.(type) {
case wireFormatConnection:
raw = i.Connection.(*rawConnection)
case *rawConnection:
raw = i
}
raw.internalClose(ErrClosed)
raw.loopWG.Wait()
}