assertions are ued. With suite.Required() there are issues in getting the test results correct. Instead, use standard assertions and use suite.T().Failed() to do early returns.
135 lines
2.9 KiB
Go
135 lines
2.9 KiB
Go
package iowrappers
|
|
|
|
import (
|
|
"context"
|
|
"github.com/stretchr/testify/suite"
|
|
"log"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type ChannelReadWriterTestSuite struct {
|
|
suite.Suite
|
|
|
|
ctx context.Context
|
|
cancelFunc context.CancelFunc
|
|
toChannel chan<- []byte
|
|
fromChannel <-chan []byte
|
|
conn *ChannelReadWriter
|
|
}
|
|
|
|
func TestChannelReadWriterSuite(t *testing.T) {
|
|
suite.Run(t, &ChannelReadWriterTestSuite{})
|
|
}
|
|
|
|
func (suite *ChannelReadWriterTestSuite) createChannel() {
|
|
toChannel := make(chan []byte)
|
|
fromChannel := make(chan []byte)
|
|
suite.toChannel = toChannel
|
|
suite.fromChannel = fromChannel
|
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
|
ctx, timeoutCancelFunc := context.WithTimeout(ctx, 10*time.Second)
|
|
suite.ctx = ctx
|
|
suite.cancelFunc = func() {
|
|
timeoutCancelFunc()
|
|
cancelFunc()
|
|
}
|
|
suite.conn = NewChannelReadWriter(ctx, toChannel, fromChannel)
|
|
}
|
|
|
|
func (suite *ChannelReadWriterTestSuite) SetupTest() {
|
|
suite.createChannel()
|
|
}
|
|
|
|
func (suite *ChannelReadWriterTestSuite) TearDownTest() {
|
|
suite.cancelFunc()
|
|
}
|
|
|
|
type TestFunc func() any
|
|
|
|
func (suite *ChannelReadWriterTestSuite) runAndWait(functions ...TestFunc) []any {
|
|
wg := sync.WaitGroup{}
|
|
wg.Add(len(functions))
|
|
res := make([]any, len(functions))
|
|
for i, function := range functions {
|
|
go func() {
|
|
defer func() {
|
|
wg.Done()
|
|
}()
|
|
res[i] = function()
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
return res
|
|
}
|
|
|
|
func (suite *ChannelReadWriterTestSuite) Test_SuccessfulCommunication() {
|
|
tests := []struct {
|
|
name string
|
|
data string
|
|
chunkSizes []int
|
|
chunks []string
|
|
}{
|
|
{
|
|
name: "buffer_large_enough",
|
|
data: "hello",
|
|
chunkSizes: []int{10},
|
|
chunks: []string{"hello"},
|
|
},
|
|
{
|
|
name: "two_reads_required",
|
|
data: "hello",
|
|
chunkSizes: []int{3, 10},
|
|
chunks: []string{"hel", "lo"},
|
|
},
|
|
{
|
|
name: "many_reads_required",
|
|
data: "hello",
|
|
chunkSizes: []int{1, 1, 1, 1, 1},
|
|
chunks: []string{"h", "e", "l", "l", "o"},
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
suite.Run(test.name, func() {
|
|
suite.runAndWait(
|
|
func() any {
|
|
select {
|
|
case <-suite.ctx.Done():
|
|
suite.FailNow("deadline reached")
|
|
log.Println("Write deadline exceeded")
|
|
case suite.toChannel <- []byte(test.data):
|
|
}
|
|
return nil
|
|
},
|
|
func() any {
|
|
remainder := test.data
|
|
for i, chunkSize := range test.chunkSizes {
|
|
buf := make([]byte, chunkSize)
|
|
n, err := suite.conn.Read(buf)
|
|
suite.Nil(err)
|
|
suite.Equal(n, len(test.chunks[i]))
|
|
suite.Equal([]byte(remainder[:n]), buf[:n])
|
|
remainder = remainder[n:]
|
|
}
|
|
return nil
|
|
},
|
|
)
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func (suite *ChannelReadWriterTestSuite) Test_Close() {
|
|
suite.FailNow("todo")
|
|
}
|
|
|
|
func (suite *ChannelReadWriterTestSuite) Test_CloseTwice() {
|
|
suite.FailNow("todo")
|
|
}
|
|
|
|
func (suite *ChannelReadWriterTestSuite) Test_ContextCanceled() {
|
|
suite.FailNow("todo")
|
|
}
|