Merge ~vultaire/charm-graylog:adding-zaza-tests into ~graylog-charmers/charm-graylog:master

Proposed by Paul Goins
Status: Merged
Approved by: Xav Paice
Approved revision: 8168d755429d15d38e832c112440d6f42896636f
Merged at revision: 9e01c58565939a645ab53d617cddaebbdbcca467
Proposed branch: ~vultaire/charm-graylog:adding-zaza-tests
Merge into: ~graylog-charmers/charm-graylog:master
Diff against target: 317 lines (+206/-10)
7 files modified
lib/charms/layer/graylog/logextract.py (+12/-4)
tests/README.md (+12/-0)
tests/bundles/bionic-graylog2.yaml (+9/-2)
tests/bundles/bionic-graylog3.yaml (+45/-0)
tests/bundles/bionic-ha.yaml (+8/-0)
tests/test_legacy.py (+110/-0)
tests/tests.yaml (+10/-4)
Reviewer Review Type Date Requested Status
Xav Paice (community) Approve
Alvaro Uria (community) Approve
Canonical IS Reviewers Pending
Review via email: mp+378537@code.launchpad.net

Commit message

Adding initial zaza tests via "tox -e func"

This patch provides zaza-compatible ports of the charm's original
amulet-based test suite along with the relevant modifications
necessary to enable them to be run. This is intended to provide a
base for future development which includes functional testing.

Description of the change

* lib/charms/layer/graylog/logextract.py: Converted class-level 'url' variables into properties; is_v2() calls juju helpers and thus is not suitable to be called at import-time. If left as-is, tests cannot run because of the missing juju helper binaries.

* tests/README.md: Provided simple instructions about how to build the charm and run the functional tests. Includes important notes about running behind a proxy.

