diff --git a/.gitignore b/.gitignore index b44e2dc..9b27813 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +/build/ + bin .coverage .testrepository diff --git a/README.md b/README.md index 49be5e1..91dd0a4 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ development and testing, however. ``` tox -e pep8 -tox -e py34 # or py27 or py35 +tox -e py3 tox -e build +cd build/builds/neutron-arista +export TEST_ARISTA_IMAGE=/tmp/arista-cvx-virt-test.qcow2 +tox -e func ``` diff --git a/requirements.txt b/requirements.txt index b43288f..5f2fff3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,10 @@ -# Requirements to build the charm +# This file is managed centrally by release-tools and should not be modified +# within individual charm repos. See the 'global' dir contents for available +# choices of *requirements.txt files for OpenStack Charms: +# https://github.com/openstack-charmers/release-tools +# +# Build requirements charm-tools>=2.4.4 +# importlib-resources 1.1.0 removed Python 3.5 support +importlib-resources<1.1.0 simplejson -flake8 diff --git a/src/test-requirements.txt b/src/test-requirements.txt new file mode 100644 index 0000000..d3c9be8 --- /dev/null +++ b/src/test-requirements.txt @@ -0,0 +1,8 @@ +# This file is managed centrally by release-tools and should not be modified +# within individual charm repos. See the 'global' dir contents for available +# choices of *requirements.txt files for OpenStack Charms: +# https://github.com/openstack-charmers/release-tools +# +# Functional Test Requirements (let Zaza's dependencies solve all dependencies here!) +git+https://github.com/openstack-charmers/zaza.git#egg=zaza +git+https://github.com/openstack-charmers/zaza-openstack-tests.git#egg=zaza.openstack diff --git a/src/tests/00-setup b/src/tests/00-setup deleted file mode 100755 index f0616a5..0000000 --- a/src/tests/00-setup +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -sudo add-apt-repository ppa:juju/stable -y -sudo apt-get update -sudo apt-get install amulet python-requests -y diff --git a/src/tests/10-deploy b/src/tests/10-deploy deleted file mode 100755 index d177d2e..0000000 --- a/src/tests/10-deploy +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/python3 - -import amulet -import requests -import unittest - - -class TestCharm(unittest.TestCase): - def setUp(self): - self.d = amulet.Deployment() - - self.d.add('charm-neutron-arista') - self.d.expose('charm-neutron-arista') - - self.d.setup(timeout=900) - self.d.sentry.wait() - - self.unit = self.d.sentry['charm-neutron-arista'][0] - - def test_service(self): - # test we can access over http - page = requests.get('http://{}'.format(self.unit.info['public-address'])) - self.assertEqual(page.status_code, 200) - # Now you can use self.d.sentry[SERVICE][UNIT] to address each of the units and perform - # more in-depth steps. Each self.d.sentry[SERVICE][UNIT] has the following methods: - # - .info - An array of the information of that unit from Juju - # - .file(PATH) - Get the details of a file on that unit - # - .file_contents(PATH) - Get plain text output of PATH file from that unit - # - .directory(PATH) - Get details of directory - # - .directory_contents(PATH) - List files and folders in PATH on that unit - # - .relation(relation, service:rel) - Get relation data from return service - - -if __name__ == '__main__': - unittest.main() diff --git a/src/tests/README.md b/src/tests/README.md new file mode 100644 index 0000000..4a386ad --- /dev/null +++ b/src/tests/README.md @@ -0,0 +1,13 @@ +# Overview + +This directory provides Zaza tests to verify basic deployment functionality +from the perspective of this charm, its requirements and its features, as +exercised in a subset of the full OpenStack deployment test bundle topology. + +For full details on functional testing of OpenStack charms please refer to +the [functional testing][charm-guide-functional-testing] section of the +OpenStack Charm Guide. + + + +[charm-guide-functional-testing]: https://docs.openstack.org/charm-guide/latest/testing.html#functional-testing diff --git a/src/tests/bundles/bionic-queens.yaml b/src/tests/bundles/bionic-queens.yaml new file mode 100644 index 0000000..aef0f09 --- /dev/null +++ b/src/tests/bundles/bionic-queens.yaml @@ -0,0 +1,142 @@ +series: bionic + +applications: + + glance: + charm: cs:~openstack-charmers-next/glance + num_units: 1 + + keystone: + charm: cs:~openstack-charmers-next/keystone + num_units: 1 + + mysql: + charm: cs:~openstack-charmers-next/percona-cluster + num_units: 1 + + neutron-api: + # Temporary fork until we refactor neutron-arista: + charm: cs:~aurelien-lourot/neutron-api-arista-test-fixture + num_units: 1 + options: + enable-arista: True + enable-ml2-dns: False + flat-network-providers: default + vlan-ranges: default:1000:3000 + vni-ranges: 1001:2000 + neutron-security-groups: True + overlay-network-type: vxlan + use-internal-endpoints: True + enable-l3ha: True + dhcp-agents-per-network: 2 + enable-ml2-port-security: True + default-tenant-network-type: vlan + l2-population: False + ipv4-ptr-zone-prefix-size: + reverse-dns-lookup: False + dns-domain: + manage-neutron-plugin-legacy-mode: True + + neutron-openvswitch: + charm: cs:~openstack-charmers-next/neutron-openvswitch + num_units: 0 + options: + prevent-arp-spoofing: True + firewall-driver: openvswitch + enable-local-dhcp-and-metadata: True + bridge-mappings: default:br-data + data-port: ens7 + + nova-cloud-controller: + charm: cs:~openstack-charmers-next/nova-cloud-controller + num_units: 1 + options: + network-manager: Neutron + + neutron-arista: + charm: ../../../neutron-arista + num_units: 0 + options: + # Fake IP, will be set to arista-virt-test-fixture's IP address on test + # setup: + eapi-host: 192.0.2.42 + eapi-username: admin + eapi-password: password123 + api-type: EAPI + service-plugins: router + + nova-compute: + charm: cs:~openstack-charmers-next/nova-compute + num_units: 2 + constraints: mem=4G cores=4 + options: + config-flags: default_ephemeral_format=ext4 + enable-live-migration: true + enable-resize: true + migration-auth-type: ssh + + rabbitmq-server: + charm: cs:~openstack-charmers-next/rabbitmq-server + num_units: 1 + + openstack-dashboard: + charm: cs:openstack-dashboard + num_units: 1 + + lldpd: + charm: cs:lldpd + options: + interfaces-regex: 'en*' + short-name: true + + arista-virt-test-fixture: + charm: cs:~openstack-charmers-next/arista-virt-test-fixture + num_units: 1 + +relations: +- - nova-compute:amqp + - rabbitmq-server:amqp +- - keystone:shared-db + - mysql:shared-db +- - nova-cloud-controller:identity-service + - keystone:identity-service +- - glance:identity-service + - keystone:identity-service +- - neutron-api:identity-service + - keystone:identity-service +- - neutron-openvswitch:neutron-plugin-api + - neutron-api:neutron-plugin-api +- - neutron-api:shared-db + - mysql:shared-db +- - neutron-api:amqp + - rabbitmq-server:amqp +- - glance:shared-db + - mysql:shared-db +- - glance:amqp + - rabbitmq-server:amqp +- - nova-cloud-controller:image-service + - glance:image-service +- - nova-compute:image-service + - glance:image-service +- - nova-cloud-controller:cloud-compute + - nova-compute:cloud-compute +- - nova-cloud-controller:amqp + - rabbitmq-server:amqp +- - nova-compute:neutron-plugin + - neutron-openvswitch:neutron-plugin +- - neutron-openvswitch:amqp + - rabbitmq-server:amqp +- - nova-cloud-controller:shared-db + - mysql:shared-db +- - nova-cloud-controller:neutron-api + - neutron-api:neutron-api +- - neutron-api + - neutron-arista +- - neutron-api:neutron-plugin-api-subordinate + - neutron-arista:neutron-plugin-api-subordinate +- - openstack-dashboard + - mysql +- - openstack-dashboard:identity-service + - keystone:identity-service +- - lldpd + - nova-compute diff --git a/src/tests/bundles/bionic-rocky.yaml b/src/tests/bundles/bionic-rocky.yaml new file mode 100644 index 0000000..c171fd3 --- /dev/null +++ b/src/tests/bundles/bionic-rocky.yaml @@ -0,0 +1,151 @@ +series: bionic + +applications: + + glance: + charm: cs:~openstack-charmers-next/glance + num_units: 1 + options: + openstack-origin: cloud:bionic-rocky + + keystone: + charm: cs:~openstack-charmers-next/keystone + num_units: 1 + options: + openstack-origin: cloud:bionic-rocky + + mysql: + charm: cs:~openstack-charmers-next/percona-cluster + num_units: 1 + + neutron-api: + # Temporary fork until we refactor neutron-arista: + charm: cs:~aurelien-lourot/neutron-api-arista-test-fixture + num_units: 1 + options: + openstack-origin: cloud:bionic-rocky + enable-arista: True + enable-ml2-dns: False + flat-network-providers: default + vlan-ranges: default:1000:3000 + vni-ranges: 1001:2000 + neutron-security-groups: True + overlay-network-type: vxlan + use-internal-endpoints: True + enable-l3ha: True + dhcp-agents-per-network: 2 + enable-ml2-port-security: True + default-tenant-network-type: vlan + l2-population: False + ipv4-ptr-zone-prefix-size: + reverse-dns-lookup: False + dns-domain: + manage-neutron-plugin-legacy-mode: True + + neutron-openvswitch: + charm: cs:~openstack-charmers-next/neutron-openvswitch + num_units: 0 + options: + prevent-arp-spoofing: True + firewall-driver: openvswitch + enable-local-dhcp-and-metadata: True + bridge-mappings: default:br-data + data-port: ens7 + + nova-cloud-controller: + charm: cs:~openstack-charmers-next/nova-cloud-controller + num_units: 1 + options: + openstack-origin: cloud:bionic-rocky + network-manager: Neutron + + neutron-arista: + charm: ../../../neutron-arista + num_units: 0 + options: + # Fake IP, will be set to arista-virt-test-fixture's IP address on test + # setup: + eapi-host: 192.0.2.42 + eapi-username: admin + eapi-password: password123 + api-type: EAPI + service-plugins: router + + nova-compute: + charm: cs:~openstack-charmers-next/nova-compute + num_units: 2 + constraints: mem=4G cores=4 + options: + openstack-origin: cloud:bionic-rocky + config-flags: default_ephemeral_format=ext4 + enable-live-migration: true + enable-resize: true + migration-auth-type: ssh + + rabbitmq-server: + charm: cs:~openstack-charmers-next/rabbitmq-server + num_units: 1 + + openstack-dashboard: + charm: cs:openstack-dashboard + num_units: 1 + options: + openstack-origin: cloud:bionic-rocky + + lldpd: + charm: cs:lldpd + options: + interfaces-regex: 'en*' + short-name: true + + arista-virt-test-fixture: + charm: cs:~openstack-charmers-next/arista-virt-test-fixture + num_units: 1 + +relations: +- - nova-compute:amqp + - rabbitmq-server:amqp +- - keystone:shared-db + - mysql:shared-db +- - nova-cloud-controller:identity-service + - keystone:identity-service +- - glance:identity-service + - keystone:identity-service +- - neutron-api:identity-service + - keystone:identity-service +- - neutron-openvswitch:neutron-plugin-api + - neutron-api:neutron-plugin-api +- - neutron-api:shared-db + - mysql:shared-db +- - neutron-api:amqp + - rabbitmq-server:amqp +- - glance:shared-db + - mysql:shared-db +- - glance:amqp + - rabbitmq-server:amqp +- - nova-cloud-controller:image-service + - glance:image-service +- - nova-compute:image-service + - glance:image-service +- - nova-cloud-controller:cloud-compute + - nova-compute:cloud-compute +- - nova-cloud-controller:amqp + - rabbitmq-server:amqp +- - nova-compute:neutron-plugin + - neutron-openvswitch:neutron-plugin +- - neutron-openvswitch:amqp + - rabbitmq-server:amqp +- - nova-cloud-controller:shared-db + - mysql:shared-db +- - nova-cloud-controller:neutron-api + - neutron-api:neutron-api +- - neutron-api + - neutron-arista +- - neutron-api:neutron-plugin-api-subordinate + - neutron-arista:neutron-plugin-api-subordinate +- - openstack-dashboard + - mysql +- - openstack-dashboard:identity-service + - keystone:identity-service +- - lldpd + - nova-compute diff --git a/src/tests/bundles/overlays/bionic-queens.yaml.j2 b/src/tests/bundles/overlays/bionic-queens.yaml.j2 new file mode 100644 index 0000000..682a7de --- /dev/null +++ b/src/tests/bundles/overlays/bionic-queens.yaml.j2 @@ -0,0 +1,4 @@ +applications: + arista-virt-test-fixture: + resources: + arista-image: '{{ TEST_ARISTA_IMAGE }}' diff --git a/src/tests/bundles/overlays/bionic-rocky.yaml.j2 b/src/tests/bundles/overlays/bionic-rocky.yaml.j2 new file mode 100644 index 0000000..682a7de --- /dev/null +++ b/src/tests/bundles/overlays/bionic-rocky.yaml.j2 @@ -0,0 +1,4 @@ +applications: + arista-virt-test-fixture: + resources: + arista-image: '{{ TEST_ARISTA_IMAGE }}' diff --git a/src/tests/bundles/overlays/xenial-queens.yaml.j2 b/src/tests/bundles/overlays/xenial-queens.yaml.j2 new file mode 100644 index 0000000..682a7de --- /dev/null +++ b/src/tests/bundles/overlays/xenial-queens.yaml.j2 @@ -0,0 +1,4 @@ +applications: + arista-virt-test-fixture: + resources: + arista-image: '{{ TEST_ARISTA_IMAGE }}' diff --git a/src/tests/bundles/xenial-queens.yaml b/src/tests/bundles/xenial-queens.yaml new file mode 100644 index 0000000..803b9cc --- /dev/null +++ b/src/tests/bundles/xenial-queens.yaml @@ -0,0 +1,151 @@ +series: xenial + +applications: + + glance: + charm: cs:~openstack-charmers-next/glance + num_units: 1 + options: + openstack-origin: cloud:xenial-queens + + keystone: + charm: cs:~openstack-charmers-next/keystone + num_units: 1 + options: + openstack-origin: cloud:xenial-queens + + mysql: + charm: cs:~openstack-charmers-next/percona-cluster + num_units: 1 + + neutron-api: + # Temporary fork until we refactor neutron-arista: + charm: cs:~aurelien-lourot/neutron-api-arista-test-fixture + num_units: 1 + options: + openstack-origin: cloud:xenial-queens + enable-arista: True + enable-ml2-dns: False + flat-network-providers: default + vlan-ranges: default:1000:3000 + vni-ranges: 1001:2000 + neutron-security-groups: True + overlay-network-type: vxlan + use-internal-endpoints: True + enable-l3ha: True + dhcp-agents-per-network: 2 + enable-ml2-port-security: True + default-tenant-network-type: vlan + l2-population: False + ipv4-ptr-zone-prefix-size: + reverse-dns-lookup: False + dns-domain: + manage-neutron-plugin-legacy-mode: True + + neutron-openvswitch: + charm: cs:~openstack-charmers-next/neutron-openvswitch + num_units: 0 + options: + prevent-arp-spoofing: True + firewall-driver: openvswitch + enable-local-dhcp-and-metadata: True + bridge-mappings: default:br-data + data-port: ens7 + + nova-cloud-controller: + charm: cs:~openstack-charmers-next/nova-cloud-controller + num_units: 1 + options: + openstack-origin: cloud:xenial-queens + network-manager: Neutron + + neutron-arista: + charm: ../../../neutron-arista + num_units: 0 + options: + # Fake IP, will be set to arista-virt-test-fixture's IP address on test + # setup: + eapi-host: 192.0.2.42 + eapi-username: admin + eapi-password: password123 + api-type: EAPI + service-plugins: router + + nova-compute: + charm: cs:~openstack-charmers-next/nova-compute + num_units: 2 + constraints: mem=4G cores=4 + options: + openstack-origin: cloud:xenial-queens + config-flags: default_ephemeral_format=ext4 + enable-live-migration: true + enable-resize: true + migration-auth-type: ssh + + rabbitmq-server: + charm: cs:~openstack-charmers-next/rabbitmq-server + num_units: 1 + + openstack-dashboard: + charm: cs:openstack-dashboard + num_units: 1 + options: + openstack-origin: cloud:xenial-queens + + lldpd: + charm: cs:lldpd + options: + interfaces-regex: 'en*' + short-name: true + + arista-virt-test-fixture: + charm: cs:~openstack-charmers-next/arista-virt-test-fixture + num_units: 1 + +relations: +- - nova-compute:amqp + - rabbitmq-server:amqp +- - keystone:shared-db + - mysql:shared-db +- - nova-cloud-controller:identity-service + - keystone:identity-service +- - glance:identity-service + - keystone:identity-service +- - neutron-api:identity-service + - keystone:identity-service +- - neutron-openvswitch:neutron-plugin-api + - neutron-api:neutron-plugin-api +- - neutron-api:shared-db + - mysql:shared-db +- - neutron-api:amqp + - rabbitmq-server:amqp +- - glance:shared-db + - mysql:shared-db +- - glance:amqp + - rabbitmq-server:amqp +- - nova-cloud-controller:image-service + - glance:image-service +- - nova-compute:image-service + - glance:image-service +- - nova-cloud-controller:cloud-compute + - nova-compute:cloud-compute +- - nova-cloud-controller:amqp + - rabbitmq-server:amqp +- - nova-compute:neutron-plugin + - neutron-openvswitch:neutron-plugin +- - neutron-openvswitch:amqp + - rabbitmq-server:amqp +- - nova-cloud-controller:shared-db + - mysql:shared-db +- - nova-cloud-controller:neutron-api + - neutron-api:neutron-api +- - neutron-api + - neutron-arista +- - neutron-api:neutron-plugin-api-subordinate + - neutron-arista:neutron-plugin-api-subordinate +- - openstack-dashboard + - mysql +- - openstack-dashboard:identity-service + - keystone:identity-service +- - lldpd + - nova-compute diff --git a/src/tests/tests.yaml b/src/tests/tests.yaml new file mode 100644 index 0000000..4804456 --- /dev/null +++ b/src/tests/tests.yaml @@ -0,0 +1,11 @@ +charm_name: neutron-arista +smoke_bundles: +- bionic-queens +gate_bundles: +- xenial-queens +- bionic-queens +- bionic-rocky +configure: +- zaza.openstack.charm_tests.neutron_arista.setup.test_fixture +tests: +- zaza.openstack.charm_tests.neutron_arista.tests.NeutronCreateAristaNetworkTest diff --git a/src/tox.ini b/src/tox.ini new file mode 100644 index 0000000..07a7adc --- /dev/null +++ b/src/tox.ini @@ -0,0 +1,50 @@ +# Source charm (with zaza): ./src/tox.ini +# This file is managed centrally by release-tools and should not be modified +# within individual charm repos. See the 'global' dir contents for available +# choices of tox.ini for OpenStack Charms: +# https://github.com/openstack-charmers/release-tools + +[tox] +envlist = pep8 +skipsdist = True +# NOTE: Avoid build/test env pollution by not enabling sitepackages. +sitepackages = False +# NOTE: Avoid false positives by not skipping missing interpreters. +skip_missing_interpreters = False + +[testenv] +setenv = VIRTUAL_ENV={envdir} + PYTHONHASHSEED=0 +whitelist_externals = juju +passenv = HOME TERM CS_* OS_* TEST_* +deps = -r{toxinidir}/test-requirements.txt +install_command = + pip install {opts} {packages} + +[testenv:pep8] +basepython = python3 +deps=charm-tools +commands = charm-proof + +[testenv:func-noop] +basepython = python3 +commands = + functest-run-suite --help + +[testenv:func] +basepython = python3 +commands = + functest-run-suite --keep-model + +[testenv:func-smoke] +basepython = python3 +commands = + functest-run-suite --keep-model --smoke + +[testenv:func-target] +basepython = python3 +commands = + functest-run-suite --keep-model --bundle {posargs} + +[testenv:venv] +commands = {posargs} diff --git a/test-requirements.txt b/test-requirements.txt index 9a0bed8..0ab97f6 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,7 +1,23 @@ -# Unit test requirements +# This file is managed centrally by release-tools and should not be modified +# within individual charm repos. See the 'global' dir contents for available +# choices of *requirements.txt files for OpenStack Charms: +# https://github.com/openstack-charmers/release-tools +# +# Lint and unit test requirements flake8>=2.2.4,<=2.4.1 -os-testr>=0.4.1 +stestr>=2.2.0 +requests>=2.18.4 charms.reactive mock>=1.2 +nose>=1.3.7 coverage>=3.6 -git+https://github.com/openstack/charms.openstack#egg=charms.openstack +git+https://github.com/openstack/charms.openstack.git#egg=charms.openstack +# +# Revisit for removal / mock improvement: +netifaces # vault +psycopg2-binary # vault +tenacity # vault +pbr # vault +cryptography # vault, keystone-saml-mellon +lxml # keystone-saml-mellon +hvac # vault, barbican-vault diff --git a/tox.ini b/tox.ini index 733add4..afd48f0 100644 --- a/tox.ini +++ b/tox.ini @@ -1,14 +1,25 @@ +# Source charm: ./tox.ini +# This file is managed centrally by release-tools and should not be modified +# within individual charm repos. See the 'global' dir contents for available +# choices of tox.ini for OpenStack Charms: +# https://github.com/openstack-charmers/release-tools + [tox] skipsdist = True envlist = pep8,py3 +# NOTE: Avoid build/test env pollution by not enabling sitepackages. +sitepackages = False +# NOTE: Avoid false positives by not skipping missing interpreters. +skip_missing_interpreters = False [testenv] setenv = VIRTUAL_ENV={envdir} PYTHONHASHSEED=0 TERM=linux LAYER_PATH={toxinidir}/layers + INTERFACE_PATH={toxinidir}/interfaces JUJU_REPOSITORY={toxinidir}/build -passenv = http_proxy https_proxy INTERFACE_PATH LAYER_PATH +passenv = http_proxy https_proxy INTERFACE_PATH LAYER_PATH JUJU_REPOSITORY install_command = pip install {opts} {packages} deps = @@ -22,27 +33,65 @@ commands = [testenv:py3] basepython = python3 deps = -r{toxinidir}/test-requirements.txt -commands = stestr run {posargs} +commands = stestr run --slowest {posargs} [testenv:py35] basepython = python3.5 deps = -r{toxinidir}/test-requirements.txt -commands = stestr run {posargs} +commands = stestr run --slowest {posargs} [testenv:py36] basepython = python3.6 deps = -r{toxinidir}/test-requirements.txt -commands = stestr run {posargs} +commands = stestr run --slowest {posargs} + +[testenv:py37] +basepython = python3.7 +deps = -r{toxinidir}/test-requirements.txt +commands = stestr run --slowest {posargs} + +[testenv:py38] +basepython = python3.8 +deps = -r{toxinidir}/test-requirements.txt +commands = stestr run --slowest {posargs} [testenv:pep8] basepython = python3 deps = -r{toxinidir}/test-requirements.txt commands = flake8 {posargs} src unit_tests +[testenv:cover] +# Technique based heavily upon +# https://github.com/openstack/nova/blob/master/tox.ini +basepython = python3 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt +setenv = + {[testenv]setenv} + PYTHON=coverage run +commands = + coverage erase + stestr run --slowest {posargs} + coverage combine + coverage html -d cover + coverage xml -o cover/coverage.xml + coverage report + +[coverage:run] +branch = True +concurrency = multiprocessing +parallel = True +source = + . +omit = + .tox/* + */charmhelpers/* + unit_tests/* + [testenv:venv] basepython = python3 commands = {posargs} [flake8] # E402 ignore necessary for path append before sys module import in actions -ignore = E402 +ignore = E402,W504