Skip to content

tralston/bats-file

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bats-file

GitHub license GitHub release Build Status

bats-file is a helper library providing common filesystem related assertions and helpers for Bats.

Assertions are functions that perform a test and output relevant information on failure to help debugging. They return 1 on failure and 0 otherwise. Output, formatted for readability, is sent to the standard error to make assertions usable outside of @test blocks too.

Features:

Dependencies:

  • bats-support - output formatting, function call restriction

See the shared documentation to learn how to install and load this library.

Index of all functions

Test File Types Test File Attributes Test File Content
Check if a file or directory exist!
- assert_exist
- assert_not_exist
Check if file is executable!
- assert_file_executable
- assert_file_not_executable
Check if file is empty!
- assert_file_empty
- assert_file_not_empty
Check if a file exist!
- assert_file_exist
- assert_file_not_exist
Check the owner of a file!
- assert_file_owner
- assert_file_not_owner
Check if file contains regex!
- assert_file_contains
- assert_file_not_contains
Check if a directory exist!
- assert_dir_exist
- assert_dir_not_exist
Check the permission of a file!
- assert_file_permission
- assert_not_file_permission
Check if file is a symlink to target!
- assert_symlink_to
- assert_not_symlink_to
Check if a link exist!
- assert_link_exist
- assert_link_not_exist
Check the size of a file by bytes!
- assert_file_size_equals
Check if a block special file exist!
- assert_block_exist
- assert_block_not_exist
Check if a file have zero bytes!
- assert_size_zero
- assert_size_not_zero
Check if a character special file exist!
- assert_character_exist
- assert_character_not_exist
Check the groupID of a file!
- assert_file_group_id_set
- assert_file_not_group_id_set
Check if a socket exist!
- assert_socket_exist
- assert_socket_not_exist
Check the userID of a file!
- assert_file_user_id_set
- assert_file_not_user_id_set
Check if a fifo special file exist!
- assert_fifo_exist
- assert_fifo_not_exist
Check if a stickybit is set!
- assert_sticky_bit
- assert_no_sticky_bit

Usage

Test File Types:

assert_exist

Fail if the given file or directory does not exist.

@test 'assert_exist()' {
  assert_exist /path/to/non-existent-file-or-dir
}

On failure, the path is displayed.

-- file or directory does not exist --
path : /path/to/non-existent-file-or-dir
--

Back to index

assert_not_exist

Fail if the given file or directory does exist.

@test 'assert_not_exist()' {
  assert_not_exist /path/to/existent-file-or-dir
}

On failure, the path is displayed.

-- file or directory exists, but it was expected to be absent --
path : /path/to/existent-file-or-dir
--

Back to index


assert_file_exist

Fail if the given file does not exist.

@test 'assert_file_exist()' {
  assert_file_exist /path/to/non-existent-file
}

On failure, the path is displayed.

-- file does not exist --
path : /path/to/non-existent-file
--

Back to index

assert_file_not_exist

Fail if the given file or directory exists.

@test 'assert_file_not_exist() {
  assert_file_not_exist /path/to/existing-file
}

On failure, the path is displayed.

-- file or directory exists, but it was expected to be absent --
path : /path/to/existing-file
--

Back to index


assert_dir_exist

Fail if the given directory does not exist.

@test 'assert_dir_exist()' {
  assert_file_exist /path/to/non-existent-directory
}

On failure, the path is displayed.

-- directory does not exist --
path : /path/to/non-existent-directory
--

Back to index

assert_dir_not_exist

Fail if the given directory exists.

@test 'assert_dir_not_exist() {
  assert_dir_not_exist /path/to/existing-directory
}

On failure, the path is displayed.

-- directory exists, but it was expected to be absent --
path : /path/to/existing-directory
--

Back to index


assert_link_exist

Fail if the given symbolic link does not exist.

@test 'assert_link_exist()' {
  assert_file_exist /path/to/non-existent-link-file
}

On failure, the path is displayed.

-- symbolic link does not exist --
path : /path/to/non-existent-link-file
--

Back to index

assert_link_not_exist

