如何在BATS测试中的Bash功能中激活ssh帐户



上下文

作为使用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"
}

最新更新