|
|
|
@ -1,9 +1,10 @@
|
|
|
|
|
package e2e
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"encoding/json"
|
|
|
|
|
nomadApi "github.com/hashicorp/nomad/api"
|
|
|
|
|
"github.com/openHPI/poseidon/internal/api"
|
|
|
|
|
"github.com/openHPI/poseidon/internal/runner"
|
|
|
|
|
"github.com/openHPI/poseidon/internal/nomad"
|
|
|
|
|
"github.com/openHPI/poseidon/pkg/dto"
|
|
|
|
|
"github.com/openHPI/poseidon/tests"
|
|
|
|
|
"github.com/openHPI/poseidon/tests/helpers"
|
|
|
|
@ -65,7 +66,213 @@ func TestCreateOrUpdateEnvironment(t *testing.T) {
|
|
|
|
|
validateJob(t, request)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
cleanupJobsForEnvironment(t, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
deleteEnvironment(t, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestListEnvironments(t *testing.T) {
|
|
|
|
|
path := helpers.BuildURL(api.BasePath, api.EnvironmentsPath)
|
|
|
|
|
|
|
|
|
|
t.Run("returns list with one element", func(t *testing.T) {
|
|
|
|
|
response, err := http.Get(path) //nolint:gosec // because we build this path right above
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusOK, response.StatusCode)
|
|
|
|
|
environmentsArray := assertEnvironmentArrayInResponse(t, response)
|
|
|
|
|
assert.Equal(t, 1, len(environmentsArray))
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("returns list including the default environment", func(t *testing.T) {
|
|
|
|
|
response, err := http.Get(path) //nolint:gosec // because we build this path right above
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, http.StatusOK, response.StatusCode)
|
|
|
|
|
|
|
|
|
|
environmentsArray := assertEnvironmentArrayInResponse(t, response)
|
|
|
|
|
require.Equal(t, 1, len(environmentsArray))
|
|
|
|
|
|
|
|
|
|
assertEnvironment(t, environmentsArray[0], tests.DefaultEnvironmentIDAsInteger)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("Added environments can be retrieved without fetch", func(t *testing.T) {
|
|
|
|
|
createEnvironment(t, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
|
|
|
|
|
response, err := http.Get(path) //nolint:gosec // because we build this path right above
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, http.StatusOK, response.StatusCode)
|
|
|
|
|
|
|
|
|
|
environmentsArray := assertEnvironmentArrayInResponse(t, response)
|
|
|
|
|
require.Equal(t, 2, len(environmentsArray))
|
|
|
|
|
foundIDs := parseIDsFromEnvironments(t, environmentsArray)
|
|
|
|
|
assert.Contains(t, foundIDs, dto.EnvironmentID(tests.AnotherEnvironmentIDAsInteger))
|
|
|
|
|
})
|
|
|
|
|
deleteEnvironment(t, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
|
|
|
|
|
t.Run("Added environments can be retrieved with fetch", func(t *testing.T) {
|
|
|
|
|
// Add environment without Poseidon
|
|
|
|
|
_, job := helpers.CreateTemplateJob()
|
|
|
|
|
jobID := nomad.TemplateJobID(tests.AnotherEnvironmentIDAsInteger)
|
|
|
|
|
job.ID = &jobID
|
|
|
|
|
job.Name = &jobID
|
|
|
|
|
_, _, err := nomadClient.Jobs().Register(job, nil)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
// List without fetch should not include the added environment
|
|
|
|
|
response, err := http.Get(path) //nolint:gosec // because we build this path right above
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, http.StatusOK, response.StatusCode)
|
|
|
|
|
environmentsArray := assertEnvironmentArrayInResponse(t, response)
|
|
|
|
|
require.Equal(t, 1, len(environmentsArray))
|
|
|
|
|
assertEnvironment(t, environmentsArray[0], tests.DefaultEnvironmentIDAsInteger)
|
|
|
|
|
|
|
|
|
|
// List with fetch should include the added environment
|
|
|
|
|
response, err = http.Get(path + "?fetch=true") //nolint:gosec // because we build this path right above
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, http.StatusOK, response.StatusCode)
|
|
|
|
|
environmentsArray = assertEnvironmentArrayInResponse(t, response)
|
|
|
|
|
require.Equal(t, 2, len(environmentsArray))
|
|
|
|
|
foundIDs := parseIDsFromEnvironments(t, environmentsArray)
|
|
|
|
|
assert.Contains(t, foundIDs, dto.EnvironmentID(tests.AnotherEnvironmentIDAsInteger))
|
|
|
|
|
})
|
|
|
|
|
deleteEnvironment(t, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestGetEnvironment(t *testing.T) {
|
|
|
|
|
t.Run("returns the default environment", func(t *testing.T) {
|
|
|
|
|
path := helpers.BuildURL(api.BasePath, api.EnvironmentsPath, tests.DefaultEnvironmentIDAsString)
|
|
|
|
|
response, err := http.Get(path) //nolint:gosec // because we build this path right above
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, http.StatusOK, response.StatusCode)
|
|
|
|
|
|
|
|
|
|
environment := getEnvironmentFromResponse(t, response)
|
|
|
|
|
assertEnvironment(t, environment, tests.DefaultEnvironmentIDAsInteger)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("Added environments can be retrieved without fetch", func(t *testing.T) {
|
|
|
|
|
createEnvironment(t, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
|
|
|
|
|
path := helpers.BuildURL(api.BasePath, api.EnvironmentsPath, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
response, err := http.Get(path) //nolint:gosec // because we build this path right above
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, http.StatusOK, response.StatusCode)
|
|
|
|
|
|
|
|
|
|
environment := getEnvironmentFromResponse(t, response)
|
|
|
|
|
assertEnvironment(t, environment, tests.AnotherEnvironmentIDAsInteger)
|
|
|
|
|
})
|
|
|
|
|
deleteEnvironment(t, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
|
|
|
|
|
t.Run("Added environments can be retrieved with fetch", func(t *testing.T) {
|
|
|
|
|
// Add environment without Poseidon
|
|
|
|
|
_, job := helpers.CreateTemplateJob()
|
|
|
|
|
jobID := nomad.TemplateJobID(tests.AnotherEnvironmentIDAsInteger)
|
|
|
|
|
job.ID = &jobID
|
|
|
|
|
job.Name = &jobID
|
|
|
|
|
_, _, err := nomadClient.Jobs().Register(job, nil)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
// List without fetch should not include the added environment
|
|
|
|
|
path := helpers.BuildURL(api.BasePath, api.EnvironmentsPath, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
response, err := http.Get(path) //nolint:gosec // because we build this path right above
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, http.StatusNotFound, response.StatusCode)
|
|
|
|
|
|
|
|
|
|
// List with fetch should include the added environment
|
|
|
|
|
response, err = http.Get(path + "?fetch=true") //nolint:gosec // because we build this path right above
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, http.StatusOK, response.StatusCode)
|
|
|
|
|
environment := getEnvironmentFromResponse(t, response)
|
|
|
|
|
assertEnvironment(t, environment, tests.AnotherEnvironmentIDAsInteger)
|
|
|
|
|
})
|
|
|
|
|
deleteEnvironment(t, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestDeleteEnvironment(t *testing.T) {
|
|
|
|
|
t.Run("Removes added environment", func(t *testing.T) {
|
|
|
|
|
createEnvironment(t, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
|
|
|
|
|
path := helpers.BuildURL(api.BasePath, api.EnvironmentsPath, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
response, err := helpers.HTTPDelete(path, nil)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.Equal(t, http.StatusNoContent, response.StatusCode)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("Removes Nomad Job", func(t *testing.T) {
|
|
|
|
|
createEnvironment(t, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
|
|
|
|
|
// Expect created Nomad job
|
|
|
|
|
jobID := nomad.TemplateJobID(tests.AnotherEnvironmentIDAsInteger)
|
|
|
|
|
job, _, err := nomadClient.Jobs().Info(jobID, nil)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.Equal(t, jobID, *job.ID)
|
|
|
|
|
|
|
|
|
|
// Delete the job
|
|
|
|
|
path := helpers.BuildURL(api.BasePath, api.EnvironmentsPath, tests.AnotherEnvironmentIDAsString)
|
|
|
|
|
response, err := helpers.HTTPDelete(path, nil)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.Equal(t, http.StatusNoContent, response.StatusCode)
|
|
|
|
|
|
|
|
|
|
// Expect not to find the Nomad job
|
|
|
|
|
_, _, err = nomadClient.Jobs().Info(jobID, nil)
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseIDsFromEnvironments(t *testing.T, environments []interface{}) (ids []dto.EnvironmentID) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
for _, environment := range environments {
|
|
|
|
|
id, _ := parseEnvironment(t, environment)
|
|
|
|
|
ids = append(ids, id)
|
|
|
|
|
}
|
|
|
|
|
return ids
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func assertEnvironment(t *testing.T, environment interface{}, expectedID dto.EnvironmentID) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
id, defaultEnvironmentParams := parseEnvironment(t, environment)
|
|
|
|
|
|
|
|
|
|
assert.Equal(t, expectedID, id)
|
|
|
|
|
expectedKeys := []string{"prewarmingPoolSize", "cpuLimit", "memoryLimit", "image", "networkAccess", "exposedPorts"}
|
|
|
|
|
for _, key := range expectedKeys {
|
|
|
|
|
_, ok := defaultEnvironmentParams[key]
|
|
|
|
|
assert.True(t, ok)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseEnvironment(t *testing.T, environment interface{}) (id dto.EnvironmentID, params map[string]interface{}) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
environmentParams, ok := environment.(map[string]interface{})
|
|
|
|
|
require.True(t, ok)
|
|
|
|
|
idInterface, ok := environmentParams["id"]
|
|
|
|
|
require.True(t, ok)
|
|
|
|
|
idFloat, ok := idInterface.(float64)
|
|
|
|
|
require.True(t, ok)
|
|
|
|
|
return dto.EnvironmentID(int(idFloat)), environmentParams
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func assertEnvironmentArrayInResponse(t *testing.T, response *http.Response) []interface{} {
|
|
|
|
|
t.Helper()
|
|
|
|
|
paramMap := make(map[string]interface{})
|
|
|
|
|
err := json.NewDecoder(response.Body).Decode(¶mMap)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
environments, ok := paramMap["executionEnvironments"]
|
|
|
|
|
assert.True(t, ok)
|
|
|
|
|
environmentsArray, ok := environments.([]interface{})
|
|
|
|
|
assert.True(t, ok)
|
|
|
|
|
return environmentsArray
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getEnvironmentFromResponse(t *testing.T, response *http.Response) interface{} {
|
|
|
|
|
t.Helper()
|
|
|
|
|
var environment interface{}
|
|
|
|
|
err := json.NewDecoder(response.Body).Decode(&environment)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
return environment
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//nolint:unparam // Because its more clear if the environment id is written in the real test
|
|
|
|
|
func deleteEnvironment(t *testing.T, id string) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
path := helpers.BuildURL(api.BasePath, api.EnvironmentsPath, id)
|
|
|
|
|
_, err := helpers.HTTPDelete(path, nil)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func cleanupJobsForEnvironment(t *testing.T, environmentID string) {
|
|
|
|
@ -84,6 +291,21 @@ func cleanupJobsForEnvironment(t *testing.T, environmentID string) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//nolint:unparam // Because its more clear if the environment id is written in the real test
|
|
|
|
|
func createEnvironment(t *testing.T, environmentID string) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
path := helpers.BuildURL(api.BasePath, api.EnvironmentsPath, environmentID)
|
|
|
|
|
request := dto.ExecutionEnvironmentRequest{
|
|
|
|
|
PrewarmingPoolSize: 1,
|
|
|
|
|
CPULimit: 100,
|
|
|
|
|
MemoryLimit: 100,
|
|
|
|
|
Image: *testDockerImage,
|
|
|
|
|
NetworkAccess: false,
|
|
|
|
|
ExposedPorts: nil,
|
|
|
|
|
}
|
|
|
|
|
assertPutReturnsStatusAndZeroContent(t, path, request, http.StatusCreated)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func assertPutReturnsStatusAndZeroContent(t *testing.T, path string,
|
|
|
|
|
request dto.ExecutionEnvironmentRequest, status int) {
|
|
|
|
|
t.Helper()
|
|
|
|
@ -133,9 +355,9 @@ func validateJob(t *testing.T, expected dto.ExecutionEnvironmentRequest) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func findTemplateJob(t *testing.T, id runner.EnvironmentID) *nomadApi.Job {
|
|
|
|
|
func findTemplateJob(t *testing.T, id dto.EnvironmentID) *nomadApi.Job {
|
|
|
|
|
t.Helper()
|
|
|
|
|
job, _, err := nomadClient.Jobs().Info(runner.TemplateJobID(id), nil)
|
|
|
|
|
job, _, err := nomadClient.Jobs().Info(nomad.TemplateJobID(id), nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Error retrieving Nomad job: %v", err)
|
|
|
|
|
}
|
|
|
|
|