Context
As part of a Bash script that is tested using the BATS, I noticed that my tests are not terminated when I run a function that activates an ssh-account.
Code
The following function assumes a private and public ssh key pair exists in /home/<username>/.ssh/. If I run it manually using source src/the_bash_script.sh && activate_ssh_account <my_git_username>, it works and says 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"
}
However, when it is ran from the test with:
#!./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"
}
It hangs indefinitely.
Question
How can I activate an ssh-account without causing the BATS tests to hang indefinitely?
The test hangs indefinitely because BATS waits for
ssh-agentto terminate (which runs in the background once lineeval "$(ssh-agent -s)"is executed). To be more specific, BATS waits for file descriptor 3 to be closed (which is being held open byssh-agent).Thus, this can be solved by either implementing the workaround mentioned in the documentation or by killing
ssh-agent.Workaround from documentation:
This closes fd 3 for
ssh-agentand BATS will no longer hang. Note that this leavesssh-agentrunning in the background, even after BATS exits. It is unclear from your question if that is desired or not. If it's not, use the alternative below.Kill
ssh-agent:Add a cleanup trap to
activate_ssh_account:The trap is executed when the function exits and kills
ssh-agentusing the pid exported byeval "$(ssh-agent -s)"(i.e. variableSSH_AGENT_PID).If you don't want to use a trap for some reason, this will also work:
Note that the
||construct is necessary because BATS will stop executing the function's code once a command fails (i.e. without||,killwill not be executed ifssh-addfails).As a side note, to actually test if
activate_ssh_accountsucceeds or fails, you should useassert_successinstead ofassert_equal(unless there is more code that you omitted in your question).