Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@mbland
Copy link
Contributor

@mbland mbland commented Jul 1, 2018

Closes #113. This should be robust enough to handle the /bin => /usr/bin symlink on CentOS7 as originally reported, as well as any manner of symlink chains leading to the bin/bats executable in the installation directory. Maintains portability between readlink implementations by not relying on the GNU-specific -e option.

There's no perceptible performance impact.

This renames the original bats_absolute_path function to the more obvious bats_resolve_absolute_root_dir, and introduces the BATS_MAX_SYMLINKS variable to ensure symlink resolution short-circuits in case cycles appear. While this can be user-controlled, I've not documented it in the README, hoping that no one will need to change the setting in a real-world situation.

Also tweaks the value of BATS_TEST_SUITE_TMPDIR from tmp to bats-test-tmp to avoid potential collisions with other BATS_TMPDIR directories.

cc: @rgm3

Closes #113. This should be robust enough to handle the /bin => /usr/bin
symlink on CentOS7 as originally reported, but any manner of symlink
chains leading to the `bin/bats` executable in the installation
directory. Maintains portability between `readlink` implementations by
not relying on the GNU-specific `-e` option.

There's no perceptible performance impact.

This renames the original `bats_absolute_path` function to the more
obvious `bats_resolve_absolute_root_dir`, and introduces the
`BATS_MAX_SYMLINKS` variable to ensure symlink resolution short-circuits
in case cycles appear. While this can be user-controlled, I've not
documented it in the README, hoping that no one will need to change the
setting in a real-world situation.

Also tweaks the value of `BATS_TEST_SUITE_TMPDIR` from `tmp` to
`bats-test-tmp` to avoid potential collisions with other `BATS_TMPDIR`
directories.
@mbland mbland requested a review from a team July 1, 2018 16:31
@ghost ghost assigned mbland Jul 1, 2018
@ghost ghost added the review label Jul 1, 2018
mbland added 3 commits July 1, 2018 14:19
I realized that the `while [[ -L "$PWD" && "$((--limit))" -ne -1 ]]`
loop could drop `limit` to `-1` before reaching the following check for
`[[ "$((--limit))" -ne -1 ]]`.

Added the "parent directories exhaust BATS_MAX_SYMLINKS" test case to
reproduce, which didn't cause an infinite loop, but failed when `cd`-ing
to `/usr/bin` terminated the inner loop, causing
`/usr/libexec/bats-core/bin/bats` not to be found.

Also added the "find BATS_ROOT without symlinks" test case to ensure the
loop executes correctly when `bin/bats` is executed directly, and added
`BATS_MAX_SYMLINKS=8` to "set BATS_ROOT with extreme symlink resolution"
to make sure the test traverses the exact number of expected symlinks.
Meant to remove this before the previous commit.
I realized that if the `bin/bats` script is executing, the operating
system has already traversed all the symbolic links to it, so enforcing
our own threshold is pointless.
@mbland
Copy link
Contributor Author

mbland commented Jul 1, 2018

Whoops... I realized that if the bin/bats script is executing, the operating system has already traversed all the symbolic links to it, so enforcing our own threshold is pointless. Hence I've removed BATS_MAX_SYMLINKS and the tests that exercised it.

mbland added 2 commits July 1, 2018 19:48
Today I learned about the `set -P` option, which causes `cd` to set
`PWD` to the physical directory, containing no symlinks. This eliminated
the need for the inner `while` loop to resolve `PWD` symlinks.

The Bash man page wording is a little confusing, but there's a great
example demonstrating the option at:

  https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html

The result is the same, but subshells are only spawned to resolve
target_name links, making the code a little smaller and improving the
performance ever-so-slightly.
Should've been preserved by the previous commit.
@mbland
Copy link
Contributor Author

mbland commented Jul 1, 2018

And today I learned about set -P. See my comments for commit 8d9afca for details.

Should've tried this two commits ago. Verified manually that Bash parses
the options to `set` in order, such that you can safely disable and
renable an option in the same invocation.
@mbland
Copy link
Contributor Author

mbland commented Jul 3, 2018

Whoops, I posted this to #113 yesterday, meant to post it here:

@bats-core/bats-core barring any suggestions/objections, I'll look to merge this by tomorrow.

@mbland mbland merged commit ace73a2 into master Jul 3, 2018
@mbland mbland deleted the fix-symlink-resolution-#113 branch July 3, 2018 19:45
@ghost ghost removed the review label Jul 3, 2018
rico-chet added a commit to rico-chet/bats-core that referenced this pull request Apr 10, 2020
Bats 1.1.0 - 2018-07-08

This is the first release with new features relative to the original Bats 0.4.0.

Added:
* The `-r, --recursive` flag to scan directory arguments recursively for
  `*.bats` files (bats-core#109)
* The `contrib/rpm/bats.spec` file to build RPMs (bats-core#111)

Changed:
* Travis exercises latest versions of Bash from 3.2 through 4.4 (bats-core#116, bats-core#117)
* Error output highlights invalid command line options (bats-core#45, bats-core#46, bats-core#118)
* Replaced `echo` with `printf` (bats-core#120)

Fixed:
* Fixed `BATS_ERROR_STATUS` getting lost when `bats_error_trap` fired multiple
  times under Bash 4.2.x (bats-core#110)
* Updated `bin/bats` symlink resolution, handling the case on CentOS where
  `/bin` is a symlink to `/usr/bin` (bats-core#113, bats-core#115)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bats can't find BATS_ROOT on CentOS 7 when /bin -> /usr/bin

3 participants