Merge pull request #187 from dgarros/unittest

Add Unitest for Ansible modules using Virtual Devices in the Cloud
This commit is contained in:
Nitin Kumar 2016-12-21 10:49:00 +05:30 коммит произвёл GitHub
Родитель 4aec751949 62c3ece6c9
Коммит a2b271ed72
19 изменённых файлов: 584 добавлений и 2 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -41,3 +41,5 @@ nosetests.xml
docs/build
docs/*.rst
docs/_build/
tests/.vagrant/*

33
.travis.yml Normal file
Просмотреть файл

@ -0,0 +1,33 @@
language: python
python:
- 2.7
sudo: required
dist: trusty
env:
- ANSIBLE_VERSION=2.2.0.0
- ANSIBLE_VERSION=2.1.3.0
install:
## Create Docker with Ansible modules and all dependancies
- docker build --build-arg ver_ansible=$ANSIBLE_VERSION -t juniper/pyez-ansible:travis .
## Install Ansible locally for Ravello and install Roles
- pip install -q ansible==$ANSIBLE_VERSION
- cd tests
- mkdir library
- git clone https://github.com/Juniper/ravello-ansible.git library/ravello-ansible
- pip install -r library/ravello-ansible/requirements.txt
- cp .travis_ansible_python.yaml group_vars/all/travis_ansible_python.yaml
script:
## Start Virtual topology on Ravello with 2 VQFX and collect IP addresses
## Anyone can connect here to see the list of applications running and see the VMs
## https://cloud.ravellosystems.com/#/GtHFbCOuKgD1pcfkvCCIgenj6DOtn3VgRLjaYipdideCsiPC1NxJitt1UHfhF0Bf/apps
- ansible-playbook -i ravello.ini pb.rav.token.create-deploy.yaml
- ansible-playbook -i ravello.ini pb.rav.token.fqdn_get.yaml
- rm group_vars/all/travis_ansible_python.yaml
## Execute Tests with Docker
- docker run -t -i -v $(pwd):/project juniper/pyez-ansible:travis ansible-playbook -i ravello.ini pb.junos_ping.yaml
- docker run -t -i -v $(pwd):/project juniper/pyez-ansible:travis ansible-playbook -i ravello.ini pb.junos_jsnapy.yaml

Просмотреть файл

@ -1,6 +1,9 @@
FROM juniper/pyez:2.0.1
MAINTAINER ntwrkguru@gmail.com
ARG ver_ansible=2.2.0.0
ARG ver_jsnapy=1.0.0
WORKDIR /tmp
RUN mkdir /tmp/ansible-junos-stdlib &&\
mkdir /tmp/ansible-junos-stdlib/library &&\
@ -15,8 +18,8 @@ RUN tar -czf Juniper.junos ansible-junos-stdlib &&\
apk add build-base gcc g++ make python-dev &&\
pip install junos-netconify &&\
pip install jxmlease &&\
pip install ansible &&\
pip install jsnapy &&\
pip install -q ansible==$ver_ansible &&\
pip install -q jsnapy==$ver_jsnapy &&\
ansible-galaxy install Juniper.junos &&\
apk del -r --purge gcc make g++ &&\
rm -rf /source/* &&\

2
requirements.txt Normal file
Просмотреть файл

@ -0,0 +1,2 @@
junos-eznc
jxmlease

Просмотреть файл

@ -0,0 +1 @@
ansible_python_interpreter: "/home/travis/virtualenv/python2.7.10/bin/python"

4
tests/ansible.cfg Normal file
Просмотреть файл

@ -0,0 +1,4 @@
[defaults]
hash_behaviour=merge
roles_path = /etc/ansible/roles:library/ravello-ansible/roles

Просмотреть файл

Просмотреть файл

@ -0,0 +1,3 @@
set routing-instances LO10 interface lo0.10
set routing-instances LO10 instance-type virtual-router
set interfaces lo0 unit 10 family inet

Просмотреть файл

@ -0,0 +1,2 @@
delete routing-instances LO10
delete interfaces lo0 unit 10

Просмотреть файл

@ -0,0 +1,11 @@
tests_include:
- check_storage
check_storage:
- command: show system storage
- iterate:
xpath: //system-storage-information/filesystem[normalize-space(mounted-on)='/']
tests:
- is-lt: used-percent, 95
info: "File system {{post['mounted-on']}} use less than 95%"
err: "File system {{post['mounted-on']}} use {{post['used-percent']}} %"

Просмотреть файл

@ -0,0 +1,16 @@
tests_include:
- test_command_version
test_command_version:
- command: show interfaces terse lo*
- iterate:
xpath: //logical-interface
id: './name'
tests:
- list-not-more: admin-status
err: "Test Failed!! name list changed, <{{pre['admin-status']}}> with name <{{id_0}}> is not found in post snapshot"
info: "Test successful!! name list is same, with name <{{id_0}}>"
- list-not-less: admin-status
err: "Test Failed!! name list changed, <{{pre['admin-status']}}> with name <{{id_0}}> was not present in PRE snapshot"
info: "Test successful!! name list is same, with name <{{id_0}}>"

Просмотреть файл

@ -0,0 +1,12 @@
tests_include:
- test_version_check
test_version_check:
- command: show version
- iterate:
id: host-name
xpath: //software-information
tests:
- exists: //package-information/name
info: "Test Succeeded!! node //package-information/name exists with name <{{pre['//package-information/name']}}> and hostname: <{{id_0}} > "
err: "Test Failed!!! node //package-information/name does not exists in hostname: <{{id_0}}> !! "

Просмотреть файл

@ -0,0 +1,26 @@
---
- name: Test junos_get_facts module
hosts: all
connection: local
gather_facts: no
roles:
- Juniper.junos
tasks:
- name: "TEST 1 - Gather Facts"
junos_get_facts:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
ignore_errors: True
register: test1
# - debug: var=test1
- name: Check TEST 1
assert:
that:
- test1.facts.hostname
- test1.facts.serialnumber
- test1.facts.model
- test1.facts.fqdn

217
tests/pb.junos_jsnapy.yaml Normal file
Просмотреть файл

@ -0,0 +1,217 @@
---
- name: Test junos_ping module
hosts: all
connection: local
gather_facts: no
roles:
- Juniper.junos
tasks:
##################################################
#### TEST 1 ##
##################################################
- name: "TEST 1 - Execute SNAPCHECK with 1 test file / no dir"
junos_jsnapy:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
test_files: junos_jsnapy/test_junos_storage.yml
action: snapcheck
register: test1
ignore_errors: True
tags: [ test1 ]
# - debug: var=test1
- name: Check TEST 1
assert:
that:
- test1|succeeded
- test1.passPercentage == 100
- test1.total_tests == 1
tags: [ test1 ]
##################################################
#### TEST 2 ##
##################################################
- name: "TEST 2 - Execute SNAPCHECK with 2 test file & dir"
junos_jsnapy:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
test_files:
- test_junos_storage.yml
- test_version.yml
dir: junos_jsnapy
action: snapcheck
register: test2
ignore_errors: True
tags: [ test2 ]
# - debug: var=test2
- name: Check TEST 2
assert:
that:
- test2|succeeded
- test2.passPercentage == 100
- test2.total_tests == 2
tags: [ test2 ]
##################################################
#### TEST 3 ##
##################################################
- name: "TEST 3 - Wrong test file"
junos_jsnapy:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
test_files: file_that_doesnt_exist.yml
action: snapcheck
register: test3
ignore_errors: True
tags: [ test3 ]
# - debug: var=test3
- name: Check TEST 3
assert:
that:
- test3|failed
tags: [ test3 ]
##################################################
#### TEST 4 ##
##################################################
- name: "TEST 4 - SNAP_PRE"
junos_jsnapy:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
test_files: junos_jsnapy/test_loopback.yml
action: snap_pre
register: test4
ignore_errors: True
tags: [ test4 ]
# - debug: var=test4
- name: Check TEST 4
assert:
that:
- test4|succeeded
tags: [ test4 ]
##################################################
#### TEST 5 ##
##################################################
- name: "TEST 5 - SNAP_POST"
junos_jsnapy:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
test_files: junos_jsnapy/test_loopback.yml
action: snap_post
register: test5
ignore_errors: True
tags: [ test5 ]
# - debug: var=test5
- name: Check TEST 5
assert:
that:
- test5|succeeded
tags: [ test5 ]
##################################################
#### TEST 6 ##
##################################################
- name: "TEST 6 - CHECK"
junos_jsnapy:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
test_files: junos_jsnapy/test_loopback.yml
action: check
register: test6
ignore_errors: True
tags: [ test6 ]
- debug: var=test6
- name: Check TEST 6
assert:
that:
- test6|succeeded
- test6.passPercentage == 100
tags: [ test6 ]
##################################################
#### TEST 7 ##
##################################################
- name: "PRE-TEST 7 - Add loopback address"
junos_install_config:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
file: junos_jsnapy/add_loopback.set
overwrite: no
register: test7_1
ignore_errors: True
tags: [ test7 ]
- name: Wait for loopback to come up
pause: seconds=15
- name: "TEST 7 - SNAP_POST with additional loopback"
junos_jsnapy:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
test_files: junos_jsnapy/test_loopback.yml
action: snap_post
register: test7_2
ignore_errors: True
tags: [ test7 ]
# - debug: var=pretest7
- name: "TEST 7 - CHECK"
junos_jsnapy:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
test_files: junos_jsnapy/test_loopback.yml
action: check
register: test7
ignore_errors: True
tags: [ test7 ]
- debug: var=test7
- name: "TEST 7 - Cleanup"
junos_install_config:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
file: junos_jsnapy/delete_loopback.set
overwrite: no
register: test7_3
ignore_errors: True
tags: [ test7 ]
- name: Check TEST 7
assert:
that:
- test7_1|succeeded
- test7_2|succeeded
- test7_3|succeeded
- test7|succeeded
- test7.passPercentage == 50
- test7.total_tests == 2
tags: [ test7 ]

59
tests/pb.junos_ping.yaml Normal file
Просмотреть файл

@ -0,0 +1,59 @@
---
- name: Test junos_ping module
hosts: all
connection: local
gather_facts: no
roles:
- Juniper.junos
tasks:
- name: "TEST 1 - Ping Google DNS"
junos_ping:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
dest_ip: 8.8.8.8
register: test1
ignore_errors: True
# - debug: var=test1
- name: Check TEST 1
assert:
that:
- test1.packet_loss == '0'
############
- name: "TEST 2 - Ping Wrong IP"
junos_ping:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
dest_ip: 8.8.1.1
register: test2
ignore_errors: True
# - debug: var=test2
- name: Check TEST 2
assert:
that:
- test2.packet_loss == '100'
#################
- name: "TEST 3 - Change nbr packets"
junos_ping:
host: "{{ ansible_ssh_host }}"
port: "{{ ansible_ssh_port }}"
user: "{{ ansible_ssh_user }}"
passwd: "{{ ansible_ssh_pass }}"
dest_ip: 8.8.8.8
count: 3
register: test3
ignore_errors: True
# - debug: var=test3
- name: Check TEST 3
assert:
that:
- test3.packets_sent == '3'

Просмотреть файл

@ -0,0 +1,34 @@
---
- name: Get FQDN for all VM on Ravello
connection: local
hosts: all
gather_facts: no
roles:
- ravello.lib
tasks:
###############################
## Get VM ID ###
###############################
- name: Get App ID from Ravello
ravello_get_id:
resource_name: "{{ ravello_ci_app_name }}"
resource_type: applications
token: "{{ ravello_ci_token }}"
register: app
run_once: true
###############################
## Delete the application ##
###############################
- name: Stop Application on Ravello
uri:
url: "https://cloud.ravellosystems.com/api/v1/applications/{{ app.json.id }}/stop"
method: POST
status_code: 202
HEADER_Content-Type: 'application/json'
HEADER_Accept: 'application/json'
HEADER_X-Ephemeral-Token-Authorization: "{{ ravello_ci_token }}"
run_once: true
changed_when: true

Просмотреть файл

@ -0,0 +1,85 @@
---
- name: Create Application on Ravello for CI
connection: local
hosts: all
gather_facts: no
roles:
- ravello.lib
vars:
ravello_deploy_topology_cloud: AMAZON
ravello_deploy_topology_region: Oregon
ravello_deploy_topology_optimization: PERFORMANCE_OPTIMIZED
ravello_deploy_topology_start_all: true
tasks:
- name: Create Application from Blueprint for CI
uri:
url: "https://cloud.ravellosystems.com/api/v1/applications/"
method: POST
status_code: 201
HEADER_Content-Type: 'application/json'
HEADER_Accept: 'application/json'
HEADER_X-Ephemeral-Token-Authorization: "{{ ravello_ci_token }}"
body:
name: "{{ ravello_ci_app_name }}"
description: "App created by Travis CI"
baseBlueprintId: "{{ ravello_ci_blueprint }}"
body_format: json
run_once: true
changed_when: true
- name: Get App ID from Ravello
ravello_get_id:
resource_name: "{{ ravello_ci_app_name }}"
resource_type: applications
token: "{{ ravello_ci_token }}"
register: app
run_once: true
- debug: var=app
run_once: true
#######################################################
## Deploy Application(s) ##
#######################################################
- name: Deploy Application On Ravello
uri:
url: "https://cloud.ravellosystems.com/api/v1/applications/{{ app.json.id }}/publish"
method: POST
status_code: 202
HEADER_Content-Type: 'application/json'
HEADER_Accept: 'application/json'
HEADER_X-Ephemeral-Token-Authorization: "{{ ravello_ci_token }}"
body: >
{
"preferredCloud": "{{ ravello_deploy_topology_cloud }}",
"preferredRegion": "{{ ravello_deploy_topology_region }}",
"optimizationLevel": "{{ ravello_deploy_topology_optimization }}",
"startAllVms": "{{ ravello_deploy_topology_start_all }}"
}
body_format: json
run_once: true
########################################
## Set application Expiration time ##
########################################
- name: Set Application Expiration time
uri:
url: "https://cloud.ravellosystems.com/api/v1/applications/{{ app.json.id }}/setExpiration"
method: POST
status_code: 200
HEADER_Content-Type: 'application/json'
HEADER_Accept: 'application/json'
HEADER_X-Ephemeral-Token-Authorization: "{{ ravello_ci_token }}"
body: '{ "expirationFromNowSeconds": {{ ravello_ci_expiration_time_min * 60 }} }'
body_format: json
run_once: true
- name: Wait for devices to come up
pause: minutes=5
- name: Wait for devices to come up
pause: minutes=5
- name: Wait for devices to come up
pause: minutes=2

Просмотреть файл

@ -0,0 +1,54 @@
---
- name: Get FQDN for all VM on Ravello
connection: local
hosts: junos
gather_facts: no
roles:
- ravello.lib
tasks:
###############################
## Get VM ID ###
###############################
- name: Get App ID from Ravello
ravello_get_id:
resource_name: "{{ ravello_ci_app_name }}"
resource_type: applications
token: "{{ ravello_ci_token }}"
register: app
run_once: true
# - debug: var=app
- name: Get VM ID from Ravello
ravello_get_id:
application_id: "{{ app.json.id }}"
resource_type: vms
resource_name: "{{ inventory_hostname }}"
token: "{{ ravello_ci_token }}"
failed_if_not_found: true
register: vm
# - debug: var=vm
- name: Get VM public FQDN
uri:
url: "https://cloud.ravellosystems.com/api/v1/applications/{{ app.json.id }}/vms/{{ vm.json.id }}/fqdn;deployment"
method: GET
status_code: 200
HEADER_Content-Type: 'application/json'
HEADER_Accept: 'application/json'
HEADER_X-Ephemeral-Token-Authorization: "{{ ravello_ci_token }}"
register: ravello_public_ip
- name: Delete previous file
file:
path: "host_vars/{{ inventory_hostname}}/fqdn.yaml"
state: absent
- name: Populate ansible_ssh_host Variable based on FQDN
lineinfile:
create: yes
dest: "host_vars/{{ inventory_hostname}}/fqdn.yaml"
line: "ansible_ssh_host: {{ ravello_public_ip.json.value }}"

18
tests/ravello.ini Normal file
Просмотреть файл

@ -0,0 +1,18 @@
[all:children]
junos
[junos]
vqfx-01
vqfx-02
###################################
### Define variables per groups ###
###################################
[all:vars]
ansible_ssh_user=root
ansible_ssh_pass=Juniper
ansible_ssh_port=22
ravello_ci_app_name="Ansible-junos-stdlib Ansible_{{ lookup('env','ANSIBLE_VERSION') }} Travis_{{ lookup('env','TRAVIS_JOB_ID') }} {{ lookup('env','TRAVIS_COMMIT') }}"
ravello_ci_blueprint="75695295"
ravello_ci_token="GtHFbCOuKgD1pcfkvCCIgenj6DOtn3VgRLjaYipdideCsiPC1NxJitt1UHfhF0Bf"
ravello_ci_expiration_time_min=50