* tests/bundles/**: Temporarily removed the bionic-ha bundle (since we don't yet have HA support), and replaced the bionic bundle with different versions for Graylog 2 and 3. Other small changes were done, including (but not limited to) changes to better allow tests to run via Zaza.

* tests/test_legacy.py: This is a suite of tests based upon the original Amulet-driven tests included with this charm in the past, but ported to work with Zaza. The majority of the original test coverage should be provided by these new tests.

* tests/tests.yaml: This file appears to have been more-or-less a placeholder. Now it provides a real test and has been updated to allow clean deploy and settlement of the bundles.

* tox.ini: A build command has been added, and minimal changes have been made to the func target to allow it to run zaza tests correctly.

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Alvaro Uria (aluria) wrote :

Overall, everything looks good, thank you. I added minor comments (ie. make tests support future HA), and a strong suggestion to use Makefile (and document it in tests/README) to build the charm and run func tests. The Makefile is already there, so the MP probably needs a minor tweak and the tests/README to be updated.

review: Needs Fixing
Revision history for this message
Paul Goins (vultaire) wrote :

Understood. I will make the updates regarding get_graylog_client() and the Makefile. I will also update this to go more in line with the path Peter has taken in his MR regarding building charms (https://code.launchpad.net/~peter-sabaini/graylog-charm/+git/graylog-charm/+merge/377651).

Revision history for this message
Paul Goins (vultaire) wrote :

OK; I've re-worked my code upon the new code in trunk. This is ready for review once more.

Revision history for this message
Alvaro Uria (aluria) wrote :

MP looks great, thank you. I haven't run "make test" but skimmed the changes below.

review: Approve
Revision history for this message
Xav Paice (xavpaice) wrote :

Can we please rebase this against master? Currently won't merge.

review: Needs Fixing
Revision history for this message
Xav Paice (xavpaice) wrote :

Although the actual tests are still failing for me, I'm aware there's other changes queued up that fix this and this change makes a lot of progress towards good testing. Manual testing the charm as is works fine, including looking at the resulting zaza model. Approving.

review: Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision 9e01c58565939a645ab53d617cddaebbdbcca467

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/lib/charms/layer/graylog/logextract.py b/lib/charms/layer/graylog/logextract.py
index 5d1ae27..42c034b 100644
--- a/lib/charms/layer/graylog/logextract.py
+++ b/lib/charms/layer/graylog/logextract.py
@@ -48,13 +48,21 @@ class GraylogTitleSourceItems:
4848
4949
50class GraylogPipelines(GraylogTitleSourceItems):50class GraylogPipelines(GraylogTitleSourceItems):
51 url = '{}/system/pipelines/pipeline'.format(51 @property
52 '/plugins/org.graylog.plugins.pipelineprocessor' if is_v2() else '')52 def url(self):
53 if is_v2():
54 return '/plugins/org.graylog.plugins.pipelineprocessor/system/pipelines/pipeline'
55 else:
56 return '/system/pipelines/pipeline'
5357
5458
55class GraylogRules(GraylogTitleSourceItems):59class GraylogRules(GraylogTitleSourceItems):
56 url = '{}/system/pipelines/rule'.format(60 @property
57 '/plugins/org.graylog.plugins.pipelineprocessor' if is_v2() else '')61 def url(self):
62 if is_v2():
63 return '/plugins/org.graylog.plugins.pipelineprocessor/system/pipelines/rule'
64 else:
65 return '/system/pipelines/rule'
5866
5967
60class GraylogStreams:68class GraylogStreams:
diff --git a/tests/README.md b/tests/README.md
61new file mode 10064469new file mode 100644
index 0000000..50a965f
--- /dev/null
+++ b/tests/README.md
@@ -0,0 +1,12 @@
1# How to run functional tests
2
31. export JUJU_REPOSITORY=<directory for built charms>
42. Optional: export MODEL_SETTINGS=<semicolon-separated list of "juju model-config" settings>
53. From the repository root, run: make test
6
7NOTE: If you are behind a proxy, be sure to export a MODEL_SETTINGS variable as
8described above. Note that you will need to use the http-proxy, https-proxy and
9similar settings rather than the app-specific settings as the elasticsearch
10charm (at the time of writing) requires the environment setting for running
11Ansible apt-key actions, but the charm doesn't presently provide a way of
12setting this.
diff --git a/tests/bundles/bionic.yaml b/tests/bundles/bionic-graylog2.yaml
0similarity index 91%13similarity index 91%
1rename from tests/bundles/bionic.yaml14rename from tests/bundles/bionic.yaml
2rename to tests/bundles/bionic-graylog2.yaml15rename to tests/bundles/bionic-graylog2.yaml
index b646c7a..bd256db 100644
--- a/tests/bundles/bionic.yaml
+++ b/tests/bundles/bionic-graylog2.yaml
@@ -12,11 +12,13 @@ applications:
12 graylog:12 graylog:
13 num_units: 113 num_units: 1
14 series: bionic14 series: bionic
15 15 options:
16 channel: 2/stable
17
16 elastic:18 elastic:
17 charm: cs:elasticsearch19 charm: cs:elasticsearch
18 num_units: 120 num_units: 1
19 21
20 mongo:22 mongo:
21 charm: cs:mongodb23 charm: cs:mongodb
22 num_units: 124 num_units: 1
@@ -25,6 +27,9 @@ applications:
25 charm: cs:haproxy27 charm: cs:haproxy
26 num_units: 128 num_units: 1
2729
30 nrpe:
31 charm: cs:nrpe
32
28relations:33relations:
29 - - ubuntu34 - - ubuntu
30 - filebeat35 - filebeat
@@ -36,3 +41,5 @@ relations:
36 - elastic41 - elastic
37 - - graylog42 - - graylog
38 - haproxy43 - haproxy
44 - - graylog
45 - nrpe
diff --git a/tests/bundles/bionic-graylog3.yaml b/tests/bundles/bionic-graylog3.yaml
39new file mode 10064446new file mode 100644
index 0000000..596cf7d
--- /dev/null
+++ b/tests/bundles/bionic-graylog3.yaml
@@ -0,0 +1,45 @@
1series: bionic
2
3applications:
4 ubuntu:
5 charm: cs:ubuntu
6 num_units: 1
7
8 filebeat:
9 charm: cs:filebeat
10 num_units: 0
11
12 graylog:
13 num_units: 1
14 series: bionic
15 options:
16 channel: 3/stable
17
18 elastic:
19 charm: cs:elasticsearch
20 num_units: 1
21
22 mongo:
23 charm: cs:mongodb
24 num_units: 1
25
26 haproxy:
27 charm: cs:haproxy
28 num_units: 1
29
30 nrpe:
31 charm: cs:nrpe
32
33relations:
34 - - ubuntu
35 - filebeat
36 - - graylog:beats
37 - filebeat:logstash
38 - - graylog
39 - mongo
40 - - graylog
41 - elastic
42 - - graylog
43 - haproxy
44 - - graylog
45 - nrpe
diff --git a/tests/bundles/bionic-ha.yaml b/tests/bundles/bionic-ha.yaml
index 516cff6..70cc1e9 100644
--- a/tests/bundles/bionic-ha.yaml
+++ b/tests/bundles/bionic-ha.yaml
@@ -1,3 +1,4 @@
1# NOTE: Not in use yet.
1series: bionic2series: bionic
23
3applications:4applications:
@@ -12,6 +13,8 @@ applications:
12 graylog:13 graylog:
13 num_units: 314 num_units: 3
14 series: bionic15 series: bionic
16 options:
17 channel: 3/stable
15 18
16 elastic:19 elastic:
17 charm: cs:elasticsearch20 charm: cs:elasticsearch
@@ -25,6 +28,9 @@ applications:
25 charm: cs:haproxy28 charm: cs:haproxy
26 num_units: 129 num_units: 1
2730
31 nrpe:
32 charm: cs:nrpe
33
28relations:34relations:
29 - - ubuntu35 - - ubuntu
30 - filebeat36 - filebeat
@@ -36,3 +42,5 @@ relations:
36 - elastic42 - elastic
37 - - graylog43 - - graylog
38 - haproxy44 - haproxy
45 - - graylog
46 - nrpe
diff --git a/tests/test_legacy.py b/tests/test_legacy.py
39new file mode 10064447new file mode 100644
index 0000000..a92d927
--- /dev/null
+++ b/tests/test_legacy.py
@@ -0,0 +1,110 @@
1import re
2import unittest
3import yaml
4from zaza.utilities import juju
5from zaza import model
6
7from api import GraylogApi
8
9
10DEFAULT_API_PORT = "9001" # Graylog 2 only
11DEFAULT_WEB_PORT = "9000"
12
13
14class LegacyTests(unittest.TestCase):
15
16 # These tests were ported from tests/test_10_basic.py in changeset a3b54c2.
17 # They were temporarily deleted during the conversion from Amulet to Zaza.
18 # Aside from porting to work with libjuju and some refactoring, these tests
19 # are largely as they were before.
20
21 def test_api_ready(self):
22 """Curl the api endpoint on the graylog unit."""
23 port = self.get_api_port()
24 curl_command = "curl http://localhost:{} --connect-timeout 30".format(port)
25 self.run_command("graylog/0", curl_command)
26
27 def test_elasticsearch_active(self):
28 self._assert_remote_address_in_server_conf("elastic/0", "client")
29 # This was also stuck in the same test...
30 api = self.get_graylog_clients()[0]
31 resp = api.indexer_cluster_health()
32 self.assertTrue(resp["status"] == "green")
33
34 def test_mongodb_active(self):
35 self._assert_remote_address_in_server_conf("mongo/0", "database")
36 # This was also stuck in the same test...
37 api = self.get_graylog_clients()[0]
38 resp = api.cluster_get()
39 self.assertTrue(resp[list(resp)[0]]["is_processing"])
40
41 def _assert_remote_address_in_server_conf(self, remote_unit, remote_relation_name):
42 # This is a very simplistic, naive check, but it's equivalent to
43 # that from tests/test_10_basic.py in a3b54c2.
44 source_unit = "graylog/0"
45 remote_addr = juju.get_relation_from_unit(
46 source_unit, remote_unit, remote_relation_name
47 )["private-address"]
48 assert remote_addr in self.get_file_contents(
49 source_unit, "/var/snap/graylog/common/server.conf"
50 )
51
52 def get_graylog_clients(self):
53 graylog_units = juju.get_full_juju_status().applications["graylog"]["units"]
54 graylog_addrs = [unit["public-address"] for unit in graylog_units.values()]
55 port = self.get_api_port()
56 password = self.get_graylog_admin_password()
57 return [
58 GraylogApi("http://{}:{}/api".format(graylog_addr, port), "admin", password)
59 for graylog_addr in graylog_addrs
60 ]
61
62 def get_api_port(self):
63 port = DEFAULT_API_PORT if self.is_v2() else DEFAULT_WEB_PORT
64 return port
65
66 def get_graylog_admin_password(self):
67 result = model.run_action("graylog/0", "show-admin-password")
68 password = result.data["results"]["admin-password"]
69 return password
70
71 def test_website_active(self):
72 data = juju.get_relation_from_unit("haproxy/0", "graylog/0", "website")
73 self.assertEqual(data["port"], DEFAULT_WEB_PORT)
74
75 service_ports = {}
76 for service in yaml.safe_load(data["all_services"]):
77 service_ports[service["service_name"]] = service["service_port"]
78
79 self.assertEqual(str(service_ports["web"]), DEFAULT_WEB_PORT)
80 if self.is_v2():
81 self.assertEqual(str(service_ports["api"]), DEFAULT_API_PORT)
82
83 def run_command(self, target, command, timeout=30):
84 result = model.run_on_unit(target, command, timeout=timeout)
85 assert result["Code"] == "0"
86 return result
87
88 def is_v2(self):
89 return (
90 juju.get_full_juju_status()
91 .applications["graylog"]["workload-version"]
92 .startswith("2.")
93 )
94
95 def test_nrpe_config(self):
96 cfg = self.get_file_contents(
97 "nrpe/0", "/etc/nagios/nrpe.d/check_graylog_health.cfg"
98 )
99 self.assertTrue(re.search(r"command.*check_graylog_health", cfg))
100
101 def test_nrpe_health_check(self):
102 cfg = self.get_file_contents(
103 "nrpe/0", "/usr/local/lib/nagios/plugins/check_graylog_health.py"
104 )
105 self.assertTrue(re.search(r"CRITICAL", cfg))
106
107 def get_file_contents(self, unit, filename):
108 result = self.run_command(unit, "cat '{}'".format(filename))
109 assert result["Code"] == "0"
110 return result["Stdout"]
diff --git a/tests/tests.yaml b/tests/tests.yaml
index 3a0510d..658fc3e 100644
--- a/tests/tests.yaml
+++ b/tests/tests.yaml
@@ -1,14 +1,20 @@
1charm_name: graylog1charm_name: graylog
2gate_bundles:2gate_bundles:
3 - bionic3 - bionic-graylog2
4 - bionic-ha4 - bionic-graylog3
5 #- bionic-ha # Currently bionic-ha is identical to bionic-graylog3; enable
6 # once we make changes.
5smoke_bundles:7smoke_bundles:
6 - bionic8 - bionic-graylog3
7dev_bundles:9dev_bundles:
8 - bionic10 - bionic-graylog3
9tests:11tests:
12 - tests.test_legacy.LegacyTests
10 - tests.test_graylog_charm.CharmOperationTest13 - tests.test_graylog_charm.CharmOperationTest
11target_deploy_status:14target_deploy_status:
12 filebeat:15 filebeat:
13 workload-status: active16 workload-status: active
14 workload-status-message: 'Filebeat ready.'17 workload-status-message: 'Filebeat ready.'
18 haproxy:
19 workload-status: unknown
20 workload-status-message: ""

Subscribers

People subscribed via source and target branches

to all changes: