Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ansible Community Instruqt tracks #46

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

pip3 install ansible-core

echo "Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin" > /etc/sudoers.d/sudo_secure_path
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: "2"
virtualmachines:
- name: shell
image: centos-cloud/centos-8
shell: /usr/bin/su - devops
machine_type: n1-standard-1
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

pip3 install --upgrade pip
283 changes: 283 additions & 0 deletions tracks/adding-integration-tests-to-ansible-collections/track.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
slug: adding-integration-tests-to-ansible-collections
id: b8al21byeix5
type: track
title: '3. Ansible Community: Adding integration tests to Ansible Collections'
description: |
After completing this scenario, users will be able to write integration tests for the modules inside a collection and test them localling using `ansible-test` tool.
Ompragash marked this conversation as resolved.
Show resolved Hide resolved

## What you'll do

- Write integration tests for modules in Ansible Collection
- Run integration tests using ansible-test
icon: https://www.ansible.com/hubfs/2016_Images/Assets/Ansible-Mark-Large-RGB-Pool.png?hsLang=en-us
level: beginner
tags:
- ""
owner: redhat
developers:
- ompragash.viswanathan@gmail.com
private: false
published: true
challenges:
- slug: install-ansible-package
id: zqalvhgzqyxg
type: challenge
title: Install Ansible package
notes:
- type: text
contents: '##'
assignment: |-
Ansible v2.10 is the first release of Ansible that fully supports Collections and it contains a minimal amount of Core supported modules and plugins.

Install the latest version of `ansible-core` package which also includes `ansible-playbook` and `ansible-galaxy` binaries.

```
pip3 install ansible-core --user
```

Confirm that the latest ansible-core package is installed successfully by executing the below command:

```
ansible --version
```

~~~
ansible [core 2.11.4]
config file = None
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /rusr/share/lib64/python3.6/site-packages/ansible
ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
executable location = /home/ansible/developing_colelction/bin/ansible
python version = 3.6.12 (default, Sep 15 2020, 12:49:50) [GCC 4.8.5 20150623 (Red Hat 4.8.5-37)]
jinja version = 2.11.3
libyaml = True
~~~

You can verify ansible-core version from the first line of the above output.
tabs:
- title: Shell
type: terminal
hostname: shell
difficulty: basic
timelimit: 600
- slug: clone-collection-that-requires-integration-tests
id: d3cye2zxcpyr
type: challenge
title: Choose a Collection that needs integration tests
teaser: '#'
assignment: |-
For this course, we'll use `community.postgresql` collection and write a basic integration test for the postgresql_info module.

Create the following directory for use of `community.postgresql` collection:

```
mkdir -p ~/ansible_collections/community/postgresql
```

Clone `community.postgresql` into the newly created directory:

```
git clone https://github.com/ansible-collections/community.postgresql ~/ansible_collections/community/postgresql
```

```
cd ~/ansible_collections/community/postgresql
```

Switch to `integration_example` branch:

```
git checkout integration_example
```

Verify that you're on `integration_example` branch by running the below command:

```
git branch
```
tabs:
- title: shell
type: terminal
hostname: shell
difficulty: basic
timelimit: 600
- slug: cd-integration-directory
id: nsynktrioxvc
type: challenge
title: Create directory structure for integration tests
teaser: '#'
assignment: |-
You must place integration tests in the appropriate tests/integration/targets/ directory.

We will start with creating a setup target that will install all required packages and will run PostgreSQL service.

Change directory to Collection path:

```
cd ~/ansible_collections/community/postgresql/
```

Create the following directories:

```
mkdir -p tests/integration/targets/setup_postgresql_db/tasks
```

Create tests/integration/targets/setup_postgresql_db/tasks/main.yml and copy paste the below:

```
vim tests/integration/targets/setup_postgresql_db/tasks/main.yml
```

Note: Turn on `paste` mode in vim by typing `:set paste` and then paste the below text to avoid indendation errors.

```yaml
- name: Install required packages
package:
name:
- apt-utils
- postgresql
- postgresql-common
- python3-psycopg2
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This package set looks like it will only work on Debian-derivatives. Is that a problem or should it be called out as a prerequisite for this track?


- name: Initialize PostgreSQL
shell: . /usr/share/postgresql-common/maintscripts-functions && set_system_locale && /usr/bin/pg_createcluster -u postgres 12 main
args:
creates: /etc/postgresql/12/

- name: Start PostgreSQL service
service:
name: postgresql
state: started
```
tabs:
- title: Shell
type: terminal
hostname: shell
difficulty: basic
timelimit: 600
- slug: module-test-directory
id: qrchjl6ugo0o
type: challenge
title: Writing Integration Tests for postgresql_info module
teaser: '#'
assignment: |
For module integration tests, you can use the module name alone. For example, you would place integration tests for `plugins/modules/postgresql_info.py` in a directory called `tests/integration/targets/postgresql_info/`.

Change directory to collection path:

```
cd ~/ansible_collections/community/postgresql/
```

Create the following directories for the `postgresql_info` target:

~~~
mkdir -p tests/integration/targets/postgresql_info/tasks tests/integration/targets/postgresql_info/meta
~~~

