How to test install and uninstall scenario with Molecule for Ansible?
Asked Answered
H

1

6

In the Ansible role that I'm creating, I'm covering both an install and an uninstall scenario:

  • foo-install.yml is called from main.yml when the install flag is set to true.
  • foo-uninstall.yml is called from main.yml when the install flag is set to false.

While the install covers installing an RPM package, copying config files, and starting a system service, the uninstall steps basically reverse the installation: Stop the system service, uninstall the RPM package, remove the application folder.

As a good citizen, I have created a test for the role using Molecule, which runs the role in a CentOS Vagrant box. This works fine for the install scenario, where I use Python tests (using testinfra) to validate the RPM is installed, the service is started, etc.

How can I use Molecule to now test the uninstall scenario as well? Is there a way to change the steps in Molecule that it does something like this (simplified)?

  • create
  • converge (run the install parts of the role)
  • idempotence (for the install part)
  • verify (the install steps)
  • converge (run the uninstall parts of the role)
  • idempotence (for the uninstall part)
  • verify (the uninstall steps)
  • destroy

Maybe I'm missing something, but I have not found an obvious way (or examples) on how to do something like this.

Is there a way to cover scenarios like this? Or am I better off with just testing the install scenario?

Hawsehole answered 23/5, 2019 at 13:51 Comment(0)
E
5

Recommended Solution

The recommended way to address this is using multiple Molecule Scenarios. You could use your install scenario as the default, and then add a second uninstall scenario that just runs and tests the uninstall steps.

When setting this up, simply create a second scenario directory in your role's molecule folder (copy the default one), and then make some changes:

  • (Edit: this step was necessary for molecule < 3.0. scenario.name was removed in later versions) In the molecule.yml file change the scenario.name attribute to uninstall.
  • In the same file, use the default scenario's playbook.yml file as the playbook for the prepare step:
    provisioner:
      name: ansible
      playbooks:
        prepare: ../default/playbook.yml
        converge: playbook.yml
  • Adjust the tests for the uninstall scenario to verify the uninstall steps.

This will ensure that the same steps are used for installing the software as in the install/default scenario, and you can focus on the uninstall steps.

To run the scenarios you can either run all of them or a single one:

# Run all scenarios
molecule test --all

# Run only the uninstall scenario
molecule test --scenario-name uninstall

This should get you pretty close to what you want to do, without replicating any code.

If you want to try some other things, here are a couple of other thoughts:

Alternatives

I would keep a scenario for the install only that would play all the needed tests (lint, idempotency, check, verify....) and create an install_uninstall specific scenario.

Playing install_uninstall will never be idempotent. So this scenario should disable the idempotency tests that will never pass. You might as well want to disable the check test that is played in your other scenario, lint... This can be done in molecule.yml by adjusting the parameters for scenario.test_sequence:

scenario:
  name: install_uninstall
  test_sequence:
    - destroy
    - create
    - prepare
    - converge
    - verify
    - destroy

Of course you can adjust to your real needs (like dropping verify also if you have no testinfra tests for this case).

Once this is done you only have to add two plays in your scenario playbook:

---
- name: install
  hosts: all
  roles:
    - role: my_role
      install: true

- name: uninstall
  hosts: all
  roles:
    - role: my_role
      install: false

And you should be ready to test with:

molecule test -s install_uninstall

Edit: An other option would be to keep only your current install scenario but launch the individual molecule commands rather than a full test. Assuming your current working scenario is in default

# Check and lint my files
molecule lint
# Make sure no box/container is on the way
molecule destroy
# Create my box/container for tests
molecule create
# Play my default playbook
molecule converge
# Idempotency check
molecule idempotence
# Verify we can correctly use check mode
molecule check
# Play testinfra tests
molecule verify
# Now play the uninstall
molecule converge -- -e install=false
## add more tests you can think off ##
# and finally cleanup
molecule destroy.

Unfortunately, unless this feature was very recently added to molecule, it is not possible to call idempotency and check with extra variables

Eugeniusz answered 23/5, 2019 at 16:43 Comment(5)
Thanks for the detailed response! I managed to get this two work using two scenarios like you outlined, even including full idempotency for the uninstall. I used the "default" scenario for the install case, and then created a second "uninstall" scenario that simply calls the ../default/playbook.yml in the prepare phase. Thus I don't have to replicate the install steps, and can focus on just the uninstall steps in the uninstall playbook.yml. This works rather nicely - exactly what I wanted.Hawsehole
Nice one! That is the best solution indeed and I didn't think of it ;)Eugeniusz
Since your answer doesn't fully address my solution: Should I submit my solution as a separate answer, or should I reword your answer to show what I've done? (I would like to give you credit for pointing me in the right direction...)Hawsehole
That's very kind of you. I suggest you edit my answer and add the final correct solution at top, keeping as far as possible the original info that is lead to this.Eugeniusz
That's the way I like SO ! You try to teach something and your are taught in return ! Awesome !Eugeniusz

© 2022 - 2024 — McMap. All rights reserved.