github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/internal/wasitest/nonblock_test.go (about) 1 // Copyright 2023 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 // Not all systems have syscall.Mkfifo. 6 //go:build !aix && !plan9 && !solaris && !wasm && !windows 7 8 package wasi_test 9 10 import ( 11 "bufio" 12 "fmt" 13 "io" 14 "math/rand" 15 "os" 16 "os/exec" 17 "path/filepath" 18 "syscall" 19 "testing" 20 ) 21 22 // This test creates a set of FIFOs and writes to them in reverse order. It 23 // checks that the output order matches the write order. The test binary opens 24 // the FIFOs in their original order and spawns a goroutine for each that reads 25 // from the FIFO and writes the result to stderr. If I/O was blocking, all 26 // goroutines would be blocked waiting for one read call to return, and the 27 // output order wouldn't match. 28 29 type fifo struct { 30 file *os.File 31 path string 32 } 33 34 func TestNonblock(t *testing.T) { 35 if target != "wasip1/wasm" { 36 t.Skip() 37 } 38 39 switch os.Getenv("GOWASIRUNTIME") { 40 case "wasmer": 41 t.Skip("wasmer does not support non-blocking I/O") 42 } 43 44 for _, mode := range []string{"os.OpenFile", "os.NewFile"} { 45 t.Run(mode, func(t *testing.T) { 46 args := []string{"run", "./testdata/nonblock.go", mode} 47 48 fifos := make([]*fifo, 8) 49 for i := range fifos { 50 path := filepath.Join(t.TempDir(), fmt.Sprintf("wasip1-nonblock-fifo-%d-%d", rand.Uint32(), i)) 51 if err := syscall.Mkfifo(path, 0666); err != nil { 52 t.Fatal(err) 53 } 54 55 file, err := os.OpenFile(path, os.O_RDWR, 0) 56 if err != nil { 57 t.Fatal(err) 58 } 59 defer file.Close() 60 61 args = append(args, path) 62 fifos[len(fifos)-i-1] = &fifo{file, path} 63 } 64 65 subProcess := exec.Command("go", args...) 66 67 subProcess.Env = append(os.Environ(), "GOOS=wasip1", "GOARCH=wasm") 68 69 pr, pw := io.Pipe() 70 defer pw.Close() 71 72 subProcess.Stderr = pw 73 74 if err := subProcess.Start(); err != nil { 75 t.Fatal(err) 76 } 77 78 scanner := bufio.NewScanner(pr) 79 if !scanner.Scan() { 80 t.Fatal("expected line:", scanner.Err()) 81 } else if scanner.Text() != "waiting" { 82 t.Fatal("unexpected output:", scanner.Text()) 83 } 84 85 for _, fifo := range fifos { 86 if _, err := fifo.file.WriteString(fifo.path + "\n"); err != nil { 87 t.Fatal(err) 88 } 89 if !scanner.Scan() { 90 t.Fatal("expected line:", scanner.Err()) 91 } else if scanner.Text() != fifo.path { 92 t.Fatal("unexpected line:", scanner.Text()) 93 } 94 } 95 96 if err := subProcess.Wait(); err != nil { 97 t.Fatal(err) 98 } 99 }) 100 } 101 }