diff options
Diffstat (limited to 'plumbing/filemode/filemode_test.go')
-rw-r--r-- | plumbing/filemode/filemode_test.go | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/plumbing/filemode/filemode_test.go b/plumbing/filemode/filemode_test.go new file mode 100644 index 0000000..299c96a --- /dev/null +++ b/plumbing/filemode/filemode_test.go @@ -0,0 +1,348 @@ +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) + } + } +} |