To make the setup_postgresql_db target running before the postgresql_info target as a dependency, create the tests/integration/targets/postgresql_info/meta/main.yml and add the following code to it:

```
vim tests/integration/targets/postgresql_info/meta/main.yml
```

Note: Turn on `paste` mode in vim by typing `:set paste` and then paste the below text to avoid indendation errors.

```
dependencies:
- setup_postgresql_db
```

Now we are ready to add our first test task for the `postgresql_info` module.

Create the tests/integration/targets/postgresql_info/tasks/main.yml file and add the following code to it:

```
vim tests/integration/targets/postgresql_info/tasks/main.yml
```

```
- name: Test postgresql_info module
become: yes
become_user: postgres
postgresql_info:
login_user: postgres
login_db: postgres
register: result

- name: Check the module returns what we expect
assert:
that:
- result is not changed
- result.version.major == 12
- result.version.minor == 8
```

In the first task, we run the postgresql_info module to fetch information from the database we installed and ran with the setup_postgresql_db target. We save values returned by the module into the result variable.

In the second task, we check with the assert module what our task returns. We expect that, among other things, it returns the server version and reports that the system state has not been changed.
tabs:
- title: shell
type: terminal
hostname: shell
difficulty: basic
timelimit: 600
- slug: run-integration-tests
id: ncixnpax0yim
type: challenge
title: Running Integration Tests
teaser: '#'
assignment: |-
To run integration tests for a collection you'll have to use `ansible-test` binary.

`ansible-test` is distributed as part of the ansible-core (and therefore ansible) package.

`ansible-test` supports three types of tests:

- Sanity
- Unit
- Integration

You must always execute `ansible-test` from the root directory of a collection.

Although these tests may run automatically when sending a pull request (PR), we should run them locally to catch errors before sending new commits for review.

For this example we will be running the Integration Tests in the Ubuntu 20.04 docker container using `ansible-test, by doing:

```
cd ~/ansible_collections/community/postgresql/
```

```
sudo ansible-test integration postgresql_info --docker ubuntu2004 -v
```

We prefer to run the tests in Docker as it ensures all test dependencies are installed, and nothing pollutes the host operating system.

Note: You can specify multiple target names. Each target name is the name of a directory in `tests/integration/targets/`.

The tests should pass. If we look at the output, we should see something like the following:

~~~
TASK [postgresql_info : Check the module returns what we expect] ***************
ok: [testhost] => {
"changed": false,
"msg": "All assertions passed"
}
~~~

If your tests fail when you are working on your project. Examine the output to see at which step the failure occurred. Investigate the issue, try fixing it, and run again. Repeat the cycle until the test passes.

## Congratulations!

You added a integration test for `community.postgresql.postgresql_info` module.

See [Testing collections](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections_testing.html#testing-collections) and [Adding integration tests](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections_testing.html#adding-integration-tests) pages for pointers on testing your collection and ensure that your code works well and integrates well with the rest of the Ansible ecosystem.
tabs:
- title: shell
type: terminal
hostname: shell
difficulty: basic
timelimit: 600
checksum: "15328825550301005200"
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

/usr/sbin/useradd -m -U -G google-sudoers -s /bin/bash devops

yum install -y yum-utils

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

yum install -y docker-ce docker-ce-cli containerd.io

systemctl start docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: "2"
virtualmachines:
- name: shell
image: centos-cloud/centos-8
shell: /bin/su - devops -s /bin/bash
machine_type: n1-standard-1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

if [ ! -d /home/devops/collections/ansible_collections/community/clock ]; then
echo "Collection community.clock isn't created. To continue, create it using ansible-galaxy command."
exit 1
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

rm -rf ~/collections/
unset ANSIBLE_COLLECTIONS_PATH
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

pip3 install --upgrade pip
pip3 install ansible-core
yum install -y tree
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

mkdir -p ~/collections/ansible_collections
export ANSIBLE_COLLECTIONS_PATH=~/collections/ansible_collections
cd ~/collections/ansible_collections && ansible-galaxy collection init community.clock && cd ~
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

if [ ! -d /home/devops/collections/ansible_collections/community/clock/plugins/modules ]; then
echo "Collection community.clock is missing with modules directory. To continue create "modules" sub directory inside community.clock collection."
exit 1
fi

if [ ! -f /home/devops/collections/ansible_collections/community/clock/plugins/modules/timezone.py ]; then
echo "Collection community.clock is missing with timezone.py module file. To continue download timezone.py file."
exit 1
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

pip3 install --upgrade pip
pip3 install ansible-core
yum install -y tree
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

mkdir /home/devops/collections/ansible_collections/community/clock/plugins/modules
cd /home/devops/collections/ansible_collections/community/clock/plugins/modules ; curl -O https://raw.githubusercontent.com/ansible/ansible/stable-2.9/lib/ansible/modules/system/timezone.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

if [ ! -f /home/devops/.local/bin/ansible ]; then
fail-message "Ansible doesn't appear to be installed"
exit 1
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

pip3 uninstall ansible-core -y
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

pip3 install --upgrade pip
yum install -y tree
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

. /etc/profile.d/instruqt-env.sh

pip3 install ansible-core