【发布时间】:2016-06-27 06:00:56
【问题描述】:
我正在使用 PHPUnit 进行一组功能测试。在这些测试期间访问远程数据库。该数据库只能通过 SSH 隧道访问。因此,每次运行这些测试时,我都会在单独的终端中手动启动隧道。
有没有一种优雅的方法可以在 PHPUnit 设置期间启动 SSH 隧道,然后在拆卸时关闭隧道?
【问题讨论】:
我正在使用 PHPUnit 进行一组功能测试。在这些测试期间访问远程数据库。该数据库只能通过 SSH 隧道访问。因此,每次运行这些测试时,我都会在单独的终端中手动启动隧道。
有没有一种优雅的方法可以在 PHPUnit 设置期间启动 SSH 隧道,然后在拆卸时关闭隧道?
【问题讨论】:
我能想到的最干净的方法是“热线”引导代码:
// 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 隧道可用于多个测试,这很有用。
对于单个测试,您可以查看 setUpBeforeClass 和 tearDownAfterClass。
更多详情请点击此处: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);
}
}
我将它放在其他测试扩展的类中,因此隧道只设置一次并运行直到所有测试完成或我们终止进程。
【讨论】: