PHPUnit 测试期间的 SSH 隧道

SSH tunnel for duration of PHPUnit test

我正在使用 PHPUnit 进行一组功能测试。在这些测试期间访问远程数据库。数据库只能通过 SSH 隧道访问。因此,每次我 运行 这些测试时,我都会在单独的终端中手动启动隧道。

有没有一种优雅的方法可以在 PHPUnit 设置期间启动 SSH 隧道,然后在拆卸时关闭隧道?

我能想到的最干净的方法是 "hotwire" bootstrap 代码:

// your bootstrap code above

// this gets called before first test
system("script_to_start_ssh_tunnel");

// this gets called after last test
register_shutdown_function(function(){
    system("script_to_stop_ssh_tunnel");
});

// i went with 'system()' so you can also see the output.
// if you don't need it, go with 'exec()'

如果您需要 ssh 隧道可用于多个测试,这将很有用。

对于单个测试,您可以查看 setUpBeforeClasstearDownAfterClass

此处提供更多详细信息:phpunit docs

@alex-tartan 让我走对了方向。 This post 也有帮助。为了完整起见,这里是我正在使用的解决方案。使用控制套接字将 SSH 隧道作为后台进程启动。在关闭时检查套接字并退出后台进程。在每个单元测试设置中检查控制套接字并跳过启动 SSH 如果它已经 运行。

protected function setUp()
{
    ...
    if (!file_exists('/tmp/tunnel_ctrl_socket')) {
        // Redirect to /dev/null or exec will never return
        exec("ssh -M -S /tmp/tunnel_ctrl_socket -fnNT -i $key -L 3306:$db:3306 $user@$host &>/dev/null");
        $closeTunnel = function($signo = 0) use ($user, $host) {
            if (file_exists('/tmp/tunnel_ctrl_socket')) {
                exec("ssh -S /tmp/tunnel_ctrl_socket -O exit $user@$host");
            }
        };
        register_shutdown_function($closeTunnel);
        // In case we kill the tests early...
        pcntl_signal(SIGTERM, $closeTunnel);
    }
}

我把它放在其他测试扩展的 class 中,因此隧道只设置一次并运行直到所有测试完成或我们终止进程。