-
Notifications
You must be signed in to change notification settings - Fork 0
/
example_fifo_test.go
139 lines (111 loc) · 3.96 KB
/
example_fifo_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package non_blocking_io_test
import (
"bytes"
"fmt"
"log"
"os/exec"
"strings"
"time"
"golang.org/x/sys/unix"
nbio "github.com/kontera-technologies/non-blocking-io"
)
// To read from the stdout of a sub-process, use the ``NewFifo`` function and pass the ``Fd`` pointer to the ``Stdout``
// parameter of the command.
func ExampleNewFifo_stdout() {
var err error
output, err := nbio.NewFifo()
if err != nil {
panic(err)
}
defer output.Close()
// testdata/endless-foo.sh will output "foo" every 100 milliseconds.
cmd := exec.Command("testdata/endless-foo.sh")
cmd.Stdout = output
err = cmd.Start()
if err != nil {
panic(err)
}
defer cmd.Process.Kill()
// Wait for a few milliseconds to give the process time to start, to make sure first read will succeed.
time.Sleep(time.Millisecond * 100)
buf := make([]byte, 100)
start := time.Now()
n, err := output.Read(buf)
if err != nil {
panic(err)
}
if dur := time.Since(start); dur.Microseconds() > 500 {
panic(fmt.Sprintf("Took %d microseconds to read %d bytes", dur.Microseconds(), n))
}
fmt.Printf("Took less than 500 microseconds to read %d bytes: \"%s\".\n", n, strings.ReplaceAll(string(buf[:n]), "\n", "\\n"))
// Second read will fail because no data is available.
buf = make([]byte, 100)
start = time.Now()
n, err = output.Read(buf)
if dur := time.Since(start); dur.Microseconds() > 500 {
panic(fmt.Sprintf("Took %d microseconds to read %d bytes", dur.Microseconds(), n))
}
fmt.Printf("Took less than 500 microseconds to read %d bytes.\n", n)
fmt.Printf("Expected timeout error - %v.\n", err)
// third read will wait until data is available.
buf = make([]byte, 100)
start = time.Now()
n, err = output.SelectRead(buf, unix.Timeval{Usec: 100000}) // 100ms = 100000μs
if err != nil {
log.Println(err)
}
if dur := time.Since(start); !(dur.Milliseconds() < 110 && dur.Milliseconds() > 90) {
panic(fmt.Sprintf("Took %s milliseconds to read %d bytes.", dur, n))
}
fmt.Printf("Took about 100 milliseconds to read %d bytes: \"%s\".\n", n, strings.ReplaceAll(string(buf[:n]), "\n", "\\n"))
// Output: Took less than 500 microseconds to read 4 bytes: "foo\n".
// Took less than 500 microseconds to read 0 bytes.
// Expected timeout error - resource temporarily unavailable.
// Took about 100 milliseconds to read 4 bytes: "foo\n".
}
// To write to the stdout of a sub-process, use the ``NewFifo`` function and pass the ``Fd`` pointer to the ``Stdin``
// parameter of the command.
func ExampleNewFifo_stdin() {
var err error
input, err := nbio.NewFifo()
if err != nil {
panic(err)
}
defer input.Close()
cmd := exec.Command("testdata/endless-read.sh")
cmd.Stdin = input
err = cmd.Start()
if err != nil {
panic(err)
}
defer cmd.Process.Kill()
// Wait for a few milliseconds to give the process time to start, to make sure first write will succeed.
time.Sleep(time.Millisecond * 100)
data := append(bytes.Repeat([]byte("foo"), 100000), '\n')
start := time.Now()
n, err := input.Write(data)
if err != nil {
panic(err)
}
if dur := time.Since(start); dur.Microseconds() > 500 {
panic(fmt.Sprintf("Took %d microseconds to write %d bytes", dur.Microseconds(), n))
}
if n >= len(data) {
panic(fmt.Sprintf("Took less than 500 microseconds to write %d bytes", n))
}
fmt.Printf("Took less than 500 microseconds to write less than %d bytes\n", len(data))
// Second read will fail because no data is available.
start = time.Now()
n, err = input.Write(data)
if dur := time.Since(start); dur.Microseconds() > 500 {
panic(fmt.Sprintf("Took %d microseconds to write %d bytes", dur.Microseconds(), n))
}
if n > 0 {
panic(fmt.Sprintf("Took less than 500 microseconds to write %d bytes", n))
}
fmt.Printf("Took less than 500 microseconds to write 0 bytes\n")
fmt.Printf("Expected timeout error - %v\n", err)
// Output: Took less than 500 microseconds to write less than 300001 bytes
// Took less than 500 microseconds to write 0 bytes
// Expected timeout error - resource temporarily unavailable
}