Programming Language

Nocter

A self-contained systems language built around simplicity, encapsulation, and foolproof design.

/development/std/process/capture_launch_tests_darwin.nct

capture_launch_tests_darwin.nct

//! Native qualification for child capture setup rejection and parent cleanup.

see ./capture_launch_darwin.nct
see ./capture_session_darwin.nct
see ./launch_report_darwin.nct
see ./pipe_darwin.nct
see ./subprocess_darwin.nct

test captured_child_reports_descriptor_setup_rejection {
    match create_cloexec_pipe() {
        PipeAttempt.failed(_) {
            return error.new("std.process.test", "setup report pipe creation failed")
        }
        PipeAttempt.ready(report) {
            match create_capture_session() {
                CapturePreparationAttempt.failed(_) {
                    return error.new("std.process.test", "setup capture creation failed")
                }
                CapturePreparationAttempt.ready(captures) {
                    var capture = move captures
                    close_pipe_write(&+capture.stdout_pipe)
                    match fork_process() {
                        ForkAttempt.failed(_) {
                            return error.new("std.process.test", "setup test fork failed")
                        }
                        ForkAttempt.child {
                            exec_captured_child(0, 0, 0, move report, move capture)
                        }
                        ForkAttempt.parent(pid) {
                            let launch = read_launch_report(move report)
                            let drained = drain_captured_streams(move capture)
                            let terminal = wait_for_child(pid)

                            match move launch {
                                LaunchReportAttempt.setup_rejected(errno) {
                                    if errno == 0 {
                                        return error.new("std.process.test", "setup rejection lost errno")
                                    }
                                }
                                LaunchReportAttempt.executed {
                                    return error.new("std.process.test", "setup rejection became execution")
                                }
                                LaunchReportAttempt.exec_rejected(_) {
                                    return error.new("std.process.test", "setup rejection became exec rejection")
                                }
                                LaunchReportAttempt.channel_failed(_) {
                                    return error.new("std.process.test", "setup rejection lost its report")
                                }
                                LaunchReportAttempt.malformed {
                                    return error.new("std.process.test", "setup rejection became malformed")
                                }
                            }
                            match move drained {
                                CaptureSessionAttempt.complete(stdout, stderr) {
                                    if stdout.len() != 0 || stderr.len() != 0 {
                                        return error.new("std.process.test", "setup rejection fabricated output")
                                    }
                                }
                                CaptureSessionAttempt.failed(_) {
                                    return error.new("std.process.test", "setup rejection broke capture cleanup")
                                }
                                CaptureSessionAttempt.malformed {
                                    return error.new("std.process.test", "setup rejection malformed capture cleanup")
                                }
                            }
                            match move terminal {
                                WaitOutcome.exited(code) {
                                    if code != 127 {
                                        return error.new("std.process.test", "setup rejection exit code changed")
                                    }
                                }
                                WaitOutcome.signaled(_) {
                                    return error.new("std.process.test", "setup rejection became a signal")
                                }
                                WaitOutcome.failed(_) {
                                    return error.new("std.process.test", "setup child was not reaped")
                                }
                                WaitOutcome.invalid(_) {
                                    return error.new("std.process.test", "setup child status was invalid")
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return
}