/development/std/process/command_io_tests_darwin.nct
command_io_tests_darwin.nct
//! Native qualification for three-direction readiness and bounded transfer facts.
see ./command_io_darwin.nct
see ./pipe_darwin.nct
use /internal/os/darwin.SyscallResult
use /internal/os/darwin
use /internal/ptr as internal_ptr
use /ptr
test command_io_classification_preserves_direction_and_broken_pipe {
if !events_match_interest(POLL_INPUT, POLL_INPUT)
|| !events_match_interest(POLL_OUTPUT, POLL_OUTPUT)
|| events_match_interest(POLL_INPUT, POLL_OUTPUT)
|| events_match_interest(POLL_OUTPUT, POLL_INPUT) {
return error.new("std.process.test", "poll direction validation changed")
}
match classify_command_io_read(SyscallResult { value: 1, errno: 0 }, 1) {
CommandIoReadAttempt.bytes(count) {
if count != 1 { return error.new("std.process.test", "read count changed") }
}
_ { return error.new("std.process.test", "read bytes changed classification") }
}
match classify_command_io_write(
SyscallResult { value: 0, errno: darwin.ERRNO_BROKEN_PIPE },
1,
) {
CommandIoWriteAttempt.broken_pipe {}
_ { return error.new("std.process.test", "broken pipe changed classification") }
}
match classify_command_io_write(SyscallResult { value: 2, errno: 0 }, 1) {
CommandIoWriteAttempt.malformed {}
_ { return error.new("std.process.test", "oversized write became progress") }
}
match classify_command_io_write(
SyscallResult { value: 0, errno: darwin.ERRNO_WOULD_BLOCK },
1,
) {
CommandIoWriteAttempt.would_block {}
_ { return error.new("std.process.test", "would-block write changed classification") }
}
return
}
test command_io_poll_observes_writer_and_reader_together {
match create_cloexec_pipe() {
PipeAttempt.failed(_) {
return error.new("std.process.test", "input readiness pipe creation failed")
}
PipeAttempt.ready(input_pipe) {
var input = move input_pipe
match configure_pipe_writer_for_async_io(&input) {
PipeConfigurationAttempt.failed(_) {
return error.new("std.process.test", "asynchronous writer configuration failed")
}
PipeConfigurationAttempt.ready {}
}
match create_cloexec_pipe() {
PipeAttempt.failed(_) {
return error.new("std.process.test", "output readiness pipe creation failed")
}
PipeAttempt.ready(output_pipe) {
var output = move output_pipe
let sent: u8 = 71
let written = darwin.syscall3(
darwin.SYS_WRITE,
pipe_write_fd(&output),
ptr.addr(ptr.from_ref(&sent)),
1,
)
if written.errno != 0 || written.value != 1 {
return error.new("std.process.test", "readiness fixture write failed")
}
match poll_command_io_once(
pipe_write_fd(&input),
true,
pipe_read_fd(&output),
true,
0,
false,
) {
CommandIoPollAttempt.ready(input_events, stdout_events, stderr_events) {
if !input_events.writable || input_events.readable
|| !stdout_events.readable || stdout_events.writable
|| stderr_events.readable || stderr_events.writable
|| stderr_events.error || stderr_events.hangup
|| stderr_events.invalid {
return error.new("std.process.test", "three-direction readiness changed")
}
}
_ { return error.new("std.process.test", "three-direction poll failed") }
}
close_pipe_read(&+input)
let byte: u8 = 1
match write_command_input_once(
pipe_write_fd(&input),
internal_input_byte(&byte),
0,
) {
CommandIoWriteAttempt.broken_pipe {}
_ { return error.new("std.process.test", "owned writer raised SIGPIPE or lost EPIPE") }
}
drop output
drop input
}
}
}
}
return
}
noalloc func internal_input_byte(value: &u8): &[u8] {
return internal_ptr.slice_from_raw_parts_value(ptr.from_ref(value), 1)
}