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