| 127 | } |
| 128 | |
| 129 | func TestPipelineReadFromSlowly2(t *testing.T) { |
| 130 | if runtime.GOOS == "windows" { |
| 131 | t.Skip("FIXME: test skipped on Windows: 'seq' unavailable") |
| 132 | } |
| 133 | |
| 134 | t.Parallel() |
| 135 | ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) |
| 136 | defer cancel() |
| 137 | |
| 138 | r, w := io.Pipe() |
| 139 | |
| 140 | var buf []byte |
| 141 | readErr := make(chan error, 1) |
| 142 | |
| 143 | go func() { |
| 144 | time.Sleep(100 * time.Millisecond) |
| 145 | for { |
| 146 | var c [1]byte |
| 147 | _, err := r.Read(c[:]) |
| 148 | if err != nil { |
| 149 | if err == io.EOF { |
| 150 | readErr <- nil |
| 151 | return |
| 152 | } |
| 153 | readErr <- err |
| 154 | return |
| 155 | } |
| 156 | buf = append(buf, c[0]) |
| 157 | time.Sleep(1 * time.Millisecond) |
| 158 | } |
| 159 | }() |
| 160 | |
| 161 | p := pipe.New(pipe.WithStdout(w)) |
| 162 | p.Add(pipe.Command("seq", "100")) |
| 163 | assert.NoError(t, p.Run(ctx)) |
| 164 | |
| 165 | time.Sleep(200 * time.Millisecond) |
| 166 | // It's not super-intuitive, but `w` has to be closed here so that |
| 167 | // the `ioutil.ReadAll()` call above knows that it's done: |
| 168 | _ = w.Close() |
| 169 | |
| 170 | assert.NoError(t, <-readErr) |
| 171 | assert.Equal(t, 292, len(buf)) |
| 172 | } |
| 173 | |
| 174 | func TestPipelineTwoCommandsPiping(t *testing.T) { |
| 175 | t.Parallel() |