github.com/olljanat/moby@v1.13.1/pkg/gitutils/gitutils_test.go (about)

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