From 604a76bdd9688f4f883321d62136475fa40856da Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Thu, 21 Nov 2019 00:30:53 +0100 Subject: [PATCH] Read build args for metricbeat system tests from file (#14520) (#14614) A new file is being added to add information about the supported versions of a service, use this file to obtain the build args for docker images needed by metricbeat system tests. Python tests can now be decorated using the parameterized library instead of manually copying them. MySQL test files and docker compose definition has been moved to its own directory. (cherry picked from commit 9913bbf6b85c44da8c7c71194e5048a7140c304f) --- CHANGELOG-developer.next.asciidoc | 1 + libbeat/tests/system/requirements.txt | 2 +- metricbeat/docker-compose.yml | 9 ---- .../apache/_meta/supported-versions.yml | 3 ++ metricbeat/module/apache/test_apache.py | 34 ++++++------- .../module/mysql/_meta/supported-versions.yml | 15 ++++++ metricbeat/module/mysql/docker-compose.yml | 11 +++++ .../system => module/mysql}/test_mysql.py | 48 ++----------------- metricbeat/tests/system/metricbeat.py | 34 +++++++++++++ 9 files changed, 88 insertions(+), 69 deletions(-) create mode 100644 metricbeat/module/apache/_meta/supported-versions.yml create mode 100644 metricbeat/module/mysql/_meta/supported-versions.yml create mode 100644 metricbeat/module/mysql/docker-compose.yml rename metricbeat/{tests/system => module/mysql}/test_mysql.py (63%) diff --git a/CHANGELOG-developer.next.asciidoc b/CHANGELOG-developer.next.asciidoc index 10f92aa8f835..c8a13f29463f 100644 --- a/CHANGELOG-developer.next.asciidoc +++ b/CHANGELOG-developer.next.asciidoc @@ -60,3 +60,4 @@ The list below covers the major changes between 7.0.0-rc2 and master only. - Strip debug symbols from binaries to reduce binary sizes. {issue}12768[12768] - Compare event by event in `testadata` framework to avoid sorting problems {pull}13747[13747] - Added a `default_field` option to fields in fields.yml to offer a way to exclude fields from the default_field list. {issue}14262[14262] {pull}14341[14341] +- `supported-versions.yml` can be used in metricbeat python system tests to obtain the build args for docker compose builds. {pull}14520[14520] diff --git a/libbeat/tests/system/requirements.txt b/libbeat/tests/system/requirements.txt index 05c10695853d..7c9135e0ddca 100644 --- a/libbeat/tests/system/requirements.txt +++ b/libbeat/tests/system/requirements.txt @@ -27,6 +27,6 @@ termcolor==1.1.0 texttable==0.9.1 urllib3==1.24.2 websocket-client==0.47.0 -parameterized==0.6.1 +parameterized==0.7.0 jsondiff==1.1.2 semver==2.8.1 diff --git a/metricbeat/docker-compose.yml b/metricbeat/docker-compose.yml index ef8970d649c1..ccbba1ef42a9 100644 --- a/metricbeat/docker-compose.yml +++ b/metricbeat/docker-compose.yml @@ -231,15 +231,6 @@ services: ports: - 4949 - mysql: - image: docker.elastic.co/observability-ci/beats-integration-mysql:${MYSQL_VARIANT:-mysql}-${MYSQL_VERSION:-5.7.12}-1 - build: - context: ./module/mysql/_meta - args: - MYSQL_IMAGE: ${MYSQL_VARIANT:-mysql}:${MYSQL_VERSION:-5.7.12} - ports: - - 3306 - nats: image: docker.elastic.co/observability-ci/beats-integration-nats:${NATS_VERSION:-2.0.4}-1 build: diff --git a/metricbeat/module/apache/_meta/supported-versions.yml b/metricbeat/module/apache/_meta/supported-versions.yml new file mode 100644 index 000000000000..cecc98367c8b --- /dev/null +++ b/metricbeat/module/apache/_meta/supported-versions.yml @@ -0,0 +1,3 @@ +variants: + - APACHE_VERSION: 2.4.12 + - APACHE_VERSION: 2.4.20 diff --git a/metricbeat/module/apache/test_apache.py b/metricbeat/module/apache/test_apache.py index 65c7c439a28c..283487b0a2f6 100644 --- a/metricbeat/module/apache/test_apache.py +++ b/metricbeat/module/apache/test_apache.py @@ -3,6 +3,7 @@ from nose.plugins.attrib import attr import urllib2 import time +import semver import sys sys.path.append(os.path.join(os.path.dirname(__file__), '../../tests/system')) @@ -30,6 +31,7 @@ ] +@metricbeat.parameterized_with_supported_versions class ApacheStatusTest(metricbeat.BaseTest): COMPOSE_SERVICES = ['apache'] @@ -74,22 +76,22 @@ def test_output(self): def verify_fields(self, evt): self.assertItemsEqual(self.de_dot(APACHE_FIELDS), evt.keys()) apache_status = evt["apache"]["status"] - self.assertItemsEqual( - self.de_dot(APACHE_STATUS_FIELDS), apache_status.keys()) - self.assertItemsEqual( - self.de_dot(CPU_FIELDS), apache_status["cpu"].keys()) - # There are more fields that could be checked. + if self.old_apache_version(): + self.assertItemsEqual( + self.de_dot(APACHE_OLD_STATUS_FIELDS), apache_status.keys()) + else: + self.assertItemsEqual( + self.de_dot(APACHE_STATUS_FIELDS), apache_status.keys()) + self.assertItemsEqual( + self.de_dot(CPU_FIELDS), apache_status["cpu"].keys()) + # There are more fields that could be checked. + + def old_apache_version(self): + if not 'APACHE_VERSION' in self.COMPOSE_ENV: + return False + + version = self.COMPOSE_ENV['APACHE_VERSION'] + return semver.compare(version, '2.4.12') <= 0 def get_hosts(self): return ['http://' + self.compose_host()] - - -class ApacheOldStatusTest(ApacheStatusTest): - - COMPOSE_ENV = {'APACHE_VERSION': '2.4.12'} - - def verify_fields(self, evt): - self.assertItemsEqual(self.de_dot(APACHE_FIELDS), evt.keys()) - apache_status = evt["apache"]["status"] - self.assertItemsEqual( - self.de_dot(APACHE_OLD_STATUS_FIELDS), apache_status.keys()) diff --git a/metricbeat/module/mysql/_meta/supported-versions.yml b/metricbeat/module/mysql/_meta/supported-versions.yml new file mode 100644 index 000000000000..1b55490d41cc --- /dev/null +++ b/metricbeat/module/mysql/_meta/supported-versions.yml @@ -0,0 +1,15 @@ +variants: + - MYSQL_VARIANT: mysql + MYSQL_VERSION: 5.7.12 + - MYSQL_VARIANT: mysql + MYSQL_VERSION: 8.0.13 + - MYSQL_VARIANT: percona + MYSQL_VERSION: 5.7.24 + - MYSQL_VARIANT: percona + MYSQL_VERSION: 8.0.13-4 + - MYSQL_VARIANT: mariadb + MYSQL_VERSION: 10.2.23 + - MYSQL_VARIANT: mariadb + MYSQL_VERSION: 10.3.14 + - MYSQL_VARIANT: mariadb + MYSQL_VERSION: 10.4.4 diff --git a/metricbeat/module/mysql/docker-compose.yml b/metricbeat/module/mysql/docker-compose.yml new file mode 100644 index 000000000000..8ce049cb618b --- /dev/null +++ b/metricbeat/module/mysql/docker-compose.yml @@ -0,0 +1,11 @@ +version: '2.3' + +services: + mysql: + image: docker.elastic.co/observability-ci/beats-integration-mysql:${MYSQL_VARIANT:-mysql}-${MYSQL_VERSION:-5.7.12}-1 + build: + context: ./_meta + args: + MYSQL_IMAGE: ${MYSQL_VARIANT:-mysql}:${MYSQL_VERSION:-5.7.12} + ports: + - 3306 diff --git a/metricbeat/tests/system/test_mysql.py b/metricbeat/module/mysql/test_mysql.py similarity index 63% rename from metricbeat/tests/system/test_mysql.py rename to metricbeat/module/mysql/test_mysql.py index f0859e320dd9..998082bccf44 100644 --- a/metricbeat/tests/system/test_mysql.py +++ b/metricbeat/module/mysql/test_mysql.py @@ -1,14 +1,18 @@ import os -import metricbeat +import sys import unittest from nose.plugins.attrib import attr +sys.path.append(os.path.join(os.path.dirname(__file__), '../../tests/system')) +import metricbeat + MYSQL_FIELDS = metricbeat.COMMON_FIELDS + ["mysql"] MYSQL_STATUS_FIELDS = ["clients", "cluster", "cpu", "keyspace", "memory", "persistence", "replication", "server", "stats"] +@metricbeat.parameterized_with_supported_versions class Test(metricbeat.BaseTest): COMPOSE_SERVICES = ['mysql'] @@ -44,45 +48,3 @@ def test_status(self): def get_hosts(self): return ['root:test@tcp({})/'.format(self.compose_host())] - - -class TestMysql80(Test): - COMPOSE_ENV = { - 'MYSQL_VARIANT': 'mysql', - 'MYSQL_VERSION': '8.0.13', - } - - -class TestPercona57(Test): - COMPOSE_ENV = { - 'MYSQL_VARIANT': 'percona', - 'MYSQL_VERSION': '5.7.24', - } - - -class TestPercona80(Test): - COMPOSE_ENV = { - 'MYSQL_VARIANT': 'percona', - 'MYSQL_VERSION': '8.0.13-4', - } - - -class TestMariadb102(Test): - COMPOSE_ENV = { - 'MYSQL_VARIANT': 'mariadb', - 'MYSQL_VERSION': '10.2.23', - } - - -class TestMariadb103(Test): - COMPOSE_ENV = { - 'MYSQL_VARIANT': 'mariadb', - 'MYSQL_VERSION': '10.3.14', - } - - -class TestMariadb104(Test): - COMPOSE_ENV = { - 'MYSQL_VARIANT': 'mariadb', - 'MYSQL_VERSION': '10.4.4', - } diff --git a/metricbeat/tests/system/metricbeat.py b/metricbeat/tests/system/metricbeat.py index e54007987c55..54c76f65ddf1 100644 --- a/metricbeat/tests/system/metricbeat.py +++ b/metricbeat/tests/system/metricbeat.py @@ -1,10 +1,12 @@ import re import sys import os +import yaml sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../libbeat/tests/system'))) from beat.beat import TestCase +from parameterized import parameterized_class COMMON_FIELDS = ["@timestamp", "agent", "metricset.name", "metricset.host", "metricset.module", "metricset.rtt", "host.name", "service.name", "event", "ecs"] @@ -105,3 +107,35 @@ def check_metricset(self, module, metricset, hosts, fields=[], extras=[]): self.assertItemsEqual(self.de_dot(fields), evt.keys()) self.assert_fields_are_documented(evt) + + +def supported_versions(path): + """ + Returns variants information as expected by parameterized_class, + that is as a list of lists with an only element that is used to + override the value of COMPOSE_ENV. + """ + if not os.path.exists(path): + # Return an empty variant so a class is instantiated with defaults + return [[{}]] + + variants = [] + with open(path) as f: + versions_info = yaml.safe_load(f) + + for variant in versions_info['variants']: + variants += [[variant]] + + return variants + + +def parameterized_with_supported_versions(base_class): + """ + Decorates a class so instead of the base class, multiple copies + of it are registered, one for each supported version. + """ + class_dir = os.path.abspath(os.path.dirname(sys.modules[base_class.__module__].__file__)) + versions_path = os.path.join(class_dir, '_meta', 'supported-versions.yml') + variants = supported_versions(versions_path) + decorator = parameterized_class(['COMPOSE_ENV'], variants) + decorator(base_class)