github.com/Aayushi-Bansal/sys@v0.0.0-20180118120756-90d962a959d8/unix/syscall_linux_test.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build linux 6 7 package unix_test 8 9 import ( 10 "io/ioutil" 11 "os" 12 "runtime" 13 "testing" 14 "time" 15 16 "golang.org/x/sys/unix" 17 ) 18 19 func TestFchmodat(t *testing.T) { 20 defer chtmpdir(t)() 21 22 touch(t, "file1") 23 err := os.Symlink("file1", "symlink1") 24 if err != nil { 25 t.Fatal(err) 26 } 27 28 err = unix.Fchmodat(unix.AT_FDCWD, "symlink1", 0444, 0) 29 if err != nil { 30 t.Fatalf("Fchmodat: unexpected error: %v", err) 31 } 32 33 fi, err := os.Stat("file1") 34 if err != nil { 35 t.Fatal(err) 36 } 37 38 if fi.Mode() != 0444 { 39 t.Errorf("Fchmodat: failed to change mode: expected %v, got %v", 0444, fi.Mode()) 40 } 41 42 err = unix.Fchmodat(unix.AT_FDCWD, "symlink1", 0444, unix.AT_SYMLINK_NOFOLLOW) 43 if err != unix.EOPNOTSUPP { 44 t.Fatalf("Fchmodat: unexpected error: %v, expected EOPNOTSUPP", err) 45 } 46 } 47 48 func TestIoctlGetInt(t *testing.T) { 49 f, err := os.Open("/dev/random") 50 if err != nil { 51 t.Fatalf("failed to open device: %v", err) 52 } 53 defer f.Close() 54 55 v, err := unix.IoctlGetInt(int(f.Fd()), unix.RNDGETENTCNT) 56 if err != nil { 57 t.Fatalf("failed to perform ioctl: %v", err) 58 } 59 60 t.Logf("%d bits of entropy available", v) 61 } 62 63 func TestPpoll(t *testing.T) { 64 f, cleanup := mktmpfifo(t) 65 defer cleanup() 66 67 const timeout = 100 * time.Millisecond 68 69 ok := make(chan bool, 1) 70 go func() { 71 select { 72 case <-time.After(10 * timeout): 73 t.Errorf("Ppoll: failed to timeout after %d", 10*timeout) 74 case <-ok: 75 } 76 }() 77 78 fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}} 79 timeoutTs := unix.NsecToTimespec(int64(timeout)) 80 n, err := unix.Ppoll(fds, &timeoutTs, nil) 81 ok <- true 82 if err != nil { 83 t.Errorf("Ppoll: unexpected error: %v", err) 84 return 85 } 86 if n != 0 { 87 t.Errorf("Ppoll: wrong number of events: got %v, expected %v", n, 0) 88 return 89 } 90 } 91 92 func TestTime(t *testing.T) { 93 var ut unix.Time_t 94 ut2, err := unix.Time(&ut) 95 if err != nil { 96 t.Fatalf("Time: %v", err) 97 } 98 if ut != ut2 { 99 t.Errorf("Time: return value %v should be equal to argument %v", ut2, ut) 100 } 101 102 var now time.Time 103 104 for i := 0; i < 10; i++ { 105 ut, err = unix.Time(nil) 106 if err != nil { 107 t.Fatalf("Time: %v", err) 108 } 109 110 now = time.Now() 111 112 if int64(ut) == now.Unix() { 113 return 114 } 115 } 116 117 t.Errorf("Time: return value %v should be nearly equal to time.Now().Unix() %v", ut, now.Unix()) 118 } 119 120 func TestUtime(t *testing.T) { 121 defer chtmpdir(t)() 122 123 touch(t, "file1") 124 125 buf := &unix.Utimbuf{ 126 Modtime: 12345, 127 } 128 129 err := unix.Utime("file1", buf) 130 if err != nil { 131 t.Fatalf("Utime: %v", err) 132 } 133 134 fi, err := os.Stat("file1") 135 if err != nil { 136 t.Fatal(err) 137 } 138 139 if fi.ModTime().Unix() != 12345 { 140 t.Errorf("Utime: failed to change modtime: expected %v, got %v", 12345, fi.ModTime().Unix()) 141 } 142 } 143 144 func TestUtimesNanoAt(t *testing.T) { 145 defer chtmpdir(t)() 146 147 symlink := "symlink1" 148 os.Remove(symlink) 149 err := os.Symlink("nonexisting", symlink) 150 if err != nil { 151 t.Fatal(err) 152 } 153 154 ts := []unix.Timespec{ 155 {Sec: 1111, Nsec: 2222}, 156 {Sec: 3333, Nsec: 4444}, 157 } 158 err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW) 159 if err != nil { 160 t.Fatalf("UtimesNanoAt: %v", err) 161 } 162 163 var st unix.Stat_t 164 err = unix.Lstat(symlink, &st) 165 if err != nil { 166 t.Fatalf("Lstat: %v", err) 167 } 168 if st.Atim != ts[0] { 169 t.Errorf("UtimesNanoAt: wrong atime: %v", st.Atim) 170 } 171 if st.Mtim != ts[1] { 172 t.Errorf("UtimesNanoAt: wrong mtime: %v", st.Mtim) 173 } 174 } 175 176 func TestGetrlimit(t *testing.T) { 177 var rlim unix.Rlimit 178 err := unix.Getrlimit(unix.RLIMIT_AS, &rlim) 179 if err != nil { 180 t.Fatalf("Getrlimit: %v", err) 181 } 182 } 183 184 func TestSelect(t *testing.T) { 185 _, err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0}) 186 if err != nil { 187 t.Fatalf("Select: %v", err) 188 } 189 190 dur := 150 * time.Millisecond 191 tv := unix.NsecToTimeval(int64(dur)) 192 start := time.Now() 193 _, err = unix.Select(0, nil, nil, nil, &tv) 194 took := time.Since(start) 195 if err != nil { 196 t.Fatalf("Select: %v", err) 197 } 198 199 if took < dur { 200 t.Errorf("Select: timeout should have been at least %v, got %v", dur, took) 201 } 202 } 203 204 func TestPselect(t *testing.T) { 205 _, err := unix.Pselect(0, nil, nil, nil, &unix.Timespec{Sec: 0, Nsec: 0}, nil) 206 if err != nil { 207 t.Fatalf("Pselect: %v", err) 208 } 209 210 dur := 2500 * time.Microsecond 211 ts := unix.NsecToTimespec(int64(dur)) 212 start := time.Now() 213 _, err = unix.Pselect(0, nil, nil, nil, &ts, nil) 214 took := time.Since(start) 215 if err != nil { 216 t.Fatalf("Pselect: %v", err) 217 } 218 219 if took < dur { 220 t.Errorf("Pselect: timeout should have been at least %v, got %v", dur, took) 221 } 222 } 223 224 func TestFstatat(t *testing.T) { 225 defer chtmpdir(t)() 226 227 touch(t, "file1") 228 229 var st1 unix.Stat_t 230 err := unix.Stat("file1", &st1) 231 if err != nil { 232 t.Fatalf("Stat: %v", err) 233 } 234 235 var st2 unix.Stat_t 236 err = unix.Fstatat(unix.AT_FDCWD, "file1", &st2, 0) 237 if err != nil { 238 t.Fatalf("Fstatat: %v", err) 239 } 240 241 if st1 != st2 { 242 t.Errorf("Fstatat: returned stat does not match Stat") 243 } 244 245 err = os.Symlink("file1", "symlink1") 246 if err != nil { 247 t.Fatal(err) 248 } 249 250 err = unix.Lstat("symlink1", &st1) 251 if err != nil { 252 t.Fatalf("Lstat: %v", err) 253 } 254 255 err = unix.Fstatat(unix.AT_FDCWD, "symlink1", &st2, unix.AT_SYMLINK_NOFOLLOW) 256 if err != nil { 257 t.Fatalf("Fstatat: %v", err) 258 } 259 260 if st1 != st2 { 261 t.Errorf("Fstatat: returned stat does not match Lstat") 262 } 263 } 264 265 func TestSchedSetaffinity(t *testing.T) { 266 runtime.LockOSThread() 267 defer runtime.UnlockOSThread() 268 269 var oldMask unix.CPUSet 270 err := unix.SchedGetaffinity(0, &oldMask) 271 if err != nil { 272 t.Fatalf("SchedGetaffinity: %v", err) 273 } 274 275 var newMask unix.CPUSet 276 newMask.Zero() 277 if newMask.Count() != 0 { 278 t.Errorf("CpuZero: didn't zero CPU set: %v", newMask) 279 } 280 cpu := 1 281 newMask.Set(cpu) 282 if newMask.Count() != 1 || !newMask.IsSet(cpu) { 283 t.Errorf("CpuSet: didn't set CPU %d in set: %v", cpu, newMask) 284 } 285 cpu = 5 286 newMask.Set(cpu) 287 if newMask.Count() != 2 || !newMask.IsSet(cpu) { 288 t.Errorf("CpuSet: didn't set CPU %d in set: %v", cpu, newMask) 289 } 290 newMask.Clear(cpu) 291 if newMask.Count() != 1 || newMask.IsSet(cpu) { 292 t.Errorf("CpuClr: didn't clear CPU %d in set: %v", cpu, newMask) 293 } 294 295 err = unix.SchedSetaffinity(0, &newMask) 296 if err != nil { 297 t.Fatalf("SchedSetaffinity: %v", err) 298 } 299 300 var gotMask unix.CPUSet 301 err = unix.SchedGetaffinity(0, &gotMask) 302 if err != nil { 303 t.Fatalf("SchedGetaffinity: %v", err) 304 } 305 306 if gotMask != newMask { 307 t.Errorf("SchedSetaffinity: returned affinity mask does not match set affinity mask") 308 } 309 310 // Restore old mask so it doesn't affect successive tests 311 err = unix.SchedSetaffinity(0, &oldMask) 312 if err != nil { 313 t.Fatalf("SchedSetaffinity: %v", err) 314 } 315 } 316 317 func TestStatx(t *testing.T) { 318 var stx unix.Statx_t 319 err := unix.Statx(unix.AT_FDCWD, ".", 0, 0, &stx) 320 if err == unix.ENOSYS { 321 t.Skip("statx syscall is not available, skipping test") 322 } else if err != nil { 323 t.Fatalf("Statx: %v", err) 324 } 325 326 defer chtmpdir(t)() 327 touch(t, "file1") 328 329 var st unix.Stat_t 330 err = unix.Stat("file1", &st) 331 if err != nil { 332 t.Fatalf("Stat: %v", err) 333 } 334 335 flags := unix.AT_STATX_SYNC_AS_STAT 336 err = unix.Statx(unix.AT_FDCWD, "file1", flags, unix.STATX_ALL, &stx) 337 if err != nil { 338 t.Fatalf("Statx: %v", err) 339 } 340 341 if uint32(stx.Mode) != st.Mode { 342 t.Errorf("Statx: returned stat mode does not match Stat") 343 } 344 345 atime := unix.StatxTimestamp{Sec: int64(st.Atim.Sec), Nsec: uint32(st.Atim.Nsec)} 346 ctime := unix.StatxTimestamp{Sec: int64(st.Ctim.Sec), Nsec: uint32(st.Ctim.Nsec)} 347 mtime := unix.StatxTimestamp{Sec: int64(st.Mtim.Sec), Nsec: uint32(st.Mtim.Nsec)} 348 349 if stx.Atime != atime { 350 t.Errorf("Statx: returned stat atime does not match Stat") 351 } 352 if stx.Ctime != ctime { 353 t.Errorf("Statx: returned stat ctime does not match Stat") 354 } 355 if stx.Mtime != mtime { 356 t.Errorf("Statx: returned stat mtime does not match Stat") 357 } 358 359 err = os.Symlink("file1", "symlink1") 360 if err != nil { 361 t.Fatal(err) 362 } 363 364 err = unix.Lstat("symlink1", &st) 365 if err != nil { 366 t.Fatalf("Lstat: %v", err) 367 } 368 369 err = unix.Statx(unix.AT_FDCWD, "symlink1", flags, unix.STATX_BASIC_STATS, &stx) 370 if err != nil { 371 t.Fatalf("Statx: %v", err) 372 } 373 374 // follow symlink, expect a regulat file 375 if stx.Mode&unix.S_IFREG == 0 { 376 t.Errorf("Statx: didn't follow symlink") 377 } 378 379 err = unix.Statx(unix.AT_FDCWD, "symlink1", flags|unix.AT_SYMLINK_NOFOLLOW, unix.STATX_ALL, &stx) 380 if err != nil { 381 t.Fatalf("Statx: %v", err) 382 } 383 384 // follow symlink, expect a symlink 385 if stx.Mode&unix.S_IFLNK == 0 { 386 t.Errorf("Statx: unexpectedly followed symlink") 387 } 388 if uint32(stx.Mode) != st.Mode { 389 t.Errorf("Statx: returned stat mode does not match Lstat") 390 } 391 392 atime = unix.StatxTimestamp{Sec: int64(st.Atim.Sec), Nsec: uint32(st.Atim.Nsec)} 393 ctime = unix.StatxTimestamp{Sec: int64(st.Ctim.Sec), Nsec: uint32(st.Ctim.Nsec)} 394 mtime = unix.StatxTimestamp{Sec: int64(st.Mtim.Sec), Nsec: uint32(st.Mtim.Nsec)} 395 396 if stx.Atime != atime { 397 t.Errorf("Statx: returned stat atime does not match Lstat") 398 } 399 if stx.Ctime != ctime { 400 t.Errorf("Statx: returned stat ctime does not match Lstat") 401 } 402 if stx.Mtime != mtime { 403 t.Errorf("Statx: returned stat mtime does not match Lstat") 404 } 405 } 406 407 // utilities taken from os/os_test.go 408 409 func touch(t *testing.T, name string) { 410 f, err := os.Create(name) 411 if err != nil { 412 t.Fatal(err) 413 } 414 if err := f.Close(); err != nil { 415 t.Fatal(err) 416 } 417 } 418 419 // chtmpdir changes the working directory to a new temporary directory and 420 // provides a cleanup function. Used when PWD is read-only. 421 func chtmpdir(t *testing.T) func() { 422 oldwd, err := os.Getwd() 423 if err != nil { 424 t.Fatalf("chtmpdir: %v", err) 425 } 426 d, err := ioutil.TempDir("", "test") 427 if err != nil { 428 t.Fatalf("chtmpdir: %v", err) 429 } 430 if err := os.Chdir(d); err != nil { 431 t.Fatalf("chtmpdir: %v", err) 432 } 433 return func() { 434 if err := os.Chdir(oldwd); err != nil { 435 t.Fatalf("chtmpdir: %v", err) 436 } 437 os.RemoveAll(d) 438 } 439 }