github.com/HACKERALERT/Picocrypt/src/external/sys@v0.0.0-20210609020157-e519952f829f/unix/epoll_zos_test.go (about)

     1  // Copyright 2020 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  //go:build zos && s390x
     6  // +build zos,s390x
     7  
     8  package unix_test
     9  
    10  // Modified from Linux tests for epoll.
    11  
    12  import (
    13  	"os"
    14  	"testing"
    15  
    16  	"golang.org/x/sys/unix"
    17  )
    18  
    19  func TestEpollIn(t *testing.T) {
    20  	efd, err := unix.EpollCreate1(0) // no CLOEXEC equivalent on z/OS
    21  	if err != nil {
    22  		t.Fatalf("EpollCreate1: %v", err)
    23  	}
    24  	// no need to defer a close on efd, as it's not a real file descriptor on zos
    25  
    26  	r, w, err := os.Pipe()
    27  	if err != nil {
    28  		t.Fatal(err)
    29  	}
    30  	defer r.Close()
    31  	defer w.Close()
    32  
    33  	fd := int(r.Fd())
    34  	ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
    35  
    36  	err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
    37  	if err != nil {
    38  		t.Fatalf("EpollCtl: %v", err)
    39  	}
    40  
    41  	if _, err := w.Write([]byte("HELLO GOPHER")); err != nil {
    42  		t.Fatal(err)
    43  	}
    44  
    45  	events := make([]unix.EpollEvent, 128)
    46  	n, err := unix.EpollWait(efd, events, 1)
    47  	if err != nil {
    48  		t.Fatalf("EpollWait: %v", err)
    49  	}
    50  
    51  	if n != 1 {
    52  		t.Errorf("EpollWait: wrong number of events: got %v, expected 1", n)
    53  	}
    54  
    55  	got := int(events[0].Fd)
    56  	if got != fd {
    57  		t.Errorf("EpollWait: wrong Fd in event: got %v, expected %v", got, fd)
    58  	}
    59  
    60  	if events[0].Events&unix.EPOLLIN == 0 {
    61  		t.Errorf("Expected EPOLLIN flag to be set, got %b", events[0].Events)
    62  	}
    63  }
    64  
    65  func TestEpollHup(t *testing.T) {
    66  	efd, err := unix.EpollCreate1(0)
    67  	if err != nil {
    68  		t.Fatalf("EpollCreate1: %v", err)
    69  	}
    70  	// no need to defer a close on efd, as it's not a real file descriptor on zos
    71  
    72  	r, w, err := os.Pipe()
    73  	if err != nil {
    74  		t.Fatal(err)
    75  	}
    76  	defer r.Close()
    77  
    78  	fd := int(r.Fd())
    79  	// EPOLLHUP should be reported even if not explicitly requested
    80  	ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
    81  
    82  	err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
    83  	if err != nil {
    84  		t.Fatalf("EpollCtl: %v", err)
    85  	}
    86  
    87  	events := make([]unix.EpollEvent, 128)
    88  	n, err := unix.EpollWait(efd, events, 1)
    89  	if err != nil {
    90  		t.Fatalf("EpollWait: %v", err)
    91  	}
    92  
    93  	if events[0].Events&unix.EPOLLHUP != 0 {
    94  		t.Errorf("EPOLLHUP flag aset without hangup event; got n=%d, flags=%b", n, events[0].Events)
    95  	}
    96  
    97  	w.Close()
    98  
    99  	events = make([]unix.EpollEvent, 128)
   100  	n, err = unix.EpollWait(efd, events, 1)
   101  	if err != nil {
   102  		t.Fatalf("EpollWait: %v", err)
   103  	}
   104  
   105  	if n < 1 || events[0].Events&unix.EPOLLHUP == 0 {
   106  		t.Errorf("Expected EPOLLHUP flag to be set, got n=%d, flags=%b", n, events[0].Events)
   107  	}
   108  
   109  }
   110  
   111  func TestEpollInManyFds(t *testing.T) {
   112  	efd, err := unix.EpollCreate1(4) // Like on Linux, size arg is ignored.
   113  	if err != nil {
   114  		t.Fatalf("EpollCreate: %v", err)
   115  	}
   116  	// no need to defer a close on efd, as it's not a real file descriptor on zos
   117  
   118  	rFds := make([]int, 10)
   119  	wPipes := make([]*os.File, 10)
   120  
   121  	for i := 0; i < 10; i++ {
   122  		r, w, err := os.Pipe()
   123  		if err != nil {
   124  			t.Fatal(err)
   125  		}
   126  		defer r.Close()
   127  		defer w.Close()
   128  
   129  		rFds[i] = int(r.Fd())
   130  		wPipes[i] = w
   131  	}
   132  
   133  	// Monitor all 10 read pipes
   134  	for _, fd := range rFds {
   135  		ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
   136  		err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
   137  		if err != nil {
   138  			t.Fatalf("EpollCtl: %v", err)
   139  		}
   140  	}
   141  
   142  	// Write to only 5 odd-numbered pipes
   143  	for i, w := range wPipes {
   144  		if i%2 == 0 {
   145  			continue
   146  		}
   147  		if _, err := w.Write([]byte("HELLO")); err != nil {
   148  			t.Fatal(err)
   149  		}
   150  	}
   151  
   152  	events := make([]unix.EpollEvent, 128)
   153  	n, err := unix.EpollWait(efd, events, 1)
   154  	if err != nil {
   155  		t.Fatalf("EpollWait: %v", err)
   156  	}
   157  
   158  	if n != 5 {
   159  		t.Errorf("EpollWait: wrong number of events: got %v, expected 5", n)
   160  	}
   161  
   162  	// Check level triggering here
   163  	if _, err := wPipes[0].Write([]byte("HELLO")); err != nil {
   164  		t.Fatal(err)
   165  	}
   166  
   167  	// Now, a total of 6 pipes have been written to - level triggered notifis should number 6
   168  	events = make([]unix.EpollEvent, 128)
   169  	n, err = unix.EpollWait(efd, events, 1)
   170  	if err != nil {
   171  		t.Fatalf("EpollWait: %v", err)
   172  	}
   173  
   174  	if n != 6 {
   175  		t.Errorf("EpollWait: wrong number of events: got %v, expected 6", n)
   176  	}
   177  
   178  }
   179  
   180  func TestMultipleEpolls(t *testing.T) {
   181  	efd1, err := unix.EpollCreate1(4)
   182  	if err != nil {
   183  		t.Fatalf("EpollCreate: %v", err)
   184  	}
   185  	// no need to defer a close on efd1, as it's not a real file descriptor on zos
   186  
   187  	efd2, err := unix.EpollCreate1(4)
   188  	if err != nil {
   189  		t.Fatalf("EpollCreate: %v", err)
   190  	}
   191  	// no need to defer a close on efd2, as it's not a real file descriptor on zos
   192  
   193  	rFds := make([]int, 10)
   194  	wPipes := make([]*os.File, 10)
   195  
   196  	for i := 0; i < 10; i++ {
   197  		r, w, err := os.Pipe()
   198  		if err != nil {
   199  			t.Fatal(err)
   200  		}
   201  		defer r.Close()
   202  		defer w.Close()
   203  
   204  		rFds[i] = int(r.Fd())
   205  		wPipes[i] = w
   206  	}
   207  
   208  	// Monitor first 7 read pipes on epoll1, last 3 on epoll2
   209  	for i, fd := range rFds {
   210  		var efd int
   211  		if i < 7 {
   212  			efd = efd1
   213  		} else {
   214  			efd = efd2
   215  		}
   216  		ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
   217  		err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev)
   218  		if err != nil {
   219  			t.Fatalf("EpollCtl: %v", err)
   220  		}
   221  	}
   222  
   223  	// Write to all 10 pipes
   224  	for _, w := range wPipes {
   225  		if _, err := w.Write([]byte("HELLO")); err != nil {
   226  			t.Fatal(err)
   227  		}
   228  	}
   229  
   230  	events := make([]unix.EpollEvent, 128)
   231  	n, err := unix.EpollWait(efd1, events, 1)
   232  	if err != nil {
   233  		t.Fatalf("EpollWait: %v", err)
   234  	}
   235  	if n != 7 {
   236  		t.Errorf("EpollWait: wrong number of events on ep1: got %v, expected 7", n)
   237  	}
   238  
   239  	events = make([]unix.EpollEvent, 128)
   240  	n, err = unix.EpollWait(efd2, events, 1)
   241  	if err != nil {
   242  		t.Fatalf("EpollWait: %v", err)
   243  	}
   244  	if n != 3 {
   245  		t.Errorf("EpollWait: wrong number of events on ep2: got %v, expected 3", n)
   246  	}
   247  }
   248  
   249  func TestEpollErrors(t *testing.T) {
   250  	efd, err := unix.EpollCreate1(4)
   251  	if err != nil {
   252  		t.Fatalf("EpollCreate: %v", err)
   253  	}
   254  	// no need to defer a close on efd, as it's not a real file descriptor on zos
   255  
   256  	r, w, err := os.Pipe()
   257  	if err != nil {
   258  		t.Fatal(err)
   259  	}
   260  	defer r.Close()
   261  	defer w.Close()
   262  
   263  	fd := int(r.Fd())
   264  
   265  	ev := unix.EpollEvent{Events: unix.EPOLLIN, Fd: int32(fd)}
   266  	if err = unix.EpollCtl(efd+1, unix.EPOLL_CTL_ADD, fd, &ev); err != unix.EBADF {
   267  		t.Errorf("EpollCtl: got %v when EpollCtl ADD called with invalid epfd, expected EBADF", err)
   268  	}
   269  
   270  	if err = unix.EpollCtl(efd, unix.EPOLL_CTL_ADD, fd, &ev); err != nil {
   271  		t.Fatalf("EpollCtl: %v", err)
   272  	}
   273  
   274  	if err = unix.EpollCtl(efd, unix.EPOLL_CTL_MOD, -2, &ev); err != unix.ENOENT {
   275  		t.Errorf("EpollCtl: got %v when EpollCtl MOD called with invalid fd, expected ENOENT", err)
   276  	}
   277  }