Browse Source

Fixes test_metrics test

Ceilometer API was removed in Queens, meaning that test_metrics has
not way to validate the metrics collected by the ceilometer-polling
agent.

The metrics are instead sent and collected by Gnocchi.

This patch adds a Gnocchi client, and updates the test_metrics
to use this client properly.

Change-Id: Id999d758505de10abb356befb854736e1904f6ee
tags/0.2.0
Claudiu Belu 1 year ago
parent
commit
dac28d1334

+ 1
- 1
oswin_tempest_plugin/config.py View File

@@ -79,7 +79,7 @@ HyperVGroup = [
79 79
                     "published by the compute node's ceilometer-polling "
80 80
                     "agent. The value must be greater by ~15-20 seconds "
81 81
                     "than the agent's publish interval, defined in its "
82
-                    "pipeline.yaml file (typically, the intervals are 600 "
82
+                    "polling.yaml file (typically, the intervals are 600 "
83 83
                     "seconds)."),
84 84
 ]
85 85
 

+ 12
- 0
oswin_tempest_plugin/plugin.py View File

@@ -51,3 +51,15 @@ class OSWinTempestPlugin(plugins.TempestPlugin):
51 51
         """
52 52
         return [(group.name, opts)
53 53
                 for group, opts in project_config.list_opts()]
54
+
55
+    def get_service_clients(self):
56
+        metric_config = config.service_client_config('metric')
57
+        metric_v1_params = {
58
+            'name': 'metric_v1',
59
+            'service_version': 'metric.v1',
60
+            'module_path': 'oswin_tempest_plugin.services.gnocchi_client',
61
+            'client_names': ['GnocchiClient'],
62
+        }
63
+        metric_v1_params.update(metric_config)
64
+
65
+        return [metric_v1_params]

+ 0
- 0
oswin_tempest_plugin/services/__init__.py View File


+ 50
- 0
oswin_tempest_plugin/services/gnocchi_client.py View File

@@ -0,0 +1,50 @@
1
+# Copyright 2018 Cloudbase Solutions Srl
2
+#
3
+# All Rights Reserved.
4
+#
5
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
6
+#    not use this file except in compliance with the License. You may obtain
7
+#    a copy of the License at
8
+#
9
+#         http://www.apache.org/licenses/LICENSE-2.0
10
+#
11
+#    Unless required by applicable law or agreed to in writing, software
12
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+#    License for the specific language governing permissions and limitations
15
+#    under the License.
16
+
17
+from oslo_serialization import jsonutils as json
18
+from tempest.lib.common import rest_client
19
+
20
+from oswin_tempest_plugin import config
21
+
22
+CONF = config.CONF
23
+
24
+
25
+class GnocchiClient(rest_client.RestClient):
26
+
27
+    uri_prefix = 'v1'
28
+
29
+    def deserialize(self, body):
30
+        return json.loads(body.replace("\n", ""))
31
+
32
+    def _helper_list(self, uri):
33
+        resp, body = self.get(uri)
34
+        self.expected_success(200, resp.status)
35
+        body = self.deserialize(body)
36
+        return rest_client.ResponseBodyList(resp, body)
37
+
38
+    def list_resources(self):
39
+        uri = '%s/resource/generic' % self.uri_prefix
40
+        return self._helper_list(uri)
41
+
42
+    def list_samples(self, resource_id, meter_name):
43
+        """Returns a list of samples for the given resource and meter.
44
+
45
+        :returns: list, each item being a list containing the following values
46
+            in this order: timestamp, granularity, value.
47
+        """
48
+        uri = '%s/resource/generic/%s/metric/%s/measures' % (
49
+            self.uri_prefix, resource_id, meter_name)
50
+        return self._helper_list(uri)

+ 24
- 39
oswin_tempest_plugin/tests/scenario/test_metrics_collection.py View File

@@ -15,12 +15,6 @@
15 15
 
16 16
 import time
17 17
 
18
-try:
19
-    # NOTE(claudiub): ceilometer might not be installed, it is not mandatory.
20
-    from ceilometer.tests.tempest.service import client as telemetry_client
21
-except Exception:
22
-    telemetry_client = None
23
-
24 18
 from oslo_log import log as logging
25 19
 from tempest import clients
26 20
 
@@ -36,11 +30,10 @@ class ClientManager(clients.Manager):
36 30
     def __init__(self, *args, **kwargs):
37 31
         super(ClientManager, self).__init__(*args, **kwargs)
38 32
 
39
-        self._set_telemetry_clients()
33
+        self.set_gnocchi_client()
40 34
 
41
-    def _set_telemetry_clients(self):
42
-        self.telemetry_client = telemetry_client.TelemetryClient(
43
-            self.auth_provider, **telemetry_client.Manager.telemetry_params)
35
+    def set_gnocchi_client(self):
36
+        self.gnocchi_client = self.metric_v1.GnocchiClient()
44 37
 
45 38
 
46 39
 class MetricsCollectionTestCase(test_base.TestBase):
@@ -65,7 +58,7 @@ class MetricsCollectionTestCase(test_base.TestBase):
65 58
         a. Configure tempest's polled_metric_delay, by adding the
66 59
         following line in tempest.conf, in the hyperv section:
67 60
         polled_metrics_delay = <desired value>
68
-        b. Set the interval value in pipeline.yaml on the compute node to
61
+        b. Set the interval value in polling.yaml on the compute node to
69 62
         the desired value and restart the ceilometer polling agent. The
70 63
         interval value is set either for the 'meter_source' or for each
71 64
         of the following: 'cpu_source', 'disk_source', 'network_source'.
@@ -73,7 +66,7 @@ class MetricsCollectionTestCase(test_base.TestBase):
73 66
     Note: If the polled_metrics_delay value is too low, the tests might not
74 67
     find any samples and fail because of this. As a recommandation,
75 68
     polled_metrics_delay's value should be:
76
-        polled_metric_delay = <pipeline.yaml interval value> + <15-20 seconds>
69
+        polled_metric_delay = <polling.yaml interval value> + <15-20 seconds>
77 70
 
78 71
     tests:
79 72
         1. test_metrics - tests values for the following metrics:
@@ -84,7 +77,7 @@ class MetricsCollectionTestCase(test_base.TestBase):
84 77
     assumptions:
85 78
         1. Ceilometer agent on the compute node is running.
86 79
         2. Ceilometer agent on the compute node has the polling interval
87
-        defined in pipeline.yaml lower than the polled_metrics_delay defined
80
+        defined in polling.yaml lower than the polled_metrics_delay defined
88 81
         in this test suite.
89 82
         3. The compute nodes' nova-compute and neutron-hyperv-agent services
90 83
         have been configured to enable metrics collection.
@@ -96,9 +89,9 @@ class MetricsCollectionTestCase(test_base.TestBase):
96 89
     def skip_checks(cls):
97 90
         super(MetricsCollectionTestCase, cls).skip_checks()
98 91
 
99
-        if (not CONF.service_available.ceilometer or
100
-                not CONF.telemetry.deprecated_api_enabled):
101
-            raise cls.skipException("Ceilometer API support is required.")
92
+        for service in ['ceilometer', 'gnocchi']:
93
+            if not getattr(CONF.service_available, service):
94
+                raise cls.skipException("%s service is required." % service)
102 95
 
103 96
         if not CONF.hyperv.collected_metrics:
104 97
             raise cls.skipException("Collected metrics not configured.")
@@ -108,26 +101,20 @@ class MetricsCollectionTestCase(test_base.TestBase):
108 101
         super(MetricsCollectionTestCase, cls).setup_clients()
109 102
 
110 103
         # Telemetry client
111
-        cls.telemetry_client = cls.os_primary.telemetry_client
104
+        cls.telemetry_client = cls.os_primary.gnocchi_client
112 105
 
113
-    def _telemetry_check_samples(self, resource_id, meter_name):
106
+    def _check_samples(self, resource_id, meter_name):
114 107
         LOG.info("Checking %(meter_name)s for resource %(resource_id)s" % {
115 108
             'meter_name': meter_name, 'resource_id': resource_id})
116 109
 
117
-        samples = self.telemetry_client.list_samples(meter_name)
118
-        self.assertNotEmpty(samples,
119
-                            'Telemetry client returned no samples.')
120
-
121
-        resource_samples = [s for s in samples if
122
-                            s['resource_id'] == resource_id]
110
+        samples = self.telemetry_client.list_samples(resource_id, meter_name)
123 111
         self.assertNotEmpty(
124
-            resource_samples,
125
-            'No meter %(meter_name)s samples for resource '
126
-            '%(resource_id)s found.' % {'meter_name': meter_name,
127
-                                        'resource_id': resource_id})
112
+            samples,
113
+            'Client returned no samples for the given resource '
114
+            '"%(resource_id)s" and meter "%(meter_name)s".' % {
115
+                'resource_id': resource_id, 'meter_name': meter_name})
128 116
 
129
-        non_zero_valued_samples = [s for s in resource_samples if
130
-                                   s['counter_volume'] > 0]
117
+        non_zero_valued_samples = [s for s in samples if s[2] > 0]
131 118
         self.assertNotEmpty(
132 119
             non_zero_valued_samples,
133 120
             'All meter %(meter_name)s samples for resource '
@@ -145,12 +132,12 @@ class MetricsCollectionTestCase(test_base.TestBase):
145 132
         # %(OS-EXT-SRV-ATTR:instance_name)s-%(instance_id)s-%(port_id)s
146 133
         # the instance returned by self.servers_client does not contain the
147 134
         # OS-EXT-SRV-ATTR:instance_name field. Which means that the resource_id
148
-        # must be found in ceilometer's resources.
135
+        # must be found in gnocchi's resources.
149 136
         start_res_id = server['id']
150 137
         resources = self.telemetry_client.list_resources()
151
-        res_ids = [r['resource_id'] for r in resources
152
-                   if r['resource_id'].startswith('instance-') and
153
-                   start_res_id in r['resource_id']]
138
+        res_ids = [r['id'] for r in resources
139
+                   if r['original_resource_id'].startswith('instance-') and
140
+                   start_res_id in r['original_resource_id']]
154 141
 
155 142
         self.assertEqual(1, len(res_ids))
156 143
         return res_ids[0]
@@ -162,19 +149,17 @@ class MetricsCollectionTestCase(test_base.TestBase):
162 149
         time.sleep(CONF.hyperv.polled_metrics_delay)
163 150
 
164 151
         # TODO(claudiub): Add more metrics.
165
-
166 152
         if 'cpu' in CONF.hyperv.collected_metrics:
167 153
             cpu_res_id = self._get_instance_cpu_resource_id(server)
168
-            self._telemetry_check_samples(cpu_res_id, 'cpu')
154
+            self._check_samples(cpu_res_id, 'cpu')
169 155
 
170 156
         if 'network.outgoing.bytes' in CONF.hyperv.collected_metrics:
171 157
             port_res_id = self._get_instance_port_resource_id(server)
172
-            self._telemetry_check_samples(port_res_id,
173
-                                          'network.outgoing.bytes')
158
+            self._check_samples(port_res_id, 'network.outgoing.bytes')
174 159
 
175 160
         if 'disk.read.bytes' in CONF.hyperv.collected_metrics:
176 161
             disk_resource_id = self._get_instance_disk_resource_id(server)
177
-            self._telemetry_check_samples(disk_resource_id, 'disk.read.bytes')
162
+            self._check_samples(disk_resource_id, 'disk.read.bytes')
178 163
 
179 164
     def test_metrics(self):
180 165
         server_tuple = self._create_server()

Loading…
Cancel
Save