Add tests for codeOceanToRaw and null readers

The tests ensure the readers do not return when there is no data
available.
This commit is contained in:
Konrad Hanff
2021-06-18 09:14:07 +02:00
parent 17c1e379c2
commit 92f1af83ae
3 changed files with 85 additions and 1 deletions

View File

@ -16,11 +16,13 @@ import (
"gitlab.hpi.de/codeocean/codemoon/poseidon/api/dto" "gitlab.hpi.de/codeocean/codemoon/poseidon/api/dto"
"gitlab.hpi.de/codeocean/codemoon/poseidon/nomad" "gitlab.hpi.de/codeocean/codemoon/poseidon/nomad"
"gitlab.hpi.de/codeocean/codemoon/poseidon/runner" "gitlab.hpi.de/codeocean/codemoon/poseidon/runner"
"gitlab.hpi.de/codeocean/codemoon/poseidon/tests"
"gitlab.hpi.de/codeocean/codemoon/poseidon/tests/helpers" "gitlab.hpi.de/codeocean/codemoon/poseidon/tests/helpers"
"io" "io"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
"strings"
"testing" "testing"
"time" "time"
) )
@ -305,8 +307,70 @@ func TestRawToCodeOceanWriter(t *testing.T) {
assert.Equal(t, expected, message) assert.Equal(t, expected, message)
} }
func TestCodeOceanToRawReaderReturnsOnlyAfterOneByteWasRead(t *testing.T) {
reader := newCodeOceanToRawReader(nil)
read := make(chan int)
go func() {
p := make([]byte, 10)
n, _ := reader.Read(p)
read <- n
}()
t.Run("Does not return immediately when there is no data", func(t *testing.T) {
assert.False(t, waitForChannel(read, tests.ShortTimeout))
})
t.Run("Returns when there is data available", func(t *testing.T) {
reader.buffer <- byte(42)
assert.True(t, waitForChannel(read, tests.ShortTimeout))
})
}
func TestCodeOceanToRawReaderReturnsOnlyAfterOneByteWasReadFromConnection(t *testing.T) {
messages := make(chan io.Reader)
connection := &webSocketConnectionMock{}
connection.On("WriteMessage", mock.AnythingOfType("int"), mock.AnythingOfType("[]uint8")).Return(nil)
connection.On("CloseHandler").Return(nil)
connection.On("SetCloseHandler", mock.Anything).Return()
call := connection.On("NextReader")
call.Run(func(_ mock.Arguments) {
call.Return(websocket.TextMessage, <-messages, nil)
})
reader := newCodeOceanToRawReader(connection)
cancel := reader.readInputLoop()
defer cancel()
read := make(chan int)
message := make([]byte, 10)
go func() {
n, _ := reader.Read(message)
read <- n
}()
t.Run("Does not return immediately when there is no data", func(t *testing.T) {
assert.False(t, waitForChannel(read, tests.ShortTimeout))
})
t.Run("Returns when there is data available", func(t *testing.T) {
messages <- strings.NewReader("Hello")
assert.True(t, waitForChannel(read, tests.ShortTimeout))
})
}
// --- Test suite specific test helpers --- // --- Test suite specific test helpers ---
func waitForChannel(ch chan int, duration time.Duration) bool {
select {
case <-ch:
return true
case <-time.After(duration):
return false
}
}
func newNomadAllocationWithMockedApiClient(runnerId string) (r runner.Runner, mock *nomad.ExecutorAPIMock) { func newNomadAllocationWithMockedApiClient(runnerId string) (r runner.Runner, mock *nomad.ExecutorAPIMock) {
mock = &nomad.ExecutorAPIMock{} mock = &nomad.ExecutorAPIMock{}
r = runner.NewNomadJob(runnerId, mock) r = runner.NewNomadJob(runnerId, mock)

View File

@ -750,3 +750,19 @@ func (s *ExecuteCommandTestSuite) mockExecute(command interface{}, exitCode int,
Run(runFunc). Run(runFunc).
Return(exitCode, err) Return(exitCode, err)
} }
func TestNullReaderDoesNotReturnImmediately(t *testing.T) {
reader := &nullReader{}
readerReturned := make(chan bool)
go func() {
p := make([]byte, 5)
_, _ = reader.Read(p)
close(readerReturned)
}()
select {
case <-readerReturned:
t.Fatal("Read should not return immediately.")
case <-time.After(tests.ShortTimeout):
}
}

View File

@ -1,6 +1,9 @@
package tests package tests
import "errors" import (
"errors"
"time"
)
const ( const (
NonExistingIntegerID = 9999 NonExistingIntegerID = 9999
@ -21,6 +24,7 @@ const (
AnotherRunnerID = AnotherJobID AnotherRunnerID = AnotherJobID
DefaultExecutionID = "s0m3-3x3cu710n-1d" DefaultExecutionID = "s0m3-3x3cu710n-1d"
DefaultMockID = "m0ck-1d" DefaultMockID = "m0ck-1d"
ShortTimeout = 100 * time.Millisecond
) )
var ( var (