github.com/rita33cool1/iot-system-gateway@v0.0.0-20200911033302-e65bde238cc5/docker-engine/builder/remotecontext/git/gitutils_test.go (about) 1 package git // import "github.com/docker/docker/builder/remotecontext/git" 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net/http" 7 "net/http/httptest" 8 "net/url" 9 "os" 10 "os/exec" 11 "path/filepath" 12 "runtime" 13 "strings" 14 "testing" 15 16 "github.com/google/go-cmp/cmp" 17 "github.com/gotestyourself/gotestyourself/assert" 18 is "github.com/gotestyourself/gotestyourself/assert/cmp" 19 ) 20 21 func TestParseRemoteURL(t *testing.T) { 22 dir, err := parseRemoteURL("git://github.com/user/repo.git") 23 assert.NilError(t, err) 24 assert.Check(t, is.DeepEqual(gitRepo{"git://github.com/user/repo.git", "master", ""}, dir, cmpGitRepoOpt)) 25 26 dir, err = parseRemoteURL("git://github.com/user/repo.git#mybranch:mydir/mysubdir/") 27 assert.NilError(t, err) 28 assert.Check(t, is.DeepEqual(gitRepo{"git://github.com/user/repo.git", "mybranch", "mydir/mysubdir/"}, dir, cmpGitRepoOpt)) 29 30 dir, err = parseRemoteURL("https://github.com/user/repo.git") 31 assert.NilError(t, err) 32 assert.Check(t, is.DeepEqual(gitRepo{"https://github.com/user/repo.git", "master", ""}, dir, cmpGitRepoOpt)) 33 34 dir, err = parseRemoteURL("https://github.com/user/repo.git#mybranch:mydir/mysubdir/") 35 assert.NilError(t, err) 36 assert.Check(t, is.DeepEqual(gitRepo{"https://github.com/user/repo.git", "mybranch", "mydir/mysubdir/"}, dir, cmpGitRepoOpt)) 37 38 dir, err = parseRemoteURL("git@github.com:user/repo.git") 39 assert.NilError(t, err) 40 assert.Check(t, is.DeepEqual(gitRepo{"git@github.com:user/repo.git", "master", ""}, dir, cmpGitRepoOpt)) 41 42 dir, err = parseRemoteURL("git@github.com:user/repo.git#mybranch:mydir/mysubdir/") 43 assert.NilError(t, err) 44 assert.Check(t, is.DeepEqual(gitRepo{"git@github.com:user/repo.git", "mybranch", "mydir/mysubdir/"}, dir, cmpGitRepoOpt)) 45 } 46 47 var cmpGitRepoOpt = cmp.AllowUnexported(gitRepo{}) 48 49 func TestCloneArgsSmartHttp(t *testing.T) { 50 mux := http.NewServeMux() 51 server := httptest.NewServer(mux) 52 serverURL, _ := url.Parse(server.URL) 53 54 serverURL.Path = "/repo.git" 55 56 mux.HandleFunc("/repo.git/info/refs", func(w http.ResponseWriter, r *http.Request) { 57 q := r.URL.Query().Get("service") 58 w.Header().Set("Content-Type", fmt.Sprintf("application/x-%s-advertisement", q)) 59 }) 60 61 args := fetchArgs(serverURL.String(), "master") 62 exp := []string{"fetch", "--depth", "1", "origin", "master"} 63 assert.Check(t, is.DeepEqual(exp, args)) 64 } 65 66 func TestCloneArgsDumbHttp(t *testing.T) { 67 mux := http.NewServeMux() 68 server := httptest.NewServer(mux) 69 serverURL, _ := url.Parse(server.URL) 70 71 serverURL.Path = "/repo.git" 72 73 mux.HandleFunc("/repo.git/info/refs", func(w http.ResponseWriter, r *http.Request) { 74 w.Header().Set("Content-Type", "text/plain") 75 }) 76 77 args := fetchArgs(serverURL.String(), "master") 78 exp := []string{"fetch", "origin", "master"} 79 assert.Check(t, is.DeepEqual(exp, args)) 80 } 81 82 func TestCloneArgsGit(t *testing.T) { 83 args := fetchArgs("git://github.com/docker/docker", "master") 84 exp := []string{"fetch", "--depth", "1", "origin", "master"} 85 assert.Check(t, is.DeepEqual(exp, args)) 86 } 87 88 func gitGetConfig(name string) string { 89 b, err := git([]string{"config", "--get", name}...) 90 if err != nil { 91 // since we are interested in empty or non empty string, 92 // we can safely ignore the err here. 93 return "" 94 } 95 return strings.TrimSpace(string(b)) 96 } 97 98 func TestCheckoutGit(t *testing.T) { 99 root, err := ioutil.TempDir("", "docker-build-git-checkout") 100 assert.NilError(t, err) 101 defer os.RemoveAll(root) 102 103 autocrlf := gitGetConfig("core.autocrlf") 104 if !(autocrlf == "true" || autocrlf == "false" || 105 autocrlf == "input" || autocrlf == "") { 106 t.Logf("unknown core.autocrlf value: \"%s\"", autocrlf) 107 } 108 eol := "\n" 109 if autocrlf == "true" { 110 eol = "\r\n" 111 } 112 113 gitDir := filepath.Join(root, "repo") 114 _, err = git("init", gitDir) 115 assert.NilError(t, err) 116 117 _, err = gitWithinDir(gitDir, "config", "user.email", "test@docker.com") 118 assert.NilError(t, err) 119 120 _, err = gitWithinDir(gitDir, "config", "user.name", "Docker test") 121 assert.NilError(t, err) 122 123 err = ioutil.WriteFile(filepath.Join(gitDir, "Dockerfile"), []byte("FROM scratch"), 0644) 124 assert.NilError(t, err) 125 126 subDir := filepath.Join(gitDir, "subdir") 127 assert.NilError(t, os.Mkdir(subDir, 0755)) 128 129 err = ioutil.WriteFile(filepath.Join(subDir, "Dockerfile"), []byte("FROM scratch\nEXPOSE 5000"), 0644) 130 assert.NilError(t, err) 131 132 if runtime.GOOS != "windows" { 133 if err = os.Symlink("../subdir", filepath.Join(gitDir, "parentlink")); err != nil { 134 t.Fatal(err) 135 } 136 137 if err = os.Symlink("/subdir", filepath.Join(gitDir, "absolutelink")); err != nil { 138 t.Fatal(err) 139 } 140 } 141 142 _, err = gitWithinDir(gitDir, "add", "-A") 143 assert.NilError(t, err) 144 145 _, err = gitWithinDir(gitDir, "commit", "-am", "First commit") 146 assert.NilError(t, err) 147 148 _, err = gitWithinDir(gitDir, "checkout", "-b", "test") 149 assert.NilError(t, err) 150 151 err = ioutil.WriteFile(filepath.Join(gitDir, "Dockerfile"), []byte("FROM scratch\nEXPOSE 3000"), 0644) 152 assert.NilError(t, err) 153 154 err = ioutil.WriteFile(filepath.Join(subDir, "Dockerfile"), []byte("FROM busybox\nEXPOSE 5000"), 0644) 155 assert.NilError(t, err) 156 157 _, err = gitWithinDir(gitDir, "add", "-A") 158 assert.NilError(t, err) 159 160 _, err = gitWithinDir(gitDir, "commit", "-am", "Branch commit") 161 assert.NilError(t, err) 162 163 _, err = gitWithinDir(gitDir, "checkout", "master") 164 assert.NilError(t, err) 165 166 // set up submodule 167 subrepoDir := filepath.Join(root, "subrepo") 168 _, err = git("init", subrepoDir) 169 assert.NilError(t, err) 170 171 _, err = gitWithinDir(subrepoDir, "config", "user.email", "test@docker.com") 172 assert.NilError(t, err) 173 174 _, err = gitWithinDir(subrepoDir, "config", "user.name", "Docker test") 175 assert.NilError(t, err) 176 177 err = ioutil.WriteFile(filepath.Join(subrepoDir, "subfile"), []byte("subcontents"), 0644) 178 assert.NilError(t, err) 179 180 _, err = gitWithinDir(subrepoDir, "add", "-A") 181 assert.NilError(t, err) 182 183 _, err = gitWithinDir(subrepoDir, "commit", "-am", "Subrepo initial") 184 assert.NilError(t, err) 185 186 cmd := exec.Command("git", "submodule", "add", subrepoDir, "sub") // this command doesn't work with --work-tree 187 cmd.Dir = gitDir 188 assert.NilError(t, cmd.Run()) 189 190 _, err = gitWithinDir(gitDir, "add", "-A") 191 assert.NilError(t, err) 192 193 _, err = gitWithinDir(gitDir, "commit", "-am", "With submodule") 194 assert.NilError(t, err) 195 196 type singleCase struct { 197 frag string 198 exp string 199 fail bool 200 submodule bool 201 } 202 203 cases := []singleCase{ 204 {"", "FROM scratch", false, true}, 205 {"master", "FROM scratch", false, true}, 206 {":subdir", "FROM scratch" + eol + "EXPOSE 5000", false, false}, 207 {":nosubdir", "", true, false}, // missing directory error 208 {":Dockerfile", "", true, false}, // not a directory error 209 {"master:nosubdir", "", true, false}, 210 {"master:subdir", "FROM scratch" + eol + "EXPOSE 5000", false, false}, 211 {"master:../subdir", "", true, false}, 212 {"test", "FROM scratch" + eol + "EXPOSE 3000", false, false}, 213 {"test:", "FROM scratch" + eol + "EXPOSE 3000", false, false}, 214 {"test:subdir", "FROM busybox" + eol + "EXPOSE 5000", false, false}, 215 } 216 217 if runtime.GOOS != "windows" { 218 // Windows GIT (2.7.1 x64) does not support parentlink/absolutelink. Sample output below 219 // git --work-tree .\repo --git-dir .\repo\.git add -A 220 // error: readlink("absolutelink"): Function not implemented 221 // error: unable to index file absolutelink 222 // fatal: adding files failed 223 cases = append(cases, singleCase{frag: "master:absolutelink", exp: "FROM scratch" + eol + "EXPOSE 5000", fail: false}) 224 cases = append(cases, singleCase{frag: "master:parentlink", exp: "FROM scratch" + eol + "EXPOSE 5000", fail: false}) 225 } 226 227 for _, c := range cases { 228 ref, subdir := getRefAndSubdir(c.frag) 229 r, err := cloneGitRepo(gitRepo{remote: gitDir, ref: ref, subdir: subdir}) 230 231 if c.fail { 232 assert.Check(t, is.ErrorContains(err, "")) 233 continue 234 } 235 assert.NilError(t, err) 236 defer os.RemoveAll(r) 237 if c.submodule { 238 b, err := ioutil.ReadFile(filepath.Join(r, "sub/subfile")) 239 assert.NilError(t, err) 240 assert.Check(t, is.Equal("subcontents", string(b))) 241 } else { 242 _, err := os.Stat(filepath.Join(r, "sub/subfile")) 243 assert.Assert(t, is.ErrorContains(err, "")) 244 assert.Assert(t, os.IsNotExist(err)) 245 } 246 247 b, err := ioutil.ReadFile(filepath.Join(r, "Dockerfile")) 248 assert.NilError(t, err) 249 assert.Check(t, is.Equal(c.exp, string(b))) 250 } 251 } 252 253 func TestValidGitTransport(t *testing.T) { 254 gitUrls := []string{ 255 "git://github.com/docker/docker", 256 "git@github.com:docker/docker.git", 257 "git@bitbucket.org:atlassianlabs/atlassian-docker.git", 258 "https://github.com/docker/docker.git", 259 "http://github.com/docker/docker.git", 260 "http://github.com/docker/docker.git#branch", 261 "http://github.com/docker/docker.git#:dir", 262 } 263 incompleteGitUrls := []string{ 264 "github.com/docker/docker", 265 } 266 267 for _, url := range gitUrls { 268 if !isGitTransport(url) { 269 t.Fatalf("%q should be detected as valid Git prefix", url) 270 } 271 } 272 273 for _, url := range incompleteGitUrls { 274 if isGitTransport(url) { 275 t.Fatalf("%q should not be detected as valid Git prefix", url) 276 } 277 } 278 }