Skip to content

Commit

Permalink
restructure test to check for errors
Browse files Browse the repository at this point in the history
Signed-off-by: leongross <[email protected]>
  • Loading branch information
leongross committed Jun 14, 2024
1 parent bebe7e5 commit 38c58f8
Showing 1 changed file with 20 additions and 59 deletions.
79 changes: 20 additions & 59 deletions src/os/os_chmod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,75 +33,36 @@ func TestChmod(t *testing.T) {

}

func TestChown(t *testing.T) {
var (
TEST_UID_1 = 1001
TEST_GID_1 = 127
TEST_UID_2 = 0
TEST_GID_2 = 0
ERR_PERM_DENIED = "permission denied"
ERR_OP_NOT_PERMITTED = "operation not permitted"
)

// Since testing syscalls requires a static, predictable environment that has to be controlled
// by the CI, we don't test for success but for failures and verify that the error messages are as expected.
// EACCES is returned when the user does not have the required permissions to change the ownership of the file
// ENOENT is returned when the file does not exist
// ENOTDIR is returned when the file is not a directory
func TestChownErr(t *testing.T) {
if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
t.Skip()
t.Skip("skipping on " + runtime.GOOS)
}

var (
TEST_UID_ROOT = 0
TEST_GID_ROOT = 0
)

f := newFile("TestChown", t)
defer Remove(f.Name())
defer f.Close()

// User with CI permissions run chown on owned file
// This test does not change the initial permissions of the file
// It only checks if the chown operation was successful and consistent
if err := Chown(f.Name(), TEST_UID_1, TEST_GID_1); err != nil {
if err.Error() != ERR_OP_NOT_PERMITTED {
t.Fatalf("chown(%s, uid=%v, gid=%v): got %v, want != nil", f.Name(), TEST_UID_1, TEST_GID_1, err)
// EACCES
if err := Chown(f.Name(), TEST_UID_ROOT, TEST_GID_ROOT); err != nil {
if err.(syscall.Errno) != syscall.EPERM {
t.Fatalf("chown(%s, uid=%v, gid=%v): got '%v', want %v", f.Name(), TEST_UID_ROOT, TEST_GID_ROOT, err, syscall.EPERM)
}
}
fi, err := Stat(f.Name())
if err != nil {
t.Fatalf("stat %s: got %v, want nil", f.Name(), err)
}

if fi.Sys() == nil {
t.Fatalf("stat %s: fi.Sys(): got nil", f.Name())
}

s, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
t.Fatalf("stat %s: fi.Sys(): is not *syscall.Stat_t", f.Name())
}

uid, gid := s.Uid, s.Gid
if uid != uint32(TEST_UID_1) || gid != uint32(TEST_GID_1) {
t.Fatalf("chown(%s, %d, %d): want (%d,%d), got (%d, %d)", f.Name(), TEST_UID_1, TEST_GID_1, TEST_UID_1, TEST_GID_1, uid, gid)
}

// Root permission denied
if err = Chown(f.Name(), TEST_UID_2, TEST_GID_2); err.Error() != ERR_PERM_DENIED {
t.Fatalf("chown(%s, uid=%v, gid=%v): got %v, want != nil", f.Name(), TEST_UID_2, TEST_GID_2, err)
}

fi, err = Stat(f.Name())
if err != nil {
t.Fatalf("stat %s: got %v, want nil", f.Name(), err)
}

if fi.Sys() == nil {
t.Fatalf("stat %s: fi.Sys(): got nil", f.Name())
}

s, ok = fi.Sys().(*syscall.Stat_t)
if !ok {
t.Fatalf("stat %s: fi.Sys(): is not *syscall.Stat_t", f.Name())
}

uid, gid = s.Uid, s.Gid
if uid != uint32(TEST_UID_2) || gid != uint32(TEST_GID_2) {
// Chown will fail due to permissions denied, so the UID and GID should stay the same
if uid != uint32(TEST_UID_1) && gid != uint32(TEST_GID_1) {
t.Fatalf("chown(%s, %d, %d): want (%d,%d), got (%d, %d)", f.Name(), TEST_UID_2, TEST_GID_2, TEST_UID_2, TEST_GID_2, uid, gid)
// ENOENT
if err := Chown("invalid", Geteuid(), Getgid()); err != nil {
if err.(syscall.Errno) != syscall.ENOENT {
t.Fatalf("chown(%s, uid=%v, gid=%v): got '%v', want %v", f.Name(), Geteuid(), Getegid(), err, syscall.ENOENT)
}
}
}

0 comments on commit 38c58f8

Please sign in to comment.