Fail if the given symbolic link exists.

@test 'assert_link_not_exist() {
  assert_file_not_exist /path/to/existing-link-file
}

On failure, the path is displayed.

-- symbolic link exists, but it was expected to be absent --
path : /path/to/existing-link-file
--

Back to index


assert_block_exist

Fail if the given block special file does not exist.

@test 'assert_block_exist()' {
  assert_file_exist /path/to/non-existent-block-file
}

On failure, the path is displayed.

-- block special file does not exist --
path : /path/to/non-existent-block-file
--

Back to index

assert_block_not_exist

Fail if the given block special file exists.

@test 'assert_block_not_exist() {
  assert_file_not_exist /path/to/existing-block-file
}

On failure, the path is displayed.

-- block special file exists, but it was expected to be absent --
path : /path/to/existing-block-file
--

Back to index


assert_character_exist

Fail if the given character special file does not exist.

@test 'assert_character_exist()' {
  assert_file_exist /path/to/non-existent-character-file
}

On failure, the path is displayed.

-- character special file does not exist --
path : /path/to/non-existent-character-file
--

Back to index

assert_character_not_exist

Fail if the given character special file exists.

@test 'assert_character_not_exist() {
  assert_file_not_exist /path/to/existing-character-file
}

On failure, the path is displayed.

-- character special file exists, but it was expected to be absent --
path : /path/to/existing-character-file
--

Back to index


assert_socket_exist

Fail if the given socket does not exist.

@test 'assert_socket_exist()' {
  assert_file_exist /path/to/non-existent-socket
}

On failure, the path is displayed.

-- socket does not exist --
path : /path/to/non-existent-socket
--

Back to index

assert_socket_not_exist

Fail if the given socket exists.

@test 'assert_socket_not_exist() {
  assert_file_not_exist /path/to/existing-socket
}

On failure, the path is displayed.

-- socket exists, but it was expected to be absent --
path : /path/to/existing-socket
--

Back to index


assert_fifo_exist

Fail if the given named pipe does not exist.

@test 'assert_fifo_exist()' {
  assert_file_exist /path/to/non-existent-fifo-file
}

On failure, the path is displayed.

-- fifo does not exist --
path : /path/to/non-existent-fifo-file
--

Back to index

assert_fifo_not_exist

Fail if the given named pipe exists.

@test 'assert_fifo_not_exist()' {
  assert_file_not_exist /path/to/existing-fifo-file
}

On failure, the path is displayed.

-- named pipe exists, but it was expected to be absent --
path : /path/to/existing-fifo-file
--

Back to index



Test File Attributes:

assert_file_executable

Fail if the given file is not executable.

@test 'assert_file_executable()' {
  assert_file_executable /path/to/executable-file
}

On failure, the path is displayed.

-- file is not executable --
path : /path/to/executable-file
--

Back to index

assert_file_not_executable

Fail if the given file is executable.

@test 'assert_file_not_executable()' {
  assert_file_not_executable /path/to/executable-file
}

On failure, the path is displayed.

-- file is executable, but it was expected to be not executable --
path : /path/to/executable-file
--

Back to index


assert_file_owner

Fail if given user is not the owner of the given file.

@test 'assert_file_owner() {
  assert_file_owner $owner /path/to/owner
}

On failure, the path is displayed.

-- user is not the owner of the file --
path : /path/to/notowner
owner : user
--

Back to index

assert_not_file_owner

Fail if given user is the owner of the given file.

@test 'assert_not_file_owner() {
  assert_not_file_owner $owner /path/to/notowner
}

On failure, the path is displayed.

-- Fail if given user is the owner, but it was expected not to be --
path : /path/to/owner
owner : $owner
--

Back to index


assert_file_permission

Fail if given file does not have given permission.

@test 'assert_file_permission() {
  assert_file_permission $permission /path/to/permission
}

On failure, the path is displayed.

-- given file does not have permissions 777 --
path : /path/to/nopermission
permission: $permission
--

Back to index

assert_not_file_permission

Fail if given file has given permission.

