---
# System prepended metadata

title: Molecule hands on
tags: [Documentation]

---

# Molecule hands on
###### tags: `Documentation`

## Setup
python3 virtualenv
pip install molecule
pip install molecule[docker]
pip install selinux
* need docker installed
* need selinux python 
```
python2-libselinux-2.9-3.1.fc30.x86_64
python3-libselinux-2.9-3.1.fc30.x86_64
```

## Setup part duex

First of all we need to clone tripleo-quickstart

`git clone https://opendev.org/openstack/tripleo-quickstart`

Go to fetch-images role

`cd tripleo-quickstart/roles/fetch-images`

Create a molecule scenario inside the role

`molecule init scenario -r fetch-images`

Expected output:
> --> Initializing new scenario default...
Initialized scenario in /var/home/arxcruz/tmp/molecule/tripleo-quickstart/roles/fetch-images/molecule/default successfully.

## List the tests

`molecule list`

Expected output:
```
--> Validating schema /var/home/arxcruz/tmp/molecule/tripleo-quickstart/roles/fetch-images/molecule/default/molecule.yml.
Validation completed successfully.
Instance Name    Driver Name    Provisioner Name    Scenario Name    Created    Converged
---------------  -------------  ------------------  ---------------  ---------  -----------
instance         docker         ansible             default          false      false

```

## Create docker image

This command will create the container

`molecule create`

## Log into docker

Login into the container

`molecule login`

## Run molecule test

This first run will fail because we have lint enabled that will fail

`molecule test`

Let's disable the lint for now

`vim molecule/default/molecule.yml`

```yaml
---
dependency:
  name: galaxy
driver:
  name: docker
lint:
  name: yamllint
  enabled: false  # <--
platforms:
  - name: instance
    image: centos:7
provisioner:
  name: ansible
  lint:
    name: ansible-lint
    enabled: false  # <--
verifier:
  name: testinfra
  lint:
    name: flake8
    enabled: false  # <--
```

## Steps for each scenario

Okay, now we disable the lint, but you may notice that our tests follow some steps: lint, depedency, cleanup, destroy, syntax, create, etc. We don't need to follow all these steps, in general, what we want is destroy any container that might exist, create again, converge, and then destroy again. We can do it adding a test_sequence in the scenario:

`vim molecule/default/molecule.yml`

```yaml
scenario:
  test_sequence:
    - destroy
    - create
    - converge
    - destroy
```

Let's run the test again:

:::spoiler molecule test
```
put here long output here...
....
```
:::

This time will fail because we don't have the user stack on this image, so let's create the image and add the user

`molecule create`

Login to the container with

`molecule login`

Create the user

`adduser stack`

Exit the container and now let's execute the test again, this time passing the --destroy never

`molecule test --destroy never`

There's another failure, this time related to images that is not defined, but let's do something else first.

But not only that, this approach works only because we create the container, login into it and manually add the user stack there, if we run it again, without the --destroy never option, it will fail, because the previous container will be destroyed, a new one will be created without the user stack. Solve this is easy, we can just add a new task in our playbook, that will create the user stack. Think this is as the setupClass in python unittest.

So, as you can see, if you run again without the --destroy option, it will fail.

`molecule test`

Let's create the user in the playbook then

`vim molecule/default/playbook.yml`

```yaml
---
- name: Converge
  hosts: all
  tasks:
    - name: Create user stack
      user:
        name: stack
        comment: Stack user
    - name: Execute the role
      include_role:
        name: fetch-images
```

Let's run again and you will see the user bein created

`molecule test`

As you can see, there is no longer stack user failures, let's fix now the issue with the images.

In this case, we have a bug in the role, because all the variables used by the role, should be in the defaults/main.yml, thanks to molecule, now we can fix it!

`vim defaults/main.yml`

```yaml
images:
  - name: centos-7-image
    url: "http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img"
    type: img
    md5sum: 'ee1eca47dc88f4879d8a229cc70a07c6'
```

We could also add a different image in the molecule test since we should not rely on internet to run our tests
```
vim molecule/default/playbook.yml
```
```yaml
  - name: Create dummy image file
    copy:
      dest: /tmp/image-test.img
      content: |
        foo
```

And add the vars:

```yaml
      vars:
        # This image is not a real image, it's just for
        # test purpose
        images:
          - name: centos-7-image
            url: "file:///tmp/image-test.img"
            type: img
            md5sum: 'd3b07384d113edec49eaa6238ad5ff00'
```

And we are done, now we have a molecule test covering the fetch-images role!

```bash
molecule test
```

All tests should be executed fine