revid: added multiSender test to check that Write returns when active func return false in send retry

This commit is contained in:
Saxon 2019-03-12 18:28:20 +10:30
parent 42bf44afdf
commit da1532b9d1
1 changed files with 63 additions and 0 deletions

View File

@ -31,6 +31,7 @@ package revid
import ( import (
"errors" "errors"
"fmt" "fmt"
"sync"
"testing" "testing"
"time" "time"
@ -355,19 +356,26 @@ func TestMultiSenderNotActiveNoRetry(t *testing.T) {
newDummyLoadSender(false), newDummyLoadSender(false),
newDummyLoadSender(false), newDummyLoadSender(false),
} }
// This will allow us to simulate a change in running state of
// multiSender's 'owner'.
active := true active := true
activeFunc := func() bool { activeFunc := func() bool {
return active return active
} }
ms, err := newMultiSender(senders, false, activeFunc) ms, err := newMultiSender(senders, false, activeFunc)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
// We will perform two writes. We expect the second write not to be complete,
// i.e. the senders should not send anything on this write.
ms.Write([]byte{0x00}) ms.Write([]byte{0x00})
active = false active = false
ms.Write([]byte{0x01}) ms.Write([]byte{0x01})
// Check that the senders only sent data once.
for _, dest := range ms.senders { for _, dest := range ms.senders {
if len(dest.(*dummyLoadSender).buf) != 1 { if len(dest.(*dummyLoadSender).buf) != 1 {
t.Errorf("length of sender buf is not 1 as expected") t.Errorf("length of sender buf is not 1 as expected")
@ -375,5 +383,60 @@ func TestMultiSenderNotActiveNoRetry(t *testing.T) {
} }
} }
// TestMultiSenderNotActiveRetry checks that we correctly returns from a call to
// multiSender.Write when the active callback func return false during repeated
// send retries.
func TestMultiSenderNotActiveRetry(t *testing.T) {
senders := []loadSender{
newDummyLoadSender(false),
}
// Active will simulate the running state of the multiSender's 'owner'.
active := true
// We will run the ms.Write as routine so we need some sync.
var mu sync.Mutex
// After the write is running as a routine we will call this to change the
// running state of the 'owner'.
setActive := func(b bool) {
mu.Lock()
defer mu.Unlock()
active = b
}
// Once we use setActive to change the state of the fake owner, this will
// return false and we expect the ms.Write method to return from the continous
// send retry state.
activeFunc := func() bool {
mu.Lock()
defer mu.Unlock()
return active
}
ms, err := newMultiSender(senders, false, activeFunc)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
// We run this in background so that we can change running state during the
// the write. We then expect done to be true after some period of time.
done := false
go func() {
ms.Write([]byte{0x00})
done = true
}()
// Wait for half a second and then change the active state.
time.Sleep(500 * time.Millisecond)
setActive(false)
// Wait half a second for the routine to return and check that done is true.
time.Sleep(500 * time.Millisecond)
if !done {
t.Fatal("multiSender.Write did not return as expected with active=false")
}
}
// TODO: test that send retry works // TODO: test that send retry works
// TODO: test that send fail works with no retry // TODO: test that send fail works with no retry