@test 'assert_not_file_permission() {
  assert_not_file_permission $permission /path/to/nopermission
}

On failure, the path is displayed.

-- given file has permissions 777, but it was expected not to have --
path : /path/to/permission
permission : $permission
--

Back to index


assert_file_size_equals

Fail if the given file size does not match the input.

@test 'assert_file_size_equals() {
    assert_file_size_equals /path/to/non-empty-file bytecount
}

On failure, the path and expected bytecount are displayed.

Back to index


assert_size_zero

Fail if file is not zero byte.

@test 'assert_size_zero() {
  assert_size_zero /path/to/zerobyte
}

On failure, the path is displayed.

-- file is not zero byte --
path : /path/to/notzerobyte
--

Back to index

assert_size_not_zero

Fail if file size is zero byte.

@test 'assert_size_not_zero() {
  assert_size_not_zero /path/to/notzerobyte
}

On failure, the path is displayed.

-- file is 0 byte, but it was expected not to be --
path : /path/to/zerobyte
--

Back to index


assert_file_group_id_set

Fail if group id is not set.

@test 'assert_file_group_id_set() {
  assert_file_group_id_set /path/to/groupidset
}

On failure, the path is displayed.

-- group id is not set --
path : /path/to/groupidnotset
--

Back to index

assert_file_not_group_id_set

Fail if group id is set.

@test 'assert_file_not_group_id_set() {
  assert_file_not_group_id_set /path/to/groupidnotset
}

On failure, the path is displayed.

-- group id is set, but it was expected not to be --
path : /path/to/groupdidset
--

Back to index


assert_file_user_id_set

Fail if user id is not set.

@test 'assert_file_user_id_set() {
  assert_file_user_id_set /path/to/useridset
}

On failure, the path is displayed.

-- user id is not set --
path : /path/to/useridnotset
--

Back to index

assert_file_not_user_id_set

Fail if user id is set.

@test 'assert_file_not_user_id_set() {
  assert_file_not_user_id_set /path/to/groupidnotset
}

On failure, the path is displayed.

-- user id is set, but it was expected not to be --
path : /path/to/userdidset
--

Back to index


assert_sticky_bit

Fail if stickybit is not set.

@test 'assert_sticky_bit() {
  assert_sticky_bit /path/to/stickybit
}

On failure, the path is displayed.

-- stickybit is not set --
path : /path/to/notstickybit
--

Back to index

assert_not_sticky_bit

Fail if stickybit is set.

@test 'assert_not_sticky_bit() {
  assert_not_sticky_bit /path/to/notstickybit
}

On failure, the path is displayed.

-- stickybit is set, but it was expected not to be --
path : /path/to/stickybit
--

Back to index


Test File Content:

assert_file_empty

Fail if the given file or directory is not empty.

@test 'assert_file_empty()' {
  assert_file_empty /path/to/empty-file
}

On failure, the path and the content of the file is displayed.

-- file is not empty --
path : /path/to/empty-file
output (2 lines) : content-line-1
content-line-2
--

Back to index

assert_file_not_empty

Fail if the given file or directory empty.

@test 'assert_file_not_empty() {
  assert_file_not_empty /path/to/non-empty-file
}

On failure, the path is displayed.

-- file empty, but it was expected to contain something --
path : /path/to/non-empty-file
--

Back to index


assert_file_contains

Fail if the given file does not contain the regex.

@test 'assert_file_contains() {
    assert_file_contains /path/to/non-empty-file regex
}

On failure, the path and expected regex are displayed.

Back to index


assert_symlink_to

Fail if the given file is not a symbolic to a defined target.

@test 'assert_symlink_to() {
  assert_symlink_to /path/to/source-file /path/to/symlink
}

On failure, the path is displayed.

-- symbolic link does not have the correct target --
path : /path/to/symlink
--

Back to index

assert_not_symlink_to

Fail if the given file is a symbolic to a defined target.

@test 'assert_not_symlink_to() {
  assert_not_symlink_to /path/to/source-file /path/to/symlink
}

On failure, the path is displayed.

