func init() { Describe("Testing with Ginkgo", func() { It("home dir", func() { osFs, _ := createOsFs() homeDir, err := osFs.HomeDir("root") Expect(err).ToNot(HaveOccurred()) Expect(homeDir).To(ContainSubstring("/root")) }) It("expand path", func() { osFs, _ := createOsFs() expandedPath, err := osFs.ExpandPath("~/fake-dir/fake-file.txt") Expect(err).ToNot(HaveOccurred()) currentUser, err := osuser.Current() Expect(err).ToNot(HaveOccurred()) Expect(expandedPath).To(Equal(currentUser.HomeDir + "/fake-dir/fake-file.txt")) expandedPath, err = osFs.ExpandPath("/fake-dir//fake-file.txt") Expect(err).ToNot(HaveOccurred()) Expect(expandedPath).To(Equal("/fake-dir/fake-file.txt")) expandedPath, err = osFs.ExpandPath("./fake-file.txt") Expect(err).ToNot(HaveOccurred()) currentDir, err := os.Getwd() Expect(err).ToNot(HaveOccurred()) Expect(expandedPath).To(Equal(currentDir + "/fake-file.txt")) }) It("mkdir all", func() { osFs, _ := createOsFs() tmpPath := os.TempDir() testPath := filepath.Join(tmpPath, "MkdirAllTestDir", "bar", "baz") defer os.RemoveAll(filepath.Join(tmpPath, "MkdirAllTestDir")) _, err := os.Stat(testPath) Expect(err).To(HaveOccurred()) Expect(os.IsNotExist(err)).To(BeTrue()) fileMode := os.FileMode(0700) err = osFs.MkdirAll(testPath, fileMode) Expect(err).ToNot(HaveOccurred()) stat, err := os.Stat(testPath) Expect(err).ToNot(HaveOccurred()) Expect(stat.IsDir()).To(BeTrue()) Expect(stat.Mode().Perm()).To(Equal(fileMode)) err = osFs.MkdirAll(testPath, fileMode) Expect(err).ToNot(HaveOccurred()) }) It("chown", func() { osFs, _ := createOsFs() testPath := filepath.Join(os.TempDir(), "ChownTestDir") err := os.Mkdir(testPath, os.FileMode(0700)) Expect(err).ToNot(HaveOccurred()) defer os.RemoveAll(testPath) err = osFs.Chown(testPath, "garbage-foo") Expect(err).To(HaveOccurred()) }) It("chmod", func() { osFs, _ := createOsFs() testPath := filepath.Join(os.TempDir(), "ChmodTestDir") _, err := os.Create(testPath) Expect(err).ToNot(HaveOccurred()) defer os.Remove(testPath) os.Chmod(testPath, os.FileMode(0666)) err = osFs.Chmod(testPath, os.FileMode(0644)) Expect(err).ToNot(HaveOccurred()) fileStat, err := os.Stat(testPath) Expect(err).ToNot(HaveOccurred()) Expect(fileStat.Mode()).To(Equal(os.FileMode(0644))) }) It("opens file", func() { osFs, _ := createOsFs() testPath := filepath.Join(os.TempDir(), "OpenFileTestFile") file, err := osFs.OpenFile(testPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.FileMode(0644)) defer os.Remove(testPath) Expect(err).ToNot(HaveOccurred()) file.Write([]byte("testing new file")) file.Close() createdFile, err := os.Open(testPath) Expect(err).ToNot(HaveOccurred()) defer createdFile.Close() Expect(readFile(createdFile)).To(Equal("testing new file")) }) Context("the file already exists and is not write only", func() { It("writes to file", func() { osFs, _ := createOsFs() testPath := filepath.Join(os.TempDir(), "subDir", "ConvergeFileContentsTestFile") _, err := os.Stat(testPath) Expect(err).To(HaveOccurred()) written, err := osFs.ConvergeFileContents(testPath, []byte("initial write")) Expect(err).ToNot(HaveOccurred()) Expect(written).To(BeTrue()) defer os.Remove(testPath) file, err := os.Open(testPath) Expect(err).ToNot(HaveOccurred()) defer file.Close() Expect(readFile(file)).To(Equal("initial write")) written, err = osFs.ConvergeFileContents(testPath, []byte("second write")) Expect(err).ToNot(HaveOccurred()) Expect(written).To(BeTrue()) file.Close() file, err = os.Open(testPath) Expect(err).ToNot(HaveOccurred()) Expect(readFile(file)).To(Equal("second write")) file.Close() file, err = os.Open(testPath) written, err = osFs.ConvergeFileContents(testPath, []byte("second write")) Expect(err).ToNot(HaveOccurred()) Expect(written).To(BeFalse()) Expect(readFile(file)).To(Equal("second write")) }) }) Context("the file already exists and is write only", func() { It("writes to file", func() { osFs, _ := createOsFs() testPath := filepath.Join(os.TempDir(), "subDir", "ConvergeFileContentsTestFile") _, err := os.OpenFile(testPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(0200)) Expect(err).ToNot(HaveOccurred()) defer os.Remove(testPath) err = osFs.WriteFile(testPath, []byte("test")) Expect(err).ToNot(HaveOccurred()) }) }) Context("the file parent fir does not exist", func() { BeforeEach(func() { err := os.RemoveAll(filepath.Join(os.TempDir(), "subDirNew")) Expect(err).ToNot(HaveOccurred()) }) AfterEach(func() { err := os.RemoveAll(filepath.Join(os.TempDir(), "subDirNew")) Expect(err).ToNot(HaveOccurred()) }) It("writes to file", func() { osFs, _ := createOsFs() testPath := filepath.Join(os.TempDir(), "subDirNew", "ConvergeFileContentsTestFile") err := osFs.WriteFile(testPath, []byte("test")) Expect(err).ToNot(HaveOccurred()) }) }) It("read file", func() { osFs, _ := createOsFs() testPath := filepath.Join(os.TempDir(), "ReadFileTestFile") osFs.WriteFileString(testPath, "some contents") defer os.Remove(testPath) content, err := osFs.ReadFile(testPath) Expect(err).ToNot(HaveOccurred()) Expect("some contents").To(Equal(string(content))) }) It("file exists", func() { osFs, _ := createOsFs() testPath := filepath.Join(os.TempDir(), "FileExistsTestFile") Expect(osFs.FileExists(testPath)).To(BeFalse()) osFs.WriteFileString(testPath, "initial write") defer os.Remove(testPath) Expect(osFs.FileExists(testPath)).To(BeTrue()) }) It("rename", func() { osFs, _ := createOsFs() tempDir := os.TempDir() oldPath := filepath.Join(tempDir, "old") oldFilePath := filepath.Join(oldPath, "test.txt") newPath := filepath.Join(tempDir, "new") os.Mkdir(oldPath, os.ModePerm) _, err := os.Create(oldFilePath) Expect(err).ToNot(HaveOccurred()) err = osFs.Rename(oldPath, newPath) Expect(err).ToNot(HaveOccurred()) Expect(osFs.FileExists(newPath)).To(BeTrue()) newFilePath := filepath.Join(newPath, "test.txt") Expect(osFs.FileExists(newFilePath)).To(BeTrue()) }) It("symlink", func() { osFs, _ := createOsFs() filePath := filepath.Join(os.TempDir(), "SymlinkTestFile") containingDir := filepath.Join(os.TempDir(), "SubDir") os.Remove(containingDir) symlinkPath := filepath.Join(containingDir, "SymlinkTestSymlink") osFs.WriteFileString(filePath, "some content") defer os.Remove(filePath) osFs.Symlink(filePath, symlinkPath) defer os.Remove(containingDir) symlinkStats, err := os.Lstat(symlinkPath) Expect(err).ToNot(HaveOccurred()) Expect(os.ModeSymlink).To(Equal(os.ModeSymlink & symlinkStats.Mode())) symlinkFile, err := os.Open(symlinkPath) Expect(err).ToNot(HaveOccurred()) Expect("some content").To(Equal(readFile(symlinkFile))) }) It("symlink when link already exists and links to the intended path", func() { osFs, _ := createOsFs() filePath := filepath.Join(os.TempDir(), "SymlinkTestIdempotent1File") symlinkPath := filepath.Join(os.TempDir(), "SymlinkTestIdempotent1Symlink") osFs.WriteFileString(filePath, "some content") defer os.Remove(filePath) osFs.Symlink(filePath, symlinkPath) defer os.Remove(symlinkPath) firstSymlinkStats, err := os.Lstat(symlinkPath) Expect(err).ToNot(HaveOccurred()) err = osFs.Symlink(filePath, symlinkPath) Expect(err).ToNot(HaveOccurred()) secondSymlinkStats, err := os.Lstat(symlinkPath) Expect(err).ToNot(HaveOccurred()) Expect(firstSymlinkStats.ModTime()).To(Equal(secondSymlinkStats.ModTime())) }) It("symlink when link already exists and does not link to the intended path", func() { osFs, _ := createOsFs() filePath := filepath.Join(os.TempDir(), "SymlinkTestIdempotent1File") otherFilePath := filepath.Join(os.TempDir(), "SymlinkTestIdempotent1OtherFile") symlinkPath := filepath.Join(os.TempDir(), "SymlinkTestIdempotent1Symlink") osFs.WriteFileString(filePath, "some content") defer os.Remove(filePath) osFs.WriteFileString(otherFilePath, "other content") defer os.Remove(otherFilePath) err := osFs.Symlink(otherFilePath, symlinkPath) Expect(err).ToNot(HaveOccurred()) err = osFs.Symlink(filePath, symlinkPath) Expect(err).ToNot(HaveOccurred()) defer os.Remove(symlinkPath) symlinkStats, err := os.Lstat(symlinkPath) Expect(err).ToNot(HaveOccurred()) Expect(os.ModeSymlink).To(Equal(os.ModeSymlink & symlinkStats.Mode())) symlinkFile, err := os.Open(symlinkPath) Expect(err).ToNot(HaveOccurred()) Expect("some content").To(Equal(readFile(symlinkFile))) }) It("symlink when a file exists at intended path", func() { osFs, _ := createOsFs() filePath := filepath.Join(os.TempDir(), "SymlinkTestIdempotent1File") symlinkPath := filepath.Join(os.TempDir(), "SymlinkTestIdempotent1Symlink") osFs.WriteFileString(filePath, "some content") defer os.Remove(filePath) osFs.WriteFileString(symlinkPath, "some other content") defer os.Remove(symlinkPath) err := osFs.Symlink(filePath, symlinkPath) Expect(err).ToNot(HaveOccurred()) defer os.Remove(symlinkPath) symlinkStats, err := os.Lstat(symlinkPath) Expect(err).ToNot(HaveOccurred()) Expect(os.ModeSymlink).To(Equal(os.ModeSymlink & symlinkStats.Mode())) symlinkFile, err := os.Open(symlinkPath) Expect(err).ToNot(HaveOccurred()) Expect("some content").To(Equal(readFile(symlinkFile))) }) It("read link", func() { osFs, _ := createOsFs() filePath := filepath.Join(os.TempDir(), "SymlinkTestFile") containingDir := filepath.Join(os.TempDir(), "SubDir") os.Remove(containingDir) symlinkPath := filepath.Join(containingDir, "SymlinkTestSymlink") osFs.WriteFileString(filePath, "some content") defer os.Remove(filePath) err := osFs.Symlink(filePath, symlinkPath) Expect(err).ToNot(HaveOccurred()) defer os.Remove(containingDir) actualFilePath, err := osFs.ReadLink(symlinkPath) Expect(err).ToNot(HaveOccurred()) // on Mac OS /var -> private/var absPath, err := filepath.EvalSymlinks(filePath) Expect(err).ToNot(HaveOccurred()) Expect(actualFilePath).To(Equal(absPath)) }) It("temp file", func() { osFs, _ := createOsFs() file1, err := osFs.TempFile("fake-prefix") Expect(err).ToNot(HaveOccurred()) assert.NotEmpty(GinkgoT(), file1) defer os.Remove(file1.Name()) file2, err := osFs.TempFile("fake-prefix") Expect(err).ToNot(HaveOccurred()) assert.NotEmpty(GinkgoT(), file2) defer os.Remove(file2.Name()) assert.NotEqual(GinkgoT(), file1.Name(), file2.Name()) }) It("temp dir", func() { osFs, _ := createOsFs() path1, err := osFs.TempDir("fake-prefix") Expect(err).ToNot(HaveOccurred()) assert.NotEmpty(GinkgoT(), path1) defer os.Remove(path1) path2, err := osFs.TempDir("fake-prefix") Expect(err).ToNot(HaveOccurred()) assert.NotEmpty(GinkgoT(), path2) defer os.Remove(path2) assert.NotEqual(GinkgoT(), path1, path2) }) Describe("Temporary directories and files", func() { var ( osFs FileSystem testTempDir string ) BeforeEach(func() { osFs, _ = createOsFs() var err error testTempDir, err = ioutil.TempDir("", "os_filesystem_test") Expect(err).ToNot(HaveOccurred()) }) AfterEach(func() { os.Remove(testTempDir) }) Context("a temp root is set", func() { BeforeEach(func() { osFs.ChangeTempRoot(testTempDir) }) It("creates temp files under that root", func() { file, err := osFs.TempFile("some-file-prefix") Expect(err).ToNot(HaveOccurred()) Expect(file.Name()).To(HavePrefix(filepath.Join(testTempDir, "some-file-prefix"))) }) It("creates temp directories under that root", func() { dirName, err := osFs.TempDir("some-dir-prefix") Expect(err).ToNot(HaveOccurred()) Expect(dirName).To(HavePrefix(filepath.Join(testTempDir, "some-dir-prefix"))) }) }) Context("no temp root is set and was initialized as a strict temp root", func() { BeforeEach(func() { osFs = NewOsFileSystemWithStrictTempRoot(boshlog.NewLogger(boshlog.LevelNone)) }) It("should eror", func() { _, err := osFs.TempFile("some-prefix") Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("ChangeTempRoot")) _, err = osFs.TempDir("some-prefix") Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("ChangeTempRoot")) }) }) }) Describe("CopyFile", func() { It("copies file", func() { osFs, _ := createOsFs() srcPath := "test_assets/test_copy_dir_entries/foo.txt" dstFile, err := osFs.TempFile("CopyFileTestFile") Expect(err).ToNot(HaveOccurred()) defer os.Remove(dstFile.Name()) err = osFs.CopyFile(srcPath, dstFile.Name()) fooContent, err := osFs.ReadFileString(dstFile.Name()) Expect(err).ToNot(HaveOccurred()) Expect(fooContent).To(Equal("foo\n")) }) It("does not leak file descriptors", func() { osFs, _ := createOsFs() srcFile, err := osFs.TempFile("srcPath") Expect(err).ToNot(HaveOccurred()) err = srcFile.Close() Expect(err).ToNot(HaveOccurred()) dstFile, err := osFs.TempFile("dstPath") Expect(err).ToNot(HaveOccurred()) err = dstFile.Close() Expect(err).ToNot(HaveOccurred()) err = osFs.CopyFile(srcFile.Name(), dstFile.Name()) Expect(err).ToNot(HaveOccurred()) runner := NewExecCmdRunner(boshlog.NewLogger(boshlog.LevelNone)) stdout, _, _, err := runner.RunCommand("lsof") Expect(err).ToNot(HaveOccurred()) for _, line := range strings.Split(stdout, "\n") { if strings.Contains(line, srcFile.Name()) { Fail(fmt.Sprintf("CopyFile did not close: srcFile: %s", srcFile.Name())) } if strings.Contains(line, dstFile.Name()) { Fail(fmt.Sprintf("CopyFile did not close: dstFile: %s", dstFile.Name())) } } os.Remove(srcFile.Name()) os.Remove(dstFile.Name()) }) }) Describe("CopyDir", func() { var fixtureFiles = []string{ "foo.txt", "bar/bar.txt", "bar/baz/.gitkeep", } It("recursively copies directory contents", func() { osFs, _ := createOsFs() srcPath := "test_assets/test_copy_dir_entries" dstPath, err := osFs.TempDir("CopyDirTestDir") Expect(err).ToNot(HaveOccurred()) defer osFs.RemoveAll(dstPath) err = osFs.CopyDir(srcPath, dstPath) Expect(err).ToNot(HaveOccurred()) for _, fixtureFile := range fixtureFiles { srcContents, err := osFs.ReadFile(filepath.Join(srcPath, fixtureFile)) Expect(err).ToNot(HaveOccurred()) dstContents, err := osFs.ReadFile(filepath.Join(dstPath, fixtureFile)) Expect(err).ToNot(HaveOccurred()) Expect(srcContents).To(Equal(dstContents), "Copied file does not match source file: '%s", fixtureFile) } }) It("does not leak file descriptors", func() { osFs, _ := createOsFs() srcPath := "test_assets/test_copy_dir_entries" dstPath, err := osFs.TempDir("CopyDirTestDir") Expect(err).ToNot(HaveOccurred()) defer osFs.RemoveAll(dstPath) err = osFs.CopyDir(srcPath, dstPath) Expect(err).ToNot(HaveOccurred()) runner := NewExecCmdRunner(boshlog.NewLogger(boshlog.LevelNone)) stdout, _, _, err := runner.RunCommand("lsof") Expect(err).ToNot(HaveOccurred()) // lsof uses absolute paths srcPath, err = filepath.Abs(srcPath) Expect(err).ToNot(HaveOccurred()) for _, line := range strings.Split(stdout, "\n") { for _, fixtureFile := range fixtureFiles { srcFilePath := filepath.Join(srcPath, fixtureFile) if strings.Contains(line, srcFilePath) { Fail(fmt.Sprintf("CopyDir did not close source file: %s", srcFilePath)) } srcFileDirPath := filepath.Dir(srcFilePath) if strings.Contains(line, srcFileDirPath) { Fail(fmt.Sprintf("CopyDir did not close source dir: %s", srcFileDirPath)) } dstFilePath := filepath.Join(dstPath, fixtureFile) if strings.Contains(line, dstFilePath) { Fail(fmt.Sprintf("CopyDir did not close destination file: %s", dstFilePath)) } dstFileDirPath := filepath.Dir(dstFilePath) if strings.Contains(line, dstFileDirPath) { Fail(fmt.Sprintf("CopyDir did not close destination dir: %s", dstFileDirPath)) } } } }) }) It("remove all", func() { osFs, _ := createOsFs() dstFile, err := osFs.TempFile("CopyFileTestFile") Expect(err).ToNot(HaveOccurred()) defer os.Remove(dstFile.Name()) err = osFs.RemoveAll(dstFile.Name()) Expect(err).ToNot(HaveOccurred()) _, err = os.Stat(dstFile.Name()) Expect(os.IsNotExist(err)).To(BeTrue()) }) }) }
It("temp file", func() { osFs := createOsFs() file1, err := osFs.TempFile("fake-prefix") Expect(err).ToNot(HaveOccurred()) assert.NotEmpty(GinkgoT(), file1) defer os.Remove(file1.Name()) file2, err := osFs.TempFile("fake-prefix") Expect(err).ToNot(HaveOccurred()) assert.NotEmpty(GinkgoT(), file2) defer os.Remove(file2.Name()) assert.NotEqual(GinkgoT(), file1.Name(), file2.Name()) }) It("temp dir", func() { osFs := createOsFs() path1, err := osFs.TempDir("fake-prefix") Expect(err).ToNot(HaveOccurred()) assert.NotEmpty(GinkgoT(), path1) defer os.Remove(path1) path2, err := osFs.TempDir("fake-prefix") Expect(err).ToNot(HaveOccurred()) assert.NotEmpty(GinkgoT(), path2)