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 updateMetaData #51

Merged
merged 5 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
104 changes: 68 additions & 36 deletions datasetIngestor/updateMetaData.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package datasetIngestor

import (
"encoding/json"
"io/ioutil"
"io"
"log"
"net/http"
"strings"
Expand All @@ -11,14 +11,31 @@ import (
"github.com/fatih/color"
)

/*
getAVFromPolicy retrieves the AV (?) from a policy.

Parameters:
- client: An HTTP client used to send requests.
- APIServer: The URL of the API server.
- user: A map containing user information. It should contain an "accessToken" key.
- owner: The owner of the policy.

The function constructs a URL using the APIServer, owner, and user's access token, and sends a GET request to this URL.
If the response status code is 200, it reads the response body and unmarshals it into a slice of Policy structs.
If there are no policies available for the owner, it logs a warning and sets the level to "low".
If there are policies available, it sets the level to the TapeRedundancy of the first policy.

Returns:
- level: The TapeRedundancy level of the first policy if available, otherwise "low".
*/
func getAVFromPolicy(client *http.Client, APIServer string, user map[string]string, owner string) (level string) {
var myurl = APIServer + "/Policies?filter=%7B%22where%22%3A%7B%22ownerGroup%22%3A%22" + owner + "%22%7D%7D&access_token=" + user["accessToken"]
resp, _ := client.Get(myurl)
defer resp.Body.Close()

level = "low"
if resp.StatusCode == 200 {
body, _ := ioutil.ReadAll(resp.Body)
body, _ := io.ReadAll(resp.Body)
type Policy struct {
TapeRedundancy string
AutoArchive bool
Expand All @@ -36,48 +53,63 @@ func getAVFromPolicy(client *http.Client, APIServer string, user map[string]stri
return level
}

func UpdateMetaData(client *http.Client, APIServer string, user map[string]string,
originalMap map[string]string, metaDataMap map[string]interface{}, startTime time.Time, endTime time.Time, owner string, tapecopies *int) {
// add real creationTime if not yet existing
color.Set(color.FgGreen)
if metaDataMap["creationTime"] == DUMMY_TIME {
originalMap["creationTime"] = metaDataMap["creationTime"].(string)
metaDataMap["creationTime"] = startTime
log.Printf("creationTime field added: %v\n", metaDataMap["creationTime"])
}
/*
UpdateMetaData updates the metadata of a dataset.

if metaDataMap["ownerGroup"] == DUMMY_OWNER {
originalMap["ownerGroup"] = metaDataMap["ownerGroup"].(string)
metaDataMap["ownerGroup"] = owner
log.Printf("ownerGroup field added from file info: %v\n", metaDataMap["ownerGroup"])
}
Parameters:
- client: An HTTP client used to send requests.
- APIServer: The URL of the API server.
- user: A map containing user information. It should contain an "accessToken" key.
- originalMap: A map containing the original metadata.
- metaDataMap: A map containing the metadata to be updated.
- startTime: The start time of the dataset.
- endTime: The end time of the dataset.
- owner: The owner of the dataset.
- tapecopies: A pointer to an integer indicating the number of tape copies.

if metaDataMap["type"] == "raw" {
if metaDataMap["endTime"] == DUMMY_TIME {
originalMap["endTime"] = metaDataMap["endTime"].(string)
metaDataMap["endTime"] = endTime
log.Printf("endTime field added: %v\n", metaDataMap["endTime"])
}
}
The function updates the following fields in metaDataMap:
- "creationTime": If it's equal to DUMMY_TIME, it's replaced with startTime.
- "ownerGroup": If it's equal to DUMMY_OWNER, it's replaced with owner.
- "endTime": If the "type" field is "raw" and "endTime" is equal to DUMMY_TIME, it's replaced with endTime.
- "license": If it doesn't exist, it's set to "CC BY-SA 4.0".
- "isPublished": If it doesn't exist, it's set to false.
- "classification": If it doesn't exist, it's set to "IN=medium,AV=<AV from policy>,CO=low". If tapecopies is 1 or 2, the "AV" part is replaced with "AV=low" or "AV=medium" respectively.

// check other fields to be added
The function logs a message each time it updates a field. If the "classification" field contains "AV=medium", it also logs a note that the dataset will be copied to two tape copies.

if _, ok := metaDataMap["license"]; !ok {
metaDataMap["license"] = "CC BY-SA 4.0"
log.Printf("license field added: %v\n", metaDataMap["license"])
The function does not return a value.
*/
func UpdateMetaData(client *http.Client, APIServer string, user map[string]string,
originalMap map[string]string, metaDataMap map[string]interface{}, startTime time.Time, endTime time.Time, owner string, tapecopies *int) {
updateFieldIfDummy(metaDataMap, originalMap, "creationTime", DUMMY_TIME, startTime)
updateFieldIfDummy(metaDataMap, originalMap, "ownerGroup", DUMMY_OWNER, owner)

if metaDataMap["type"] == "raw" {
updateFieldIfDummy(metaDataMap, originalMap, "endTime", DUMMY_TIME, endTime)
}
if _, ok := metaDataMap["isPublished"]; !ok {
metaDataMap["isPublished"] = false
log.Printf("isPublished field added: %v\n", metaDataMap["isPublished"])

addFieldIfNotExists(metaDataMap, "license", "CC BY-SA 4.0")
addFieldIfNotExists(metaDataMap, "isPublished", false)

updateClassificationField(client, APIServer, user, metaDataMap, tapecopies)
}

func updateFieldIfDummy(metaDataMap map[string]interface{}, originalMap map[string]string, fieldName string, dummyValue interface{}, newValue interface{}) {
if metaDataMap[fieldName] == dummyValue {
originalMap[fieldName] = metaDataMap[fieldName].(string)
metaDataMap[fieldName] = newValue
log.Printf("%s field added: %v\n", fieldName, metaDataMap[fieldName])
}
}

/* update classification depending on policy settings and tapecopies parameter
precedence order from highest to lowest:
- tapecopies parameter for AV setting
- classification defined in metadata.json
- policy setting (give warning if this is different from value calculated so far)
func addFieldIfNotExists(metaDataMap map[string]interface{}, fieldName string, value interface{}) {
if _, ok := metaDataMap[fieldName]; !ok {
metaDataMap[fieldName] = value
log.Printf("%s field added: %v\n", fieldName, metaDataMap[fieldName])
}
}

*/
func updateClassificationField(client *http.Client, APIServer string, user map[string]string, metaDataMap map[string]interface{}, tapecopies *int) {
if _, ok := metaDataMap["classification"]; !ok {
// take default from policy settings
metaDataMap["classification"] = "IN=medium" + ",AV=" + getAVFromPolicy(client, APIServer, user, metaDataMap["ownerGroup"].(string)) + ",CO=low"
Expand Down
162 changes: 162 additions & 0 deletions datasetIngestor/updateMetaData_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package datasetIngestor

import (
"net/http"
"net/http/httptest"
"testing"
"time"
)

func TestGetAVFromPolicy(t *testing.T) {
// Test case 1: No policies available
ts1 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`[]`)) // empty policy list
}))
defer ts1.Close()

client := ts1.Client()

level := getAVFromPolicy(client, ts1.URL, map[string]string{"accessToken": "testToken"}, "testOwner")

if level != "low" {
t.Errorf("Expected level to be 'low', got '%s'", level)
}

// Test case 2: Policies available
ts2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`[{"TapeRedundancy": "medium", "AutoArchive": false}]`)) // policy list with one policy
}))
defer ts2.Close()

