Skip to content

Commit

Permalink
Drl 59/implement shellspec (#23)
Browse files Browse the repository at this point in the history
* add shellspec config and example tests

* Add shellspec to github workflow

* add pot mock, example tests
  • Loading branch information
msterle authored Mar 26, 2024
1 parent d9c1e0d commit 863576b
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: lint
name: lint-and-test

on: [push]

Expand All @@ -22,3 +22,22 @@ jobs:
else
echo "No shell scripts with #!/bin/sh shebang found."
fi
test:
name: Run shellspec
runs-on: ubuntu-latest

steps:
- name: Install shellspec
run: |
cd ~
wget https://github.com/shellspec/shellspec/archive/0.28.1.tar.gz
tar xzvf 0.28.1.tar.gz
mkdir ~/.local/bin
ln -s ~/shellspec-0.28.1/bin/shellspec ~/.local/bin/
- name: Check out code
uses: actions/checkout@v4

- name: Run shellspec
run: shellspec
12 changes: 12 additions & 0 deletions .shellspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--require spec_helper

## Default kcov (coverage) options
# --kcov-options "--include-path=. --path-strip-level=1"
# --kcov-options "--include-pattern=.sh"
# --kcov-options "--exclude-pattern=/.shellspec,/spec/,/coverage/,/report/"

## Example: Include script "myprog" with no extension
# --kcov-options "--include-pattern=.sh,myprog"

## Example: Only specified files/directories
# --kcov-options "--include-pattern=myprog,/lib/"
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ To configure healthchecks via `crontab -e`, add the following in your editor of
*/2 * * * * /etc/cron.d/restart-actions.sh
```

Development
-----------

### Testing
This project uses [`shellspec`](https://github.com/shellspec/shellspec) as a test framework. To run tests locally, `shellspec` must first be installed on the local system according to the `shellspec` [installation guide](https://github.com/shellspec/shellspec?tab=readme-ov-file#installation).

Tests are defined in the `spec` directory, and are all files matching the pattern `<suite_name>_spec.sh`. Mocks, custom matchers and other fixtures can be defined in the `spec/support` directory.

The `pot` mock has already been defined and is imported into all tests. By default, all `pot` subcommands return truthy with no side effects, but these can be overloaded on a per-subcommand basis, as each subcommand has its own stub function. See [here](spec/simple_spec.sh#L47) for an example of overloading the `pot exec` subcommand, and [here](spec/support/pot_mock.sh#L5) for a list of all subcommand stubs that can be overloaded.

Wrapper scripts to run GitHub actions in a jail on FreeBSD
----------------------------------------------------------
Expand Down
70 changes: 70 additions & 0 deletions spec/simple_spec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#shellcheck shell=bash

Describe 'check-pots.sh'
Include ./check-pots.sh
prepare() { pot='test'; }
Before 'prepare'

Describe 'check_tree()'
It 'Does not output a warning if the given tree exists'
tree_name='some_tree'
mkdir $tree_name
When call check_tree $tree_name
The output should not include 'was not found'
rm -fr $tree_name
End

It 'Outputs a warning if the given tree does not exist'
tree_name='some_tree'
When call check_tree $tree_name
The output should include 'was not found'
End

It 'Outputs a debug message if the given tree is empty'
tree_name='some_tree'
mkdir $tree_name
When call check_tree 'some_tree'
The output should include 'is empty'
rm -fr $tree_name
End

It 'Has no output if the tree is populated'
tree_name='some_tree'
mkdir $tree_name
touch ${tree_name}/abc
When call check_tree 'some_tree'
The output should be blank
rm -fr $tree_name
End
End

Describe 'check_pot()'
It 'Should emit a warning if sshd is disabled'
check_tree() { :; }
pot_exec() {
case $3 in
sysrc) echo 'NO';;
which) echo '/usr/sbin/pkg64';;
esac
}
When call check_pot
The lines of output should equal 1
The output should include 'sshd is disabled on'
End

It 'Should emit a warning if pkg binaries cannot be found'
check_tree() { :; }
pot_exec() {
case $3 in
sysrc) echo '';;
which) echo '';;
esac
}
When call check_pot
The lines of output should equal 3
The line 1 of output should include "pkg64 on $pot was not found"
The line 2 of output should include "pkg64c on $pot was not found"
The line 3 of output should include "pk64cb on $pot was not found"
End
End
End
24 changes: 24 additions & 0 deletions spec/spec_helper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# shellcheck shell=sh

# Defining variables and functions here will affect all specfiles.
# Change shell options inside a function may cause different behavior,
# so it is better to set them here.
# set -eu

# This callback function will be invoked only once before loading specfiles.
spec_helper_precheck() {
# Available functions: info, warn, error, abort, setenv, unsetenv
# Available variables: VERSION, SHELL_TYPE, SHELL_VERSION
: minimum_version "0.28.1"
}

# This callback function will be invoked after a specfile has been loaded.
spec_helper_loaded() {
:
}

# This callback function will be invoked after core modules has been loaded.
spec_helper_configure() {
# Available functions: import, before_each, after_each, before_all, after_all
import 'support/pot_mock'
}
61 changes: 61 additions & 0 deletions spec/support/pot_mock.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# shellcheck shell=sh

pot() {
case $1 in
help) fn='pot_help';;
version) fn='pot_version';;
config) fn='pot_config';;
ls|list) fn='pot_list';;
show) fn='pot_show';;
info) fn='pot_info';;
top) fn='pot_top';;
ps) fn='pot_ps';;
init) fn='pot_init';;
de-init) fn='pot_de_init';;
vnet-start) fn='pot_vnet_start';;
create-base) fn='pot_create_base';;
create-fscomp) fn='pot_create_fscomp';;
create-private-bridge) fn='pot_create_private_bridge';;
create) fn='pot_create';;
clone) fn='pot_clone';;
clone-fscomp) fn='pot_clone_fscomp';;
rename) fn='pot_rename';;
destroy) fn='pot_destroy';;
prune) fn='pot_prune';;
copy-in) fn='pot_copy_in';;
copy-out) fn='pot_copy_out';;
mount-in) fn='pot_mount_in';;
mount-out) fn='pot_mount_out';;
add-dep) fn='pot_add_dep';;
set-rss) fn='pot_set_rss';;
get-rss) fn='pot_get_rss';;
set-cmd) fn='pot_set_cmd';;
set-env) fn='pot_set_env';;
set-hosts) fn='pot_set_hosts';;
set-hook) fn='pot_set_hook';;
set-attribute|set-attr) fn='pot_set_attribute';;
get-attribute|get-attr) fn='pot_get_attribute';;
export-ports) fn='pot_export_ports';;
start) fn='pot_start';;
stop) fn='pot_stop';;
term) fn='pot_term';;
run) fn='pot_run';;
snap|snapshot) fn='pot_snapshot';;
rollback|revert) fn='pot_revert';;
purge-snapshots) fn='pot_purge_snapshots';;
export) fn='pot_export';;
import) fn='pot_import';;
prepare) fn='pot_prepare';;
update-config) fn='pot_update_config';;
last-run-stats) fn='pot_last_run_stats';;
signal) fn='pot_signal';;
exec) fn='pot_exec';;
*) fn='pot_other';;
esac
shift 1
if type "$fn" 2>/dev/null | grep -q 'function'; then
$fn "$@"
else
:
fi
}

0 comments on commit 863576b

Please sign in to comment.