Files
sys/unix/epoll_zos_test.go
Dmitri Shuralyov 1bfbee0e20 all: update go directive to 1.18
Done with:

go get go@1.18
go mod tidy
go fix ./...

Using go1.21.3.

Also update code generators to use only the new go:build lines,
not the old +build ones.

For golang/go#60268.

Change-Id: I6aabc42efb6ab3329981100e1db2263aac5e92a6
Reviewed-on: https://go-review.googlesource.com/c/sys/+/534222
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2023-10-11 21:54:30 +00:00

277 lines
6.2 KiB
Go

// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build zos && s390x
package unix_test
// Modified from Linux tests for epoll.
import (
"os"
"testing"
"golang.org/x/sys/unix"
)
func TestEpollIn(t *testing.T) {
efd, err := unix.EpollCreate1(0) // no CLOEXEC equivalent on z/OS
if err != nil {
t.Fatalf("EpollCreate1: %v", err)
}
// no need to defer a close on efd, as it's not a real file descriptor on zos
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
defer r.Close()
defer w.Close()
fd := int(r.Fd())
ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
if err != nil {
t.Fatalf("EpollCtl: %v", err)
}
if _, err := w.Write([]byte("HELLO GOPHER")); err != nil {
t.Fatal(err)
}
events := make([]unix.EpollEvent, 128)
n, err := unix.EpollWait(efd, events, 1)
if err != nil {
t.Fatalf("EpollWait: %v", err)
}
if n != 1 {
t.Errorf("EpollWait: wrong number of events: got %v, expected 1", n)
}
got := int(events[0].Fd)
if got != fd {
t.Errorf("EpollWait: wrong Fd in event: got %v, expected %v", got, fd)
}
if events[0].Events&unix.EPOLLIN == 0 {
t.Errorf("Expected EPOLLIN flag to be set, got %b", events[0].Events)
}
}
func TestEpollHup(t *testing.T) {
efd, err := unix.EpollCreate1(0)
if err != nil {
t.Fatalf("EpollCreate1: %v", err)
}
// no need to defer a close on efd, as it's not a real file descriptor on zos
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
defer r.Close()
fd := int(r.Fd())
// EPOLLHUP should be reported even if not explicitly requested
ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
if err != nil {
t.Fatalf("EpollCtl: %v", err)
}
events := make([]unix.EpollEvent, 128)
n, err := unix.EpollWait(efd, events, 1)
if err != nil {
t.Fatalf("EpollWait: %v", err)
}
if events[0].Events&unix.EPOLLHUP != 0 {
t.Errorf("EPOLLHUP flag aset without hangup event; got n=%d, flags=%b", n, events[0].Events)
}
w.Close()
events = make([]unix.EpollEvent, 128)
n, err = unix.EpollWait(efd, events, 1)
if err != nil {
t.Fatalf("EpollWait: %v", err)
}
if n < 1 || events[0].Events&unix.EPOLLHUP == 0 {
t.Errorf("Expected EPOLLHUP flag to be set, got n=%d, flags=%b", n, events[0].Events)
}
}
func TestEpollInManyFds(t *testing.T) {
efd, err := unix.EpollCreate1(4) // Like on Linux, size arg is ignored.
if err != nil {
t.Fatalf("EpollCreate: %v", err)
}
// no need to defer a close on efd, as it's not a real file descriptor on zos
rFds := make([]int, 10)
wPipes := make([]*os.File, 10)
for i := 0; i < 10; i++ {
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
defer r.Close()
defer w.Close()
rFds[i] = int(r.Fd())
wPipes[i] = w
}
// Monitor all 10 read pipes
for _, fd := range rFds {
ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
if err != nil {
t.Fatalf("EpollCtl: %v", err)
}
}
// Write to only 5 odd-numbered pipes
for i, w := range wPipes {
if i%2 == 0 {
continue
}
if _, err := w.Write([]byte("HELLO")); err != nil {
t.Fatal(err)
}
}
events := make([]unix.EpollEvent, 128)
n, err := unix.EpollWait(efd, events, 1)
if err != nil {
t.Fatalf("EpollWait: %v", err)
}
if n != 5 {
t.Errorf("EpollWait: wrong number of events: got %v, expected 5", n)
}
// Check level triggering here
if _, err := wPipes[0].Write([]byte("HELLO")); err != nil {
t.Fatal(err)
}
// Now, a total of 6 pipes have been written to - level triggered notifis should number 6
events = make([]unix.EpollEvent, 128)
n, err = unix.EpollWait(efd, events, 1)
if err != nil {
t.Fatalf("EpollWait: %v", err)
}
if n != 6 {
t.Errorf("EpollWait: wrong number of events: got %v, expected 6", n)
}
}
func TestMultipleEpolls(t *testing.T) {
efd1, err := unix.EpollCreate1(4)
if err != nil {
t.Fatalf("EpollCreate: %v", err)
}
// no need to defer a close on efd1, as it's not a real file descriptor on zos
efd2, err := unix.EpollCreate1(4)
if err != nil {
t.Fatalf("EpollCreate: %v", err)
}
// no need to defer a close on efd2, as it's not a real file descriptor on zos
rFds := make([]int, 10)
wPipes := make([]*os.File, 10)
for i := 0; i < 10; i++ {
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
defer r.Close()
defer w.Close()
rFds[i] = int(r.Fd())
wPipes[i] = w
}
// Monitor first 7 read pipes on epoll1, last 3 on epoll2
for i, fd := range rFds {
var efd int
if i < 7 {
efd = efd1
} else {
efd = efd2
}
ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
if err != nil {
t.Fatalf("EpollCtl: %v", err)
}
}
// Write to all 10 pipes
for _, w := range wPipes {
if _, err := w.Write([]byte("HELLO")); err != nil {
t.Fatal(err)
}
}
events := make([]unix.EpollEvent, 128)
n, err := unix.EpollWait(efd1, events, 1)
if err != nil {
t.Fatalf("EpollWait: %v", err)
}
if n != 7 {
t.Errorf("EpollWait: wrong number of events on ep1: got %v, expected 7", n)
}
events = make([]unix.EpollEvent, 128)
n, err = unix.EpollWait(efd2, events, 1)
if err != nil {
t.Fatalf("EpollWait: %v", err)
}
if n != 3 {
t.Errorf("EpollWait: wrong number of events on ep2: got %v, expected 3", n)
}
}
func TestEpollErrors(t *testing.T) {
efd, err := unix.EpollCreate1(4)
if err != nil {
t.Fatalf("EpollCreate: %v", err)
}
// no need to defer a close on efd, as it's not a real file descriptor on zos
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
defer r.Close()
defer w.Close()
fd := int(r.Fd())
ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
if err = unix.EpollCtl(efd+1, unix.EPOLL_CTL_ADD, fd, &ev); err != unix.EBADF {
t.Errorf("EpollCtl: got %v when EpollCtl ADD called with invalid epfd, expected EBADF", err)
}
if err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev); err != nil {
t.Fatalf("EpollCtl: %v", err)
}
if err = unix.EpollCtl(efd, unix.EPOLL_CTL_MOD, -2, &ev); err != unix.ENOENT {
t.Errorf("EpollCtl: got %v when EpollCtl MOD called with invalid fd, expected ENOENT", err)
}
}