| package tests_test |
| |
| import ( |
| "context" |
| "io/ioutil" |
| "os" |
| "strings" |
| "testing" |
| "time" |
| |
| "google3/third_party/golang/github_com/bramvdbogaerde/go_scp/v/v1/auth/auth" |
| "google3/third_party/golang/github_com/bramvdbogaerde/go_scp/v/v1/scp" |
| "google3/third_party/golang/go_crypto/ssh/ssh" |
| ) |
| |
| func establishConnection(t *testing.T) scp.Client { |
| // Use SSH key authentication from the auth package. |
| // During testing we ignore the host key, don't to that when you use this. |
| clientConfig, _ := auth.PasswordKey("bram", "test", ssh.InsecureIgnoreHostKey()) |
| |
| // Create a new SCP client. |
| client := scp.NewClient("127.0.0.1:2244", &clientConfig) |
| |
| // Connect to the remote server. |
| err := client.Connect() |
| if err != nil { |
| t.Fatalf("Couldn't establish a connection to the remote server: %s", err) |
| } |
| return client |
| } |
| |
| // TestCopy tests the basic functionality of copying a file to the remote |
| // destination. |
| // |
| // It assumes that a Docker container is running an SSH server at port 2244 |
| // that is using password authentication. It also assumes that the directory |
| // /data is writable within that container and is mapped to ./tmp/ within the |
| // directory the test is run from. |
| func TestCopy(t *testing.T) { |
| client := establishConnection(t) |
| defer client.Close() |
| |
| // Open a file we can transfer to the remote container. |
| f, _ := os.Open("./data/upload_file.txt") |
| defer f.Close() |
| |
| // Create a file name with exotic characters and spaces in them. |
| // If this test works for this, simpler files should not be a problem. |
| filename := "Exöt1ç uploaded file.txt" |
| |
| // Finaly, copy the file over. |
| // Usage: CopyFile(fileReader, remotePath, permission). |
| err := client.CopyFile(context.Background(), f, "/data/"+filename, "0777") |
| if err != nil { |
| t.Errorf("Error while copying file: %s", err) |
| } |
| |
| // Read what the receiver have written to disk. |
| content, err := ioutil.ReadFile("./tmp/" + filename) |
| if err != nil { |
| t.Errorf("Result file could not be read: %s", err) |
| } |
| |
| text := string(content) |
| expected := "It Works\n" |
| if strings.Compare(text, expected) != 0 { |
| t.Errorf("Got different text than expected, expected %q got, %q", expected, text) |
| } |
| } |
| |
| // TestDownloadFile tests the basic functionality of copying a file from the |
| // remote destination. |
| // |
| // It assumes that a Docker container is running an SSH server at port 2244 |
| // that is using password authentication. It also assumes that the directory |
| // /data is writable within that container and is mapped to ./tmp/ within the |
| // directory the test is run from. |
| func TestDownloadFile(t *testing.T) { |
| client := establishConnection(t) |
| defer client.Close() |
| |
| // Open a file we can transfer to the remote container. |
| f, _ := os.Open("./data/input.txt") |
| defer f.Close() |
| |
| // Create a local file to write to. |
| f, err := os.OpenFile("./tmp/output.txt", os.O_RDWR|os.O_CREATE, 0777) |
| if err != nil { |
| t.Errorf("Couldn't open the output file") |
| } |
| defer f.Close() |
| |
| // Use a file name with exotic characters and spaces in them. |
| // If this test works for this, simpler files should not be a problem. |
| err = client.CopyFromRemote(context.Background(), f, "/input/Exöt1ç download file.txt.txt") |
| if err != nil { |
| t.Errorf("Copy failed from remote: %s", err.Error()) |
| } |
| |
| content, err := ioutil.ReadFile("./tmp/output.txt") |
| if err != nil { |
| t.Errorf("Result file could not be read: %s", err) |
| } |
| |
| text := string(content) |
| expected := "It works for download!\n" |
| if strings.Compare(text, expected) != 0 { |
| t.Errorf("Got different text than expected, expected %q got, %q", expected, text) |
| } |
| } |
| |
| // TestTimeoutDownload tests that a timeout error is produced if the file is not copied in the given |
| // amount of time. |
| func TestTimeoutDownload(t *testing.T) { |
| client := establishConnection(t) |
| defer client.Close() |
| client.Timeout = 1 * time.Millisecond |
| |
| // Open a file we can transfer to the remote container. |
| f, _ := os.Open("./data/upload_file.txt") |
| defer f.Close() |
| |
| // Create a file name with exotic characters and spaces in them. |
| // If this test works for this, simpler files should not be a problem. |
| filename := "Exöt1ç uploaded file.txt" |
| |
| err := client.CopyFile(context.Background(), f, "/data/"+filename, "0777") |
| if err != context.DeadlineExceeded { |
| t.Errorf("Expected a timeout error but got succeeded without error") |
| } |
| } |
| |
| // TestContextCancelDownload tests that a a copy is immediately cancelled if we call context.cancel() |
| func TestContextCancelDownload(t *testing.T) { |
| client := establishConnection(t) |
| defer client.Close() |
| |
| ctx, cancel := context.WithCancel(context.Background()) |
| cancel() |
| |
| // Open a file we can transfer to the remote container. |
| f, _ := os.Open("./data/upload_file.txt") |
| defer f.Close() |
| |
| // Create a file name with exotic characters and spaces in them. |
| // If this test works for this, simpler files should not be a problem. |
| filename := "Exöt1ç uploaded file.txt" |
| |
| err := client.CopyFile(ctx, f, "/data/"+filename, "0777") |
| if err != context.Canceled { |
| t.Errorf("Expected a canceled error but transfer succeeded without error") |
| } |
| } |
| |
| func TestDownloadBadLocalFilePermissions(t *testing.T) { |
| client := establishConnection(t) |
| defer client.Close() |
| |
| // Create a file with local bad permissions |
| // This happens only on Linux |
| f, err := os.OpenFile("./tmp/output_bdf.txt", os.O_CREATE, 0644) |
| if err != nil { |
| t.Error("Couldn't open the output file", err.Error()) |
| } |
| defer f.Close() |
| |
| // This should not timeout and throw an error |
| err = client.CopyFromRemote(context.Background(), f, "/input/Exöt1ç download file.txt.txt") |
| if err == nil { |
| t.Errorf("Expected error thrown. Got nil") |
| } |
| } |
| |
| func TestFileNotFound(t *testing.T) { |
| client := establishConnection(t) |
| defer client.Close() |
| |
| f, err := os.OpenFile("./tmp/output_fnf.txt", os.O_CREATE|os.O_WRONLY, 0644) |
| if err != nil { |
| t.Error("Couldn't open the output file", err.Error()) |
| } |
| // This should throw file not found on remote |
| err = client.CopyFromRemote(context.Background(), f, "/input/no_such_file.txt") |
| if err == nil { |
| t.Errorf("Expected error thrown. Got nil") |
| } |
| expected := "scp: /input/no_such_file.txt: No such file or directory\n" |
| if err.Error() != expected { |
| t.Errorf("Expected %v, got %v", expected, err.Error()) |
| } |
| } |