github.com/chipaca/snappy@v0.0.0-20210104084008-1f06296fe8ad/osutil/stat_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2014-2015 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package osutil
    21  
    22  import (
    23  	"fmt"
    24  	"io/ioutil"
    25  	"os"
    26  	"path/filepath"
    27  	"strings"
    28  	"syscall"
    29  
    30  	. "gopkg.in/check.v1"
    31  )
    32  
    33  type StatTestSuite struct{}
    34  
    35  var _ = Suite(&StatTestSuite{})
    36  
    37  func (ts *StatTestSuite) TestFileDoesNotExist(c *C) {
    38  	c.Assert(FileExists("/i-do-not-exist"), Equals, false)
    39  }
    40  
    41  func (ts *StatTestSuite) TestFileExistsSimple(c *C) {
    42  	fname := filepath.Join(c.MkDir(), "foo")
    43  	err := ioutil.WriteFile(fname, []byte(fname), 0644)
    44  	c.Assert(err, IsNil)
    45  
    46  	c.Assert(FileExists(fname), Equals, true)
    47  }
    48  
    49  func (ts *StatTestSuite) TestFileExistsExistsOddPermissions(c *C) {
    50  	fname := filepath.Join(c.MkDir(), "foo")
    51  	err := ioutil.WriteFile(fname, []byte(fname), 0100)
    52  	c.Assert(err, IsNil)
    53  
    54  	c.Assert(FileExists(fname), Equals, true)
    55  }
    56  
    57  func (ts *StatTestSuite) TestIsDirectoryDoesNotExist(c *C) {
    58  	c.Assert(IsDirectory("/i-do-not-exist"), Equals, false)
    59  }
    60  
    61  func (ts *StatTestSuite) TestIsDirectorySimple(c *C) {
    62  	dname := filepath.Join(c.MkDir(), "bar")
    63  	err := os.Mkdir(dname, 0700)
    64  	c.Assert(err, IsNil)
    65  
    66  	c.Assert(IsDirectory(dname), Equals, true)
    67  }
    68  
    69  func (ts *StatTestSuite) TestIsSymlink(c *C) {
    70  	sname := filepath.Join(c.MkDir(), "symlink")
    71  	err := os.Symlink("/", sname)
    72  	c.Assert(err, IsNil)
    73  
    74  	c.Assert(IsSymlink(sname), Equals, true)
    75  }
    76  
    77  func (ts *StatTestSuite) TestIsSymlinkNoSymlink(c *C) {
    78  	c.Assert(IsSymlink(c.MkDir()), Equals, false)
    79  }
    80  
    81  func (ts *StatTestSuite) TestExecutableExists(c *C) {
    82  	oldPath := os.Getenv("PATH")
    83  	defer os.Setenv("PATH", oldPath)
    84  	d := c.MkDir()
    85  	os.Setenv("PATH", d)
    86  	c.Check(ExecutableExists("xyzzy"), Equals, false)
    87  
    88  	fname := filepath.Join(d, "xyzzy")
    89  	c.Assert(ioutil.WriteFile(fname, []byte{}, 0644), IsNil)
    90  	c.Check(ExecutableExists("xyzzy"), Equals, false)
    91  
    92  	c.Assert(os.Chmod(fname, 0755), IsNil)
    93  	c.Check(ExecutableExists("xyzzy"), Equals, true)
    94  }
    95  
    96  func (s *StatTestSuite) TestLookPathDefaultGivesCorrectPath(c *C) {
    97  	lookPath = func(name string) (string, error) { return "/bin/true", nil }
    98  	c.Assert(LookPathDefault("true", "/bin/foo"), Equals, "/bin/true")
    99  }
   100  
   101  func (s *StatTestSuite) TestLookPathDefaultReturnsDefaultWhenNotFound(c *C) {
   102  	lookPath = func(name string) (string, error) { return "", fmt.Errorf("Not found") }
   103  	c.Assert(LookPathDefault("bar", "/bin/bla"), Equals, "/bin/bla")
   104  }
   105  
   106  func makeTestPath(c *C, path string, mode os.FileMode) string {
   107  	return makeTestPathInDir(c, c.MkDir(), path, mode)
   108  }
   109  
   110  func makeTestPathInDir(c *C, dir, path string, mode os.FileMode) string {
   111  	mkdir := strings.HasSuffix(path, "/")
   112  	path = filepath.Join(dir, path)
   113  
   114  	if mkdir {
   115  		// request for directory
   116  		c.Assert(os.MkdirAll(path, mode), IsNil)
   117  	} else {
   118  		// request for a file
   119  		c.Assert(os.MkdirAll(filepath.Dir(path), 0755), IsNil)
   120  		c.Assert(ioutil.WriteFile(path, nil, mode), IsNil)
   121  	}
   122  
   123  	return path
   124  }
   125  
   126  func (s *StatTestSuite) TestIsWritableDir(c *C) {
   127  	for _, t := range []struct {
   128  		path       string
   129  		mode       os.FileMode
   130  		isWritable bool
   131  	}{
   132  		{"dir/", 0755, true},
   133  		{"dir/", 0555, false},
   134  		{"dir/", 0750, true},
   135  		{"dir/", 0550, false},
   136  		{"dir/", 0700, true},
   137  		{"dir/", 0500, false},
   138  
   139  		{"file", 0644, true},
   140  		{"file", 0444, false},
   141  		{"file", 0640, true},
   142  		{"file", 0440, false},
   143  		{"file", 0600, true},
   144  		{"file", 0400, false},
   145  	} {
   146  		writable := IsWritable(makeTestPath(c, t.path, t.mode))
   147  		c.Check(writable, Equals, t.isWritable, Commentf("incorrect result for %q (%s), got %v, expected %v", t.path, t.mode, writable, t.isWritable))
   148  	}
   149  }
   150  
   151  func (s *StatTestSuite) TestIsDirNotExist(c *C) {
   152  	for _, e := range []error{
   153  		os.ErrNotExist,
   154  		syscall.ENOENT,
   155  		syscall.ENOTDIR,
   156  		&os.PathError{Err: syscall.ENOENT},
   157  		&os.PathError{Err: syscall.ENOTDIR},
   158  		&os.LinkError{Err: syscall.ENOENT},
   159  		&os.LinkError{Err: syscall.ENOTDIR},
   160  		&os.SyscallError{Err: syscall.ENOENT},
   161  		&os.SyscallError{Err: syscall.ENOTDIR},
   162  	} {
   163  		c.Check(IsDirNotExist(e), Equals, true, Commentf("%#v (%v)", e, e))
   164  	}
   165  
   166  	for _, e := range []error{
   167  		nil,
   168  		fmt.Errorf("hello"),
   169  	} {
   170  		c.Check(IsDirNotExist(e), Equals, false)
   171  	}
   172  }
   173  
   174  func (s *StatTestSuite) TestDirExists(c *C) {
   175  	for _, t := range []struct {
   176  		make   string
   177  		path   string
   178  		exists bool
   179  		isDir  bool
   180  	}{
   181  		{"", "foo", false, false},
   182  		{"", "foo/bar", false, false},
   183  		{"foo", "foo/bar", false, false},
   184  		{"foo", "foo", true, false},
   185  		{"foo/", "foo", true, true},
   186  	} {
   187  		base := c.MkDir()
   188  		comm := Commentf("path:%q make:%q", t.path, t.make)
   189  		if t.make != "" {
   190  			makeTestPathInDir(c, base, t.make, 0755)
   191  		}
   192  		exists, isDir, err := DirExists(filepath.Join(base, t.path))
   193  		c.Check(exists, Equals, t.exists, comm)
   194  		c.Check(isDir, Equals, t.isDir, comm)
   195  		c.Check(err, IsNil, comm)
   196  	}
   197  
   198  	p := makeTestPath(c, "foo/bar", 0)
   199  	c.Assert(os.Chmod(filepath.Dir(p), 0), IsNil)
   200  	defer os.Chmod(filepath.Dir(p), 0755)
   201  	exists, isDir, err := DirExists(p)
   202  	c.Check(exists, Equals, false)
   203  	c.Check(isDir, Equals, false)
   204  	c.Check(err, NotNil)
   205  }
   206  
   207  func (s *StatTestSuite) TestIsExecutable(c *C) {
   208  	c.Check(IsExecutable("non-existent"), Equals, false)
   209  	c.Check(IsExecutable("."), Equals, false)
   210  	dir := c.MkDir()
   211  	c.Check(IsExecutable(dir), Equals, false)
   212  
   213  	for _, tc := range []struct {
   214  		mode os.FileMode
   215  		is   bool
   216  	}{
   217  		{0644, false},
   218  		{0444, false},
   219  		{0444, false},
   220  		{0000, false},
   221  		{0100, true},
   222  		{0010, true},
   223  		{0001, true},
   224  		{0755, true},
   225  	} {
   226  		c.Logf("tc: %v %v", tc.mode, tc.is)
   227  		p := filepath.Join(dir, "foo")
   228  		err := os.Remove(p)
   229  		c.Check(err == nil || os.IsNotExist(err), Equals, true)
   230  
   231  		err = ioutil.WriteFile(p, []byte(""), tc.mode)
   232  		c.Assert(err, IsNil)
   233  		c.Check(IsExecutable(p), Equals, tc.is)
   234  	}
   235  }