context("binary streams")

test_that("copy a binary image", {
  is_windows <- identical("windows", tolower(Sys.info()[["sysname"]]))
  olddir <- getwd()
  on.exit(setwd(olddir))
  setwd(tempdir())
  buf <- serialize(rnorm(1e6), NULL)
  writeBin(buf, "input.bin")
  if(is_windows){
    res1 <- exec_wait("cmd", c("/C", "type", "input.bin"), std_out = "out1.bin")
    res2 <- exec_wait("cmd", c("/C", "type", "input.bin", ">&2"), std_err = "out2.bin")
    pid1 <- exec_background("cmd", c("/C", "type", "input.bin"), std_out = "out3.bin")
    pid2 <- exec_background("cmd", c("/C", "type", "input.bin", ">&2"), std_err = "out4.bin")
    data1 <- exec_internal("cmd", c("/C", "type", "input.bin"))
    data2 <- exec_internal("cmd", c("/C", "type", "input.bin", ">&2"))
    writeBin(data1$stdout, "out5.bin")
    writeBin(data2$stderr, "out6.bin")
  } else {
    res1 <- exec_wait("cat", "input.bin", std_out = "out1.bin")
    res2 <- exec_wait("sh", c("-c", "cat input.bin >&2"), std_err = "out2.bin")
    pid1 <- exec_background("cat", "input.bin", std_out = "out3.bin")
    pid2 <- exec_background("sh", c("-c", "cat input.bin >&2"), std_err = "out4.bin")
    data1 <- exec_internal("cat", "input.bin")
    data2 <- exec_internal("sh", c("-c", "cat input.bin >&2"))
    writeBin(data1$stdout, "out5.bin")
    writeBin(data2$stderr, "out6.bin")
  }
  on.exit(tools::pskill(pid1), add = TRUE)
  on.exit(tools::pskill(pid2), add = TRUE)
  on.exit(unlink(sprintf("out%d.bin", 1:6)), add = TRUE)
  expect_equal(res1, 0)
  expect_equal(res2, 0)
  expect_equal(data1$status, 0)
  expect_equal(data2$status, 0)
  expect_is(pid1, "integer")
  expect_is(pid2, "integer")
  Sys.sleep(1)
  hash <- unname(tools::md5sum("input.bin"))
  expect_equal(hash, unname(tools::md5sum("out1.bin")))
  expect_equal(hash, unname(tools::md5sum("out2.bin")))
  expect_equal(hash, unname(tools::md5sum("out3.bin")))
  expect_equal(hash, unname(tools::md5sum("out4.bin")))
  expect_equal(hash, unname(tools::md5sum("out5.bin")))
  expect_equal(hash, unname(tools::md5sum("out6.bin")))
})
