Skip to content

Commit

Permalink
Check if SSH is installed. Add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kavir1698 committed Apr 3, 2024
1 parent f0352bb commit a80efc8
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 32 deletions.
31 changes: 24 additions & 7 deletions datasetIngestor/testDataCentrallyAvailable.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package datasetIngestor

import (
"errors"
"log"
"os"
"os/exec"
"runtime"
)

// execCommand is a variable that points to exec.Command, allowing it to be replaced in tests.
Expand All @@ -12,18 +14,33 @@ var execCommand = exec.Command
// TestDataCentrallyAvailable checks if a specific directory (sourceFolder) is available on a remote server (ARCHIVEServer)
// using the provided username for SSH connection. It returns an error if the directory is not available or if there's an issue with the SSH connection.
func TestDataCentrallyAvailable(username string, ARCHIVEServer string, sourceFolder string) (err error) {

// Create a new exec.Command to run the SSH command. The command checks if the directory exists on the remote server.
// The "-q" option suppresses all warnings, "-l" specifies the login name on the remote server.
cmd := execCommand("/usr/bin/ssh", "-q", "-l", username, ARCHIVEServer, "test", "-d", sourceFolder)

var cmd *exec.Cmd

// Check the operating system
switch os := runtime.GOOS; os {
case "linux", "windows", "darwin":
// Check if ssh exists
_, err := exec.LookPath("ssh") // locate a program in the user's path
if err != nil {
log.Println("SSH is not installed. Please install OpenSSH client.")
return err
}

// Create a new exec.Command to run the SSH command. The command checks if the directory exists on the remote server.
// The "-q" option suppresses all warnings, "-l" specifies the login name on the remote server.
cmd = execCommand("ssh", "-q", "-l", username, ARCHIVEServer, "test", "-d", sourceFolder)
default:
log.Printf("%s is not supported.\n", os)
return errors.New("unsupported operating system")
}

// Redirect the command's standard error to the process's standard error.
// This means that any error messages from the command will be displayed in the terminal.
cmd.Stderr = os.Stderr

// Log the command that is being run for debugging purposes.
log.Printf("Running %v.\n", cmd.Args)

// Run the command and return any error that occurs.
err = cmd.Run()
return err
Expand Down
88 changes: 63 additions & 25 deletions datasetIngestor/testDataCentrallyAvailable_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package datasetIngestor

import (
"os/exec"
"reflect"
"testing"
"os/exec"
"reflect"
"testing"
"errors"
"fmt"
"os"
"strconv"
)

// Mock for exec.Command
Expand All @@ -13,11 +17,33 @@ type execCommandMock struct {
}

func (m *execCommandMock) Command(name string, arg ...string) *exec.Cmd {
if name != "/usr/bin/ssh" || !reflect.DeepEqual(arg, m.expectedArgs) {
panic("unexpected arguments")
if !reflect.DeepEqual(arg, m.expectedArgs) {
panic(fmt.Sprintf("unexpected arguments: got %v, want %v", arg, m.expectedArgs))
}

return exec.Command("echo", "mocked")

cs := []string{"-test.run=TestHelperProcess", "--", name}
cs = append(cs, arg...)
cmd := exec.Command(os.Args[0], cs...)
cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}

if m.returnError != nil {
cmd.Env = append(cmd.Env, "EXIT_STATUS=1")
} else {
cmd.Env = append(cmd.Env, "EXIT_STATUS=0")
}

return cmd
}

// TestHelperProcess isn't a real test. It's used as a helper process
func TestHelperProcess(t *testing.T) {
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
return
}
fmt.Fprintf(os.Stdout, "output")
fmt.Fprintf(os.Stderr, "error")
exitStatus, _ := strconv.Atoi(os.Getenv("EXIT_STATUS"))
os.Exit(exitStatus)
}

func TestTestDataCentrallyAvailable(t *testing.T) {
Expand All @@ -27,6 +53,7 @@ func TestTestDataCentrallyAvailable(t *testing.T) {
archiveServer string
sourceFolder string
wantErr bool
errMsg string
}{
{
name: "test data centrally available",
Expand All @@ -35,30 +62,41 @@ func TestTestDataCentrallyAvailable(t *testing.T) {
sourceFolder: "/test/folder",
wantErr: false,
},
{
name: "test data not available",
username: "testuser",
archiveServer: "testserver",
sourceFolder: "/nonexistent/folder",
wantErr: true,
errMsg: "exit status 1",
},
// Add more test cases here.
}


}

for _, tt := range tests {
expectedArgs := []string{"-q", "-l", tt.username, tt.archiveServer, "test", "-d", tt.sourceFolder}

var returnError error
if tt.wantErr {
returnError = errors.New(tt.errMsg)
}

// Replace exec.Command with a mock
oldExecCommand := execCommand
execCommand = (&execCommandMock{
expectedArgs: []string{"-q", "-l", tt.username, tt.archiveServer, "test", "-d", tt.sourceFolder},
returnError: nil,
expectedArgs: expectedArgs,
returnError: returnError,
}).Command
defer func() { execCommand = oldExecCommand }()
defer func() { execCommand = oldExecCommand }()

t.Run(tt.name, func(t *testing.T) {
// Replace exec.Command with a mock
oldExecCommand := execCommand
execCommand = (&execCommandMock{
expectedArgs: []string{"-q", "-l", tt.username, tt.archiveServer, "test", "-d", tt.sourceFolder},
returnError: nil,
}).Command
defer func() { execCommand = oldExecCommand }()

err := TestDataCentrallyAvailable(tt.username, tt.archiveServer, tt.sourceFolder)
if (err != nil) != tt.wantErr {
t.Errorf("TestDataCentrallyAvailable() error = %v, wantErr %v", err, tt.wantErr)
}
err := TestDataCentrallyAvailable(tt.username, tt.archiveServer, tt.sourceFolder)
if (err != nil) != tt.wantErr {
t.Errorf("TestDataCentrallyAvailable() error = %v, wantErr %v", err, tt.wantErr)
}
if err != nil && tt.wantErr && err.Error() != tt.errMsg {
t.Errorf("TestDataCentrallyAvailable() errMsg = %v, wantErrMsg %v", err.Error(), tt.errMsg)
}
})
}
}

0 comments on commit a80efc8

Please sign in to comment.