-- file is a symbolic link --
path : /path/to/symlink
--
-- symbolic link does have the correct target --
path : /path/to/symlink
--

Back to index



Working with temporary directories

When testing code that manipulates the filesystem, it is good practice to run tests in clean, throw-away environments to ensure correctness and reproducibility. Therefore, this library includes convenient functions to create and destroy temporary directories.

temp_make

Create a temporary directory for the current test in BATS_TMPDIR. The directory is guaranteed to be unique and its name is derived from the test's filename and number for easy identification.

<test-filename>-<test-number>-<random-string>

This information is only available in setup, @test and teardown, thus the function must be called from one of these locations.

The path of the directory is displayed on the standard output and is meant to be captured into a variable.

setup() {
  TEST_TEMP_DIR="$(temp_make)"
}

For example, for the first test in sample.bats, this snippet creates a directory named sample.bats-1-XXXXXXXXXX, where each trailing X is a random alphanumeric character.

If the directory cannot be created, the function fails and displays an error message on the standard error.

-- ERROR: temp_make --
mktemp: failed to create directory via template ‘/etc/samle.bats-1-XXXXXXXXXX’: Permission denied
--

Directory name prefix

The directory name can be prefixed with an arbitrary string using the --prefix <prefix> option (-p <prefix> for short).

setup() {
  TEST_TEMP_DIR="$(temp_make --prefix 'myapp-')"
}

Following the previous example, this will create a directory named myapp-sample.bats-1-XXXXXXXXXX. This can be used to group temporary directories.

Generally speaking, the directory name is of the following form.

<prefix><test-filename>-<test-number>-<random-string>

temp_del

Delete a temporary directory, typically created with temp_make.

teardown() {
  temp_del "$TEST_TEMP_DIR"
}

If the directory cannot be deleted, the function fails and displays an error message on the standard error.

-- ERROR: temp_del --
rm: cannot remove '/etc/samle.bats-1-04RUVmBP7x': No such file or directory
--

Note: Actually, this function can be used to delete any file or directory. However, it is most useful in deleting temporary directories created with temp_make, hence the naming.

Preserve directory

During development, it is useful to peak into temporary directories post-mortem to see what the tested code has done.

When BATSLIB_TEMP_PRESERVE is set to 1, the function succeeds but the directory is not deleted.

$ BATSLIB_TEMP_PRESERVE=1 bats sample.bats

Preserve directory on failure

During debugging, it is useful to preserve the temporary directories of failing tests.

When BATSLIB_TEMP_PRESERVE_ON_FAILURE is set to 1, the function succeeds but the directory is not deleted if the test has failed.

$ BATSLIB_TEMP_PRESERVE_ON_FAILURE=1 bats sample.bats

The outcome of a test is only known in teardown, therefore this feature can be used only when temp_del is called from that location. Otherwise and error is displayed on the standard error.

Transforming displayed paths

Sometimes paths can be long and tiresome to parse to the human eye. To help focus on the interesting bits, all functions support hiding part of the displayed paths by replacing it with an arbitrary string.

A single pattern substitution is performed on the path before displaying it.

${path/$BATSLIB_FILE_PATH_REM/$BATSLIB_FILE_PATH_ADD}

The longest match of the pattern BATSLIB_FILE_PATH_REM is replaced with BATSLIB_FILE_PATH_ADD. To anchor the pattern to the beginning or the end, prepend # or %, respectively.

For example, the following example hides the path of the temporary directory where the test takes place.

setup {
  TEST_TEMP_DIR="$(temp_make)"
  BATSLIB_FILE_PATH_REM="#${TEST_TEMP_DIR}"
  BATSLIB_FILE_PATH_ADD='<temp>'
}

@test 'assert_file_exist()' {
  assert_file_exist "${TEST_TEMP_DIR}/path/to/non-existent-file"
}

teardown() {
  temp_del "$TEST_TEMP_DIR"
}

On failure, only the relevant part of the path is shown.

-- file does not exist --
path : <temp>/path/to/non-existent-file
--

About

Common filesystem assertions for Bats

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Shell 100.0%