Skip to content

Commit 63c446a

Browse files
committed
Update system tests (elastic#3014)
* expose elasticsearch and kibana * include pipeline registration in started consideration * check for index, pipeline, docs before destroying * disable flaky test
1 parent 6863d3e commit 63c446a

11 files changed

+159
-173
lines changed

docker-compose.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,15 @@ services:
2323
kibana: { condition: service_healthy }
2424

2525
elasticsearch:
26+
ports:
27+
- 9200:9200
2628
extends:
2729
file: ./_beats/testing/environments/${TESTING_ENVIRONMENT}.yml
2830
service: elasticsearch
2931

3032
kibana:
33+
ports:
34+
- 5601:5601
3135
extends:
3236
file: ./_beats/testing/environments/${TESTING_ENVIRONMENT}.yml
3337
service: kibana

tests/system/apmserver.py

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import os
44
import re
55
import shutil
6+
import unittest
67
from time import gmtime, strftime
78
from urlparse import urlparse
89

@@ -14,8 +15,9 @@
1415

1516
sys.path.append(os.path.join(os.path.dirname(__file__), '..',
1617
'..', '_beats', 'libbeat', 'tests', 'system'))
17-
from beat.beat import TestCase, TimeoutError
18+
from beat.beat import INTEGRATION_TESTS, TestCase, TimeoutError
1819

20+
integration_test = unittest.skipUnless(INTEGRATION_TESTS, "integration test")
1921

2022
class BaseTest(TestCase):
2123
maxDiff = None
@@ -105,11 +107,26 @@ def setUp(self):
105107
self.apmserver_proc = self.start_beat(**self.start_args())
106108
self.wait_until_started()
107109

110+
# try make sure APM Server is fully up
111+
cfg = self.config()
112+
# pipeline registration is enabled by default and only happens if the output is elasticsearch
113+
if not getattr(self, "register_pipeline_disabled", False) and \
114+
cfg.get("elasticsearch_host") and \
115+
cfg.get("register_pipeline_enabled") != "false" and cfg.get("register_pipeline_overwrite") != "false":
116+
self.wait_until_pipelines_registered()
117+
108118
def start_args(self):
109119
return {}
110120

111121
def wait_until_started(self):
112-
self.wait_until(lambda: self.log_contains("Starting apm-server"))
122+
self.wait_until(lambda: self.log_contains("Starting apm-server"), name="apm-server started")
123+
124+
def wait_until_ilm_setup(self):
125+
self.wait_until(lambda: self.log_contains("Finished index management setup."), name="ILM setup")
126+
127+
def wait_until_pipelines_registered(self):
128+
self.wait_until(lambda: self.log_contains("Registered Ingest Pipelines successfully"),
129+
name="pipelines registered")
113130

114131
def assert_no_logged_warnings(self, suppress=None):
115132
"""
@@ -130,11 +147,13 @@ def assert_no_logged_warnings(self, suppress=None):
130147
log = re.sub(s, "", log)
131148
self.assertNotRegexpMatches(log, "ERR|WARN")
132149

133-
def request_intake(self, data="", url="", headers={'content-type': 'application/x-ndjson'}):
134-
if url == "":
150+
def request_intake(self, data=None, url=None, headers=None):
151+
if not url:
135152
url = self.intake_url
136-
if data == "":
153+
if data is None:
137154
data = self.get_event_payload()
155+
if headers is None:
156+
headers = {'content-type': 'application/x-ndjson'}
138157
return requests.post(url, data=data, headers=headers)
139158

140159

@@ -181,20 +200,28 @@ def setUp(self):
181200
self.kibana_url = self.get_kibana_url()
182201

183202
# Cleanup index and template first
184-
self.es.indices.delete(index="apm*", ignore=[400, 404])
185-
for idx in self.indices:
186-
self.wait_until(lambda: not self.es.indices.exists(idx))
187-
188-
self.es.indices.delete_template(name="apm*", ignore=[400, 404])
189-
for idx in self.indices:
190-
self.wait_until(lambda: not self.es.indices.exists_template(idx))
203+
assert all(idx.startswith("apm") for idx in self.indices), "not all indices prefixed with apm, cleanup assumption broken"
204+
if self.es.indices.get("apm*"):
205+
self.es.indices.delete(index="apm*", ignore=[400, 404])
206+
for idx in self.indices:
207+
self.wait_until(lambda: not self.es.indices.exists(idx), name="index {} to be deleted".format(idx))
208+
209+
if self.es.indices.get_template(name="apm*", ignore=[400, 404]):
210+
self.es.indices.delete_template(name="apm*", ignore=[400, 404])
211+
for idx in self.indices:
212+
self.wait_until(lambda: not self.es.indices.exists_template(idx),
213+
name="index template {} to be deleted".format(idx))
191214

192215
# truncate, don't delete agent configuration index since it's only created when kibana starts up
193-
self.es.delete_by_query(self.index_acm, {"query": {"match_all": {}}},
194-
ignore_unavailable=True, wait_for_completion=True)
195-
self.wait_until(lambda: self.es.count(index=self.index_acm, ignore_unavailable=True)["count"] == 0)
216+
if self.es.count(index=self.index_acm, ignore_unavailable=True)["count"] > 0:
217+
self.es.delete_by_query(self.index_acm, {"query": {"match_all": {}}},
218+
ignore_unavailable=True, wait_for_completion=True)
219+
self.wait_until(lambda: self.es.count(index=self.index_acm, ignore_unavailable=True)["count"] == 0,
220+
max_timeout=30, name="acm index {} to be empty".format(self.index_acm))
221+
196222
# Cleanup pipelines
197-
self.es.ingest.delete_pipeline(id="*")
223+
if self.es.ingest.get_pipeline(ignore=[400, 404]):
224+
self.es.ingest.delete_pipeline(id="*")
198225

199226
super(ElasticTest, self).setUp()
200227

@@ -219,7 +246,8 @@ def load_docs_with_template(self, data_path, url, endpoint, expected_events_coun
219246
lambda: (self.es.count(index=query_index, body={
220247
"query": {"term": {"processor.name": endpoint}}}
221248
)['count'] == expected_events_count),
222-
max_timeout=max_timeout
249+
max_timeout=max_timeout,
250+
name="{} documents to reach {}".format(endpoint, expected_events_count),
223251
)
224252

225253
def check_backend_error_sourcemap(self, index, count=1):
@@ -311,7 +339,8 @@ def wait_for_sourcemaps(self, expected_ct=1):
311339
self.wait_until(
312340
lambda: (self.es.count(index=idx, body={
313341
"query": {"term": {"processor.name": 'sourcemap'}}}
314-
)['count'] == expected_ct)
342+
)['count'] == expected_ct),
343+
name="{} sourcemaps to ingest".format(expected_ct),
315344
)
316345

317346
def check_rum_error_sourcemap(self, updated, expected_err=None, count=1):

tests/system/config/apm-server.yml.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ apm-server:
7070
register.ingest.pipeline.enabled: {{ register_pipeline_enabled }}
7171
{% endif %}
7272
{% if register_pipeline_overwrite %}
73-
register.ingest.pipeline.overwrite: {{ register_pipeline_overwrite }}
73+
register.ingest.pipeline.overwrite: {{ register_pipeline_overwrite }}
7474
{% endif %}
7575

7676
{% if instrumentation_enabled %}

tests/system/test_access.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from nose.tools import raises
1111
from requests.exceptions import SSLError, ChunkedEncodingError
12-
from beat.beat import INTEGRATION_TESTS, TimeoutError
12+
from apmserver import TimeoutError, integration_test
1313
from requests.packages.urllib3.exceptions import SubjectAltNameWarning
1414
requests.packages.urllib3.disable_warnings(SubjectAltNameWarning)
1515

@@ -56,7 +56,7 @@ def oauth(v):
5656
assert r.status_code == 401, r.status_code
5757

5858

59-
@unittest.skipUnless(INTEGRATION_TESTS, "integration test")
59+
@integration_test
6060
class TestSecureServerBaseTest(ServerSetUpBaseTest):
6161
@classmethod
6262
def setUpClass(cls):
@@ -145,6 +145,7 @@ def setUp(self):
145145
super(TestSecureServerBaseTest, self).setUp()
146146

147147

148+
@integration_test
148149
class TestSSLEnabledNoClientVerificationTest(TestSecureServerBaseTest):
149150
def ssl_overrides(self):
150151
return {"ssl_client_authentication": "none"}
@@ -163,6 +164,7 @@ def test_https_server_validation_fails(self):
163164
assert r.status_code == 202, r.status_code
164165

165166

167+
@integration_test
166168
class TestSSLEnabledOptionalClientVerificationTest(TestSecureServerBaseTest):
167169
# no ssl_overrides necessary as `optional` is default
168170

@@ -183,6 +185,7 @@ def test_https_self_signed_cert(self):
183185
assert r.status_code == 202, r.status_code
184186

185187

188+
@integration_test
186189
class TestSSLEnabledOptionalClientVerificationWithCATest(TestSecureServerBaseTest):
187190
def ssl_overrides(self):
188191
return {"ssl_certificate_authorities": self.ca_cert}
@@ -205,6 +208,7 @@ def test_https_auth_cert_ok(self):
205208
assert r.status_code == 202, r.status_code
206209

207210

211+
@integration_test
208212
class TestSSLEnabledRequiredClientVerificationTest(TestSecureServerBaseTest):
209213
def ssl_overrides(self):
210214
return {"ssl_client_authentication": "required",
@@ -225,6 +229,7 @@ def test_https_auth_cert_ok(self):
225229
assert r.status_code == 202, r.status_code
226230

227231

232+
@integration_test
228233
class TestSSLDefaultSupportedProcotolsTest(TestSecureServerBaseTest):
229234
def ssl_overrides(self):
230235
return {"ssl_certificate_authorities": self.ca_cert}
@@ -240,6 +245,7 @@ def test_tls_v1_2(self):
240245
self.ssl_connect()
241246

242247

248+
@integration_test
243249
class TestSSLSupportedProcotolsTest(TestSecureServerBaseTest):
244250
def ssl_overrides(self):
245251
return {"ssl_supported_protocols": ["TLSv1.2"],
@@ -253,6 +259,7 @@ def test_tls_v1_2(self):
253259
self.ssl_connect()
254260

255261

262+
@integration_test
256263
class TestSSLSupportedCiphersTest(TestSecureServerBaseTest):
257264
def ssl_overrides(self):
258265
return {"ssl_cipher_suites": ['ECDHE-RSA-AES-128-GCM-SHA256'],

tests/system/test_export.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22
import os
33
import json
44
import shutil
5-
from apmserver import SubCommandTest
5+
from apmserver import SubCommandTest, integration_test
66

77

8-
class ExportConfigDefaultTest(SubCommandTest):
8+
class ExportCommandTest(SubCommandTest):
9+
register_pipeline_disabled = True
10+
11+
12+
@integration_test
13+
class ExportConfigDefaultTest(ExportCommandTest):
914
"""
1015
Test export config subcommand.
1116
"""
@@ -44,7 +49,8 @@ def test_export_config(self):
4449
}, config["setup"])
4550

4651

47-
class ExportConfigTest(SubCommandTest):
52+
@integration_test
53+
class ExportConfigTest(ExportCommandTest):
4854
"""
4955
Test export config subcommand.
5056
"""
@@ -86,7 +92,8 @@ def test_export_config(self):
8692
}, config["setup"])
8793

8894

89-
class TestExportTemplate(SubCommandTest):
95+
@integration_test
96+
class TestExportTemplate(ExportCommandTest):
9097
"""
9198
Test export template
9299
"""
@@ -118,7 +125,8 @@ def test_export_template_to_file(self):
118125
assert template['order'] == 1
119126

120127

121-
class TestExportILMPolicy(SubCommandTest):
128+
@integration_test
129+
class TestExportILMPolicy(ExportCommandTest):
122130
"""
123131
Test export ilm-policy
124132
"""
@@ -153,6 +161,7 @@ def test_export_ilm_policy_to_files(self):
153161
assert "delete" not in policy["policy"]["phases"]
154162

155163

164+
@integration_test
156165
class TestExportILMPolicyILMDisabled(TestExportILMPolicy):
157166
"""
158167
Test export ilm-policy independent of ILM enabled state

0 commit comments

Comments
 (0)