diff --git a/cmd/datasetIngestor/main.go b/cmd/datasetIngestor/main.go index c9c3df2..2e3cdd8 100644 --- a/cmd/datasetIngestor/main.go +++ b/cmd/datasetIngestor/main.go @@ -57,8 +57,10 @@ import ( const TOTAL_MAXFILES = 400000 +// isFlagPassed checks if a specific command-line flag has been passed to the program. func isFlagPassed(name string) bool { found := false + // The flag.Visit function is a built-in function from the Go standard library's flag package. It iterates over all command-line flags that have been set (i.e., flags that were provided when the program was run), and for each flag, it calls the provided function. flag.Visit(func(f *flag.Flag) { if f.Name == name { found = true @@ -281,7 +283,7 @@ func main() { } else if numFiles > TOTAL_MAXFILES { tooLargeDatasets++ color.Set(color.FgRed) - log.Println("This dataset exceeds the current filecount limit of the archive system of %v files and will therefore NOT be stored.\n", TOTAL_MAXFILES) + log.Printf("This dataset exceeds the current filecount limit of the archive system of %v files and will therefore NOT be stored.\n", TOTAL_MAXFILES) color.Unset() } else { datasetIngestor.UpdateMetaData(client, APIServer, user, originalMap, metaDataMap, startTime, endTime, owner, tapecopies) diff --git a/cmd/datasetIngestor/main_test.go b/cmd/datasetIngestor/main_test.go new file mode 100644 index 0000000..0270d23 --- /dev/null +++ b/cmd/datasetIngestor/main_test.go @@ -0,0 +1,62 @@ +package main + +import ( + "bytes" + "os" + "testing" +) + +// TestMainHelp is a test function that verifies the output of the main function. +// It captures the stdout, runs the main function, and checks if the output contains the expected strings. +// This just checks if the main function prints the help message. +func TestMainHelp(t *testing.T) { + // Capture stdout + // The variable 'old' stores the original value of the standard output (os.Stdout). + old := os.Stdout + // r is a ReadCloser that represents the read end of the pipe. + // w is a WriteCloser that represents the write end of the pipe. + // err is an error variable. + // The os.Pipe() function in Go is used to create a synchronous in-memory pipe. It can be used for communication between different parts of the program. + // The `os.Pipe()` function in Go is used to create a synchronous in-memory pipe. It can be used for communication between different parts of your program. + // This function returns two values: a `*os.File` for reading and a `*os.File` for writing. When you write data to the write end of the pipe, it becomes available to read from the read end of the pipe. This can be useful for passing data between goroutines or between different parts of your program without using the disk. + r, w, err1 := os.Pipe() + if err1 != nil { + // The Fatalf method is similar to log.Fatalf or fmt.Printf in that it formats a string according to a format specifier and arguments, then logs that string as an error message. However, in addition to this, Fatalf also ends the test immediately. No further code in the test function will be executed, and the test will be marked as failed. + t.Fatalf("Could not start the test. Error in reading the file: %v", err1) + } + // redirect the standard output (os.Stdout) to a different destination, represented by w. + // By default, anything written to os.Stdout will be printed to the terminal. + // The w in this line of code is expected to be a value that satisfies the io.Writer interface, which means it has a Write method. This could be a file, a buffer, a network connection, or any other type of destination for output. + // Since w is connected to r, anything written to w can be read from r. This is how we will capture the output of the main function. + os.Stdout = w + + // Restore stdout after the test + // defer is a keyword that schedules a function call to be run after the function that contains the defer statement has completed. + defer func() { + os.Stdout = old + }() + + // Run main function (assuming your main function does not take any arguments) + main() + + // Close pipe writer to flush the output + w.Close() + + //declares a variable named buf of type bytes.Buffer. The bytes.Buffer type is a struct provided by the Go standard library that implements the io.Reader and io.Writer interfaces. + var buf bytes.Buffer + // Copy pipe reader output to buf + // ReadFrom reads data from the given reader r and writes it to the buffer buf. + // It returns the number of bytes read and any error encountered. + _, err := buf.ReadFrom(r) + if err != nil { + t.Fatalf("Error reading output: %v", err) + } + + // Check if the output contains expected strings + expected := "\n\nTool to ingest datasets to the data catalog.\n\n" + //The bytes.Contains function takes two arguments, both of which are slices of bytes, and checks if the second argument is contained within the first. + // Here, expected is a string, and []byte(expected) converts that string to a slice of bytes. + if !bytes.Contains(buf.Bytes(), []byte(expected)) { + t.Errorf("Expected output %q not found in %q", expected, buf.String()) + } +} diff --git a/cmd/datasetIngestor/metadata.json b/cmd/datasetIngestor/metadata.json index 3f69f39..e5d69a9 100644 --- a/cmd/datasetIngestor/metadata.json +++ b/cmd/datasetIngestor/metadata.json @@ -2,10 +2,10 @@ "creationLocation": "/PSI/SLS/CSAXS", "datasetName": "CMakeCache", "description": "", - "owner": "Ana Diaz", - "ownerEmail": "ana.diaz@psi.ch", - "ownerGroup": "p17301", - "principalInvestigator": "ana.diaz@psi.ch", + "owner": "Ali Vahdati", + "ownerEmail": "reza.rezaee-vahdati@psi.ch", + "ownerGroup": "reza.rezaee-vahdati@psi.ch", + "principalInvestigator": "reza.rezaee-vahdati@psi.ch", "scientificMetadata": [ { "sample": { diff --git a/cmd/datasetPublishData/main.go b/cmd/datasetPublishData/main.go index 52ab04d..8c51208 100644 --- a/cmd/datasetPublishData/main.go +++ b/cmd/datasetPublishData/main.go @@ -16,20 +16,20 @@ on the publication server package main import ( - "bufio" - "bytes" - "crypto/tls" - "encoding/json" - "flag" - "fmt" - "html/template" - "io/ioutil" - "log" - "net/http" - "os" - "os/exec" + "bufio" // Provides buffered I/O operations for efficient reading and writing + "bytes" // Provides functions for operating on byte slices + "crypto/tls" // Provides functionality for secure TLS/SSL communication + "encoding/json" // Encodes and decodes JSON data + "flag" // Parses command-line flags + "fmt" // Provides formatted I/O operations + "html/template" // Parses and executes HTML templates + "io/ioutil" // Reads and writes files + "log" // Writes messages to a log file + "net/http" // Provides network communication for HTTP requests + "os" // Provides access to operating system functionality + "os/exec" // Executes external commands "scicat/datasetUtils" - "strings" + "strings" // Provides functions for manipulating strings "time" "unicode/utf8" diff --git a/cmd/datasetRetriever/main.go b/cmd/datasetRetriever/main.go index 7086c93..5720f0d 100644 --- a/cmd/datasetRetriever/main.go +++ b/cmd/datasetRetriever/main.go @@ -95,7 +95,7 @@ func main() { log.Printf("You are about to retrieve dataset(s) from the === %s === retrieve server...", env) color.Unset() - if *retrieveFlag == false { + if !*retrieveFlag { color.Set(color.FgRed) log.Printf("Note: you run in 'dry' mode to simply check which data would be fetched.\n") log.Printf("Use the -retrieve flag to actually transfer the datasets to your chosen destination path.\n") @@ -126,7 +126,7 @@ func main() { if len(datasetList) == 0 { fmt.Printf("\n\nNo datasets found on intermediate cache server.\n") - fmt.Println("Did you submit a retrieve job from the data catalog first ?\n") + fmt.Println("Did you submit a retrieve job from the data catalog first ?") } else { // get sourceFolder and other dataset related info for all Datasets datasetDetails := datasetUtils.GetDatasetDetails(client, APIServer, user["accessToken"], datasetList, *ownerGroup) diff --git a/datasetIngestor/assembleFilelisting.go b/datasetIngestor/assembleFilelisting.go index 9b6c305..2d568f5 100644 --- a/datasetIngestor/assembleFilelisting.go +++ b/datasetIngestor/assembleFilelisting.go @@ -118,7 +118,7 @@ func AssembleFilelisting(sourceFolder string, filelistingPath string, skip *stri // spin.Start() // Start the spinner e := filepath.Walk(line, func(path string, f os.FileInfo, err error) error { // ignore ./ (but keep other dot files) - if f == nil || f.IsDir == nil || f.Name == nil { + if f == nil || !f.IsDir() || f.Name() == "" { log.Printf("Missing file info for line %s and path %s", line, path) return nil } diff --git a/datasetUtils/getUserInfoFromToken.go b/datasetUtils/getUserInfoFromToken.go index 55865f9..0fc0089 100644 --- a/datasetUtils/getUserInfoFromToken.go +++ b/datasetUtils/getUserInfoFromToken.go @@ -49,7 +49,7 @@ func GetUserInfoFromToken(client *http.Client, APIServer string, token string) ( accessGroups = respObj.CurrentGroups log.Printf("User is member in following groups: %v\n", accessGroups) } else { - log.Fatalln("Could not map a user to the token %v", token) + log.Fatalf("Could not map a user to the token %v", token) } return u, accessGroups