Add testing for dynamic_inventory.py

This change introduces a testing framework for the dynamic_inventory.py
script, which will be helpful in debugging any changes made to the
script. Current testing is indirect, relying on the other, very high
level gate tests, which may take longer to identify inventory generation
issues.

Currently, it does not do actual unit testing, instead opting to start
by testing from 'outside', calling the script through a subprocess. In
time, this should be replaced, but as a start it's easier to implement
without making many changes.

The 'tests/inventory' directory has the necessary pieces symlinked in;
namely, env.d, openstack_environment.yml, and a sample
openstack_user-config.yml (based on the AIO one already used in the gates).

A new tox environment, 'inventory' was added rather than creating a new
'gate-check-inventory.sh' file. This should fit the general
openstack-infra testing framework better.

For the first test, I decided to add a loop that runs 100 times because
of the nature of the script. Since the dynamic_inventory script does not
assign IP addresses sequentially, the loop helps exercise a larger
sample than just one run per test. On my local machine, this took
approximately 2 seconds. Running it 1,000 times took about 30 seconds.
Thus, the time spent right now is minimal in comparison to the rest of
the gate jobs.

As it stands, the test suite is by no means complete, but serves as a
starting point.

Change-Id: I7410360ecec919639a299f72f2f3cc818bce8e33
This commit is contained in:
Nolan Brubaker 2015-11-05 16:17:15 -05:00 committed by Jesse Pretorius (odyssey4me)
parent 8838f3cf4b
commit 3fe2c8ccdd
6 changed files with 84 additions and 2 deletions

View File

@ -12,7 +12,9 @@ used_ips:
global_overrides:
internal_lb_vip_address: 172.29.236.100
external_lb_vip_address: {{ bootstrap_host_public_address | default(ansible_default_ipv4.address) }}
# The external IP is quoted simply to ensure that the .aio file can be used as input
# dynamic inventory testing.
external_lb_vip_address: "{{ bootstrap_host_public_address | default(ansible_default_ipv4.address) }}"
tunnel_bridge: "br-vxlan"
management_bridge: "br-mgmt"
provider_networks:

1
tests/inventory/env.d Symbolic link
View File

@ -0,0 +1 @@
../../etc/openstack_deploy/env.d

View File

@ -0,0 +1 @@
../../etc/openstack_deploy/openstack_environment.yml

View File

@ -0,0 +1 @@
../../etc/openstack_deploy/openstack_user_config.yml.aio

72
tests/test_inventory.py Normal file
View File

@ -0,0 +1,72 @@
#!/usr/bin/env python
import collections
import json
import os
from os import path
import subprocess
import unittest
INV_DIR = '../playbooks/inventory'
SCRIPT_FILENAME = 'dynamic_inventory.py'
INV_SCRIPT = path.join(INV_DIR, SCRIPT_FILENAME)
# We'll use the test directory, and have tox do the cd command for us.
TARGET_DIR = path.join(os.getcwd(), 'inventory')
# These files will be placed in TARGET_DIR by INV_SCRIPT.
# They should be cleaned up between each test.
CLEANUP = [
'openstack_inventory.json',
'openstack_hostnames_ips.yml',
'backup_openstack_inventory.tar'
]
def cleanup():
for f_name in CLEANUP:
f_file = path.join(TARGET_DIR, f_name)
if os.path.exists(f_file):
os.remove(f_file)
def get_inventory():
"Return the inventory mapping in a dict."
try:
cmd = [INV_SCRIPT, '--file', TARGET_DIR]
inventory_string = subprocess.check_output(cmd)
inventory = json.loads(inventory_string)
return inventory
finally:
# Remove the file system artifacts since we want to force fresh runs
cleanup()
class TestDuplicateIps(unittest.TestCase):
def setUp(self):
# Allow custom assertion errors.
self.longMessage = True
def test_duplicates(self):
"""Test that no duplicate IPs are made on any network."""
for i in xrange(0, 99):
inventory = get_inventory()
ips = collections.defaultdict(int)
hostvars = inventory['_meta']['hostvars']
for host, var_dict in hostvars.items():
nets = var_dict['container_networks']
for net, vals in nets.items():
if 'address' in vals.keys():
addr = vals['address']
ips[addr] += 1
self.assertEqual(1, ips[addr],
msg="IP %s duplicated." % addr)
if __name__ == '__main__':
unittest.main()

View File

@ -1,7 +1,7 @@
[tox]
minversion = 1.6
skipsdist = True
envlist = docs,linters,releasenotes
envlist = docs,linters,releasenotes,inventory
[testenv]
usedevelop = True
@ -113,3 +113,8 @@ commands =
{[testenv:bashate]commands}
{[testenv:ansible-lint]commands}
{[testenv:ansible-syntax]commands}
[testenv:inventory]
changedir = {toxinidir}/tests
commands =
python test_inventory.py