gitutils_test.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package git
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "net/http"
  6. "net/http/httptest"
  7. "net/url"
  8. "os"
  9. "path/filepath"
  10. "runtime"
  11. "strings"
  12. "testing"
  13. "github.com/stretchr/testify/assert"
  14. "github.com/stretchr/testify/require"
  15. )
  16. func TestCloneArgsSmartHttp(t *testing.T) {
  17. mux := http.NewServeMux()
  18. server := httptest.NewServer(mux)
  19. serverURL, _ := url.Parse(server.URL)
  20. serverURL.Path = "/repo.git"
  21. mux.HandleFunc("/repo.git/info/refs", func(w http.ResponseWriter, r *http.Request) {
  22. q := r.URL.Query().Get("service")
  23. w.Header().Set("Content-Type", fmt.Sprintf("application/x-%s-advertisement", q))
  24. })
  25. args := fetchArgs(serverURL, "master")
  26. exp := []string{"fetch", "--recurse-submodules=yes", "--depth", "1", "origin", "master"}
  27. assert.Equal(t, exp, args)
  28. }
  29. func TestCloneArgsDumbHttp(t *testing.T) {
  30. mux := http.NewServeMux()
  31. server := httptest.NewServer(mux)
  32. serverURL, _ := url.Parse(server.URL)
  33. serverURL.Path = "/repo.git"
  34. mux.HandleFunc("/repo.git/info/refs", func(w http.ResponseWriter, r *http.Request) {
  35. w.Header().Set("Content-Type", "text/plain")
  36. })
  37. args := fetchArgs(serverURL, "master")
  38. exp := []string{"fetch", "--recurse-submodules=yes", "origin", "master"}
  39. assert.Equal(t, exp, args)
  40. }
  41. func TestCloneArgsGit(t *testing.T) {
  42. u, _ := url.Parse("git://github.com/docker/docker")
  43. args := fetchArgs(u, "master")
  44. exp := []string{"fetch", "--recurse-submodules=yes", "--depth", "1", "origin", "master"}
  45. assert.Equal(t, exp, args)
  46. }
  47. func gitGetConfig(name string) string {
  48. b, err := git([]string{"config", "--get", name}...)
  49. if err != nil {
  50. // since we are interested in empty or non empty string,
  51. // we can safely ignore the err here.
  52. return ""
  53. }
  54. return strings.TrimSpace(string(b))
  55. }
  56. func TestCheckoutGit(t *testing.T) {
  57. root, err := ioutil.TempDir("", "docker-build-git-checkout")
  58. require.NoError(t, err)
  59. defer os.RemoveAll(root)
  60. autocrlf := gitGetConfig("core.autocrlf")
  61. if !(autocrlf == "true" || autocrlf == "false" ||
  62. autocrlf == "input" || autocrlf == "") {
  63. t.Logf("unknown core.autocrlf value: \"%s\"", autocrlf)
  64. }
  65. eol := "\n"
  66. if autocrlf == "true" {
  67. eol = "\r\n"
  68. }
  69. gitDir := filepath.Join(root, "repo")
  70. _, err = git("init", gitDir)
  71. require.NoError(t, err)
  72. _, err = gitWithinDir(gitDir, "config", "user.email", "test@docker.com")
  73. require.NoError(t, err)
  74. _, err = gitWithinDir(gitDir, "config", "user.name", "Docker test")
  75. require.NoError(t, err)
  76. err = ioutil.WriteFile(filepath.Join(gitDir, "Dockerfile"), []byte("FROM scratch"), 0644)
  77. require.NoError(t, err)
  78. subDir := filepath.Join(gitDir, "subdir")
  79. require.NoError(t, os.Mkdir(subDir, 0755))
  80. err = ioutil.WriteFile(filepath.Join(subDir, "Dockerfile"), []byte("FROM scratch\nEXPOSE 5000"), 0644)
  81. require.NoError(t, err)
  82. if runtime.GOOS != "windows" {
  83. if err = os.Symlink("../subdir", filepath.Join(gitDir, "parentlink")); err != nil {
  84. t.Fatal(err)
  85. }
  86. if err = os.Symlink("/subdir", filepath.Join(gitDir, "absolutelink")); err != nil {
  87. t.Fatal(err)
  88. }
  89. }
  90. _, err = gitWithinDir(gitDir, "add", "-A")
  91. require.NoError(t, err)
  92. _, err = gitWithinDir(gitDir, "commit", "-am", "First commit")
  93. require.NoError(t, err)
  94. _, err = gitWithinDir(gitDir, "checkout", "-b", "test")
  95. require.NoError(t, err)
  96. err = ioutil.WriteFile(filepath.Join(gitDir, "Dockerfile"), []byte("FROM scratch\nEXPOSE 3000"), 0644)
  97. require.NoError(t, err)
  98. err = ioutil.WriteFile(filepath.Join(subDir, "Dockerfile"), []byte("FROM busybox\nEXPOSE 5000"), 0644)
  99. require.NoError(t, err)
  100. _, err = gitWithinDir(gitDir, "add", "-A")
  101. require.NoError(t, err)
  102. _, err = gitWithinDir(gitDir, "commit", "-am", "Branch commit")
  103. require.NoError(t, err)
  104. _, err = gitWithinDir(gitDir, "checkout", "master")
  105. require.NoError(t, err)
  106. type singleCase struct {
  107. frag string
  108. exp string
  109. fail bool
  110. }
  111. cases := []singleCase{
  112. {"", "FROM scratch", false},
  113. {"master", "FROM scratch", false},
  114. {":subdir", "FROM scratch" + eol + "EXPOSE 5000", false},
  115. {":nosubdir", "", true}, // missing directory error
  116. {":Dockerfile", "", true}, // not a directory error
  117. {"master:nosubdir", "", true},
  118. {"master:subdir", "FROM scratch" + eol + "EXPOSE 5000", false},
  119. {"master:../subdir", "", true},
  120. {"test", "FROM scratch" + eol + "EXPOSE 3000", false},
  121. {"test:", "FROM scratch" + eol + "EXPOSE 3000", false},
  122. {"test:subdir", "FROM busybox" + eol + "EXPOSE 5000", false},
  123. }
  124. if runtime.GOOS != "windows" {
  125. // Windows GIT (2.7.1 x64) does not support parentlink/absolutelink. Sample output below
  126. // git --work-tree .\repo --git-dir .\repo\.git add -A
  127. // error: readlink("absolutelink"): Function not implemented
  128. // error: unable to index file absolutelink
  129. // fatal: adding files failed
  130. cases = append(cases, singleCase{frag: "master:absolutelink", exp: "FROM scratch" + eol + "EXPOSE 5000", fail: false})
  131. cases = append(cases, singleCase{frag: "master:parentlink", exp: "FROM scratch" + eol + "EXPOSE 5000", fail: false})
  132. }
  133. for _, c := range cases {
  134. ref, subdir := getRefAndSubdir(c.frag)
  135. r, err := checkoutGit(gitDir, ref, subdir)
  136. if c.fail {
  137. assert.Error(t, err)
  138. continue
  139. }
  140. b, err := ioutil.ReadFile(filepath.Join(r, "Dockerfile"))
  141. require.NoError(t, err)
  142. assert.Equal(t, c.exp, string(b))
  143. }
  144. }