上下文
作为使用BATS测试的Bash脚本的一部分,我注意到当我运行激活ssh帐户的函数时,我的测试不会终止。
代码
下面的函数假设/home/<username>/.ssh/
中存在一个私有和公共ssh密钥对。如果我使用source src/the_bash_script.sh && activate_ssh_account <my_git_username>
手动运行它,它会工作,并显示Identity added: /home/name/.ssh/<my_git_email>
:
#!/bin/bash
# Activates/enables the ssh for
activate_ssh_account() {
git_username=$1
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/"$git_username"
}
然而,当它从测试中运行时:
#!./test/libs/bats/bin/bats
load 'libs/bats-support/load'
load 'libs/bats-assert/load'
# https://github.com/bats-core/bats-file#Index-of-all-functions
load 'libs/bats-file/load'
# https://github.com/bats-core/bats-assert#usage
load 'assert_utils'
source src/the_bash_script.sh
@test "Check if ssh-account is activated after activating it." {
activate_ssh_account "some_git_username"
assert_equal "Something" "Something_else"
}
它无限期地挂着。
问题
如何在不导致BATS测试无限期挂起的情况下激活ssh帐户?
测试无限期挂起,因为BATS等待ssh-agent
终止(一旦执行第eval "$(ssh-agent -s)"
行,就会在后台运行(。更具体地说,BATS等待文件描述符3关闭(它由ssh-agent
保持打开(。
因此,这可以通过实现文档中提到的变通方法或通过终止ssh-agent
来解决。
文档中的解决方法:
#!/bin/bash
# Activates/enables the ssh for
activate_ssh_account() {
git_username=$1
eval "$(ssh-agent -s 3>&-)"
ssh-add ~/.ssh/"$git_username"
}
这将关闭ssh-agent
的fd 3,BATS将不再挂起。请注意,这将使ssh-agent
在后台运行,即使在BATS退出之后也是如此。从你的问题中还不清楚这是否可取。如果不是,请使用下面的备选方案。
杀死ssh-agent
:
向activate_ssh_account
:添加清除陷阱
#!/bin/bash
# Activates/enables the ssh for
activate_ssh_account() {
trap "trap - RETURN; kill $SSH_AGENT_PID" RETURN
git_username=$1
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/"$git_username"
}
当函数退出时执行陷阱,并使用eval "$(ssh-agent -s)"
导出的pid(即变量SSH_AGENT_PID
(杀死ssh-agent
。
如果你出于某种原因不想使用陷阱,这也会起作用:
#!/bin/bash
# Activates/enables the ssh for
activate_ssh_account() {
git_username=$1
eval "$(ssh-agent -s)"
result=0
ssh-add ~/.ssh/"$git_username" || result=$?
kill $SSH_AGENT_PID
return $result
}
请注意,||
构造是必要的,因为一旦命令失败,BATS将停止执行函数的代码(即,如果没有||
,如果ssh-add
失败,则不会执行kill
(。
附带说明,要实际测试activate_ssh_account
是否成功,您应该使用assert_success
而不是assert_equal
(除非您在问题中遗漏了更多代码(。
我从未使用过BATS,但通过阅读文档,我可以说有一个用于共享公共代码的特定命令。您可能需要指定完整路径:
load
:共享公共代码您可能希望在多个测试文件之间共享公共代码。Bats包含一个方便的加载命令,用于相对于当前测试文件的位置来查找Bash源文件。例如,如果您在
test/foo.bats
中进行蝙蝠测试,则命令
load test_helper
将在测试文件中获取脚本test/test_helper.bash。这对于共享功能以设置环境或加载设备非常有用。
选项1:
尝试更换
source src/the_bash_script.sh
带有
load '/full/path/to/src/the_bash_script.sh'
选项2:
尝试在@test
中添加来源
@test "Check if ssh-account is activated after activating it." {
source /full/path/to/src/the_bash_script.sh
activate_ssh_account "some_git_username"
assert_equal "Something" "Something_else"
}