client = ts2.Client()

level = getAVFromPolicy(client, ts2.URL, map[string]string{"accessToken": "testToken"}, "testOwner")

if level != "medium" {
t.Errorf("Expected level to be 'medium', got '%s'", level)
}
}

// Check whether `UpdateMetaData` correctly updates the metaDataMap
func TestUpdateMetaData(t *testing.T) {
// Create a mock server
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`[{"TapeRedundancy": "medium", "AutoArchive": false}]`)) // policy list with one policy
}))
defer ts.Close()

// Create a test client
client := ts.Client()

// Define test parameters
APIServer := ts.URL // Use the mock server's URL

user := map[string]string{"accessToken": "testToken"}
originalMap := map[string]string{}
metaDataMap := map[string]interface{}{
"creationTime": DUMMY_TIME,
"ownerGroup": DUMMY_OWNER,
"type": "raw",
"endTime": DUMMY_TIME,
}
startTime := time.Now()
endTime := startTime.Add(time.Hour)
owner := "testOwner"
tapecopies := new(int)
*tapecopies = 1

// Call the function
UpdateMetaData(client, APIServer, user, originalMap, metaDataMap, startTime, endTime, owner, tapecopies)

// Check results
if metaDataMap["creationTime"] != startTime {
t.Errorf("Expected creationTime to be '%v', got '%v'", startTime, metaDataMap["creationTime"])
}
if metaDataMap["ownerGroup"] != owner {
t.Errorf("Expected ownerGroup to be '%s', got '%s'", owner, metaDataMap["ownerGroup"])
}
if metaDataMap["endTime"] != endTime {
t.Errorf("Expected endTime to be '%v', got '%v'", endTime, metaDataMap["endTime"])
}
if metaDataMap["license"] != "CC BY-SA 4.0" {
t.Errorf("Expected license to be 'CC BY-SA 4.0', got '%s'", metaDataMap["license"])
}
if metaDataMap["isPublished"] != false {
t.Errorf("Expected isPublished to be 'false', got '%v'", metaDataMap["isPublished"])
}
if _, ok := metaDataMap["classification"]; !ok {
t.Errorf("Expected classification to be set, got '%v'", metaDataMap["classification"])
}
}

// Check if updateFieldIfDummy correctly updates the metaDataMap and originalMap when the field is a dummy value.
func TestUpdateFieldIfDummy(t *testing.T) {
// Define test parameters
metaDataMap := map[string]interface{}{
"testField": "DUMMY",
}
originalMap := map[string]string{}
fieldName := "testField"
dummyValue := "DUMMY"
newValue := "newValue"

// Call the function
updateFieldIfDummy(metaDataMap, originalMap, fieldName, dummyValue, newValue)

// Check results
if metaDataMap[fieldName] != newValue {
t.Errorf("Expected %s to be '%v', got '%v'", fieldName, newValue, metaDataMap[fieldName])
}
if originalMap[fieldName] != dummyValue {
t.Errorf("Expected original %s to be '%v', got '%v'", fieldName, dummyValue, originalMap[fieldName])
}
}

// Check if addFieldIfNotExists correctly adds a field to the metaDataMap if it does not already exist.
func TestAddFieldIfNotExists(t *testing.T) {
// Define test parameters
metaDataMap := map[string]interface{}{}
fieldName := "testField"
value := "testValue"

// Call the function
addFieldIfNotExists(metaDataMap, fieldName, value)

// Check results
if metaDataMap[fieldName] != value {
t.Errorf("Expected %s to be '%v', got '%v'", fieldName, value, metaDataMap[fieldName])
}
}

// Check if updateClassificationField correctly updates the classification field in the metaDataMap.
func TestUpdateClassificationField(t *testing.T) {
// Create a mock server
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`[{"TapeRedundancy": "medium", "AutoArchive": false}]`)) // policy list with one policy
}))
defer ts.Close()

// Create a test client
client := ts.Client()

// Define test parameters
APIServer := ts.URL // Use the mock server's URL
user := map[string]string{"accessToken": "testToken"}
metaDataMap := map[string]interface{}{
"ownerGroup": "testOwner",
}
tapecopies := new(int)
*tapecopies = 1

// Call the function
updateClassificationField(client, APIServer, user, metaDataMap, tapecopies)

// Check results
if _, ok := metaDataMap["classification"]; !ok {
minottic marked this conversation as resolved.
Show resolved Hide resolved
t.Errorf("Expected classification to be set, got '%v'", metaDataMap["classification"])
}
}
Loading