mirror of
https://github.com/Luzifer/ansible-role-version.git
synced 2024-12-25 03:51:21 +00:00
349 lines
9.7 KiB
Go
349 lines
9.7 KiB
Go
|
package filemode
|
||
|
|
||
|
import (
|
||
|
"os"
|
||
|
"testing"
|
||
|
|
||
|
. "gopkg.in/check.v1"
|
||
|
)
|
||
|
|
||
|
func Test(t *testing.T) { TestingT(t) }
|
||
|
|
||
|
type ModeSuite struct{}
|
||
|
|
||
|
var _ = Suite(&ModeSuite{})
|
||
|
|
||
|
func (s *ModeSuite) TestNew(c *C) {
|
||
|
for _, test := range [...]struct {
|
||
|
input string
|
||
|
expected FileMode
|
||
|
}{
|
||
|
// these are the ones used in the packfile codification
|
||
|
// of the tree entries
|
||
|
{input: "40000", expected: Dir},
|
||
|
{input: "100644", expected: Regular},
|
||
|
{input: "100664", expected: Deprecated},
|
||
|
{input: "100755", expected: Executable},
|
||
|
{input: "120000", expected: Symlink},
|
||
|
{input: "160000", expected: Submodule},
|
||
|
// these are are not used by standard git to codify modes in
|
||
|
// packfiles, but they often appear when parsing some git
|
||
|
// outputs ("git diff-tree", for instance).
|
||
|
{input: "000000", expected: Empty},
|
||
|
{input: "040000", expected: Dir},
|
||
|
// these are valid inputs, but probably means there is a bug
|
||
|
// somewhere.
|
||
|
{input: "0", expected: Empty},
|
||
|
{input: "42", expected: FileMode(042)},
|
||
|
{input: "00000000000100644", expected: Regular},
|
||
|
} {
|
||
|
comment := Commentf("input = %q", test.input)
|
||
|
obtained, err := New(test.input)
|
||
|
c.Assert(obtained, Equals, test.expected, comment)
|
||
|
c.Assert(err, IsNil, comment)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestNewErrors(c *C) {
|
||
|
for _, input := range [...]string{
|
||
|
"0x81a4", // Regular in hex
|
||
|
"-rw-r--r--", // Regular in default UNIX representation
|
||
|
"",
|
||
|
"-42",
|
||
|
"9", // this is no octal
|
||
|
"09", // looks like octal, but it is not
|
||
|
"mode",
|
||
|
"-100644",
|
||
|
"+100644",
|
||
|
} {
|
||
|
comment := Commentf("input = %q", input)
|
||
|
obtained, err := New(input)
|
||
|
c.Assert(obtained, Equals, Empty, comment)
|
||
|
c.Assert(err, Not(IsNil), comment)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// fixtures for testing NewModeFromOSFileMode
|
||
|
type fixture struct {
|
||
|
input os.FileMode
|
||
|
expected FileMode
|
||
|
err string // error regexp, empty string for nil error
|
||
|
}
|
||
|
|
||
|
func (f fixture) test(c *C) {
|
||
|
obtained, err := NewFromOSFileMode(f.input)
|
||
|
comment := Commentf("input = %s (%07o)", f.input, uint32(f.input))
|
||
|
c.Assert(obtained, Equals, f.expected, comment)
|
||
|
if f.err != "" {
|
||
|
c.Assert(err, ErrorMatches, f.err, comment)
|
||
|
} else {
|
||
|
c.Assert(err, IsNil, comment)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestNewFromOsFileModeSimplePerms(c *C) {
|
||
|
for _, f := range [...]fixture{
|
||
|
{os.FileMode(0755) | os.ModeDir, Dir, ""}, // drwxr-xr-x
|
||
|
{os.FileMode(0700) | os.ModeDir, Dir, ""}, // drwx------
|
||
|
{os.FileMode(0500) | os.ModeDir, Dir, ""}, // dr-x------
|
||
|
{os.FileMode(0644), Regular, ""}, // -rw-r--r--
|
||
|
{os.FileMode(0660), Regular, ""}, // -rw-rw----
|
||
|
{os.FileMode(0640), Regular, ""}, // -rw-r-----
|
||
|
{os.FileMode(0600), Regular, ""}, // -rw-------
|
||
|
{os.FileMode(0400), Regular, ""}, // -r--------
|
||
|
{os.FileMode(0000), Regular, ""}, // ----------
|
||
|
{os.FileMode(0755), Executable, ""}, // -rwxr-xr-x
|
||
|
{os.FileMode(0700), Executable, ""}, // -rwx------
|
||
|
{os.FileMode(0500), Executable, ""}, // -r-x------
|
||
|
{os.FileMode(0744), Executable, ""}, // -rwxr--r--
|
||
|
{os.FileMode(0540), Executable, ""}, // -r-xr-----
|
||
|
{os.FileMode(0550), Executable, ""}, // -r-xr-x---
|
||
|
{os.FileMode(0777) | os.ModeSymlink, Symlink, ""}, // Lrwxrwxrwx
|
||
|
} {
|
||
|
f.test(c)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestNewFromOsFileModeAppend(c *C) {
|
||
|
// append files are just regular files
|
||
|
fixture{
|
||
|
input: os.FileMode(0644) | os.ModeAppend, // arw-r--r--
|
||
|
expected: Regular, err: "",
|
||
|
}.test(c)
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestNewFromOsFileModeExclusive(c *C) {
|
||
|
// exclusive files are just regular or executable files
|
||
|
fixture{
|
||
|
input: os.FileMode(0644) | os.ModeExclusive, // lrw-r--r--
|
||
|
expected: Regular, err: "",
|
||
|
}.test(c)
|
||
|
|
||
|
fixture{
|
||
|
input: os.FileMode(0755) | os.ModeExclusive, // lrwxr-xr-x
|
||
|
expected: Executable, err: "",
|
||
|
}.test(c)
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestNewFromOsFileModeTemporary(c *C) {
|
||
|
// temporaty files are ignored
|
||
|
fixture{
|
||
|
input: os.FileMode(0644) | os.ModeTemporary, // Trw-r--r--
|
||
|
expected: Empty, err: "no equivalent.*",
|
||
|
}.test(c)
|
||
|
|
||
|
fixture{
|
||
|
input: os.FileMode(0755) | os.ModeTemporary, // Trwxr-xr-x
|
||
|
expected: Empty, err: "no equivalent.*",
|
||
|
}.test(c)
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestNewFromOsFileModeDevice(c *C) {
|
||
|
// device files has no git equivalent
|
||
|
fixture{
|
||
|
input: os.FileMode(0644) | os.ModeDevice, // Drw-r--r--
|
||
|
expected: Empty, err: "no equivalent.*",
|
||
|
}.test(c)
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestNewFromOsFileNamedPipe(c *C) {
|
||
|
// named pipes files has not git equivalent
|
||
|
fixture{
|
||
|
input: os.FileMode(0644) | os.ModeNamedPipe, // prw-r--r--
|
||
|
expected: Empty, err: "no equivalent.*",
|
||
|
}.test(c)
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestNewFromOsFileModeSocket(c *C) {
|
||
|
// sockets has no git equivalent
|
||
|
fixture{
|
||
|
input: os.FileMode(0644) | os.ModeSocket, // Srw-r--r--
|
||
|
expected: Empty, err: "no equivalent.*",
|
||
|
}.test(c)
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestNewFromOsFileModeSetuid(c *C) {
|
||
|
// Setuid are just executables
|
||
|
fixture{
|
||
|
input: os.FileMode(0755) | os.ModeSetuid, // urwxr-xr-x
|
||
|
expected: Executable, err: "",
|
||
|
}.test(c)
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestNewFromOsFileModeSetgid(c *C) {
|
||
|
// Setguid are regular or executables, depending on the owner perms
|
||
|
fixture{
|
||
|
input: os.FileMode(0644) | os.ModeSetgid, // grw-r--r--
|
||
|
expected: Regular, err: "",
|
||
|
}.test(c)
|
||
|
|
||
|
fixture{
|
||
|
input: os.FileMode(0755) | os.ModeSetgid, // grwxr-xr-x
|
||
|
expected: Executable, err: "",
|
||
|
}.test(c)
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestNewFromOsFileModeCharDevice(c *C) {
|
||
|
// char devices has no git equivalent
|
||
|
fixture{
|
||
|
input: os.FileMode(0644) | os.ModeCharDevice, // crw-r--r--
|
||
|
expected: Empty, err: "no equivalent.*",
|
||
|
}.test(c)
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestNewFromOsFileModeSticky(c *C) {
|
||
|
// dirs with the sticky bit are just dirs
|
||
|
fixture{
|
||
|
input: os.FileMode(0755) | os.ModeDir | os.ModeSticky, // dtrwxr-xr-x
|
||
|
expected: Dir, err: "",
|
||
|
}.test(c)
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestByte(c *C) {
|
||
|
for _, test := range [...]struct {
|
||
|
input FileMode
|
||
|
expected []byte
|
||
|
}{
|
||
|
{FileMode(0), []byte{0x00, 0x00, 0x00, 0x00}},
|
||
|
{FileMode(1), []byte{0x01, 0x00, 0x00, 0x00}},
|
||
|
{FileMode(15), []byte{0x0f, 0x00, 0x00, 0x00}},
|
||
|
{FileMode(16), []byte{0x10, 0x00, 0x00, 0x00}},
|
||
|
{FileMode(255), []byte{0xff, 0x00, 0x00, 0x00}},
|
||
|
{FileMode(256), []byte{0x00, 0x01, 0x00, 0x00}},
|
||
|
{Empty, []byte{0x00, 0x00, 0x00, 0x00}},
|
||
|
{Dir, []byte{0x00, 0x40, 0x00, 0x00}},
|
||
|
{Regular, []byte{0xa4, 0x81, 0x00, 0x00}},
|
||
|
{Deprecated, []byte{0xb4, 0x81, 0x00, 0x00}},
|
||
|
{Executable, []byte{0xed, 0x81, 0x00, 0x00}},
|
||
|
{Symlink, []byte{0x00, 0xa0, 0x00, 0x00}},
|
||
|
{Submodule, []byte{0x00, 0xe0, 0x00, 0x00}},
|
||
|
} {
|
||
|
c.Assert(test.input.Bytes(), DeepEquals, test.expected,
|
||
|
Commentf("input = %s", test.input))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestIsMalformed(c *C) {
|
||
|
for _, test := range [...]struct {
|
||
|
mode FileMode
|
||
|
expected bool
|
||
|
}{
|
||
|
{Empty, true},
|
||
|
{Dir, false},
|
||
|
{Regular, false},
|
||
|
{Deprecated, false},
|
||
|
{Executable, false},
|
||
|
{Symlink, false},
|
||
|
{Submodule, false},
|
||
|
{FileMode(01), true},
|
||
|
{FileMode(010), true},
|
||
|
{FileMode(0100), true},
|
||
|
{FileMode(01000), true},
|
||
|
{FileMode(010000), true},
|
||
|
{FileMode(0100000), true},
|
||
|
} {
|
||
|
c.Assert(test.mode.IsMalformed(), Equals, test.expected)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestString(c *C) {
|
||
|
for _, test := range [...]struct {
|
||
|
mode FileMode
|
||
|
expected string
|
||
|
}{
|
||
|
{Empty, "0000000"},
|
||
|
{Dir, "0040000"},
|
||
|
{Regular, "0100644"},
|
||
|
{Deprecated, "0100664"},
|
||
|
{Executable, "0100755"},
|
||
|
{Symlink, "0120000"},
|
||
|
{Submodule, "0160000"},
|
||
|
{FileMode(01), "0000001"},
|
||
|
{FileMode(010), "0000010"},
|
||
|
{FileMode(0100), "0000100"},
|
||
|
{FileMode(01000), "0001000"},
|
||
|
{FileMode(010000), "0010000"},
|
||
|
{FileMode(0100000), "0100000"},
|
||
|
} {
|
||
|
c.Assert(test.mode.String(), Equals, test.expected)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestIsRegular(c *C) {
|
||
|
for _, test := range [...]struct {
|
||
|
mode FileMode
|
||
|
expected bool
|
||
|
}{
|
||
|
{Empty, false},
|
||
|
{Dir, false},
|
||
|
{Regular, true},
|
||
|
{Deprecated, true},
|
||
|
{Executable, false},
|
||
|
{Symlink, false},
|
||
|
{Submodule, false},
|
||
|
{FileMode(01), false},
|
||
|
{FileMode(010), false},
|
||
|
{FileMode(0100), false},
|
||
|
{FileMode(01000), false},
|
||
|
{FileMode(010000), false},
|
||
|
{FileMode(0100000), false},
|
||
|
} {
|
||
|
c.Assert(test.mode.IsRegular(), Equals, test.expected)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestIsFile(c *C) {
|
||
|
for _, test := range [...]struct {
|
||
|
mode FileMode
|
||
|
expected bool
|
||
|
}{
|
||
|
{Empty, false},
|
||
|
{Dir, false},
|
||
|
{Regular, true},
|
||
|
{Deprecated, true},
|
||
|
{Executable, true},
|
||
|
{Symlink, true},
|
||
|
{Submodule, false},
|
||
|
{FileMode(01), false},
|
||
|
{FileMode(010), false},
|
||
|
{FileMode(0100), false},
|
||
|
{FileMode(01000), false},
|
||
|
{FileMode(010000), false},
|
||
|
{FileMode(0100000), false},
|
||
|
} {
|
||
|
c.Assert(test.mode.IsFile(), Equals, test.expected)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *ModeSuite) TestToOSFileMode(c *C) {
|
||
|
for _, test := range [...]struct {
|
||
|
input FileMode
|
||
|
expected os.FileMode
|
||
|
errRegExp string // empty string for nil error
|
||
|
}{
|
||
|
{Empty, os.FileMode(0), "malformed.*"},
|
||
|
{Dir, os.ModePerm | os.ModeDir, ""},
|
||
|
{Regular, os.FileMode(0644), ""},
|
||
|
{Deprecated, os.FileMode(0644), ""},
|
||
|
{Executable, os.FileMode(0755), ""},
|
||
|
{Symlink, os.ModePerm | os.ModeSymlink, ""},
|
||
|
{Submodule, os.ModePerm | os.ModeDir, ""},
|
||
|
{FileMode(01), os.FileMode(0), "malformed.*"},
|
||
|
{FileMode(010), os.FileMode(0), "malformed.*"},
|
||
|
{FileMode(0100), os.FileMode(0), "malformed.*"},
|
||
|
{FileMode(01000), os.FileMode(0), "malformed.*"},
|
||
|
{FileMode(010000), os.FileMode(0), "malformed.*"},
|
||
|
{FileMode(0100000), os.FileMode(0), "malformed.*"},
|
||
|
} {
|
||
|
obtained, err := test.input.ToOSFileMode()
|
||
|
comment := Commentf("input = %s", test.input)
|
||
|
if test.errRegExp != "" {
|
||
|
c.Assert(obtained, Equals, os.FileMode(0), comment)
|
||
|
c.Assert(err, ErrorMatches, test.errRegExp, comment)
|
||
|
} else {
|
||
|
c.Assert(obtained, Equals, test.expected, comment)
|
||
|
c.Assert(err, IsNil, comment)
|
||
|
}
|
||
|
}
|
||
|
}
|