From b0916a248554dfb28c0cf5b2ca4ad9cffb923555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Pa=C3=9F?= <22845248+mpass99@users.noreply.github.com> Date: Thu, 16 Jun 2022 09:39:56 +0200 Subject: [PATCH] #166 Adjust outdated make command pattern as with #147 a new unset command part is introduced. Also add a regression e2e test that would have caught this issue. --- .../main/java/poseidon/SimpleMakefile.java | 2 +- tests/e2e/runners_test.go | 45 ++++++++++--------- tests/e2e/websocket_test.go | 35 +++++++++++++++ 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/deploy/aws/java11Exec/src/main/java/poseidon/SimpleMakefile.java b/deploy/aws/java11Exec/src/main/java/poseidon/SimpleMakefile.java index 920305a..f555fdd 100644 --- a/deploy/aws/java11Exec/src/main/java/poseidon/SimpleMakefile.java +++ b/deploy/aws/java11Exec/src/main/java/poseidon/SimpleMakefile.java @@ -22,7 +22,7 @@ class InvalidMakefileException extends Exception {} class SimpleMakefile { // This pattern validates if a command is a make command. - private static final Pattern isMakeCommand = Pattern.compile("^make(?:\\s+(?\\w*))?(?(?:.*?=.*?)+)?$"); + private static final Pattern isMakeCommand = Pattern.compile("^(?:.* && )?make(?:\\s+(?\\w*))?(?(?:.*?=.*?)+)?(?: && .*)?$"); // This pattern identifies the rules in a makefile. private static final Pattern makeRules = Pattern.compile("(?.*):\\r?\\n(?(?:\\t.+\\r?\\n?)*)"); diff --git a/tests/e2e/runners_test.go b/tests/e2e/runners_test.go index ca6d554..9b2a641 100644 --- a/tests/e2e/runners_test.go +++ b/tests/e2e/runners_test.go @@ -9,7 +9,6 @@ import ( "github.com/openHPI/poseidon/pkg/dto" "github.com/openHPI/poseidon/tests" "github.com/openHPI/poseidon/tests/helpers" - "io" "net/http" "strings" "time" @@ -78,6 +77,18 @@ func ProvideRunner(request *dto.RunnerRequest) (string, error) { return runnerResponse.ID, nil } +// CopyFiles sends the dto.UpdateFileSystemRequest to Poseidon. +// It needs a running Poseidon instance to work. +func CopyFiles(runnerID string, request *dto.UpdateFileSystemRequest) (*http.Response, error) { + data, err := json.Marshal(request) + if err != nil { + return nil, err + } + r := bytes.NewReader(data) + return helpers.HTTPPatch(helpers.BuildURL(api.BasePath, api.RunnersPath, runnerID, api.UpdateFileSystemPath), + "application/json", r) +} + func (s *E2ETestSuite) TestDeleteRunnerRoute() { for _, environmentID := range environmentIDs { s.Run(environmentID.ToString(), func() { @@ -111,17 +122,13 @@ func (s *E2ETestSuite) TestCopyFilesRoute() { s.Run(environmentID.ToString(), func() { runnerID, err := ProvideRunner(&dto.RunnerRequest{ExecutionEnvironmentID: int(environmentID)}) s.NoError(err) - copyFilesRequestByteString, err := json.Marshal(&dto.UpdateFileSystemRequest{ + + request := &dto.UpdateFileSystemRequest{ Copy: []dto.File{{Path: tests.DefaultFileName, Content: []byte(tests.DefaultFileContent)}}, - }) - s.Require().NoError(err) - sendCopyRequest := func(reader io.Reader) (*http.Response, error) { - return helpers.HTTPPatch(helpers.BuildURL(api.BasePath, api.RunnersPath, runnerID, api.UpdateFileSystemPath), - "application/json", reader) } s.Run("File copy with valid payload succeeds", func() { - resp, err := sendCopyRequest(bytes.NewReader(copyFilesRequestByteString)) + resp, err := CopyFiles(runnerID, request) s.NoError(err) s.Equal(http.StatusNoContent, resp.StatusCode) @@ -135,15 +142,15 @@ func (s *E2ETestSuite) TestCopyFilesRoute() { relativeFileContent := "Relative file content" absoluteFilePath := "/tmp/absolute/file/path.txt" absoluteFileContent := "Absolute file content" - testFilePathsCopyRequestString, err := json.Marshal(&dto.UpdateFileSystemRequest{ + request = &dto.UpdateFileSystemRequest{ Copy: []dto.File{ {Path: dto.FilePath(relativeFilePath), Content: []byte(relativeFileContent)}, {Path: dto.FilePath(absoluteFilePath), Content: []byte(absoluteFileContent)}, }, - }) + } s.Require().NoError(err) - resp, err := sendCopyRequest(bytes.NewReader(testFilePathsCopyRequestString)) + resp, err := CopyFiles(runnerID, request) s.NoError(err) s.Equal(http.StatusNoContent, resp.StatusCode) @@ -158,12 +165,12 @@ func (s *E2ETestSuite) TestCopyFilesRoute() { }) s.Run("File deletion request deletes file on runner", func() { - copyFilesRequestByteString, err := json.Marshal(&dto.UpdateFileSystemRequest{ + request = &dto.UpdateFileSystemRequest{ Delete: []dto.FilePath{tests.DefaultFileName}, - }) + } s.Require().NoError(err) - resp, err := sendCopyRequest(bytes.NewReader(copyFilesRequestByteString)) + resp, err := CopyFiles(runnerID, request) s.NoError(err) s.Equal(http.StatusNoContent, resp.StatusCode) @@ -175,13 +182,13 @@ func (s *E2ETestSuite) TestCopyFilesRoute() { }) s.Run("File copy happens after file deletion", func() { - copyFilesRequestByteString, err := json.Marshal(&dto.UpdateFileSystemRequest{ + request = &dto.UpdateFileSystemRequest{ Delete: []dto.FilePath{tests.DefaultFileName}, Copy: []dto.File{{Path: tests.DefaultFileName, Content: []byte(tests.DefaultFileContent)}}, - }) + } s.Require().NoError(err) - resp, err := sendCopyRequest(bytes.NewReader(copyFilesRequestByteString)) + resp, err := CopyFiles(runnerID, request) s.NoError(err) s.Equal(http.StatusNoContent, resp.StatusCode) _ = resp.Body.Close() @@ -199,9 +206,7 @@ func (s *E2ETestSuite) TestCopyFilesRoute() { }) s.Run("Copying to non-existing runner returns NotFound", func() { - resp, err := helpers.HTTPPatch( - helpers.BuildURL(api.BasePath, api.RunnersPath, tests.NonExistingStringID, api.UpdateFileSystemPath), - "application/json", bytes.NewReader(copyFilesRequestByteString)) + resp, err := CopyFiles(tests.NonExistingStringID, request) s.NoError(err) s.Equal(http.StatusNotFound, resp.StatusCode) }) diff --git a/tests/e2e/websocket_test.go b/tests/e2e/websocket_test.go index 4e0839d..fe865fc 100644 --- a/tests/e2e/websocket_test.go +++ b/tests/e2e/websocket_test.go @@ -13,6 +13,7 @@ import ( "github.com/openHPI/poseidon/tests/helpers" "github.com/stretchr/testify/suite" "net/http" + "regexp" "strconv" "strings" "time" @@ -124,6 +125,40 @@ func (s *E2ETestSuite) TestCommandHead() { s.Contains(stdout, fmt.Sprintf("%s\r\n%s\r\n", hello, hello)) } +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{ + 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 = regexp.MustCompile(`\r?\n$`).ReplaceAllString(stdout, "") + s.Equal(expectedOutput, stdout) + }) + } +} + func (s *E2ETestSuite) TestCommandReturnsAfterTimeout() { for _, environmentID := range environmentIDs { s.Run(environmentID.ToString(), func() {