...

Source file src/github.com/cli/go-gh/v2/pkg/ssh/ssh_test.go

Documentation: github.com/cli/go-gh/v2/pkg/ssh

     1  package ssh
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net/url"
     7  	"os"
     8  	"os/exec"
     9  	"testing"
    10  
    11  	"github.com/MakeNowJust/heredoc"
    12  	"github.com/cli/safeexec"
    13  )
    14  
    15  func TestTranslator(t *testing.T) {
    16  	if _, err := safeexec.LookPath("ssh"); err != nil {
    17  		t.Skip("no ssh found on system")
    18  	}
    19  
    20  	tests := []struct {
    21  		name      string
    22  		sshConfig string
    23  		arg       string
    24  		want      string
    25  	}{
    26  		{
    27  			name: "translate SSH URL",
    28  			sshConfig: heredoc.Doc(`
    29  				Host github-*
    30  					Hostname github.com
    31  			`),
    32  			arg:  "ssh://git@github-foo/owner/repo.git",
    33  			want: "ssh://git@github.com/owner/repo.git",
    34  		},
    35  		{
    36  			name: "does not translate HTTPS URL",
    37  			sshConfig: heredoc.Doc(`
    38  				Host github-*
    39  					Hostname github.com
    40  			`),
    41  			arg:  "https://github-foo/owner/repo.git",
    42  			want: "https://github-foo/owner/repo.git",
    43  		},
    44  		{
    45  			name: "treats ssh.github.com as github.com",
    46  			sshConfig: heredoc.Doc(`
    47  				Host github.com
    48  					Hostname ssh.github.com
    49  			`),
    50  			arg:  "ssh://git@github.com/owner/repo.git",
    51  			want: "ssh://git@github.com/owner/repo.git",
    52  		},
    53  	}
    54  	for _, tt := range tests {
    55  		t.Run(tt.name, func(t *testing.T) {
    56  			f, err := os.CreateTemp("", "ssh-config.*")
    57  			if err != nil {
    58  				t.Fatalf("error creating file: %v", err)
    59  			}
    60  			_, err = f.WriteString(tt.sshConfig)
    61  			_ = f.Close()
    62  			if err != nil {
    63  				t.Fatalf("error writing ssh config: %v", err)
    64  			}
    65  
    66  			tr := &Translator{
    67  				newCommand: func(exe string, args ...string) *exec.Cmd {
    68  					args = append([]string{"-F", f.Name()}, args...)
    69  					return exec.Command(exe, args...)
    70  				},
    71  			}
    72  			u, err := url.Parse(tt.arg)
    73  			if err != nil {
    74  				t.Fatalf("error parsing URL: %v", err)
    75  			}
    76  			res := tr.Translate(u)
    77  			if got := res.String(); got != tt.want {
    78  				t.Errorf("expected %q, got %q", tt.want, got)
    79  			}
    80  		})
    81  	}
    82  }
    83  
    84  func TestHelperProcess(t *testing.T) {
    85  	if os.Getenv("GH_WANT_HELPER_PROCESS") != "1" {
    86  		return
    87  	}
    88  	if err := func(args []string) error {
    89  		if len(args) < 3 || args[2] == "error" {
    90  			return errors.New("fatal")
    91  		}
    92  		if args[2] == "empty.io" {
    93  			return nil
    94  		}
    95  		fmt.Fprintf(os.Stdout, "hostname %s\n", args[2])
    96  		return nil
    97  	}(os.Args[3:]); err != nil {
    98  		fmt.Fprintln(os.Stderr, err)
    99  		os.Exit(1)
   100  	}
   101  	os.Exit(0)
   102  }
   103  
   104  func TestTranslator_caching(t *testing.T) {
   105  	countLookPath := 0
   106  	countNewCommand := 0
   107  	tr := &Translator{
   108  		lookPath: func(s string) (string, error) {
   109  			countLookPath++
   110  			return "/path/to/ssh", nil
   111  		},
   112  		newCommand: func(exe string, args ...string) *exec.Cmd {
   113  			args = append([]string{"-test.run=TestHelperProcess", "--", exe}, args...)
   114  			c := exec.Command(os.Args[0], args...)
   115  			c.Env = []string{"GH_WANT_HELPER_PROCESS=1"}
   116  			countNewCommand++
   117  			return c
   118  		},
   119  	}
   120  
   121  	tests := []struct {
   122  		input  string
   123  		result string
   124  	}{
   125  		{
   126  			input:  "ssh://github1.com/owner/repo.git",
   127  			result: "github1.com",
   128  		},
   129  		{
   130  			input:  "ssh://github2.com/owner/repo.git",
   131  			result: "github2.com",
   132  		},
   133  		{
   134  			input:  "ssh://empty.io/owner/repo.git",
   135  			result: "empty.io",
   136  		},
   137  		{
   138  			input:  "ssh://error/owner/repo.git",
   139  			result: "error",
   140  		},
   141  	}
   142  	for _, tt := range tests {
   143  		t.Run(tt.input, func(t *testing.T) {
   144  			u, err := url.Parse(tt.input)
   145  			if err != nil {
   146  				t.Fatalf("error parsing URL: %v", err)
   147  			}
   148  			if res := tr.Translate(u); res.Host != tt.result {
   149  				t.Errorf("expected github.com, got: %q", res.Host)
   150  			}
   151  			if res := tr.Translate(u); res.Host != tt.result {
   152  				t.Errorf("expected github.com, got: %q (second call)", res.Host)
   153  			}
   154  		})
   155  	}
   156  
   157  	if countLookPath != 1 {
   158  		t.Errorf("expected lookPath to happen 1 time; actual: %d", countLookPath)
   159  	}
   160  	if countNewCommand != len(tests) {
   161  		t.Errorf("expected ssh command to shell out %d times; actual: %d", len(tests), countNewCommand)
   162  	}
   163  }
   164  

View as plain text