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  }