From dd5362b779180dd4f09f62951d9bf32bbd9cae10 Mon Sep 17 00:00:00 2001 From: Federico Ressi Date: Mon, 6 Apr 2020 10:43:36 +0200 Subject: [PATCH] Add Vagrant tests for infrared plugin (CentOS 8) Change-Id: Icd7d5634f1da91a4cedd3ccf5c752297c318ef22 --- roles/tests/Vagrantfile | 126 +++++++++++++++++++++++++ roles/tests/ansible.cfg | 4 + roles/tests/provision.yaml | 89 +++++++++++++++++ roles/tests/templates/ansible_hosts.j2 | 9 ++ roles/tests/templates/hosts.j2 | 14 +++ roles/tests/templates/ssh_config.j2 | 12 +++ roles/tests/test_infrared_plugin.yaml | 65 +++++++++++++ 7 files changed, 319 insertions(+) create mode 100644 roles/tests/Vagrantfile create mode 100644 roles/tests/ansible.cfg create mode 100644 roles/tests/provision.yaml create mode 100644 roles/tests/templates/ansible_hosts.j2 create mode 100644 roles/tests/templates/hosts.j2 create mode 100644 roles/tests/templates/ssh_config.j2 create mode 100644 roles/tests/test_infrared_plugin.yaml diff --git a/roles/tests/Vagrantfile b/roles/tests/Vagrantfile new file mode 100644 index 000000000..2544ca0ae --- /dev/null +++ b/roles/tests/Vagrantfile @@ -0,0 +1,126 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +# Customize the count of CPU cores on the VM +CPUS = 4 + +# Customize the amount of memory on the VM +MEMORY = 512 + +# Every Vagrant development environment requires a box. You can search for +# boxes at https://vagrantcloud.com/search. +BOX = "generic/centos8" + +TOX_INI_DIR = '../..' + +TEST_DIR = File.dirname(__FILE__) + + +# list of VMs +NODES = { + 'primary' => {'ip' => '172.18.161.6', + 'hostname' => 'primary'}, + 'secondary' => {'ip' => '172.18.161.7', + 'hostname' => 'secondary'}, +} + + +SSH_KEY_FILE = File.join([TEST_DIR, 'ssh_id']) + + +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + # The most common configuration options are documented and commented below. + # For a complete reference, please see the online documentation at + # https://docs.vagrantup.com. + + config.vm.box = BOX + + # Disable automatic box update checking. If you disable this, then + # boxes will only be checked for updates when the user runs + # `vagrant box outdated`. This is not recommended. + config.vm.box_check_update = false + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + # NOTE: This will enable public access to the opened port + # config.vm.network "forwarded_port", guest: 80, host: 8080 + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine and only allow access + # via 127.0.0.1 to disable public access + # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" + + # Create a private network, which allows host-only access to the machine + # using a specific IP. + # config.vm.network "private_network", ip: DEVSTACK_HOST_IP + + # Create a public network, which generally matched to bridged network. + # Bridged networks make the machine appear as another physical device on + # your network. + # config.vm.network "public_network", ip: "172.18.161.6" + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + # config.vm.synced_folder "../data", "/vagrant_data" + + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + # Example for VirtualBox: + + config.vm.provider "virtualbox" do |vb| + # Display the VirtualBox GUI when booting the machine + vb.gui = false + + vb.cpus = CPUS + vb.memory = MEMORY + end + + config.vm.provider "libvirt" do |libvirt| + libvirt.cpus = CPUS + libvirt.memory = MEMORY + end + + # Spawn secondary VMs + config.vm.define 'secondary' do |node| + node.vm.hostname = NODES['secondary']['hostname'] + node.vm.network "private_network", ip: NODES['secondary']['ip'] + end + + # Spawn primary VM and run test cases on it + config.vm.define 'primary' do |node| + node.vm.hostname = NODES['primary']['hostname'] + node.vm.network "private_network", ip: NODES['primary']['ip'] + + # No need to copy .tox/ dir to node to execute test cases + node.vm.synced_folder TOX_INI_DIR, "/vagrant", type: "rsync", + rsync__exclude: [".tox/"] + + # Prepare VMs using ansible playbook + node.vm.provision "ansible" do |ansible| + ansible.playbook = "provision.yaml" + ansible.limit = "all" + ansible.extra_vars = { + 'vagrant_nodes' => NODES, + 'ssh_key_file' => SSH_KEY_FILE, + } + end + + # Run all test cases + for playbook_file in Dir[File.join(TEST_DIR, 'test_*.yaml')] do + node.vm.provision "ansible" do |ansible| + ansible.limit = 'all' + ansible.playbook = playbook_file + end + end + end +end diff --git a/roles/tests/ansible.cfg b/roles/tests/ansible.cfg new file mode 100644 index 000000000..5b81cd27e --- /dev/null +++ b/roles/tests/ansible.cfg @@ -0,0 +1,4 @@ +[defaults] + +roles_path = ../ +interpreter_python = auto diff --git a/roles/tests/provision.yaml b/roles/tests/provision.yaml new file mode 100644 index 000000000..217ad41e6 --- /dev/null +++ b/roles/tests/provision.yaml @@ -0,0 +1,89 @@ +--- + +- hosts: primary + tasks: + - name: "copy /etc/resolv.conf" + become: yes + copy: + src: /etc/resolv.conf + dest: /etc/resolv.conf + owner: root + group: root + mode: '0644' + + - name: "make /etc/hosts" + become: yes + template: + src: 'hosts.j2' + dest: '/etc/hosts' + owner: root + mode: '0644' + + - name: "make ~/.ssh/config file with all Vagrant nodes" + template: + src: 'ssh_config.j2' + dest: '/home/vagrant/.ssh/config' + owner: vagrant + mode: '0600' + + - name: "generate local SSH key '{{ ssh_key_file }}'" + openssh_keypair: + path: '{{ ssh_key_file }}' + type: rsa + size: 4096 + state: present + force: no + delegate_to: localhost + + - name: "copy '{{ ssh_key_file }}' file to host" + copy: + src: '{{ ssh_key_file }}{{ item }}' + dest: '/home/vagrant/.ssh/id_rsa{{ item }}' + owner: vagrant + group: vagrant + mode: '0600' + loop: + - '' + - '.pub' + + - name: "set ansible_python_interpreter fact" + set_fact: + ansible_python_interpreter: > + {{ ansible_python_interpreter | + default("/usr/libexec/platform-python") }} + + - name: "make Ansible inventory file with vagrant nodes" + template: + src: 'ansible_hosts.j2' + dest: '/vagrant/ansible_hosts' + + +- hosts: all + tasks: + + - name: "set authorized SSH key taken from '{{ ssh_key_file }}'" + authorized_key: + user: vagrant + state: present + key: "{{ lookup('file', ssh_key_file + '.pub') }}" + + +- hosts: primary + tasks: + + - name: "check ICMP connectivity" + shell: | + set -xe + ping -c 1 '{{ item.1.ip }}' + ping -c 1 '{{ item.1.hostname }}' + register: check_icmp_connectivity + loop: '{{ vagrant_nodes | dictsort }}' + + - name: "check SSH connectivity via hostname" + shell: | + set -xe + ssh '{{ item.1.ip }}' hostname + ssh '{{ item.1.hostname }}' hostname + ssh '{{ item.0 }}' hostname + register: check_ssh_connectivity + loop: '{{ vagrant_nodes | dictsort }}' diff --git a/roles/tests/templates/ansible_hosts.j2 b/roles/tests/templates/ansible_hosts.j2 new file mode 100644 index 000000000..c2f81ac1e --- /dev/null +++ b/roles/tests/templates/ansible_hosts.j2 @@ -0,0 +1,9 @@ + +[vagrant] +{% for node in (vagrant_nodes | dictsort) %} +{{ node.0 }} +{% endfor %} + +[vagrant:vars] +ansible_python_interpreter = {{ ansible_python_interpreter }} + diff --git a/roles/tests/templates/hosts.j2 b/roles/tests/templates/hosts.j2 new file mode 100644 index 000000000..f38cdc8a6 --- /dev/null +++ b/roles/tests/templates/hosts.j2 @@ -0,0 +1,14 @@ + +# --- localhost --- + +127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 +::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 +127.0.0.1 ::1 {{ vagrant_nodes[inventory_hostname].hostname }} + + +# -- Vagrant nodes --- + +{% for node in (vagrant_nodes | dictsort) %} +{{ node.1.ip }} {{ node.1.hostname }} +{% endfor %} + diff --git a/roles/tests/templates/ssh_config.j2 b/roles/tests/templates/ssh_config.j2 new file mode 100644 index 000000000..2f99e6ac5 --- /dev/null +++ b/roles/tests/templates/ssh_config.j2 @@ -0,0 +1,12 @@ + +# --- Vagrant nodes --- + +{% for node in (vagrant_nodes | dictsort) %} +Host {{ node.0 }} {{ node.1.hostname }} {{ node.1.ip }} + Hostname {{ node.1.hostname }} + User vagrant + StrictHostkeyChecking no + UserKnownHostsFile /dev/null + IdentityFile ~/.ssh/id_rsa + +{% endfor %} diff --git a/roles/tests/test_infrared_plugin.yaml b/roles/tests/test_infrared_plugin.yaml new file mode 100644 index 000000000..9c68271e4 --- /dev/null +++ b/roles/tests/test_infrared_plugin.yaml @@ -0,0 +1,65 @@ +--- + +- hosts: primary + + vars: + test_src_dir: /vagrant + test_collect_dir: '{{ test_src_dir }}/test_results' + + roles: + - tobiko-ensure-tox + - tobiko-ensure-git + - tobiko-ensure-rsync + + tasks: + - name: "remove collected files" + file: + path: '{{ test_collect_dir }}' + state: absent + + - name: "set ansible_python_interpreter fact" + set_fact: + ansible_python_interpreter: > + {{ ansible_python_interpreter | + default("/usr/libexec/platform-python") }} + + - name: "run Tox InfraRed plugin" + command: > + '{{ tox_executable }}' -e infrared -- + --host secondary + --collect-dir '{{ test_collect_dir }}' + args: + chdir: /vagrant + ignore_errors: yes + register: run_tox + + - name: "show Tox InfraRed plugin output" + debug: var=run_tox.stdout_lines + + - name: "show Tox InfraRed plugin errors" + debug: var=run_tox.stderr_lines + when: run_tox is failed + failed_when: yes + + - name: "list collected files" + command: > + ls '{{ test_collect_dir }}' + register: list_test_result_files + + - name: "set collected files fact" + set_fact: + collected_files: '{{ list_test_result_files.stdout_lines }}' + + - name: "show collected files" + debug: var=collected_files + + - name: "check collected files" + assert: + that: + - item in collected_files + loop: + - tobiko.log + - tobiko.conf + - test_results.html + - test_results.subunit + - test_results.xml