diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c67b75 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vagrant +# vagrant virtualbox image creates this log file. so, better to ignore +*-cloudimg-console.log \ No newline at end of file diff --git a/README.md b/README.md index d4133a6..16982dd 100644 --- a/README.md +++ b/README.md @@ -947,6 +947,50 @@ path : /path/to/non-existent-file -- ``` +## **Development** + +No one would want to develop piece of bash dependant libraries on their laptops due to single mistake (globbing for instance) can cause a disaster. In order to prevent this there is a Vagrantfile that you can use. + +In order to start development environment, you have to take two steps; + +```shell +user@localhost:~/bats-file$ vagrant up +``` + +The line above spins up a brand new virtualbox image and provisions with prerequisites. + +However, as the tests require not to be on a network share due to running commands eg: `mknod`, the files are shared into the VM by `rsync` module. Rsync in vagrant only runs initialy and stops. During the active development, you regularly change files and might want to see the impact. To achive that, you have to use auto rsync. + +> `auto-rsync` is a long running command. It means that it has to run on terminal screen as long as the VM is up and running. So, you have to keep this in a dedicated terminal screen. + +After bringing up the VM, you can simply run following command; + +```shell +user@localhost:~/bats-file$ vagrant rsync-auto +``` + +**WARNING! WARNING! WARNING!:** There will be a small delay between file save and sync. When you save a file please keep eye on the terminal window/pane and sync is triggered and finished. Simply run your next test with 5s-10s delay. + +The repo files can be found under `/home/vagrant/bats-file` and you can run tests with + +```shell +user@localhost:~/bats-file$ bats test +# or +user@localhost:~/bats-file$ bats test/on-particular-test.bats +``` + +Once you're done with development, you can simply turn the VM off with + +```shell +user@localhost:~/bats-file$ vagrant halt +``` + +### Why? + +- Why Vagrant, not Docker + - This replicates the 100% CI +- Why EoL Xenial image + - This replicates the 100% CI. Also, one step at a time. This wasn't in place at all. However, this change will bring up other concerns. So, that problems should be solved at another time. diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..d914ea5 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,36 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure("2") do |config| + config.vm.box = "ubuntu/xenial64" + config.vm.network "public_network" + config.vm.synced_folder ".", "/home/vagrant/bats-file/", type: "rsync", + rsync__exclude: [ + ".git/", + ".gitignore", + "*.yml", + "*.md", + "LICENSE", + "*.json", + "*.log", + "Vagrantfile", + ], + rsync__args: ["--verbose", "--archive", "--delete", "-z"] + + config.vm.provider "virtualbox" do |vb| + # vb.gui = true + vb.memory = "1024" + end + config.vm.provision "shell", privileged: true, inline: <<-SHELL + apt-get update + apt-get install -y git vim curl + ln -s /usr/bin/python3 /usr/bin/python + SHELL + + config.vm.provision "shell", privileged: false, inline: <<-SHELL + mkdir -p $HOME/.local/bin + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /home/vagrant/.bashrc + git clone --depth 1 https://github.com/bats-core/bats-support /home/vagrant/bats-support + /home/vagrant/bats-file/script/install-bats.sh + SHELL +end diff --git a/src/file.bash b/src/file.bash index 7f41e0d..8a92430 100644 --- a/src/file.bash +++ b/src/file.bash @@ -283,27 +283,20 @@ assert_files_equal() { assert_file_owner() { local -r owner="$1" local -r file="$2" - if [[ `uname` == "Darwin" ]]; then - sudo chown root ${TEST_FIXTURE_ROOT}/dir/owner - sudo chown daemon ${TEST_FIXTURE_ROOT}/dir/notowner - if [ `stat -f '%Su' "$file"` != "$owner" ]; then - local -r rem="$BATSLIB_FILE_PATH_REM" - local -r add="$BATSLIB_FILE_PATH_ADD" - batslib_print_kv_single 4 'path' "${file/$rem/$add}" \ - | batslib_decorate "user $owner is not the owner of the file" \ - | fail + if [[ "$(uname)" == "Darwin" ]]; then + __cmd_param="-f %Su" + elif [[ "$(uname)" == "Linux" ]]; then + __cmd_param="-c %U" fi -elif [[ `uname` == "Linux" ]]; then - sudo chown root ${TEST_FIXTURE_ROOT}/dir/owner - sudo chown daemon ${TEST_FIXTURE_ROOT}/dir/notowner - if [ `stat -c "%U" "$file"` != "$owner" ]; then + __o=$(stat $__cmd_param "$file") + + if [[ "$__o" != "$owner" ]]; then local -r rem="$BATSLIB_FILE_PATH_REM" local -r add="$BATSLIB_FILE_PATH_ADD" batslib_print_kv_single 4 'path' "${file/$rem/$add}" \ | batslib_decorate "user $owner is not the owner of the file" \ | fail fi -fi } # Fail if file does not have given permissions. This diff --git a/test/59-assert-10-assert_file_owner.bats b/test/59-assert-10-assert_file_owner.bats index f32b26c..ec24089 100644 --- a/test/59-assert-10-assert_file_owner.bats +++ b/test/59-assert-10-assert_file_owner.bats @@ -4,13 +4,30 @@ load 'test_helper' fixtures 'exist' setup () { - touch ${TEST_FIXTURE_ROOT}/dir/owner ${TEST_FIXTURE_ROOT}/dir/notowner + touch ${TEST_FIXTURE_ROOT}/dir/owner ${TEST_FIXTURE_ROOT}/dir/notowner + sudo_path=$(command -v sudo 2>/dev/null) + # There is PATH addition to /usr/sbin which won't come by default on bash3 + # on macOS + chown_path=$(PATH="$PATH:/usr/sbin" command -v chown 2>/dev/null) + if [[ "$(whoami)" != 'root' ]] && [ -x "$sudo_path" ]; then + __cmd="$sudo_path $chown_path" + else + __cmd="$chown_path" + fi + $__cmd root ${TEST_FIXTURE_ROOT}/dir/owner + $__cmd daemon ${TEST_FIXTURE_ROOT}/dir/notowner } + teardown () { - rm -f ${TEST_FIXTURE_ROOT}/dir/owner ${TEST_FIXTURE_ROOT}/dir/notowner + sudo_path=$(command -v sudo 2>/dev/null) + if [[ "$(whoami)" != 'root' ]] && [ -x "$sudo_path" ]; then + __cmd="$sudo_path rm -f" + else + __cmd="rm -f" + fi + $__cmd ${TEST_FIXTURE_ROOT}/dir/owner ${TEST_FIXTURE_ROOT}/dir/notowner } - # Correctness @test 'assert_file_owner() : returns 0 if user root is the owner of the file' { local -r owner="root" @@ -18,7 +35,7 @@ teardown () { run assert_file_owner "$owner" "$file" [ "$status" -eq 0 ] echo ${#lines[@]} - [ "${#lines[@]}" -eq 0 ] + [ "${#lines[@]}" -eq 0 ] } diff --git a/test/59-assert-11-assert_not_file_owner.bats b/test/59-assert-11-assert_not_file_owner.bats index 09db94e..c80480e 100644 --- a/test/59-assert-11-assert_not_file_owner.bats +++ b/test/59-assert-11-assert_not_file_owner.bats @@ -4,10 +4,28 @@ load 'test_helper' fixtures 'exist' setup () { - touch ${TEST_FIXTURE_ROOT}/dir/owner ${TEST_FIXTURE_ROOT}/dir/notowner + touch ${TEST_FIXTURE_ROOT}/dir/owner ${TEST_FIXTURE_ROOT}/dir/notowner + sudo_path=$(command -v sudo 2>/dev/null) + # There is PATH addition to /usr/sbin which won't come by default on bash3 + # on macOS + chown_path=$(PATH="$PATH:/usr/sbin" command -v chown 2>/dev/null) + if [[ "$(whoami)" != 'root' ]] && [ -x "$sudo_path" ]; then + __cmd="$sudo_path $chown_path" + else + __cmd="$chown_path" + fi + $__cmd root ${TEST_FIXTURE_ROOT}/dir/owner + $__cmd daemon ${TEST_FIXTURE_ROOT}/dir/notowner } + teardown () { - rm -f ${TEST_FIXTURE_ROOT}/dir/owner ${TEST_FIXTURE_ROOT}/dir/notowner + sudo_path=$(command -v sudo 2>/dev/null) + if [[ "$(whoami)" != 'root' ]] && [ -x "$sudo_path" ]; then + __cmd="$sudo_path rm -f" + else + __cmd="rm -f" + fi + $__cmd ${TEST_FIXTURE_ROOT}/dir/owner ${TEST_FIXTURE_ROOT}/dir/notowner } # Correctness