github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/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 }