github.com/NeowayLabs/nash@v0.2.2-0.20200127205349-a227041ffd50/cmd/nash/install_test.go (about) 1 package main_test 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "testing" 8 9 main "github.com/madlambda/nash/cmd/nash" 10 "github.com/madlambda/nash/internal/testing/fixture" 11 ) 12 13 // TODO: test when nashpath lib already exists and has libraries inside 14 15 func TestInstallLib(t *testing.T) { 16 type testcase struct { 17 name string 18 libfiles []string 19 installpath string 20 // want will map the wanted files to the original files copied from the lib 21 // the wanted files paths are relative to inside the nashpath lib dir. 22 // the files need to be mapped to the original files because of content validation 23 // when multiple files are installed. 24 want map[string]string 25 } 26 27 cases := []testcase{ 28 { 29 name: "SingleFile", 30 libfiles: []string{ 31 "/testfile/file.sh", 32 }, 33 installpath: "/testfile/file.sh", 34 want: map[string]string{ 35 "file.sh": "/testfile/file.sh", 36 }, 37 }, 38 { 39 name: "SingleDir", 40 libfiles: []string{ 41 "/testfile/file.sh", 42 }, 43 installpath: "/testfile", 44 want: map[string]string{ 45 "/testfile/file.sh": "/testfile/file.sh", 46 }, 47 }, 48 { 49 name: "SingleDirWithMultipleFiles", 50 libfiles: []string{ 51 "/testfile/file.sh", 52 "/testfile/fileagain.sh", 53 }, 54 installpath: "/testfile", 55 want: map[string]string{ 56 "/testfile/file.sh": "/testfile/file.sh", 57 "/testfile/fileagain.sh": "/testfile/fileagain.sh", 58 }, 59 }, 60 { 61 name: "MultipleDirsWithMultipleFiles", 62 libfiles: []string{ 63 "/testfile/file.sh", 64 "/testfile/dir1/file.sh", 65 "/testfile/dir1/fileagain.sh", 66 "/testfile/dir2/file.sh", 67 "/testfile/dir2/fileagain.sh", 68 "/testfile/dir2/dir3/file.sh", 69 }, 70 installpath: "/testfile", 71 want: map[string]string{ 72 "/testfile/file.sh": "/testfile/file.sh", 73 "/testfile/dir1/file.sh": "/testfile/dir1/file.sh", 74 "/testfile/dir1/fileagain.sh": "/testfile/dir1/fileagain.sh", 75 "/testfile/dir2/file.sh": "/testfile/dir2/file.sh", 76 "/testfile/dir2/fileagain.sh": "/testfile/dir2/fileagain.sh", 77 "/testfile/dir2/dir3/file.sh": "/testfile/dir2/dir3/file.sh", 78 }, 79 }, 80 { 81 name: "InstallOnlyFilesIndicatedByInstallDir", 82 libfiles: []string{ 83 "/testfile/file.sh", 84 "/testfile/dir1/file.sh", 85 "/testfile/dir1/fileagain.sh", 86 "/testfile/dir2/file.sh", 87 "/testfile/dir2/fileagain.sh", 88 "/testfile/dir2/dir3/file.sh", 89 }, 90 installpath: "/testfile/dir2", 91 want: map[string]string{ 92 "/dir2/file.sh": "/testfile/dir2/file.sh", 93 "/dir2/fileagain.sh": "/testfile/dir2/fileagain.sh", 94 "/dir2/dir3/file.sh": "/testfile/dir2/dir3/file.sh", 95 }, 96 }, 97 } 98 99 for _, c := range cases { 100 t.Run(c.name, func(t *testing.T) { 101 nashpath, rmnashpath := fixture.Tmpdir(t) 102 defer rmnashpath() 103 104 libfilesDir, rmlibfilesDir := fixture.Tmpdir(t) 105 defer rmlibfilesDir() 106 107 nashlibdir := main.NashLibDir(nashpath) 108 libfiles := []string{} 109 110 libfileFullPath := func(libfilepath string) string { 111 return filepath.Join(libfilesDir, libfilepath) 112 } 113 114 for _, f := range c.libfiles { 115 libfiles = append(libfiles, libfileFullPath(f)) 116 } 117 118 createdLibFiles := fixture.CreateFiles(t, libfiles) 119 installpath := filepath.Join(libfilesDir, c.installpath) 120 121 err := main.InstallLib(nashpath, installpath) 122 if err != nil { 123 t.Fatal(err) 124 } 125 126 listNashPathFiles := func() []string { 127 files := []string{} 128 filepath.Walk(nashpath, func(path string, stats os.FileInfo, err error) error { 129 if stats.IsDir() { 130 return nil 131 } 132 files = append(files, path) 133 return nil 134 }) 135 return files 136 } 137 138 gotFiles := listNashPathFiles() 139 140 fatal := func() { 141 t.Errorf("nashpath: [%s]", nashpath) 142 t.Errorf("nashpath contents:") 143 144 for _, path := range gotFiles { 145 t.Errorf("[%s]", path) 146 } 147 t.Fatal("") 148 } 149 150 if len(gotFiles) != len(c.want) { 151 t.Errorf("wanted[%d] files but got[%d]", len(c.want), len(gotFiles)) 152 fatal() 153 } 154 155 for wantFilepath, libfilepath := range c.want { 156 completeLibFilepath := libfileFullPath(libfilepath) 157 wantContents, ok := createdLibFiles[completeLibFilepath] 158 159 if !ok { 160 t.Errorf("unable to find libfilepath[%s] contents on created lib files map[%+v]", completeLibFilepath, createdLibFiles) 161 t.Fatal("this probably means a wrongly specified test case with wanted files that are not present on the libfiles") 162 } 163 164 fullWantFilepath := filepath.Join(nashlibdir, wantFilepath) 165 wantFile, err := os.Open(fullWantFilepath) 166 if err != nil { 167 t.Errorf("error[%s] checking wanted file[%s]", err, wantFilepath) 168 fatal() 169 } 170 gotContentsRaw, err := ioutil.ReadAll(wantFile) 171 wantFile.Close() 172 173 if err != nil { 174 t.Errorf("error[%s] checking existence of wanted file[%s]", err, wantFilepath) 175 fatal() 176 } 177 178 gotContents := string(gotContentsRaw) 179 if gotContents != wantContents { 180 t.Errorf("for file [%s] wanted contents [%s] but got [%s]", wantFilepath, wantContents, gotContents) 181 fatal() 182 } 183 } 184 }) 185 } 186 } 187 188 func TestSourcePathCantBeEqualToNashLibDir(t *testing.T) { 189 nashpath, rmnashpath := fixture.Tmpdir(t) 190 defer rmnashpath() 191 192 nashlibdir := main.NashLibDir(nashpath) 193 194 fixture.CreateFile(t, filepath.Join(nashlibdir, "whatever.sh")) 195 196 assertInstallLibFails(t, nashpath, nashlibdir) 197 } 198 199 func TestSourcePathCantBeInsideNashLibDir(t *testing.T) { 200 nashpath, rmnashpath := fixture.Tmpdir(t) 201 defer rmnashpath() 202 203 nashlibdir := main.NashLibDir(nashpath) 204 sourcelibdir := filepath.Join(nashlibdir, "somedir") 205 fixture.CreateFile(t, filepath.Join(sourcelibdir, "whatever.sh")) 206 207 assertInstallLibFails(t, nashpath, sourcelibdir) 208 } 209 210 func TestRelativeSourcePathCantBeInsideNashLibDir(t *testing.T) { 211 nashpath, rmnashpath := fixture.Tmpdir(t) 212 defer rmnashpath() 213 214 nashlibdir := main.NashLibDir(nashpath) 215 fixture.CreateFile(t, filepath.Join(nashlibdir, "somedir", "whatever.sh")) 216 217 oldwd := fixture.WorkingDir(t) 218 defer fixture.ChangeDir(t, oldwd) 219 220 fixture.ChangeDir(t, nashlibdir) 221 222 assertInstallLibFails(t, nashpath, "./somedir") 223 } 224 225 func TestFailsOnUnexistentSourcePath(t *testing.T) { 226 nashpath, rmnashpath := fixture.Tmpdir(t) 227 defer rmnashpath() 228 229 assertInstallLibFails(t, nashpath, "/nonexistent/nash/crap") 230 } 231 232 func TestFailsOnUnreadableSourcePath(t *testing.T) { 233 nashpath, rmnashpath := fixture.Tmpdir(t) 234 defer rmnashpath() 235 236 sourcedir, rmsourcedir := fixture.Tmpdir(t) 237 defer rmsourcedir() 238 239 fixture.Chmod(t, sourcedir, writeOnly) 240 assertInstallLibFails(t, nashpath, sourcedir) 241 } 242 243 func TestFailsOnUnreadableFileInsideSourcePath(t *testing.T) { 244 nashpath, rmnashpath := fixture.Tmpdir(t) 245 defer rmnashpath() 246 247 sourcedir, rmsourcedir := fixture.Tmpdir(t) 248 defer rmsourcedir() 249 250 readableFile := filepath.Join(sourcedir, "file1.sh") 251 unreadableFile := filepath.Join(sourcedir, "file2.sh") 252 253 fixture.CreateFiles(t, []string{readableFile, unreadableFile}) 254 fixture.Chmod(t, unreadableFile, writeOnly) 255 256 assertInstallLibFails(t, nashpath, sourcedir) 257 } 258 259 func TestFailsOnUnwriteableNashPath(t *testing.T) { 260 nashpath, rmnashpath := fixture.Tmpdir(t) 261 defer rmnashpath() 262 263 sourcedir, rmsourcedir := fixture.Tmpdir(t) 264 defer rmsourcedir() 265 266 fixture.Chmod(t, nashpath, readOnly) 267 fixture.CreateFile(t, filepath.Join(sourcedir, "file.sh")) 268 269 assertInstallLibFails(t, nashpath, sourcedir) 270 } 271 272 func TestFailsOnUnwriteableFileInsideNashLibdir(t *testing.T) { 273 nashpath, rmnashpath := fixture.Tmpdir(t) 274 defer rmnashpath() 275 276 sourcedir, rmsourcedir := fixture.Tmpdir(t) 277 defer rmsourcedir() 278 279 filename := "test.sh" 280 sourcefile := filepath.Join(sourcedir, filename) 281 expectedInstalledFile := filepath.Join( 282 main.NashLibDir(nashpath), 283 filepath.Base(sourcedir), 284 filename, 285 ) 286 287 fixture.CreateFiles(t, []string{sourcefile, expectedInstalledFile}) 288 fixture.Chmod(t, expectedInstalledFile, readOnly) 289 290 assertInstallLibFails(t, nashpath, sourcedir) 291 } 292 293 func assertInstallLibFails(t *testing.T, nashpath string, sourcepath string) { 294 t.Helper() 295 296 err := main.InstallLib(nashpath, sourcepath) 297 if err == nil { 298 t.Fatal("expected error, got nil") 299 } 300 } 301 302 const writeOnly = 0333 303 const readOnly = 0555