unix: test UtimesNanoAt on *bsd and solaris

Move TestUtimesNanoAt to syscall_unix_test.go. All BSDs and
solaris/illumos provide UtimesNanoAt. The implementations on linux and
darwin are already the same and the type conversions of Timespec members
on aix should no longer be necessary since CL 177838.

Change-Id: If0d03a92b3167da08191b6e98888eec92f27c3c9
Reviewed-on: https://go-review.googlesource.com/c/sys/+/213398
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/unix/syscall_aix_test.go b/unix/syscall_aix_test.go
index 789f394..bfa2782 100644
--- a/unix/syscall_aix_test.go
+++ b/unix/syscall_aix_test.go
@@ -82,47 +82,6 @@
 	}
 }
 
-func TestUtimesNanoAt(t *testing.T) {
-	defer chtmpdir(t)()
-
-	symlink := "symlink1"
-	defer os.Remove(symlink)
-	err := os.Symlink("nonexisting", symlink)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	ts := []unix.Timespec{
-		{Sec: 1111, Nsec: 2222},
-		{Sec: 3333, Nsec: 4444},
-	}
-	err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW)
-	if err != nil {
-		t.Fatalf("UtimesNanoAt: %v", err)
-	}
-
-	var st unix.Stat_t
-	err = unix.Lstat(symlink, &st)
-	if err != nil {
-		t.Fatalf("Lstat: %v", err)
-	}
-	if runtime.GOARCH == "ppc64" {
-		if int64(st.Atim.Sec) != int64(ts[0].Sec) || st.Atim.Nsec != ts[0].Nsec {
-			t.Errorf("UtimesNanoAt: wrong atime: %v", st.Atim)
-		}
-		if int64(st.Mtim.Sec) != int64(ts[1].Sec) || st.Mtim.Nsec != ts[1].Nsec {
-			t.Errorf("UtimesNanoAt: wrong mtime: %v", st.Mtim)
-		}
-	} else {
-		if int32(st.Atim.Sec) != int32(ts[0].Sec) || int32(st.Atim.Nsec) != int32(ts[0].Nsec) {
-			t.Errorf("UtimesNanoAt: wrong atime: %v", st.Atim)
-		}
-		if int32(st.Mtim.Sec) != int32(ts[1].Sec) || int32(st.Mtim.Nsec) != int32(ts[1].Nsec) {
-			t.Errorf("UtimesNanoAt: wrong mtime: %v", st.Mtim)
-		}
-	}
-}
-
 func TestPselect(t *testing.T) {
 	if runtime.GOARCH == "ppc64" {
 		t.Skip("pselect issue with structure timespec on AIX 7.2 tl0, skipping test")
diff --git a/unix/syscall_darwin_test.go b/unix/syscall_darwin_test.go
index f24273d..4a9b50c 100644
--- a/unix/syscall_darwin_test.go
+++ b/unix/syscall_darwin_test.go
@@ -5,7 +5,6 @@
 package unix_test
 
 import (
-	"os"
 	"testing"
 
 	"golang.org/x/sys/unix"
@@ -25,43 +24,6 @@
 	return result
 }
 
-func TestUtimesNanoAt(t *testing.T) {
-	defer chtmpdir(t)()
-
-	symlink := "symlink1"
-	os.Remove(symlink)
-	err := os.Symlink("nonexisting", symlink)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	ts := []unix.Timespec{
-		{Sec: 1111, Nsec: 2222},
-		{Sec: 3333, Nsec: 4444},
-	}
-	err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW)
-	if err != nil {
-		t.Fatalf("UtimesNanoAt: %v", err)
-	}
-
-	var st unix.Stat_t
-	err = unix.Lstat(symlink, &st)
-	if err != nil {
-		t.Fatalf("Lstat: %v", err)
-	}
-
-	// Only check Mtim, Atim might not be supported by the underlying filesystem
-	expected := ts[1]
-	if st.Mtim.Nsec == 0 {
-		// Some filesystems only support 1-second time stamp resolution
-		// and will always set Nsec to 0.
-		expected.Nsec = 0
-	}
-	if st.Mtim != expected {
-		t.Errorf("UtimesNanoAt: wrong mtime: got %v, expected %v", st.Mtim, expected)
-	}
-}
-
 func TestSysctlClockinfo(t *testing.T) {
 	ci, err := unix.SysctlClockinfo("kern.clockrate")
 	if err != nil {
diff --git a/unix/syscall_linux_test.go b/unix/syscall_linux_test.go
index abdfc52..e572376 100644
--- a/unix/syscall_linux_test.go
+++ b/unix/syscall_linux_test.go
@@ -158,43 +158,6 @@
 	}
 }
 
-func TestUtimesNanoAt(t *testing.T) {
-	defer chtmpdir(t)()
-
-	symlink := "symlink1"
-	os.Remove(symlink)
-	err := os.Symlink("nonexisting", symlink)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	ts := []unix.Timespec{
-		{Sec: 1111, Nsec: 2222},
-		{Sec: 3333, Nsec: 4444},
-	}
-	err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW)
-	if err != nil {
-		t.Fatalf("UtimesNanoAt: %v", err)
-	}
-
-	var st unix.Stat_t
-	err = unix.Lstat(symlink, &st)
-	if err != nil {
-		t.Fatalf("Lstat: %v", err)
-	}
-
-	// Only check Mtim, Atim might not be supported by the underlying filesystem
-	expected := ts[1]
-	if st.Mtim.Nsec == 0 {
-		// Some filesystems only support 1-second time stamp resolution
-		// and will always set Nsec to 0.
-		expected.Nsec = 0
-	}
-	if st.Mtim != expected {
-		t.Errorf("UtimesNanoAt: wrong mtime: expected %v, got %v", expected, st.Mtim)
-	}
-}
-
 func TestRlimitAs(t *testing.T) {
 	// disable GC during to avoid flaky test
 	defer debug.SetGCPercent(debug.SetGCPercent(-1))
diff --git a/unix/syscall_unix_test.go b/unix/syscall_unix_test.go
index cf7ef0b..0ecb519 100644
--- a/unix/syscall_unix_test.go
+++ b/unix/syscall_unix_test.go
@@ -791,6 +791,45 @@
 	}
 }
 
+func TestUtimesNanoAt(t *testing.T) {
+	defer chtmpdir(t)()
+
+	symlink := "symlink1"
+	os.Remove(symlink)
+	err := os.Symlink("nonexisting", symlink)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Some filesystems only support microsecond resolution. Account for
+	// that in Nsec.
+	ts := []unix.Timespec{
+		{Sec: 1111, Nsec: 2000},
+		{Sec: 3333, Nsec: 4000},
+	}
+	err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW)
+	if err != nil {
+		t.Fatalf("UtimesNanoAt: %v", err)
+	}
+
+	var st unix.Stat_t
+	err = unix.Lstat(symlink, &st)
+	if err != nil {
+		t.Fatalf("Lstat: %v", err)
+	}
+
+	// Only check Mtim, Atim might not be supported by the underlying filesystem
+	expected := ts[1]
+	if st.Mtim.Nsec == 0 {
+		// Some filesystems only support 1-second time stamp resolution
+		// and will always set Nsec to 0.
+		expected.Nsec = 0
+	}
+	if st.Mtim != expected {
+		t.Errorf("UtimesNanoAt: wrong mtime: got %v, expected %v", st.Mtim, expected)
+	}
+}
+
 // mktmpfifo creates a temporary FIFO and provides a cleanup function.
 func mktmpfifo(t *testing.T) (*os.File, func()) {
 	err := unix.Mkfifo("fifo", 0666)