github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/cmd/go/internal/work/build_test.go (about)

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package work
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"io/ioutil"
    11  	"os"
    12  	"path"
    13  	"path/filepath"
    14  	"reflect"
    15  	"runtime"
    16  	"strings"
    17  	"testing"
    18  
    19  	"cmd/go/internal/base"
    20  	"cmd/go/internal/cfg"
    21  	"cmd/go/internal/load"
    22  )
    23  
    24  func TestRemoveDevNull(t *testing.T) {
    25  	fi, err := os.Lstat(os.DevNull)
    26  	if err != nil {
    27  		t.Skip(err)
    28  	}
    29  	if fi.Mode().IsRegular() {
    30  		t.Errorf("Lstat(%s).Mode().IsRegular() = true; expected false", os.DevNull)
    31  	}
    32  	mayberemovefile(os.DevNull)
    33  	_, err = os.Lstat(os.DevNull)
    34  	if err != nil {
    35  		t.Errorf("mayberemovefile(%s) did remove it; oops", os.DevNull)
    36  	}
    37  }
    38  
    39  func TestSplitPkgConfigOutput(t *testing.T) {
    40  	for _, test := range []struct {
    41  		in   []byte
    42  		want []string
    43  	}{
    44  		{[]byte(`-r:foo -L/usr/white\ space/lib -lfoo\ bar -lbar\ baz`), []string{"-r:foo", "-L/usr/white space/lib", "-lfoo bar", "-lbar baz"}},
    45  		{[]byte(`-lextra\ fun\ arg\\`), []string{`-lextra fun arg\`}},
    46  		{[]byte(`broken flag\`), []string{"broken", "flag"}},
    47  		{[]byte("\textra     whitespace\r\n"), []string{"extra", "whitespace"}},
    48  		{[]byte("     \r\n      "), nil},
    49  	} {
    50  		got := splitPkgConfigOutput(test.in)
    51  		if !reflect.DeepEqual(got, test.want) {
    52  			t.Errorf("splitPkgConfigOutput(%v) = %v; want %v", test.in, got, test.want)
    53  		}
    54  	}
    55  }
    56  
    57  func TestSharedLibName(t *testing.T) {
    58  	// TODO(avdva) - make these values platform-specific
    59  	prefix := "lib"
    60  	suffix := ".so"
    61  	testData := []struct {
    62  		args      []string
    63  		pkgs      []*load.Package
    64  		expected  string
    65  		expectErr bool
    66  		rootedAt  string
    67  	}{
    68  		{
    69  			args:     []string{"std"},
    70  			pkgs:     []*load.Package{},
    71  			expected: "std",
    72  		},
    73  		{
    74  			args:     []string{"std", "cmd"},
    75  			pkgs:     []*load.Package{},
    76  			expected: "std,cmd",
    77  		},
    78  		{
    79  			args:     []string{},
    80  			pkgs:     []*load.Package{pkgImportPath("gopkg.in/somelib")},
    81  			expected: "gopkg.in-somelib",
    82  		},
    83  		{
    84  			args:     []string{"./..."},
    85  			pkgs:     []*load.Package{pkgImportPath("somelib")},
    86  			expected: "somelib",
    87  			rootedAt: "somelib",
    88  		},
    89  		{
    90  			args:     []string{"../somelib", "../somelib"},
    91  			pkgs:     []*load.Package{pkgImportPath("somelib")},
    92  			expected: "somelib",
    93  		},
    94  		{
    95  			args:     []string{"../lib1", "../lib2"},
    96  			pkgs:     []*load.Package{pkgImportPath("gopkg.in/lib1"), pkgImportPath("gopkg.in/lib2")},
    97  			expected: "gopkg.in-lib1,gopkg.in-lib2",
    98  		},
    99  		{
   100  			args: []string{"./..."},
   101  			pkgs: []*load.Package{
   102  				pkgImportPath("gopkg.in/dir/lib1"),
   103  				pkgImportPath("gopkg.in/lib2"),
   104  				pkgImportPath("gopkg.in/lib3"),
   105  			},
   106  			expected: "gopkg.in",
   107  			rootedAt: "gopkg.in",
   108  		},
   109  		{
   110  			args:      []string{"std", "../lib2"},
   111  			pkgs:      []*load.Package{},
   112  			expectErr: true,
   113  		},
   114  		{
   115  			args:      []string{"all", "./"},
   116  			pkgs:      []*load.Package{},
   117  			expectErr: true,
   118  		},
   119  		{
   120  			args:      []string{"cmd", "fmt"},
   121  			pkgs:      []*load.Package{},
   122  			expectErr: true,
   123  		},
   124  	}
   125  	for _, data := range testData {
   126  		func() {
   127  			if data.rootedAt != "" {
   128  				tmpGopath, err := ioutil.TempDir("", "gopath")
   129  				if err != nil {
   130  					t.Fatal(err)
   131  				}
   132  				oldGopath := cfg.BuildContext.GOPATH
   133  				defer func() {
   134  					cfg.BuildContext.GOPATH = oldGopath
   135  					os.Chdir(base.Cwd)
   136  					err := os.RemoveAll(tmpGopath)
   137  					if err != nil {
   138  						t.Error(err)
   139  					}
   140  				}()
   141  				root := filepath.Join(tmpGopath, "src", data.rootedAt)
   142  				err = os.MkdirAll(root, 0755)
   143  				if err != nil {
   144  					t.Fatal(err)
   145  				}
   146  				cfg.BuildContext.GOPATH = tmpGopath
   147  				os.Chdir(root)
   148  			}
   149  			computed, err := libname(data.args, data.pkgs)
   150  			if err != nil {
   151  				if !data.expectErr {
   152  					t.Errorf("libname returned an error %q, expected a name", err.Error())
   153  				}
   154  			} else if data.expectErr {
   155  				t.Errorf("libname returned %q, expected an error", computed)
   156  			} else {
   157  				expected := prefix + data.expected + suffix
   158  				if expected != computed {
   159  					t.Errorf("libname returned %q, expected %q", computed, expected)
   160  				}
   161  			}
   162  		}()
   163  	}
   164  }
   165  
   166  func pkgImportPath(pkgpath string) *load.Package {
   167  	return &load.Package{
   168  		PackagePublic: load.PackagePublic{
   169  			ImportPath: pkgpath,
   170  		},
   171  	}
   172  }
   173  
   174  // When installing packages, the installed package directory should
   175  // respect the group sticky bit and group name of the destination
   176  // directory.
   177  // See https://golang.org/issue/18878.
   178  func TestRespectGroupSticky(t *testing.T) {
   179  	if runtime.GOOS == "nacl" {
   180  		t.Skip("can't set group sticky bit with chmod on nacl")
   181  	}
   182  
   183  	var b Builder
   184  	b.Init()
   185  
   186  	// Check that `cp` is called instead of `mv` by looking at the output
   187  	// of `(*Builder).ShowCmd` afterwards as a sanity check.
   188  	cfg.BuildX = true
   189  	var cmdBuf bytes.Buffer
   190  	b.Print = func(a ...interface{}) (int, error) {
   191  		return cmdBuf.WriteString(fmt.Sprint(a...))
   192  	}
   193  
   194  	stickydir := path.Join(os.TempDir(), "GroupSticky")
   195  	if err := os.Mkdir(stickydir, 0755); err != nil {
   196  		t.Fatal(err)
   197  	}
   198  	defer os.RemoveAll(stickydir)
   199  
   200  	// Mkdir doesn't always correctly set the group sticky bit.
   201  	// Change stickydir's permissions to include group sticky bit.
   202  	if err := os.Chmod(stickydir, 0755|os.ModeSetgid); err != nil {
   203  		t.Fatal(err)
   204  	}
   205  
   206  	pkgfile, err := ioutil.TempFile(b.WorkDir, "")
   207  	if err != nil {
   208  		t.Fatalf("ioutil.TempFile(%q): %v", b.WorkDir, err)
   209  	}
   210  	defer os.Remove(pkgfile.Name())
   211  	defer pkgfile.Close()
   212  
   213  	stickyFile := filepath.Join(stickydir, "sticky")
   214  	if err := b.moveOrCopyFile(nil, stickyFile, pkgfile.Name(), 0666, true); err != nil {
   215  		t.Fatalf("moveOrCopyFile: %v", err)
   216  	}
   217  
   218  	got := strings.TrimSpace(cmdBuf.String())
   219  	want := b.fmtcmd("", "cp %s %s", pkgfile.Name(), stickyFile)
   220  	if got != want {
   221  		t.Fatalf("moveOrCopyFile(%q, %q): want %q, got %q", stickyFile, pkgfile.Name(), want, got)
   222  	}
   223  }