#166 Fix AWS JAVA ignoring shell commands in combination with a Makefile.
This commit is contained in:
@ -62,19 +62,8 @@ func (s *E2ETestSuite) TestExecuteCommandRoute() {
|
||||
func (s *E2ETestSuite) TestOutputToStdout() {
|
||||
for _, environmentID := range environmentIDs {
|
||||
s.Run(environmentID.ToString(), func() {
|
||||
connection, err := ProvideWebSocketConnection(&s.Suite, environmentID,
|
||||
&dto.ExecutionRequest{Command: "echo -n Hello World"})
|
||||
s.Require().NoError(err)
|
||||
|
||||
messages, err := helpers.ReceiveAllWebSocketMessages(connection)
|
||||
s.Require().Error(err)
|
||||
s.Equal(&websocket.CloseError{Code: websocket.CloseNormalClosure}, err)
|
||||
|
||||
controlMessages := helpers.WebSocketControlMessages(messages)
|
||||
s.Require().Equal(&dto.WebSocketMessage{Type: dto.WebSocketMetaStart}, controlMessages[0])
|
||||
s.Require().Equal(&dto.WebSocketMessage{Type: dto.WebSocketExit}, controlMessages[1])
|
||||
|
||||
stdout, _, _ := helpers.WebSocketOutputMessages(messages)
|
||||
stdout, _, _ := ExecuteNonInteractive(&s.Suite, environmentID,
|
||||
&dto.ExecutionRequest{Command: "echo -n Hello World"}, nil)
|
||||
s.Require().Equal("Hello World", stdout)
|
||||
})
|
||||
}
|
||||
@ -83,23 +72,12 @@ func (s *E2ETestSuite) TestOutputToStdout() {
|
||||
func (s *E2ETestSuite) TestOutputToStderr() {
|
||||
for _, environmentID := range environmentIDs {
|
||||
s.Run(environmentID.ToString(), func() {
|
||||
connection, err := ProvideWebSocketConnection(&s.Suite, environmentID,
|
||||
&dto.ExecutionRequest{Command: "cat -invalid"})
|
||||
s.Require().NoError(err)
|
||||
stdout, stderr, exitCode := ExecuteNonInteractive(&s.Suite, environmentID,
|
||||
&dto.ExecutionRequest{Command: "cat -invalid"}, nil)
|
||||
|
||||
messages, err := helpers.ReceiveAllWebSocketMessages(connection)
|
||||
s.Require().Error(err)
|
||||
s.Equal(&websocket.CloseError{Code: websocket.CloseNormalClosure}, err)
|
||||
|
||||
controlMessages := helpers.WebSocketControlMessages(messages)
|
||||
s.Require().Equal(2, len(controlMessages))
|
||||
s.Require().Equal(&dto.WebSocketMessage{Type: dto.WebSocketMetaStart}, controlMessages[0])
|
||||
s.Require().Equal(&dto.WebSocketMessage{Type: dto.WebSocketExit, ExitCode: 1}, controlMessages[1])
|
||||
|
||||
stdout, stderr, errors := helpers.WebSocketOutputMessages(messages)
|
||||
s.NotContains(stdout, "cat: invalid option", "Stdout should not contain the error")
|
||||
s.Contains(stderr, "cat: invalid option", "Stderr should contain the error")
|
||||
s.Empty(errors)
|
||||
s.Equal(uint8(1), exitCode)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -108,7 +86,7 @@ func (s *E2ETestSuite) TestOutputToStderr() {
|
||||
func (s *E2ETestSuite) TestCommandHead() {
|
||||
hello := "Hello World!"
|
||||
connection, err := ProvideWebSocketConnection(&s.Suite, tests.DefaultEnvironmentIDAsInteger,
|
||||
&dto.ExecutionRequest{Command: "head -n 1"})
|
||||
&dto.ExecutionRequest{Command: "head -n 1"}, nil)
|
||||
s.Require().NoError(err)
|
||||
|
||||
startMessage, err := helpers.ReceiveNextWebSocketMessage(connection)
|
||||
@ -128,42 +106,64 @@ func (s *E2ETestSuite) TestCommandHead() {
|
||||
func (s *E2ETestSuite) TestCommandMake() {
|
||||
for _, environmentID := range environmentIDs {
|
||||
s.Run(environmentID.ToString(), func() {
|
||||
runnerID, err := ProvideRunner(&dto.RunnerRequest{ExecutionEnvironmentID: int(environmentID)})
|
||||
s.Require().NoError(err)
|
||||
|
||||
expectedOutput := "MeinText"
|
||||
resp, err := CopyFiles(runnerID, &dto.UpdateFileSystemRequest{
|
||||
request := &dto.UpdateFileSystemRequest{
|
||||
Copy: []dto.File{
|
||||
{Path: "Makefile", Content: []byte(
|
||||
"run:\n\t@echo " + expectedOutput + "\n\n" +
|
||||
"test:\n\t@echo Hi\n"),
|
||||
},
|
||||
},
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(http.StatusNoContent, resp.StatusCode)
|
||||
|
||||
webSocketURL, err := ProvideWebSocketURL(&s.Suite, runnerID, &dto.ExecutionRequest{Command: "make run"})
|
||||
s.Require().NoError(err)
|
||||
connection, err := ConnectToWebSocket(webSocketURL)
|
||||
s.Require().NoError(err)
|
||||
|
||||
messages, err := helpers.ReceiveAllWebSocketMessages(connection)
|
||||
s.Require().Error(err)
|
||||
s.Equal(err, &websocket.CloseError{Code: websocket.CloseNormalClosure})
|
||||
stdout, _, _ := helpers.WebSocketOutputMessages(messages)
|
||||
}
|
||||
|
||||
stdout, _, _ := ExecuteNonInteractive(&s.Suite, environmentID, &dto.ExecutionRequest{Command: "make run"}, request)
|
||||
stdout = regexp.MustCompile(`\r?\n$`).ReplaceAllString(stdout, "")
|
||||
s.Equal(expectedOutput, stdout)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *E2ETestSuite) TestEnvironmentVariables() {
|
||||
for _, environmentID := range environmentIDs {
|
||||
s.Run(environmentID.ToString(), func() {
|
||||
stdout, _, _ := ExecuteNonInteractive(&s.Suite, environmentID, &dto.ExecutionRequest{
|
||||
Command: "env",
|
||||
Environment: map[string]string{"hello": "world"},
|
||||
}, nil)
|
||||
|
||||
variables := s.expectEnvironmentVariables(stdout)
|
||||
s.Contains(variables, "hello=world")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *E2ETestSuite) TestCommandMakeEnvironmentVariables() {
|
||||
for _, environmentID := range environmentIDs {
|
||||
s.Run(environmentID.ToString(), func() {
|
||||
request := &dto.UpdateFileSystemRequest{
|
||||
Copy: []dto.File{{Path: "Makefile", Content: []byte("run:\n\t@env\n")}},
|
||||
}
|
||||
|
||||
stdout, _, _ := ExecuteNonInteractive(&s.Suite, environmentID, &dto.ExecutionRequest{Command: "make run"}, request)
|
||||
s.expectEnvironmentVariables(stdout)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *E2ETestSuite) expectEnvironmentVariables(stdout string) []string {
|
||||
variables := strings.Split(strings.ReplaceAll(stdout, "\r\n", "\n"), "\n")
|
||||
s.Contains(variables, "CODEOCEAN=true")
|
||||
for _, envVar := range variables {
|
||||
s.False(strings.HasPrefix(envVar, "AWS"))
|
||||
}
|
||||
return variables
|
||||
}
|
||||
|
||||
func (s *E2ETestSuite) TestCommandReturnsAfterTimeout() {
|
||||
for _, environmentID := range environmentIDs {
|
||||
s.Run(environmentID.ToString(), func() {
|
||||
connection, err := ProvideWebSocketConnection(&s.Suite, environmentID,
|
||||
&dto.ExecutionRequest{Command: "sleep 4", TimeLimit: 1})
|
||||
&dto.ExecutionRequest{Command: "sleep 4", TimeLimit: 1}, nil)
|
||||
s.Require().NoError(err)
|
||||
|
||||
c := make(chan bool)
|
||||
@ -189,52 +189,15 @@ func (s *E2ETestSuite) TestCommandReturnsAfterTimeout() {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *E2ETestSuite) TestEnvironmentVariables() {
|
||||
for _, environmentID := range environmentIDs {
|
||||
s.Run(environmentID.ToString(), func() {
|
||||
connection, err := ProvideWebSocketConnection(&s.Suite, environmentID, &dto.ExecutionRequest{
|
||||
Command: "env",
|
||||
Environment: map[string]string{"hello": "world"},
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
|
||||
startMessage, err := helpers.ReceiveNextWebSocketMessage(connection)
|
||||
s.Require().NoError(err)
|
||||
s.Equal(dto.WebSocketMetaStart, startMessage.Type)
|
||||
|
||||
messages, err := helpers.ReceiveAllWebSocketMessages(connection)
|
||||
s.Require().Error(err)
|
||||
s.Equal(err, &websocket.CloseError{Code: websocket.CloseNormalClosure})
|
||||
stdout, _, _ := helpers.WebSocketOutputMessages(messages)
|
||||
|
||||
variables := strings.Split(strings.ReplaceAll(stdout, "\r\n", "\n"), "\n")
|
||||
s.Contains(variables, "hello=world")
|
||||
s.Contains(variables, "CODEOCEAN=true")
|
||||
for _, envVar := range variables {
|
||||
s.False(strings.HasPrefix(envVar, "AWS"))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *E2ETestSuite) TestMemoryMaxLimit_Nomad() {
|
||||
maxMemoryLimit := defaultNomadEnvironment.MemoryLimit
|
||||
// The operating system is in charge to kill the process and sometimes tolerates small exceeding of the limit.
|
||||
maxMemoryLimit = uint(1.1 * float64(maxMemoryLimit))
|
||||
connection, err := ProvideWebSocketConnection(&s.Suite, tests.DefaultEnvironmentIDAsInteger, &dto.ExecutionRequest{
|
||||
|
||||
stdout, stderr, _ := ExecuteNonInteractive(&s.Suite, tests.DefaultEnvironmentIDAsInteger, &dto.ExecutionRequest{
|
||||
// This shell line tries to load maxMemoryLimit Bytes into the memory.
|
||||
Command: "</dev/zero head -c " + strconv.Itoa(int(maxMemoryLimit)) + "MB | tail > /dev/null",
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
|
||||
startMessage, err := helpers.ReceiveNextWebSocketMessage(connection)
|
||||
s.Require().NoError(err)
|
||||
s.Equal(dto.WebSocketMetaStart, startMessage.Type)
|
||||
|
||||
messages, err := helpers.ReceiveAllWebSocketMessages(connection)
|
||||
s.Require().Error(err)
|
||||
s.Equal(err, &websocket.CloseError{Code: websocket.CloseNormalClosure})
|
||||
stdout, stderr, _ := helpers.WebSocketOutputMessages(messages)
|
||||
}, nil)
|
||||
s.Empty(stdout)
|
||||
s.Contains(stderr, "Killed")
|
||||
}
|
||||
@ -277,14 +240,43 @@ func (s *E2ETestSuite) ListTempDirectory(runnerID string) string {
|
||||
return stdout.String()
|
||||
}
|
||||
|
||||
// ExecuteNonInteractive Executes the passed executionRequest in the required environment without providing input.
|
||||
func ExecuteNonInteractive(s *suite.Suite, environmentID dto.EnvironmentID, executionRequest *dto.ExecutionRequest,
|
||||
copyRequest *dto.UpdateFileSystemRequest) (stdout, stderr string, exitCode uint8) {
|
||||
connection, err := ProvideWebSocketConnection(s, environmentID, executionRequest, copyRequest)
|
||||
s.Require().NoError(err)
|
||||
|
||||
startMessage, err := helpers.ReceiveNextWebSocketMessage(connection)
|
||||
s.Require().NoError(err)
|
||||
s.Equal(dto.WebSocketMetaStart, startMessage.Type)
|
||||
|
||||
messages, err := helpers.ReceiveAllWebSocketMessages(connection)
|
||||
s.Require().Error(err)
|
||||
s.Equal(err, &websocket.CloseError{Code: websocket.CloseNormalClosure})
|
||||
|
||||
controlMessages := helpers.WebSocketControlMessages(messages)
|
||||
s.Require().Equal(1, len(controlMessages))
|
||||
exitMessage := controlMessages[0]
|
||||
s.Require().Equal(dto.WebSocketExit, exitMessage.Type)
|
||||
|
||||
stdout, stderr, errors := helpers.WebSocketOutputMessages(messages)
|
||||
s.Empty(errors)
|
||||
return stdout, stderr, exitMessage.ExitCode
|
||||
}
|
||||
|
||||
// ProvideWebSocketConnection establishes a client WebSocket connection to run the passed ExecutionRequest.
|
||||
func ProvideWebSocketConnection(
|
||||
s *suite.Suite, environmentID dto.EnvironmentID, request *dto.ExecutionRequest) (*websocket.Conn, error) {
|
||||
func ProvideWebSocketConnection(s *suite.Suite, environmentID dto.EnvironmentID, executionRequest *dto.ExecutionRequest,
|
||||
copyRequest *dto.UpdateFileSystemRequest) (*websocket.Conn, error) {
|
||||
runnerID, err := ProvideRunner(&dto.RunnerRequest{ExecutionEnvironmentID: int(environmentID)})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error providing runner: %w", err)
|
||||
}
|
||||
webSocketURL, err := ProvideWebSocketURL(s, runnerID, request)
|
||||
if copyRequest != nil {
|
||||
resp, err := CopyFiles(runnerID, copyRequest)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(http.StatusNoContent, resp.StatusCode)
|
||||
}
|
||||
webSocketURL, err := ProvideWebSocketURL(s, runnerID, executionRequest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error providing WebSocket URL: %w", err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user