Skip to content
This repository has been archived by the owner on Nov 2, 2022. It is now read-only.

Commit

Permalink
Replace Docker tests with Molecule. Fix acceptance tests. (#57)
Browse files Browse the repository at this point in the history
* [NEW]: added Molecule support
* [UPDATE]: fix linting errors
* [UPDATE]: Fixed missing smbclient dependency in travis config file
* Changed container name; added nmblookup version check
* [UPDATE]: Added samba-testsuite package in travis.yml
  • Loading branch information
robinoph committed Jun 20, 2020
1 parent 83b6add commit 8126435
Show file tree
Hide file tree
Showing 10 changed files with 578 additions and 28 deletions.
53 changes: 29 additions & 24 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,38 +1,43 @@
# .travis.yml Execution script for role tests on Travis-CI
---
language: python

# Use the new container infrastructure
sudo: required

env:
global:
- ROLE_NAME: samba
matrix:
- DISTRIBUTION: centos
VERSION: 7
- DISTRIBUTION: ubuntu
VERSION: 18.04
- DISTRIBUTION: debian
VERSION: 9
- DISTRIBUTION: fedora
VERSION: 29
- MOLECULE_DISTRO: centos7
- MOLECULE_DISTRO: debian9
- MOLECULE_DISTRO: fedora29
- MOLECULE_DISTRO: ubuntu1804

#Enable docker support
services:
- docker

before_install:
# Install latest Git
install:
- sudo apt-get update
- sudo apt-get install --only-upgrade git
- sudo apt-get install smbclient
# Allow fetching other branches than master
- git config remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
# Fetch the branch with test code
- git fetch origin docker-tests
- git worktree add docker-tests origin/docker-tests
- sudo apt-get install bats curl smbclient samba-testsuite
# Install dependencies for Molecule test
- python3 -m pip install molecule yamllint ansible-lint docker
# Check ansible, molecule and nmblookup version
- ansible --version
- molecule --version
- nmblookup --version
# Create ansible.cfg with correct roles_path
- printf '[defaults]\nroles_path=../' >ansible.cfg

script:
# Create container and apply test playbook
- ./docker-tests/docker-tests.sh
before_script:
#Renames ansible-role-bind to bertvv.bind to make it match with Ansible Galaxy
- cd ../
- mv ansible-role-$ROLE_NAME bertvv.$ROLE_NAME
- cd bertvv.$ROLE_NAME

# Run functional tests on the container
- SUT_IP=172.17.0.2 ./docker-tests/functional-tests.sh
script:
#Run molecule test
- molecule test

notifications:
webhooks: https://galaxy.ansible.com/api/v1/notifications/
webhooks: https://galaxy.ansible.com/api/v1/notifications/
33 changes: 33 additions & 0 deletions .yamllint
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
# Based on ansible-lint config
extends: default

rules:
braces:
max-spaces-inside: 1
level: error
brackets:
max-spaces-inside: 1
level: error
colons:
max-spaces-after: -1
level: error
commas:
max-spaces-after: -1
level: error
comments: disable
comments-indentation: disable
document-start: disable
empty-lines:
max: 3
level: error
hyphens:
level: error
indentation: disable
key-duplicates: enable
line-length: disable
new-line-at-end-of-file: disable
new-lines:
type: unix
trailing-spaces: disable
truthy: disable
49 changes: 45 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,50 @@ See the [test playbook](https://github.com/bertvv/ansible-role-samba/blob/docker

## Testing

Two test environments are provided for this role: one set up with Vagrant, one with Docker. The Docker test environment is also used for the Travis-CI tests. Each test environment is stored in a separate orphan branch. See the README of each for details on how to set it up locally.
This role is tested using [Ansible Molecule](https://molecule.readthedocs.io/). Tests are launched automatically on [Travis CI](https://travis-ci.org/bertvv/ansible-role-samba) after each commit and PR.

- [Docker tests](https://github.com/bertvv/ansible-role-samba/blob/docker-tests/README.md)
- [Vagrant tests](https://github.com/bertvv/ansible-role-samba/blob/vagrant-tests/README.md)
This Molecule configuration will:

- Run Yamllint and Ansible Lint
- Create a Docker container
- Run a syntax check
- Apply the role with a [test playbook](molecule/default/converge.yml)
- Run acceptance tests with [BATS](https://github.com/bats-core/bats-core/)

This process is repeated for the supported Linux distributions.

### Local test environment

If you want to set up a local test environment, you can use this reproducible setup based on Vagrant+VirtualBox: <https://github.com/bertvv/ansible-testenv>. Steps to install the necessary tools manually:

1. Docker, BATS and smbclient should be installed on your machine (assumed to run Linux). No Docker containers should be running when you start the test.
2. As recommended by Molecule, create a python virtual environment
3. Install the software tools `python3 -m pip install molecule docker yamllint ansible-lint`
4. Navigate to the root of the role directory and run `molecule test`

Molecule automatically deletes the containers after a test. If you would like to check out the containers yourself, run `molecule converge` followed by `molecule login --host HOSTNAME`.

The Docker containers are based on images created by [Jeff Geerling](https://hub.docker.com/u/geerlingguy), specifically for Ansible testing (look for images named `geerlingguy/docker-DISTRO-ansible`). You can use any of his images, but only the distributions mentioned in [meta/main.yml](meta/main.yml) are supported.

The default config will start a Centos 7 container. Choose another distro by setting the `MOLECULE_DISTRO` variable with the command, e.g.:

``` bash
MOLECULE_DISTRO=debian9 molecule test
```

or

``` bash
MOLECULE_DISTRO=debian9 molecule converge
```

You can run the acceptance tests on both servers with `molecule verify` or manually with

```console
SUT_IP=172.17.0.2 bats molecule/default/files/samba.bats
```

You need to initialise the variable `SUT_IP`, the system under test's IP address. The server, `smb1`, should have IP address 172.17.0.2.

## Contributing

Expand Down Expand Up @@ -250,4 +290,5 @@ Pull requests are also very welcome. Please create a topic branch for your propo
[Sven Eeckeman](https://github.com/SvenEeckeman),
[Tiemo Kieft](https://github.com/blubber),
[Tobias Wolter](https://github.com/towo),
[Tomohiko Ozawa](https://github.com/kota65535).
[Tomohiko Ozawa](https://github.com/kota65535),
[Robin Ophalvens](https://github.com/RobinOphalvens).
93 changes: 93 additions & 0 deletions molecule/default/converge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
- name: Converge
hosts: all
pre_tasks:
- name: Ensure package database is up-to-date
apt:
update-cache: true
failed_when: false
changed_when: false
when: ansible_os_family == 'Debian'
- name: Create users
user:
name: "{{ item }}"
groups: users
append: true
with_items:
- usr1
- usr2
- timemachine
vars:
samba_netbios_name: SAMBA_TEST
samba_server_string: 'Welcome to the test file server'
samba_workgroup: TESTGROUP
samba_global_include: global-include.conf
samba_load_homes: true
samba_load_printers: false
samba_create_varwww_symlinks: true
samba_log: /var/log/samba.log
samba_log_size: 60000
samba_log_level: '3 passdb:5 auth:10 winbind:2 '
# The smbclient version of the Travis CI environment crashes when `min
# protocol' is set:
# protocol negotiation failed: NT_STATUS_INVALID_NETWORK_RESPONSE
# Uncomment the following lines if you want to test this setting locally.
#
# samba_server_min_protocol: SMB2
# samba_server_max_protocol: SMB3
samba_map_to_guest: Never
samba_users:
- name: usr1
password: usr1
- name: usr2
password: usr2
- name: timemachine
password: timemachine
samba_username_map:
- from: 'User Two'
to: usr2
samba_shares_root: /srv/samba
samba_shares:
- name: restrictedshare
- name: privateshare
comment: 'Only readable/writeable by usr1'
valid_users: usr1
write_list: usr1
group: usr1
browseable: 'no'
- name: protectedshare
public: 'yes'
comment: 'Public, but only writeable by usr2'
write_list: usr2
group: users
browseable: 'yes'
include_file: protectedshare-include.conf
- name: publicshare
comment: 'Public share, writeable by all members of group ‘users’'
public: 'yes'
write_list: +users
group: users
setype: public_content_t
browseable: 'yes'
- name: guestshare
comment: 'Share accessible for guests'
guest_ok: 'yes'
writable: 'yes'
browseable: 'yes'
- name: TimeMachine
comment: 'Share useable as a TimeMachine backup target on MacOS'
vfs_objects:
- name: fruit
options:
- name: time machine
value: 'yes'
- name: streams_xattr
path: /srv/timemachine
write_list: timemachine
owner: timemachine
group: timemachine
public: 'no'
guest_ok: 'no'
browseable: 'no'
roles:
- role: bertvv.samba
111 changes: 111 additions & 0 deletions molecule/default/files/functional-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#! /usr/bin/env bash
#
# Author: Bert Van Vreckem <[email protected]>
#
# Run BATS test files in the current directory, and the ones in the subdirectory
# matching the host name.
#
# The script installs BATS if needed. It's best to put ${bats_install_dir} in
# your .gitignore.

set -o errexit # abort on nonzero exitstatus
set -o nounset # abort on unbound variable

#{{{ Variables

test_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

bats_archive="v1.1.0.tar.gz"
bats_url="https://github.com/bats-core/bats-core/archive/${bats_archive}"
bats_install_dir="/opt"
bats_default_location="${bats_install_dir}/bats/libexec/bats"
test_file_pattern="*.bats"

# Color definitions
readonly reset='\e[0m'
readonly yellow='\e[0;33m'
readonly cyan='\e[0;36m'
#}}}

main() {

bats=$(find_bats_executable)

if [ -z "${bats}" ]; then
install_bats
bats="${bats_default_location}"
fi

debug "Using BATS executable at: ${bats}"

# List all test cases (i.e. files in the test dir matching the test file
# pattern)

# Tests to be run on all hosts
global_tests=$(find_tests "${test_dir}" 1)

# Tests for individual hosts
host_tests=$(find_tests "${test_dir}/${HOSTNAME}")

# Loop over test files
for test_case in ${global_tests} ${host_tests}; do
info "Running test ${test_case}"
${bats} "${test_case}"
done
}

#{{{ Functions

# Tries to find BATS executable in the PATH or the place where this script
# installs it.
find_bats_executable() {
if which bats > /dev/null; then
which bats
elif [ -x "${bats_default_location}" ]; then
echo "${bats_default_location}"
else
echo ""
fi
}

# Usage: install_bats
install_bats() {
pushd "${bats_install_dir}" > /dev/null 2>&1
curl --location --remote-name "${bats_url}"
tar xzf "${bats_archive}"
mv bats-* bats
rm "${bats_archive}"
popd > /dev/null 2>&1
}

# Usage: find_tests DIR [MAX_DEPTH]
#
# Finds BATS test suites in the specified directory
find_tests() {
local max_depth=""
if [ "$#" -eq "2" ]; then
max_depth="-maxdepth $2"
fi

local tests
tests=$(find "$1" ${max_depth} -type f -name "${test_file_pattern}" -printf '%p\n' 2> /dev/null)

echo "${tests}"
}

# Usage: info [ARG]...
#
# Prints all arguments on the standard output stream
info() {
printf "${yellow}### %s${reset}\n" "${*}"
}

# Usage: debug [ARG]...
#
# Prints all arguments on the standard output stream
debug() {
printf "${cyan}### %s${reset}\n" "${*}"
}
#}}}

main
Loading

0 comments on commit 8126435

Please sign in to comment.