@@ -34,56 +34,74 @@ func TestChmod(t *testing.T) {
34
34
}
35
35
36
36
func TestChown (t * testing.T ) {
37
+ var (
38
+ TEST_UID_1 = 1001
39
+ TEST_GID_1 = 127
40
+ TEST_UID_2 = 0
41
+ TEST_GID_2 = 0
42
+ ERR_PERM_DENIED = "permission denied"
43
+ ERR_OP_NOT_PERMITTED = "operation not permitted"
44
+ )
45
+
37
46
if runtime .GOOS == "windows" || runtime .GOOS == "plan9" {
38
47
t .Skip ()
39
48
}
40
49
41
- testCases := map [string ]struct {
42
- uid int
43
- gid int
44
- wantErr bool
45
- }{
46
- "root" : {
47
- uid : 0 ,
48
- gid : 0 ,
49
- wantErr : true ,
50
- },
51
- "user-" + runtime .GOOS : {
52
- uid : 1001 ,
53
- gid : 127 ,
54
- wantErr : false ,
55
- },
50
+ f := newFile ("TestChown" , t )
51
+ defer Remove (f .Name ())
52
+ defer f .Close ()
53
+
54
+ // User with CI permissions run chown on owned file
55
+ // This test does not change the initial permissions of the file
56
+ // It only checks if the chown operation was successful and consistent
57
+ if err := Chown (f .Name (), TEST_UID_1 , TEST_GID_1 ); err != nil {
58
+ if err .Error () != ERR_OP_NOT_PERMITTED {
59
+ t .Fatalf ("chown(%s, uid=%v, gid=%v): got %v, want != nil" , f .Name (), TEST_UID_1 , TEST_GID_1 , err )
60
+ }
61
+ }
62
+ fi , err := Stat (f .Name ())
63
+ if err != nil {
64
+ t .Fatalf ("stat %s: got %v, want nil" , f .Name (), err )
65
+ }
66
+
67
+ if fi .Sys () == nil {
68
+ t .Fatalf ("stat %s: fi.Sys(): got nil" , f .Name ())
69
+ }
70
+
71
+ s , ok := fi .Sys ().(* syscall.Stat_t )
72
+ if ! ok {
73
+ t .Fatalf ("stat %s: fi.Sys(): is not *syscall.Stat_t" , f .Name ())
74
+ }
75
+
76
+ uid , gid := s .Uid , s .Gid
77
+ if uid != uint32 (TEST_UID_1 ) || gid != uint32 (TEST_GID_1 ) {
78
+ 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 )
79
+ }
80
+
81
+ // Root permission denied
82
+ if err = Chown (f .Name (), TEST_UID_2 , TEST_GID_2 ); err .Error () != ERR_PERM_DENIED {
83
+ t .Fatalf ("chown(%s, uid=%v, gid=%v): got %v, want != nil" , f .Name (), TEST_UID_2 , TEST_GID_2 , err )
84
+ }
85
+
86
+ fi , err = Stat (f .Name ())
87
+ if err != nil {
88
+ t .Fatalf ("stat %s: got %v, want nil" , f .Name (), err )
89
+ }
90
+
91
+ if fi .Sys () == nil {
92
+ t .Fatalf ("stat %s: fi.Sys(): got nil" , f .Name ())
93
+ }
94
+
95
+ s , ok = fi .Sys ().(* syscall.Stat_t )
96
+ if ! ok {
97
+ t .Fatalf ("stat %s: fi.Sys(): is not *syscall.Stat_t" , f .Name ())
56
98
}
57
99
58
- for name , tc := range testCases {
59
- t .Run (name , func (t * testing.T ) {
60
- f := newFile ("TestChown" , t )
61
- defer Remove (f .Name ())
62
- defer f .Close ()
63
-
64
- err := Chown (f .Name (), tc .uid , tc .gid )
65
- if (tc .wantErr && err == nil ) || (! tc .wantErr && err != nil ) {
66
- t .Fatalf ("chown(%s, uid=%v, gid=%v): got %v, want error: %v" , f .Name (), tc .uid , tc .gid , err , tc .wantErr )
67
- }
68
-
69
- fi , err := Stat (f .Name ())
70
- if err != nil {
71
- t .Fatalf ("stat %s: got %v, want nil" , f .Name (), err )
72
- }
73
-
74
- if fi .Sys () == nil {
75
- t .Fatalf ("stat %s: fi.Sys(): got nil" , f .Name ())
76
- }
77
-
78
- s , ok := fi .Sys ().(* syscall.Stat_t )
79
- if ! ok {
80
- t .Fatalf ("stat %s: fi.Sys(): is not *syscall.Stat_t" , f .Name ())
81
- }
82
-
83
- uid , gid := s .Uid , s .Gid
84
- if uid != uint32 (tc .uid ) || gid != uint32 (tc .gid ) {
85
- t .Fatalf ("chown(%s, %d, %d): want (%d,%d), got (%d, %d)" , f .Name (), tc .uid , tc .gid , tc .uid , tc .gid , uid , gid )
86
- }
87
- })
100
+ uid , gid = s .Uid , s .Gid
101
+ if uid != uint32 (TEST_UID_2 ) || gid != uint32 (TEST_GID_2 ) {
102
+ // Chown will fail due to permissions denied, so the UID and GID should stay the same
103
+ if uid != uint32 (TEST_UID_1 ) && gid != uint32 (TEST_GID_1 ) {
104
+ 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 )
105
+ }
88
106
}
89
107
}
0 commit comments