1
2context("io")
3
4test_that("Output and error are discarded by default", {
5
6  px <- get_tool("px")
7  p <- process$new(px, c("outln", "foobar"))
8  on.exit(try_silently(p$kill(grace = 0)), add = TRUE)
9
10  expect_error(p$read_output_lines(n=1),  "not a pipe")
11  expect_error(p$read_all_output_lines(), "not a pipe")
12  expect_error(p$read_all_output(),       "not a pipe")
13  expect_error(p$read_error_lines(n=1),   "not a pipe")
14  expect_error(p$read_all_error_lines(),  "not a pipe")
15  expect_error(p$read_all_error(),        "not a pipe")
16})
17
18test_that("We can get the output", {
19
20  px <- get_tool("px")
21
22  p <- process$new(px, c("out", "foo\nbar\nfoobar\n"),
23                   stdout = "|", stderr = "|")
24  on.exit(try_silently(p$kill(grace = 0)), add = TRUE)
25
26  out <- p$read_all_output_lines()
27  expect_identical(out, c("foo", "bar", "foobar"))
28})
29
30test_that("We can get the error stream", {
31
32  tmp <- tempfile(fileext = ".bat")
33  on.exit(unlink(tmp), add = TRUE)
34
35  cat(">&2 echo hello", ">&2 echo world", sep = "\n", file = tmp)
36  Sys.chmod(tmp, "700")
37
38  p <- process$new(tmp, stderr = "|")
39  on.exit(try_silently(p$kill(grace = 0)), add = TRUE)
40
41  out <- sort(p$read_all_error_lines())
42  expect_identical(out, c("hello", "world"))
43})
44
45test_that("Output & error at the same time", {
46
47  tmp <- tempfile(fileext = ".bat")
48  on.exit(unlink(tmp), add = TRUE)
49
50  cat(
51    if (os_type() == "windows") "@echo off",
52    ">&2 echo hello",
53    "echo wow",
54    ">&2 echo world",
55    "echo wooow",
56    sep = "\n", file = tmp
57  )
58  Sys.chmod(tmp, "700")
59
60  p <- process$new(tmp, stdout = "|", stderr = "|")
61  on.exit(try_silently(p$kill(grace = 0)), add = TRUE)
62
63  out <- p$read_all_output_lines()
64  expect_identical(out, c("wow", "wooow"))
65
66  err <- p$read_all_error_lines()
67  expect_identical(err, c("hello", "world"))
68})
69
70test_that("Output and error to specific files", {
71
72  tmp <- tempfile(fileext = ".bat")
73  on.exit(unlink(tmp), add = TRUE)
74
75  cat(
76    if (os_type() == "windows") "@echo off",
77    ">&2 echo hello",
78    "echo wow",
79    ">&2 echo world",
80    "echo wooow",
81    sep = "\n", file = tmp
82  )
83  Sys.chmod(tmp, "700")
84
85  tmpout <- tempfile()
86  tmperr <- tempfile()
87
88  p <- process$new(tmp, stdout = tmpout, stderr = tmperr)
89  on.exit(try_silently(p$kill(grace = 0)), add = TRUE)
90
91  p$wait()
92
93  ## In theory this is a race condition, because the OS might be still
94  ## writing the files. But it is hard to wait until they are done.
95  ## We'll see if this fails in practice, hopefully not.
96  expect_identical(readLines(tmpout), c("wow", "wooow"))
97  expect_identical(readLines(tmperr), c("hello", "world"))
98})
99
100test_that("is_incomplete", {
101
102  px <- get_tool("px")
103  p <- process$new(px, c("out", "foo\nbar\nfoobar\n"), stdout = "|")
104  on.exit(p$kill(), add = TRUE)
105
106  expect_true(p$is_incomplete_output())
107
108  p$read_output_lines(n = 1)
109  expect_true(p$is_incomplete_output())
110
111  p$read_all_output_lines()
112  expect_false(p$is_incomplete_output())
113})
114
115test_that("readChar on IO, unix", {
116
117  ## Need to skip, because of the different EOL character
118  skip_other_platforms("unix")
119
120  px <- get_tool("px")
121
122  p <- process$new(px, c("outln", "hello world!"), stdout = "|")
123  on.exit(p$kill(), add = TRUE)
124  p$wait()
125
126  p$poll_io(-1)
127  expect_equal(p$read_output(5), "hello")
128  expect_equal(p$read_output(5), " worl")
129  expect_equal(p$read_output(5), "d!\n")
130})
131
132test_that("readChar on IO, windows", {
133
134  ## Need to skip, because of the different EOL character
135  skip_other_platforms("windows")
136
137  px <- get_tool("px")
138  p <- process$new(px, c("outln", "hello world!"), stdout = "|")
139  on.exit(p$kill(), add = TRUE)
140  p$wait()
141
142  p$poll_io(-1)
143  expect_equal(p$read_output(5), "hello")
144  p$poll_io(-1)
145  expect_equal(p$read_output(5), " worl")
146  p$poll_io(-1)
147  expect_equal(p$read_output(5), "d!\r\n")
148})
149
150test_that("same pipe", {
151  px <- get_tool("px")
152  cmd <- c("out", "o1", "err", "e1", "out", "o2", "err", "e2")
153  p <- process$new(px, cmd, stdout = "|", stderr = "2>&1")
154  on.exit(p$kill(), add = TRUE)
155  p$wait(2000)
156  expect_equal(p$get_exit_status(), 0L)
157
158  out <- p$read_all_output()
159  expect_equal(out, "o1e1o2e2")
160  expect_error(p$read_all_error_lines(), "not a pipe")
161})
162
163test_that("same file", {
164  px <- get_tool("px")
165  cmd <- c("out", "o1", "err", "e1", "out", "o2", "errln", "e2")
166  tmp <- tempfile()
167  on.exit(unlink(tmp, recursive = TRUE), add = TRUE)
168  p <- process$new(px, cmd, stdout = tmp, stderr = "2>&1")
169  p$wait(2000)
170  p$kill()
171  expect_equal(p$get_exit_status(), 0L)
172
173  expect_equal(readLines(tmp), "o1e1o2e2")
174  expect_error(p$read_all_output_lines(), "not a pipe")
175  expect_error(p$read_all_error_lines(), "not a pipe")
176})
177
178test_that("same NULL, for completeness", {
179  px <- get_tool("px")
180  cmd <- c("out", "o1", "err", "e1", "out", "o2", "errln", "e2")
181  p <- process$new(px, cmd, stdout = NULL, stderr = "2>&1")
182  p$wait(2000)
183  p$kill()
184  expect_equal(p$get_exit_status(), 0L)
185  expect_error(p$read_all_output_lines(), "not a pipe")
186  expect_error(p$read_all_error_lines(), "not a pipe")
187})
188