如何在 BATS 测试中激活 Bash 函数中的 ssh 帐户?
How to activate an ssh-account in Bash function in BATS test?
上下文
作为使用 BATS 测试的 Bash 脚本的一部分,我注意到当我 运行 一个激活 ssh 帐户的函数时,我的测试没有终止。
代码
以下函数假设 /home/<username>/.ssh/
中存在私有和 public 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=
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,但通过阅读文档,我可以说有一个用于共享公共代码的特定命令。不过您可能需要指定完整路径:
load
: Share common code
You may want to share common code across multiple test files. Bats includes a convenient load command for sourcing a Bash source file relative to the location of the current test file. For example, if you have a Bats test in test/foo.bats
, the command
load test_helper
will source the script test/test_helper.bash in your test file. This can be useful for sharing functions to set up your environment or load fixtures.
选项 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"
}
测试无限期挂起,因为 BATS 等待 ssh-agent
终止(一旦执行第 eval "$(ssh-agent -s)"
行,它就会在后台运行)。更具体地说,BATS 等待 文件描述符 3 关闭(它由 ssh-agent
保持打开状态)。
因此,这可以通过实施 workaround mentioned in the documentation 或杀死 ssh-agent
.
来解决
文档中的解决方法:
#!/bin/bash
# Activates/enables the ssh for
activate_ssh_account() {
git_username=
eval "$(ssh-agent -s 3>&-)"
ssh-add ~/.ssh/"$git_username"
}
这将关闭 ssh-agent
的 fd 3,BATS 将不再挂起。请注意,即使在 BATS 退出后,这也会在后台留下 ssh-agent
运行。从您的问题中不清楚是否需要这样做。如果不是,请使用下面的替代方法。
杀死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=
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=
eval "$(ssh-agent -s)"
result=0
ssh-add ~/.ssh/"$git_username" || result=$?
kill $SSH_AGENT_PID
return $result
}
请注意,||
结构是必要的,因为一旦命令失败,BATS 将停止执行函数的代码(即没有 ||
,如果 [=27] 将不会执行 kill
=]失败)。
作为旁注,要实际测试 activate_ssh_account
是成功还是失败,您应该使用 assert_success
而不是 assert_equal
(除非您在问题中省略了更多代码).
上下文
作为使用 BATS 测试的 Bash 脚本的一部分,我注意到当我 运行 一个激活 ssh 帐户的函数时,我的测试没有终止。
代码
以下函数假设 /home/<username>/.ssh/
中存在私有和 public 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=
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,但通过阅读文档,我可以说有一个用于共享公共代码的特定命令。不过您可能需要指定完整路径:
load
: Share common codeYou may want to share common code across multiple test files. Bats includes a convenient load command for sourcing a Bash source file relative to the location of the current test file. For example, if you have a Bats test in
test/foo.bats
, the command
load test_helper
will source the script test/test_helper.bash in your test file. This can be useful for sharing functions to set up your environment or load fixtures.
选项 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"
}
测试无限期挂起,因为 BATS 等待 ssh-agent
终止(一旦执行第 eval "$(ssh-agent -s)"
行,它就会在后台运行)。更具体地说,BATS 等待 文件描述符 3 关闭(它由 ssh-agent
保持打开状态)。
因此,这可以通过实施 workaround mentioned in the documentation 或杀死 ssh-agent
.
文档中的解决方法:
#!/bin/bash
# Activates/enables the ssh for
activate_ssh_account() {
git_username=
eval "$(ssh-agent -s 3>&-)"
ssh-add ~/.ssh/"$git_username"
}
这将关闭 ssh-agent
的 fd 3,BATS 将不再挂起。请注意,即使在 BATS 退出后,这也会在后台留下 ssh-agent
运行。从您的问题中不清楚是否需要这样做。如果不是,请使用下面的替代方法。
杀死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=
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=
eval "$(ssh-agent -s)"
result=0
ssh-add ~/.ssh/"$git_username" || result=$?
kill $SSH_AGENT_PID
return $result
}
请注意,||
结构是必要的,因为一旦命令失败,BATS 将停止执行函数的代码(即没有 ||
,如果 [=27] 将不会执行 kill
=]失败)。
作为旁注,要实际测试 activate_ssh_account
是成功还是失败,您应该使用 assert_success
而不是 assert_equal
(除非您在问题中省略了更多代码).