Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Unified Diff: vpython/filesystem/filesystem_test.go

Issue 2703793003: vpython: Add filesystem operation / test packages. (Closed)
Patch Set: test now path Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « vpython/filesystem/filesystem.go ('k') | vpython/filesystem/remove_all.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: vpython/filesystem/filesystem_test.go
diff --git a/vpython/filesystem/filesystem_test.go b/vpython/filesystem/filesystem_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..ef4ffdd082ea35ee877d7e50932e88404c8f6df5
--- /dev/null
+++ b/vpython/filesystem/filesystem_test.go
@@ -0,0 +1,240 @@
+// Copyright 2017 The LUCI Authors. All rights reserved.
+// Use of this source code is governed under the Apache License, Version 2.0
+// that can be found in the LICENSE file.
+
+package filesystem
+
+import (
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "testing"
+ "time"
+
+ "github.com/luci/luci-go/common/errors"
+
+ . "github.com/smartystreets/goconvey/convey"
+)
+
+func withTempDir(t *testing.T, fn func(string)) {
+ tdir, err := ioutil.TempDir("", "vpython-filesystem")
+ if err != nil {
+ t.Fatalf("failed to create temporary directory: %s", err)
+ }
+ defer func() {
+ // Mark all files writable.
+ rmErr := recursiveChmod(tdir, nil, func(mode os.FileMode) os.FileMode {
+ return mode | 0222
+ })
+ if rmErr != nil {
+ t.Errorf("failed to mark temporary directory as writable [%s]: %s", tdir, rmErr)
+ }
+ if rmErr := os.RemoveAll(tdir); rmErr != nil {
+ t.Errorf("failed to remove temporary directory [%s]: %s", tdir, rmErr)
+ }
+ }()
+ fn(tdir)
+}
+
+func TestIsNotExist(t *testing.T) {
+ t.Parallel()
+
+ // Create a temporary directory so we control its contents. This will let us
+ // safely create an IsNotExist error.
+ withTempDir(t, func(tdir string) {
+ dnePath := filepath.Join(tdir, "anything")
+ _, err := os.Open(dnePath)
+ if !os.IsNotExist(err) {
+ t.Fatalf("failed to get IsNotExist error: %s", err)
+ }
+
+ Convey(`IsNotExist works`, t, func() {
+ So(IsNotExist(nil), ShouldBeFalse)
+ So(IsNotExist(errors.New("something")), ShouldBeFalse)
+
+ So(IsNotExist(err), ShouldBeTrue)
+ So(IsNotExist(errors.Annotate(err).Reason("annotated").Err()), ShouldBeTrue)
+ })
+ })
+}
+
+func TestAbsPath(t *testing.T) {
+ t.Parallel()
+
+ // Create a temporary directory so we control its contents. This will let us
+ // safely create an IsNotExist error.
+ withTempDir(t, func(tdir string) {
+ tdirName := filepath.Base(tdir)
+
+ Convey(`AbsPath works`, t, func() {
+ base := filepath.Join(tdir, "..", tdirName, "file.txt")
+ So(AbsPath(&base), ShouldBeNil)
+ So(base, ShouldEqual, filepath.Join(tdir, "file.txt"))
+ })
+ })
+}
+
+func TestTouch(t *testing.T) {
+ t.Parallel()
+
+ Convey(`Can Touch a new file`, t, func() {
+ withTempDir(t, func(tdir string) {
+ thePast := time.Now().Add(-10 * time.Second)
+
+ Convey(`Can update a directory timestamp`, func() {
+ path := filepath.Join(tdir, "subdir")
+
+ So(os.Mkdir(path, 0755), ShouldBeNil)
+ st, err := os.Lstat(path)
+ So(err, ShouldBeNil)
+ initialModTime := st.ModTime()
+
+ So(Touch(path, thePast, 0), ShouldBeNil)
+ st, err = os.Lstat(path)
+ So(err, ShouldBeNil)
+
+ So(st.ModTime(), ShouldHappenBefore, initialModTime)
+ })
+
+ Convey(`Can update an empty file timestamp`, func() {
+ path := filepath.Join(tdir, "touch")
+
+ So(Touch(path, time.Time{}, 0644), ShouldBeNil)
+ st, err := os.Lstat(path)
+ So(err, ShouldBeNil)
+ initialModTime := st.ModTime()
+
+ So(Touch(path, thePast, 0), ShouldBeNil)
+ st, err = os.Lstat(path)
+ So(err, ShouldBeNil)
+ pastModTime := st.ModTime()
+ So(pastModTime, ShouldHappenBefore, initialModTime)
+
+ // Touch back to "now".
+ So(Touch(path, time.Time{}, 0644), ShouldBeNil)
+ st, err = os.Lstat(path)
+ So(err, ShouldBeNil)
+ So(st.ModTime(), ShouldHappenOnOrAfter, pastModTime)
+ })
+
+ Convey(`Can update a populated file timestamp`, func() {
+ path := filepath.Join(tdir, "touch")
+
+ So(ioutil.WriteFile(path, []byte("sup"), 0644), ShouldBeNil)
+ st, err := os.Lstat(path)
+ So(err, ShouldBeNil)
+ initialModTime := st.ModTime()
+
+ So(Touch(path, thePast, 0), ShouldBeNil)
+ st, err = os.Lstat(path)
+ So(err, ShouldBeNil)
+
+ So(st.ModTime(), ShouldHappenBefore, initialModTime)
+ })
+ })
+ })
+}
+
+func TestMakeReadOnly(t *testing.T) {
+ t.Parallel()
+
+ Convey(`Can RemoveAll`, t, func() {
+ withTempDir(t, func(tdir string) {
+
+ for _, path := range []string{
+ filepath.Join(tdir, "foo", "bar"),
+ filepath.Join(tdir, "foo", "baz"),
+ filepath.Join(tdir, "qux"),
+ } {
+ base := filepath.Dir(path)
+ if err := os.MkdirAll(base, 0755); err != nil {
+ t.Fatalf("failed to populate directory [%s]: %s", base, err)
+ }
+ if err := ioutil.WriteFile(path, []byte("junk"), 0644); err != nil {
+ t.Fatalf("failed to create file [%s]: %s", path, err)
+ }
+ }
+
+ Convey(`Can mark the entire subdirectory read-only`, func() {
+ So(MakeReadOnly(tdir, nil), ShouldBeNil)
+ filepath.Walk(tdir, func(path string, info os.FileInfo, err error) error {
+ So(err, ShouldBeNil)
+ So(info.Mode()&0222, ShouldEqual, 0)
+ return nil
+ })
+ })
+
+ Convey(`Can selectively mark files read-only`, func() {
+ // Don't mark <TMP>/foo read-only.
+ fooPath := filepath.Join(tdir, "foo")
+
+ So(MakeReadOnly(tdir, func(path string) bool {
+ return path != fooPath
+ }), ShouldBeNil)
+
+ filepath.Walk(tdir, func(path string, info os.FileInfo, err error) error {
+ So(err, ShouldBeNil)
+ if path == fooPath {
+ So(info.Mode()&0222, ShouldNotEqual, 0)
+ } else {
+ So(info.Mode()&0222, ShouldEqual, 0)
+ }
+ return nil
+ })
+ })
+ })
+ })
+}
+
+func TestRemoveAll(t *testing.T) {
+ t.Parallel()
+
+ isGone := func(path string) bool {
+ if _, err := os.Lstat(path); err != nil {
+ return os.IsNotExist(err)
+ }
+ return false
+ }
+
+ Convey(`Can RemoveAll`, t, func() {
+ withTempDir(t, func(tdir string) {
+
+ subDir := filepath.Join(tdir, "sub")
+
+ Convey(`With directory contents...`, func() {
+ for _, path := range []string{
+ filepath.Join(subDir, "foo", "bar"),
+ filepath.Join(subDir, "foo", "baz"),
+ filepath.Join(subDir, "qux"),
+ } {
+ base := filepath.Dir(path)
+ if err := os.MkdirAll(base, 0755); err != nil {
+ t.Fatalf("failed to populate directory [%s]: %s", base, err)
+ }
+ if err := ioutil.WriteFile(path, []byte("junk"), 0644); err != nil {
+ t.Fatalf("failed to create file [%s]: %s", path, err)
+ }
+ }
+
+ Convey(`Can remove the directory`, func() {
+ So(RemoveAll(subDir), ShouldBeNil)
+ So(isGone(subDir), ShouldBeTrue)
+ })
+
+ Convey(`Can remove the directory when it is read-only`, func() {
+ // Make the directory read-only, and assert that classic os.RemoveAll
+ // fails.
+ So(MakeReadOnly(subDir, nil), ShouldBeNil)
+ So(os.RemoveAll(subDir), ShouldNotBeNil)
+
+ So(RemoveAll(subDir), ShouldBeNil)
+ So(isGone(subDir), ShouldBeTrue)
+ })
+ })
+
+ Convey(`Will return nil if the target does not exist`, func() {
+ So(RemoveAll(filepath.Join(tdir, "dne")), ShouldBeNil)
+ })
+ })
+ })
+}
« no previous file with comments | « vpython/filesystem/filesystem.go ('k') | vpython/filesystem/remove_all.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698