Boost::Process Pipe Streams and Unit Test

偶尔善良 提交于 2021-02-10 15:56:17

问题


I have source which two stream like this:

bp::ipstream StdOut;
bp::opstream StdIn;
bp::child MyProcess = bp::child(processPath, bp::std_out > StdOut, bp::std_in < StdIn);
// Doing some stuff with StdOut and StdIn

I wanted to know if there is a way to write manually into this StdOut and read from StdIn in order to do unit tests? Thank you very much!


回答1:


You can write to them as a normal stream:

Live On Coliru

#include <boost/process.hpp>
#include <iostream>

namespace bp = boost::process;

int main() {
    bp::ipstream StdOut;
    bp::opstream StdIn;
    bp::child MyProcess = bp::child("/usr/bin/rev", bp::std_out > StdOut, bp::std_in < StdIn);

    for (int i = 0; i<100; ++i) {
        StdIn << "Sure no problem, " << i << std::endl;
    }
    StdIn.flush();
    StdIn.pipe().close();

    std::string il;
    while (getline(StdOut, il)) {
        std::cout << il << std::endl;
    }

    std::cout << "Bye\n";
}

Prints

0 ,melborp on eruS
1 ,melborp on eruS
2 ,melborp on eruS
...
99 ,melborp on eruS
Bye

Note, like the documentation warns, if your process requires async IO you could end up deadlocking (e.g. waiting for output while the child process is waiting for input).

To achieve this, use Asio's asynchronous operations:

Live On Coliru

#include <boost/process.hpp>
#include <boost/asio.hpp>
#include <boost/process/async.hpp>
#include <iostream>

namespace ba = boost::asio;
namespace bp = boost::process;

int main() {
    ba::io_context io;
    bp::async_pipe ip(io), op(io);
    //bp::async_pipe StdIn(io);

    bp::child MyProcess = bp::child("/usr/bin/tac", bp::std_out > op, bp::std_in < ip, io);

    std::function<void()> send_loop, recv_loop;

    ba::streambuf sb;
    send_loop = [&, i=0]() mutable {
        if (++i<100) {
            std::ostream(&sb) << "Sure no problem, " << i << std::endl;
            ba::async_write(ip, sb, [&send_loop](auto ec, auto /*tx*/) {
                //std::cout << "Sent " << tx << " bytes (" << ec.message() << ")\n";
                if (!ec) send_loop();
            });
        } else ip.close();
    };

    ba::streambuf rb;
    recv_loop = [&]() {
        ba::async_read_until(op, rb, "\n", [&](auto ec, auto /*tx*/) {
            //std::cout << "Received " << tx << " bytes (" << ec.message() << ")\n";
            std::cout << &rb << std::flush;
            if (!ec) recv_loop();
        });
    };

    io.post(send_loop);
    io.post(recv_loop);
    io.run();

    std::cout << "Bye\n";
}

Prints the expected:

Sure no problem, 99
Sure no problem, 98
Sure no problem, 97
Sure no problem, 96
Sure no problem, 95
Sure no problem, 94
Sure no problem, 93
Sure no problem, 92
Sure no problem, 91
Sure no problem, 90
Sure no problem, 89
Sure no problem, 88
Sure no problem, 87
Sure no problem, 86
Sure no problem, 85
Sure no problem, 84
Sure no problem, 83
Sure no problem, 82
Sure no problem, 81
Sure no problem, 80
Sure no problem, 79
Sure no problem, 78
Sure no problem, 77
Sure no problem, 76
Sure no problem, 75
Sure no problem, 74
Sure no problem, 73
Sure no problem, 72
Sure no problem, 71
Sure no problem, 70
Sure no problem, 69
Sure no problem, 68
Sure no problem, 67
Sure no problem, 66
Sure no problem, 65
Sure no problem, 64
Sure no problem, 63
Sure no problem, 62
Sure no problem, 61
Sure no problem, 60
Sure no problem, 59
Sure no problem, 58
Sure no problem, 57
Sure no problem, 56
Sure no problem, 55
Sure no problem, 54
Sure no problem, 53
Sure no problem, 52
Sure no problem, 51
Sure no problem, 50
Sure no problem, 49
Sure no problem, 48
Sure no problem, 47
Sure no problem, 46
Sure no problem, 45
Sure no problem, 44
Sure no problem, 43
Sure no problem, 42
Sure no problem, 41
Sure no problem, 40
Sure no problem, 39
Sure no problem, 38
Sure no problem, 37
Sure no problem, 36
Sure no problem, 35
Sure no problem, 34
Sure no problem, 33
Sure no problem, 32
Sure no problem, 31
Sure no problem, 30
Sure no problem, 29
Sure no problem, 28
Sure no problem, 27
Sure no problem, 26
Sure no problem, 25
Sure no problem, 24
Sure no problem, 23
Sure no problem, 22
Sure no problem, 21
Sure no problem, 20
Sure no problem, 19
Sure no problem, 18
Sure no problem, 17
Sure no problem, 16
Sure no problem, 15
Sure no problem, 14
Sure no problem, 13
Sure no problem, 12
Sure no problem, 11
Sure no problem, 10
Sure no problem, 9
Sure no problem, 8
Sure no problem, 7
Sure no problem, 6
Sure no problem, 5
Sure no problem, 4
Sure no problem, 3
Sure no problem, 2
Sure no problem, 1
Sure no problem, 1


来源:https://stackoverflow.com/questions/61155985/boostprocess-pipe-streams-and-unit-test

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!