Move NullReader from nomad to util package.
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/hashicorp/nomad/nomad/structs"
|
"github.com/hashicorp/nomad/nomad/structs"
|
||||||
"gitlab.hpi.de/codeocean/codemoon/poseidon/config"
|
"gitlab.hpi.de/codeocean/codemoon/poseidon/config"
|
||||||
"gitlab.hpi.de/codeocean/codemoon/poseidon/logging"
|
"gitlab.hpi.de/codeocean/codemoon/poseidon/logging"
|
||||||
|
"gitlab.hpi.de/codeocean/codemoon/poseidon/util"
|
||||||
"io"
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
@@ -287,15 +288,6 @@ func (a *APIClient) LoadEnvironmentJobs() ([]*nomadApi.Job, error) {
|
|||||||
return jobs, nil
|
return jobs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// nullReader is a struct that implements the io.Reader interface and returns nothing when reading
|
|
||||||
// from it.
|
|
||||||
type nullReader struct{}
|
|
||||||
|
|
||||||
func (r nullReader) Read(_ []byte) (int, error) {
|
|
||||||
// An empty select blocks forever.
|
|
||||||
select {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExecuteCommand executes the given command in the given allocation.
|
// ExecuteCommand executes the given command in the given allocation.
|
||||||
// If tty is true, Nomad would normally write stdout and stderr of the command
|
// If tty is true, Nomad would normally write stdout and stderr of the command
|
||||||
// both on the stdout stream. However, if the InteractiveStderr server config option is true,
|
// both on the stdout stream. However, if the InteractiveStderr server config option is true,
|
||||||
@@ -328,7 +320,7 @@ func (a *APIClient) executeCommandInteractivelyWithStderr(allocationID string, c
|
|||||||
stderrExitChan := make(chan int)
|
stderrExitChan := make(chan int)
|
||||||
go func() {
|
go func() {
|
||||||
// Catch stderr in separate execution.
|
// Catch stderr in separate execution.
|
||||||
exit, err := a.Execute(allocationID, ctx, stderrFifoCommand(currentNanoTime), true, nullReader{}, stderr, io.Discard)
|
exit, err := a.Execute(allocationID, ctx, stderrFifoCommand(currentNanoTime), true, util.NullReader{}, stderr, io.Discard)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).WithField("runner", allocationID).Warn("Stderr task finished with error")
|
log.WithError(err).WithField("runner", allocationID).Warn("Stderr task finished with error")
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"gitlab.hpi.de/codeocean/codemoon/poseidon/config"
|
"gitlab.hpi.de/codeocean/codemoon/poseidon/config"
|
||||||
"gitlab.hpi.de/codeocean/codemoon/poseidon/tests"
|
"gitlab.hpi.de/codeocean/codemoon/poseidon/tests"
|
||||||
|
"gitlab.hpi.de/codeocean/codemoon/poseidon/util"
|
||||||
"io"
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
@@ -673,7 +674,7 @@ func (s *ExecuteCommandTestSuite) TestWithSeparateStderr() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
exitCode, err := s.nomadAPIClient.
|
exitCode, err := s.nomadAPIClient.
|
||||||
ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, nullReader{}, &stdout, &stderr)
|
ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, util.NullReader{}, &stdout, &stderr)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
s.apiMock.AssertNumberOfCalls(s.T(), "Execute", 2)
|
s.apiMock.AssertNumberOfCalls(s.T(), "Execute", 2)
|
||||||
@@ -704,7 +705,7 @@ func (s *ExecuteCommandTestSuite) TestWithSeparateStderrReturnsCommandError() {
|
|||||||
s.mockExecute(s.testCommandArray, 1, tests.ErrDefault, func(args mock.Arguments) {})
|
s.mockExecute(s.testCommandArray, 1, tests.ErrDefault, func(args mock.Arguments) {})
|
||||||
s.mockExecute(mock.AnythingOfType("[]string"), 1, nil, func(args mock.Arguments) {})
|
s.mockExecute(mock.AnythingOfType("[]string"), 1, nil, func(args mock.Arguments) {})
|
||||||
_, err := s.nomadAPIClient.
|
_, err := s.nomadAPIClient.
|
||||||
ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, nullReader{}, io.Discard, io.Discard)
|
ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, util.NullReader{}, io.Discard, io.Discard)
|
||||||
s.Equal(tests.ErrDefault, err)
|
s.Equal(tests.ErrDefault, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,7 +727,7 @@ func (s *ExecuteCommandTestSuite) TestWithoutSeparateStderr() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
exitCode, err := s.nomadAPIClient.
|
exitCode, err := s.nomadAPIClient.
|
||||||
ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, nullReader{}, &stdout, &stderr)
|
ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, util.NullReader{}, &stdout, &stderr)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
s.apiMock.AssertNumberOfCalls(s.T(), "Execute", 1)
|
s.apiMock.AssertNumberOfCalls(s.T(), "Execute", 1)
|
||||||
@@ -739,7 +740,7 @@ func (s *ExecuteCommandTestSuite) TestWithoutSeparateStderrReturnsCommandError()
|
|||||||
config.Config.Server.InteractiveStderr = false
|
config.Config.Server.InteractiveStderr = false
|
||||||
s.mockExecute(s.testCommandArray, 1, tests.ErrDefault, func(args mock.Arguments) {})
|
s.mockExecute(s.testCommandArray, 1, tests.ErrDefault, func(args mock.Arguments) {})
|
||||||
_, err := s.nomadAPIClient.
|
_, err := s.nomadAPIClient.
|
||||||
ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, nullReader{}, io.Discard, io.Discard)
|
ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, util.NullReader{}, io.Discard, io.Discard)
|
||||||
s.Equal(tests.ErrDefault, err)
|
s.Equal(tests.ErrDefault, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -750,14 +751,3 @@ 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)
|
|
||||||
}()
|
|
||||||
assert.False(t, tests.ChannelReceivesSomething(readerReturned, tests.ShortTimeout))
|
|
||||||
}
|
|
||||||
|
10
util/util.go
Normal file
10
util/util.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
// NullReader is a struct that implements the io.Reader interface and returns nothing when reading
|
||||||
|
// from it.
|
||||||
|
type NullReader struct{}
|
||||||
|
|
||||||
|
func (r NullReader) Read(_ []byte) (int, error) {
|
||||||
|
// An empty select blocks forever.
|
||||||
|
select {}
|
||||||
|
}
|
18
util/util_test.go
Normal file
18
util/util_test.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"gitlab.hpi.de/codeocean/codemoon/poseidon/tests"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNullReaderDoesNotReturnImmediately(t *testing.T) {
|
||||||
|
reader := &NullReader{}
|
||||||
|
readerReturned := make(chan bool)
|
||||||
|
go func() {
|
||||||
|
p := make([]byte, 5)
|
||||||
|
_, _ = reader.Read(p)
|
||||||
|
close(readerReturned)
|
||||||
|
}()
|
||||||
|
assert.False(t, tests.ChannelReceivesSomething(readerReturned, tests.ShortTimeout))
|
||||||
|
}
|
Reference in New Issue
Block a user