Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test CreateJob #57

Merged
merged 2 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion datasetUtils/createJob.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,23 @@ type Job struct {
Id string `json:"id"`
}

/*
`CreateJob` creates a new job on the server. It takes in an HTTP client, the API server URL, a user map, a list of datasets, and a pointer to an integer representing the number of tape copies.

The function constructs a job map with various parameters, including the email of the job initiator, the type of job, the creation time, the job parameters, and the job status message. It also includes a list of datasets.

The job map is then marshalled into JSON and sent as a POST request to the server. If the server responds with a status code of 200, the function decodes the job ID from the response and returns it. If the server responds with any other status code, the function returns an empty string.

Parameters:
- client: A pointer to an http.Client instance
- APIServer: A string representing the API server URL
- user: A map with string keys and values representing user information
- datasetList: A slice of strings representing the list of datasets
- tapecopies: A pointer to an integer representing the number of tape copies

Returns:
- jobId: A string representing the job ID if the job was successfully created, or an empty string otherwise
*/
func CreateJob(client *http.Client, APIServer string, user map[string]string, datasetList []string, tapecopies *int) (jobId string) {
// important: define field with capital names and rename fields via 'json' constructs
// otherwise the marshaling will omit the fields !
Expand Down Expand Up @@ -69,7 +86,8 @@ func CreateJob(client *http.Client, APIServer string, user map[string]string, da
var j Job
err := decoder.Decode(&j)
if err != nil {
log.Fatal("Could not decode id from job:", err)
log.Println("Could not decode id from job:", err)
return ""
}
return j.Id
} else {
Expand Down
165 changes: 165 additions & 0 deletions datasetUtils/createJob_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package datasetUtils

import (
"net/http"
"net/http/httptest"
"testing"
"io"
"bytes"
"encoding/json"
"reflect"
)

type MockTransport struct {
RoundTripFunc func(req *http.Request) (*http.Response, error)
}

func (m *MockTransport) RoundTrip(req *http.Request) (*http.Response, error) {
return m.RoundTripFunc(req)
}

func TestCreateJob(t *testing.T) {
minottic marked this conversation as resolved.
Show resolved Hide resolved
t.Run("successful job creation", func(t *testing.T) {
// Create a mock server
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(`{"id": "123"}`))
}))
defer server.Close()

// Create a client
client := server.Client()

// Define the parameters
APIServer := server.URL
user := map[string]string{
"mail": "[email protected]",
"username": "testuser",
"accessToken": "testtoken",
}
datasetList := []string{"dataset1", "dataset2"}
tapecopies := new(int)
*tapecopies = 1

// Call the function
jobId := CreateJob(client, APIServer, user, datasetList, tapecopies)

// Check the result
if jobId != "123" {
t.Errorf("Expected jobId to be '123', got '%s'", jobId)
}
})

t.Run("server returns non-200 status code", func(t *testing.T) {
// Create a mock server
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(http.StatusInternalServerError)
}))
defer server.Close()

// Create a client
client := server.Client()

// Define the parameters
APIServer := server.URL
user := map[string]string{
"mail": "[email protected]",
"username": "testuser",
"accessToken": "testtoken",
}
datasetList := []string{"dataset1", "dataset2"}
tapecopies := new(int)
*tapecopies = 1

// Call the function
jobId := CreateJob(client, APIServer, user, datasetList, tapecopies)

// Check the result
if jobId != "" {
t.Errorf("Expected jobId to be '', got '%s'", jobId)
}
})

t.Run("server returns invalid JSON", func(t *testing.T) {
// Create a mock server
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(`invalid json`))
}))
defer server.Close()

// Create a client
client := server.Client()

// Define the parameters
APIServer := server.URL
user := map[string]string{
"mail": "[email protected]",
"username": "testuser",
"accessToken": "testtoken",
}
datasetList := []string{"dataset1", "dataset2"}
tapecopies := new(int)
*tapecopies = 1

// Call the function
jobId := CreateJob(client, APIServer, user, datasetList, tapecopies)

// Check the result
if jobId != "" {
t.Errorf("Expected jobId to be '', got '%s'", jobId)
}
})

t.Run("client.Do called with expected payload", func(t *testing.T) {
// Create a mock server
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(`{"id": "123"}`))
}))
defer server.Close()

user := map[string]string{
"mail": "[email protected]",
"username": "testuser",
"accessToken": "testtoken",
}
datasetList := []string{"dataset1", "dataset2"}
tapecopies := new(int)
*tapecopies = 2

// Create a mock client
client := &http.Client{
Transport: &MockTransport{
RoundTripFunc: func(req *http.Request) (*http.Response, error) {
body, _ := io.ReadAll(req.Body)

// Parse the actual and expected payloads
var actualPayload, expectedPayload map[string]interface{}
json.Unmarshal(body, &actualPayload)
json.Unmarshal([]byte(`{"creationTime":"2024-05-21T15:25:34+02:00","datasetList":[{"pid":"dataset1","files":[]},{"pid":"dataset2","files":[]}],"emailJobInitiator":"[email protected]","jobParams":{"tapeCopies":"two","username":"testuser"},"jobStatusMessage":"jobSubmitted","type":"archive"}`), &expectedPayload)

// Ignore the creationTime field
delete(actualPayload, "creationTime")
delete(expectedPayload, "creationTime")

// Check if the payloads match
if !reflect.DeepEqual(actualPayload, expectedPayload) {
t.Errorf("Expected payload to be '%v', got '%v'", expectedPayload, actualPayload)
}

// We still need to return a response
return &http.Response{
StatusCode: 200,
Body: io.NopCloser(bytes.NewBufferString(`{"id": "123"}`)),
}, nil
},
},
}

// Call the function with the mock client
jobId := CreateJob(client, server.URL, user, datasetList, tapecopies)

// Check the result
if jobId != "123" {
t.Errorf("Expected jobId to be '123', got '%s'", jobId)
}
})
}