config_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
  2. package ssh
  3. import (
  4. "fmt"
  5. "kitty/tools/utils"
  6. "os"
  7. "os/user"
  8. "path/filepath"
  9. "testing"
  10. "github.com/google/go-cmp/cmp"
  11. )
  12. var _ = fmt.Print
  13. type Pair struct {
  14. Input, Uname, Host string
  15. }
  16. func TestSSHConfigParsing(t *testing.T) {
  17. tdir := t.TempDir()
  18. hostname := "unmatched"
  19. username := ""
  20. conf := ""
  21. overrides := []string{}
  22. for_python := false
  23. cf := filepath.Join(tdir, "ssh.conf")
  24. rt := func(expected_env ...string) {
  25. if err := os.WriteFile(cf, []byte(conf), 0o600); err != nil {
  26. t.Fatal(err)
  27. }
  28. c, bad_lines, err := load_config(hostname, username, overrides, cf)
  29. if err != nil {
  30. t.Fatal(err)
  31. }
  32. if len(bad_lines) != 0 {
  33. t.Fatalf("Bad config line: %s with error: %s", bad_lines[0].Line, bad_lines[0].Err)
  34. }
  35. actual := final_env_instructions(for_python, func(key string) (string, bool) {
  36. if key == "LOCAL_ENV" {
  37. return "LOCAL_VAL", true
  38. }
  39. return "", false
  40. }, c.Env...)
  41. if expected_env == nil {
  42. expected_env = []string{}
  43. }
  44. diff := cmp.Diff(expected_env, utils.Splitlines(actual))
  45. if diff != "" {
  46. t.Fatalf("Unexpected env for\nhostname: %#v\nusername: %#v\nconf: %s\n%s", hostname, username, conf, diff)
  47. }
  48. }
  49. rt()
  50. conf = "env a=b"
  51. rt(`export 'a'="b"`)
  52. conf = "env a=b"
  53. overrides = []string{"env=c=d"}
  54. rt(`export 'a'="b"`, `export 'c'="d"`)
  55. overrides = nil
  56. conf = "env a=\\"
  57. rt(`export 'a'="\\"`)
  58. conf = `env
  59. \ a=
  60. \\`
  61. conf = "env\n \t \\ a=\n\\\\"
  62. rt(`export 'a'="\\"`)
  63. conf = `
  64. e
  65. \n
  66. \v
  67. \ a
  68. \=
  69. \\
  70. \`
  71. rt(`export 'a'="\\"`)
  72. conf = "env a=b\nhostname 2\nenv a=c\nenv b=b"
  73. rt(`export 'a'="b"`)
  74. hostname = "2"
  75. rt(`export 'a'="c"`, `export 'b'="b"`)
  76. conf = "env a="
  77. rt(`export 'a'=""`)
  78. conf = "env a"
  79. rt(`unset 'a'`)
  80. conf = "env a=b\nhostname test@2\nenv a=c\nenv b=b"
  81. hostname = "unmatched"
  82. rt(`export 'a'="b"`)
  83. hostname = "2"
  84. rt(`export 'a'="b"`)
  85. username = "test"
  86. rt(`export 'a'="c"`, `export 'b'="b"`)
  87. conf = "env a=b\nhostname 1 2\nenv a=c\nenv b=b"
  88. username = ""
  89. hostname = "unmatched"
  90. rt(`export 'a'="b"`)
  91. hostname = "1"
  92. rt(`export 'a'="c"`, `export 'b'="b"`)
  93. hostname = "2"
  94. rt(`export 'a'="c"`, `export 'b'="b"`)
  95. for_python = true
  96. rt(`export ["a","c",false]`, `export ["b","b",false]`)
  97. conf = "env a="
  98. rt(`export ["a"]`)
  99. conf = "env a"
  100. rt(`unset ["a"]`)
  101. conf = "env LOCAL_ENV=_kitty_copy_env_var_"
  102. rt(`export ["LOCAL_ENV","LOCAL_VAL",false]`)
  103. conf = "env a=b\nhostname 2\ncolor_scheme xyz"
  104. hostname = "2"
  105. rt()
  106. ci, err := ParseCopyInstruction("--exclude moose --dest=target " + cf)
  107. if err != nil {
  108. t.Fatal(err)
  109. }
  110. diff := cmp.Diff("home/target", ci[0].arcname)
  111. if diff != "" {
  112. t.Fatalf("Incorrect arcname:\n%s", diff)
  113. }
  114. diff = cmp.Diff(cf, ci[0].local_path)
  115. if diff != "" {
  116. t.Fatalf("Incorrect local_path:\n%s", diff)
  117. }
  118. diff = cmp.Diff([]string{"moose"}, ci[0].exclude_patterns)
  119. if diff != "" {
  120. t.Fatalf("Incorrect excludes:\n%s", diff)
  121. }
  122. ci, err = ParseCopyInstruction("--glob " + filepath.Join(filepath.Dir(cf), "*.conf"))
  123. if err != nil {
  124. t.Fatal(err)
  125. }
  126. diff = cmp.Diff(cf, ci[0].local_path)
  127. if diff != "" {
  128. t.Fatalf("Incorrect local_path:\n%s", diff)
  129. }
  130. if len(ci) != 1 {
  131. t.Fatal(ci)
  132. }
  133. u, _ := user.Current()
  134. un := u.Username
  135. for _, x := range []Pair{
  136. {"localhost:12", un, "localhost:12"},
  137. {"@localhost", un, "@localhost"},
  138. {"ssh://@localhost:33", un, "localhost"},
  139. {"me@localhost", "me", "localhost"},
  140. {"ssh://me@localhost:12/something?else=1", "me", "localhost"},
  141. } {
  142. ue, uh := get_destination(x.Input)
  143. q := Pair{x.Input, ue, uh}
  144. if diff := cmp.Diff(x, q); diff != "" {
  145. t.Fatalf("Failed: %s", diff)
  146. }
  147. }
  148. }