Merge ~xavpaice/charm-telegraf:lint-20.08 into charm-telegraf:master
- Git
- lp:~xavpaice/charm-telegraf
- lint-20.08
- Merge into master
Proposed by
Xav Paice
Status: | Merged |
---|---|
Approved by: | Alvaro Uria |
Approved revision: | b9e75f78db2428389d614f412f6dc0baca255fce |
Merged at revision: | 5b7391d840a618ab91dc1597864bb29138a04d19 |
Proposed branch: | ~xavpaice/charm-telegraf:lint-20.08 |
Merge into: | charm-telegraf:master |
Prerequisite: | ~xavpaice/charm-telegraf:blacken-20.08 |
Diff against target: |
1281 lines (+226/-112) 12 files modified
src/files/telegraf_exec_metrics.py (+69/-34) src/hooks/relations/apache-website/requires.py (+1/-3) src/hooks/relations/statistics/requires.py (+2/-3) src/hooks/relations/telegraf-exec/requires.py (+7/-3) src/reactive/__init__.py (+1/-0) src/reactive/telegraf.py (+82/-31) src/tests/functional/tests/test_telegraf.py (+19/-6) src/tests/unit/__init__.py (+2/-0) src/tests/unit/test_mysql.py (+2/-1) src/tests/unit/test_postgresql.py (+4/-4) src/tests/unit/test_telegraf.py (+35/-26) src/tox.ini (+2/-1) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alvaro Uria (community) | Approve | ||
James Troup (community) | Approve | ||
Canonical IS Reviewers | Pending | ||
Review via email: mp+388546@code.launchpad.net |
Commit message
Extra Linting completed for 20.08 charm release
Description of the change
To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Unable to determine commit message from repository - please click "Set commit message" and enter the commit message manually.
Revision history for this message
Alvaro Uria (aluria) wrote : | # |
+1 to this and the other 2 related MPs (makefile and blacken)
review:
Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Change successfully merged at revision 5b7391d840a618a
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/src/files/telegraf_exec_metrics.py b/src/files/telegraf_exec_metrics.py |
2 | index f03e23a..d9b3402 100755 |
3 | --- a/src/files/telegraf_exec_metrics.py |
4 | +++ b/src/files/telegraf_exec_metrics.py |
5 | @@ -1,29 +1,32 @@ |
6 | #!/usr/bin/env python3 |
7 | -import os |
8 | -import re |
9 | -import sys |
10 | +import argparse |
11 | import json |
12 | import logging |
13 | -import argparse |
14 | -import subprocess |
15 | +import os |
16 | +import re |
17 | import shutil |
18 | +import subprocess |
19 | +import sys |
20 | from collections import OrderedDict |
21 | from textwrap import dedent |
22 | |
23 | -from insights.tests import context_wrap |
24 | from insights.parsers.softnet_stat import SoftNetStats |
25 | - |
26 | +from insights.tests import context_wrap |
27 | |
28 | LOG = logging.getLogger() |
29 | |
30 | METRICS = OrderedDict() |
31 | |
32 | |
33 | -def register_metric(MetricClass): |
34 | - """A decorator to create a metric class instance and register it""" |
35 | - metric = MetricClass() |
36 | +def register_metric(metricclass): |
37 | + """Create metric class instance. |
38 | + |
39 | + Decorator that creates a metric class and registers it. |
40 | + """ |
41 | + metric = metricclass() |
42 | METRICS[metric.name] = metric |
43 | - return MetricClass |
44 | + |
45 | + return metricclass |
46 | |
47 | |
48 | class FileMetric: |
49 | @@ -46,18 +49,22 @@ class FileMetric: |
50 | LOG.info("rendering config to %s", config_path) |
51 | script = os.path.abspath(__file__) |
52 | output = self.config_template.format( |
53 | - python=python or sys.executable, script=script, name=self.name, |
54 | + python=python or sys.executable, script=script, name=self.name |
55 | ) |
56 | LOG.debug(output) |
57 | + |
58 | if not dry_run: |
59 | with open(config_path, mode="w", encoding="utf8") as f: |
60 | f.write(output) |
61 | + |
62 | return output |
63 | |
64 | def remove_config(self, configs_dir, dry_run=False): |
65 | config_path = self.config_path(configs_dir) |
66 | + |
67 | if os.path.isfile(config_path): |
68 | LOG.info("removing %s", config_path) |
69 | + |
70 | if not dry_run: |
71 | os.remove(config_path) |
72 | else: |
73 | @@ -78,6 +85,7 @@ class SockStatFileMetric(FileMetric): |
74 | |
75 | def parse(self, content): |
76 | results = {} |
77 | + |
78 | for line in content.splitlines(): |
79 | LOG.debug("parsing line: %s", line) |
80 | # line example: TCP: inuse 62 orphan 0 tw 5 alloc 222 mem 20 |
81 | @@ -86,9 +94,11 @@ class SockStatFileMetric(FileMetric): |
82 | count = len(items) |
83 | assert count % 2 == 0 |
84 | group = {} |
85 | + |
86 | for i in range(0, count, 2): |
87 | group[items[i]] = int(items[i + 1]) |
88 | results[key.strip()] = group |
89 | + |
90 | return results |
91 | |
92 | |
93 | @@ -175,18 +185,22 @@ class BuddyinfoFileMetric(FileMetric): |
94 | re_line = re.compile( |
95 | r"Node\s+(?P<node>\d+).*zone\s+(?P<zone>\w+)\s+(?P<pages>.*)" |
96 | ) |
97 | + |
98 | for line in content.splitlines(): |
99 | LOG.debug(line) |
100 | match = re_line.match(line) |
101 | + |
102 | if match: |
103 | data = match.groupdict() |
104 | LOG.debug(data) |
105 | pages = data["pages"].split() |
106 | + |
107 | if not human_sizes: |
108 | human_sizes = [ |
109 | self._get_human_size(page_size * 2 ** i) |
110 | for i, _ in enumerate(pages) |
111 | ] |
112 | + |
113 | for k, v in zip(human_sizes, pages): |
114 | items.append( |
115 | { |
116 | @@ -196,6 +210,7 @@ class BuddyinfoFileMetric(FileMetric): |
117 | "count": int(v), |
118 | } |
119 | ) |
120 | + |
121 | return items |
122 | |
123 | |
124 | @@ -228,14 +243,17 @@ class ZoneinfoFileMetric(FileMetric): |
125 | re.MULTILINE + re.DOTALL, |
126 | ) |
127 | items = [] |
128 | + |
129 | for match in pattern.finditer(content): |
130 | data = match.groupdict() |
131 | LOG.debug(data) |
132 | # convert str to int |
133 | + |
134 | for k, v in data.items(): |
135 | if v.isdigit(): |
136 | data[k] = int(v) |
137 | items.append(data) |
138 | + |
139 | return items |
140 | |
141 | |
142 | @@ -246,11 +264,14 @@ class CmdMetric(FileMetric): |
143 | def get_cmd_output(self, cmd, is_json=False): |
144 | LOG.debug("running cmd: %s", " ".join(cmd)) |
145 | output = subprocess.check_output(cmd).decode("utf8").strip() |
146 | + |
147 | return json.loads(output) if is_json else output |
148 | |
149 | def get_input_content(self): |
150 | if self.input_file: |
151 | - # if provided, still read cmd output from a file, helpful for debuging/testing. |
152 | + # if provided, still read cmd output from a file, helpful |
153 | + # for debuging/testing. |
154 | + |
155 | return super().get_input_content() |
156 | else: |
157 | return self.get_cmd_output(self.cmd) |
158 | @@ -277,17 +298,18 @@ class NetNSCmdMetric(CmdMetric): |
159 | items = [] |
160 | # find openstack/neutron netns list pattern |
161 | pattern = re.compile(r"^([\w-]+)\s+\(id:\s+(\d+)\)", flags=re.M) |
162 | + |
163 | for match in pattern.finditer(content): |
164 | items.append( |
165 | - {"namespace": match.group(1), "id": match.group(2), "state": 1,} |
166 | + {"namespace": match.group(1), "id": match.group(2), "state": 1} |
167 | ) |
168 | |
169 | # no re matches, should be in simple list format |
170 | + |
171 | if not items: |
172 | for line in content.splitlines(): |
173 | - items.append( |
174 | - {"namespace": line.strip(), "state": 1,} |
175 | - ) |
176 | + items.append({"namespace": line.strip(), "state": 1}) |
177 | + |
178 | return items |
179 | |
180 | |
181 | @@ -321,8 +343,10 @@ class OvsDumpFlowsCmdMetric(CmdMetric): |
182 | flows = {} |
183 | |
184 | ovs_cmd = "ovs-ofctl" |
185 | + |
186 | if not shutil.which(ovs_cmd): |
187 | LOG.error('openvswitch command "%s" is not available, exit', ovs_cmd) |
188 | + |
189 | return flows |
190 | |
191 | for bridge in ["br-int", "br-tun", "br-data"]: |
192 | @@ -335,7 +359,6 @@ class OvsDumpFlowsCmdMetric(CmdMetric): |
193 | def parse(self, input_content): |
194 | """Parse input content for each bridge and convert to a json list. |
195 | |
196 | - |
197 | Example final json result: |
198 | |
199 | [ |
200 | @@ -356,12 +379,14 @@ class OvsDumpFlowsCmdMetric(CmdMetric): |
201 | # input_content here is a dict with cmd output for each bridge for this metric |
202 | flows = input_content |
203 | items = [] |
204 | + |
205 | for bridge, output in flows.items(): |
206 | # when invoked via python (or redirected) it includes an extra line |
207 | # like 'NXST_FLOW reply (xid=0x4):' |
208 | # so need to substract one |
209 | lines = output.splitlines() |
210 | items.append({"bridge": bridge, "count": len(lines) - 1}) |
211 | + |
212 | return items |
213 | |
214 | |
215 | @@ -381,8 +406,9 @@ class OvsDpCtlCmdMetric(CmdMetric): |
216 | ) |
217 | |
218 | def parse_fields(self, text): |
219 | - """ |
220 | - parse lines following pattern to a dictionary, |
221 | + """Parse lines following pattern to a dictionary. |
222 | + |
223 | + Parse lines following pattern to a dictionary, |
224 | converting int/floats as relevant |
225 | 'hit:706 missed:456 lost:0' |
226 | """ |
227 | @@ -396,23 +422,26 @@ class OvsDpCtlCmdMetric(CmdMetric): |
228 | # parse lines of key/values into a dict |
229 | # hit:706 missed:489 lost:1 |
230 | data = {} |
231 | + |
232 | for datapair in text.split(): |
233 | k, v = datapair.split(":") |
234 | # do nothing if the line has question marks (no data), e.g.: |
235 | # RX packets:0 errors:? dropped:? overruns:? frame:? |
236 | + |
237 | if "?" in v: |
238 | continue |
239 | # reuse field parsing logic by recursion, no nested dicts |
240 | data[k] = self.parse_fields(v) |
241 | + |
242 | return data |
243 | + |
244 | return text |
245 | |
246 | def parse(self, input_content): |
247 | - """ |
248 | - parse the output of `ovs-appctl dpctl/show -s` |
249 | - """ |
250 | + """Parse the output of `ovs-appctl dpctl/show -s`.""" |
251 | result = [] |
252 | datapath_entry = None |
253 | + |
254 | for line in input_content.splitlines(): |
255 | if line[0].isalnum(): # datapath header, other lines start w/space or tab |
256 | if datapath_entry: # store the current one before creating a new one |
257 | @@ -422,9 +451,10 @@ class OvsDpCtlCmdMetric(CmdMetric): |
258 | "port": "", |
259 | "portname": "", |
260 | } |
261 | + |
262 | continue |
263 | |
264 | - label, rest = (l.strip() for l in line.split(":", maxsplit=1)) |
265 | + label, rest = (item.strip() for item in line.split(":", maxsplit=1)) |
266 | |
267 | if label.startswith("port"): |
268 | # complete previous entry, and initialise a new one for the new port |
269 | @@ -434,12 +464,14 @@ class OvsDpCtlCmdMetric(CmdMetric): |
270 | } |
271 | datapath_entry["port"] = label.split()[-1] |
272 | datapath_entry["portname"] = rest |
273 | + |
274 | continue |
275 | |
276 | if datapath_entry["port"]: # parsing lines corresponding to a port block |
277 | if "X packets" in label: |
278 | # parse the RX|TX packets line using a prefix |
279 | prefix, data = line.strip().split(maxsplit=1) |
280 | + |
281 | for k, v in self.parse_fields(data).items(): |
282 | datapath_entry["{}_{}".format(prefix, k)] = v |
283 | else: # parse the non-packet lines (collisions/bytes) |
284 | @@ -449,12 +481,14 @@ class OvsDpCtlCmdMetric(CmdMetric): |
285 | # use RX/TX as a prefix by removing the space |
286 | data = line.replace(" bytes", "_bytes") |
287 | datapath_entry.update(self.parse_fields(data)) |
288 | + |
289 | continue |
290 | |
291 | # all other cases, are datapairs or metrics |
292 | datapath_entry[label] = self.parse_fields(rest.rstrip()) |
293 | |
294 | # handle the end of the output |
295 | + |
296 | if datapath_entry: |
297 | result.append(datapath_entry) |
298 | |
299 | @@ -462,17 +496,18 @@ class OvsDpCtlCmdMetric(CmdMetric): |
300 | |
301 | |
302 | def render_config_files(configs_dir, python, disabled_metrics="", dry_run=False): |
303 | - """Render config files for any metrics not disabled, and remove any disabled""" |
304 | - |
305 | + """Render config files for any metrics not disabled, and remove any disabled.""" |
306 | disabled_metrics_set = ( |
307 | set(disabled_metrics.split(":")) if disabled_metrics else set([]) |
308 | ) |
309 | + |
310 | for metric in disabled_metrics_set: |
311 | try: |
312 | METRICS[metric].remove_config(configs_dir, dry_run=dry_run) |
313 | except KeyError: |
314 | LOG.warning("metric name %s not in %s", metric, ",".join(METRICS)) |
315 | enabled_metrics_set = set(METRICS.keys()) - disabled_metrics_set |
316 | + |
317 | for metric in enabled_metrics_set: |
318 | METRICS[metric].render_config(configs_dir, python, dry_run=dry_run) |
319 | |
320 | @@ -484,10 +519,7 @@ def main(): |
321 | ) |
322 | choices = list(METRICS) # sorted dict |
323 | argparser.add_argument( |
324 | - "--metric", |
325 | - choices=choices, |
326 | - default=choices[0], |
327 | - help="which metric to execuate", |
328 | + "--metric", choices=choices, default=choices[0], help="which metric to execuate" |
329 | ) |
330 | argparser.add_argument( |
331 | "-f", |
332 | @@ -499,7 +531,8 @@ def main(): |
333 | "--render-config-files", |
334 | dest="render_config_files", |
335 | action="store_true", |
336 | - help="render config files for all metrics, use --disabled-metrics to exclude specific ones", |
337 | + help="render config files for all metrics, use --disabled-metrics to " |
338 | + "exclude specific ones", |
339 | ) |
340 | argparser.add_argument( |
341 | "--disabled-metrics", |
342 | @@ -511,7 +544,8 @@ def main(): |
343 | "--python", |
344 | dest="python", |
345 | default=sys.executable, |
346 | - help="python interperter path in config file to execute this script, required for venv", |
347 | + help="python interperter path in config file to execute this script, " |
348 | + "required for venv", |
349 | ) |
350 | # useful for testing |
351 | argparser.add_argument( |
352 | @@ -521,10 +555,10 @@ def main(): |
353 | help="telegraf configs dir for exec metrics", |
354 | ) |
355 | argparser.add_argument( |
356 | - "--dry-run", action="store_true", help="dry run without real actions", |
357 | + "--dry-run", action="store_true", help="dry run without real actions" |
358 | ) |
359 | argparser.add_argument( |
360 | - "-v", "--verbose", action="store_true", help="be verbose in log", |
361 | + "-v", "--verbose", action="store_true", help="be verbose in log" |
362 | ) |
363 | |
364 | cli = argparser.parse_args() |
365 | @@ -542,6 +576,7 @@ def main(): |
366 | ) |
367 | else: |
368 | metric = METRICS[cli.metric] |
369 | + |
370 | if cli.input_file: |
371 | metric.input_file = cli.input_file |
372 | output = metric.parse(metric.get_input_content()) |
373 | diff --git a/src/hooks/relations/apache-website/requires.py b/src/hooks/relations/apache-website/requires.py |
374 | index ecb663a..861fb8f 100644 |
375 | --- a/src/hooks/relations/apache-website/requires.py |
376 | +++ b/src/hooks/relations/apache-website/requires.py |
377 | @@ -14,9 +14,7 @@ |
378 | # You should have received a copy of the GNU General Public License |
379 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
380 | |
381 | -from charms.reactive import hook |
382 | -from charms.reactive import RelationBase |
383 | -from charms.reactive import scopes |
384 | +from charms.reactive import RelationBase, hook, scopes |
385 | |
386 | |
387 | class WSGIRequires(RelationBase): |
388 | diff --git a/src/hooks/relations/statistics/requires.py b/src/hooks/relations/statistics/requires.py |
389 | index 4aafb2a..702db6f 100644 |
390 | --- a/src/hooks/relations/statistics/requires.py |
391 | +++ b/src/hooks/relations/statistics/requires.py |
392 | @@ -14,9 +14,7 @@ |
393 | # You should have received a copy of the GNU General Public License |
394 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
395 | |
396 | -from charms.reactive import hook |
397 | -from charms.reactive import RelationBase |
398 | -from charms.reactive import scopes |
399 | +from charms.reactive import RelationBase, hook, scopes |
400 | |
401 | |
402 | class WSGIRequires(RelationBase): |
403 | @@ -26,6 +24,7 @@ class WSGIRequires(RelationBase): |
404 | def changed(self): |
405 | conv = self.conversation() |
406 | conv.set_state("{relation_name}.connected") |
407 | + |
408 | if conv.get_remote("enabled"): |
409 | # this unit's conversation has a port, so |
410 | # it is part of the set of available units |
411 | diff --git a/src/hooks/relations/telegraf-exec/requires.py b/src/hooks/relations/telegraf-exec/requires.py |
412 | index 42bb783..453203b 100644 |
413 | --- a/src/hooks/relations/telegraf-exec/requires.py |
414 | +++ b/src/hooks/relations/telegraf-exec/requires.py |
415 | @@ -16,9 +16,7 @@ |
416 | |
417 | import json |
418 | |
419 | -from charms.reactive import hook |
420 | -from charms.reactive import RelationBase |
421 | -from charms.reactive import scopes |
422 | +from charms.reactive import RelationBase, hook, scopes |
423 | |
424 | |
425 | class ExecRequires(RelationBase): |
426 | @@ -29,6 +27,7 @@ class ExecRequires(RelationBase): |
427 | conv = self.conversation() |
428 | conv.set_state("{relation_name}.connected") |
429 | commands_json_dict = conv.get_remote("commands") # list of commands to run |
430 | + |
431 | if commands_json_dict is not None and json.loads(commands_json_dict): |
432 | conv.set_state("{relation_name}.available") |
433 | |
434 | @@ -40,12 +39,16 @@ class ExecRequires(RelationBase): |
435 | |
436 | def commands(self): |
437 | cmds = [] |
438 | + |
439 | for conv in self.conversations(): |
440 | commands_json_dict = conv.get_remote("commands") # list of commands dicts |
441 | + |
442 | for cmd_info in json.loads(commands_json_dict): |
443 | commands = cmd_info.pop("commands", []) # list of commands |
444 | + |
445 | if commands is None and "command" in cmd_info: |
446 | commands = [cmd_info.pop("command")] |
447 | + |
448 | if not commands: |
449 | continue |
450 | data_format = cmd_info.pop("data_format") # json, graphite, influx |
451 | @@ -57,4 +60,5 @@ class ExecRequires(RelationBase): |
452 | cmd["run_on_this_unit"] = cmd_info.pop("run_on_this_unit", True) |
453 | cmd.update(cmd_info) |
454 | cmds.append(cmd) |
455 | + |
456 | return cmds |
457 | diff --git a/src/reactive/__init__.py b/src/reactive/__init__.py |
458 | index e69de29..82e3dfc 100644 |
459 | --- a/src/reactive/__init__.py |
460 | +++ b/src/reactive/__init__.py |
461 | @@ -0,0 +1 @@ |
462 | +"""Reactive package.""" |
463 | diff --git a/src/reactive/telegraf.py b/src/reactive/telegraf.py |
464 | index ba47505..4b72eab 100644 |
465 | --- a/src/reactive/telegraf.py |
466 | +++ b/src/reactive/telegraf.py |
467 | @@ -16,40 +16,43 @@ |
468 | |
469 | import base64 |
470 | import binascii |
471 | -from distutils.version import LooseVersion |
472 | import io |
473 | import json |
474 | import os |
475 | +import re |
476 | import shutil |
477 | import socket |
478 | +import subprocess |
479 | import sys |
480 | import time |
481 | -import yaml |
482 | -import re |
483 | -import netifaces |
484 | -import subprocess |
485 | +from distutils.version import LooseVersion |
486 | + |
487 | +from charmhelpers import context |
488 | +from charmhelpers.contrib.charmsupport import nrpe |
489 | +from charmhelpers.core import hookenv, host, unitdata |
490 | +from charmhelpers.core.host import is_container |
491 | +from charmhelpers.core.templating import render |
492 | |
493 | +import charms.promreg |
494 | from charms import apt |
495 | from charms.layer import snap |
496 | from charms.reactive import ( |
497 | + clear_flag, |
498 | endpoint_from_flag, |
499 | helpers, |
500 | hook, |
501 | - when, |
502 | - when_not, |
503 | set_flag, |
504 | - clear_flag, |
505 | toggle_flag, |
506 | + when, |
507 | + when_not, |
508 | ) |
509 | from charms.reactive.bus import get_states |
510 | |
511 | -from charmhelpers import context |
512 | -from charmhelpers.core import hookenv, host, unitdata |
513 | -from charmhelpers.core.templating import render |
514 | -from charmhelpers.core.host import is_container |
515 | -from charmhelpers.contrib.charmsupport import nrpe |
516 | -import charms.promreg |
517 | -from jinja2 import Template, Environment, FileSystemLoader, exceptions |
518 | +from jinja2 import Environment, FileSystemLoader, Template, exceptions |
519 | + |
520 | +import netifaces |
521 | + |
522 | +import yaml |
523 | |
524 | DEB_BASE_DIR = "/etc/telegraf" |
525 | SNAP_BASE_DIR = "/var/snap/telegraf/current" |
526 | @@ -75,6 +78,7 @@ class InvalidInstallMethod(Exception): |
527 | |
528 | def get_install_method(): |
529 | config = hookenv.config() |
530 | + |
531 | if config["install_method"] in ["deb", "snap"]: |
532 | return config["install_method"] |
533 | else: |
534 | @@ -87,6 +91,7 @@ def get_install_method(): |
535 | |
536 | def get_base_dir(): |
537 | config = hookenv.config() |
538 | + |
539 | if config["install_method"] == "deb": |
540 | return DEB_BASE_DIR |
541 | elif config["install_method"] == "snap": |
542 | @@ -101,6 +106,7 @@ def get_base_dir(): |
543 | |
544 | def get_service(): |
545 | config = hookenv.config() |
546 | + |
547 | if config["install_method"] == "deb": |
548 | return DEB_SERVICE |
549 | elif config["install_method"] == "snap": |
550 | @@ -139,13 +145,16 @@ def list_config_files(): |
551 | config_files = [get_main_config_path()] |
552 | # only include config files for configured plugins |
553 | current_states = get_states() |
554 | + |
555 | for plugin in list_supported_plugins(): |
556 | if "plugins.{}.configured".format(plugin) in current_states.keys(): |
557 | config_path = "{}/{}.conf".format(get_configs_dir(), plugin) |
558 | config_files.append(config_path) |
559 | + |
560 | if "extra_plugins.configured" in current_states.keys(): |
561 | config_files.append("{}/extra_plugins.conf".format(get_configs_dir())) |
562 | config_files.append("{}/socket_listener.conf".format(get_configs_dir())) |
563 | + |
564 | return config_files |
565 | |
566 | |
567 | @@ -153,33 +162,40 @@ def get_hostname_label(): |
568 | config = hookenv.config() |
569 | hostname_fmt = config["hostname"] |
570 | unit = get_remote_unit_name().replace("/", "-") # / is invalid in labels. |
571 | + |
572 | if hostname_fmt == "UNIT_NAME": # Deprecated |
573 | return unit |
574 | env = os.environ |
575 | model = env.get("JUJU_ENV_NAME") or env.get("JUJU_MODEL_NAME", "") |
576 | uuid = env.get("JUJU_ENV_UUID") or env.get("JUJU_MODEL_UUID", "") |
577 | syshost = socket.gethostname() |
578 | + |
579 | return hostname_fmt.format(unit=unit, model=model, uuid=uuid, host=syshost) |
580 | |
581 | |
582 | def get_remote_unit_name(): |
583 | unit = hookenv.principal_unit() |
584 | + |
585 | if unit: |
586 | # Note(aluria): use Juju env var available since 2017 |
587 | + |
588 | return unit |
589 | else: |
590 | # Note(aluria): lookup all available IPv4/IPv6 addresses (except lo) |
591 | ip_addresses = set() |
592 | + |
593 | for iface in netifaces.interfaces(): |
594 | if iface == "lo": |
595 | continue |
596 | ip_addrs = netifaces.ifaddresses(iface) |
597 | + |
598 | for iface_type in ip_addrs: |
599 | if iface_type in (netifaces.AF_INET, netifaces.AF_INET6): |
600 | for addrs in ip_addrs[iface_type]: |
601 | ip_addresses.add(addrs["addr"]) |
602 | |
603 | # Note(aluria): and try to match them against rel['private-address'] |
604 | + |
605 | for rel_type in hookenv.metadata()["requires"].keys(): |
606 | for rel in hookenv.relations_of_type(rel_type): |
607 | if rel["private-address"] in ip_addresses: |
608 | @@ -188,6 +204,7 @@ def get_remote_unit_name(): |
609 | |
610 | def get_base_inputs(): |
611 | """Make a structure for rendering the base_inputs template. |
612 | + |
613 | Returns a dict of items for the template. |
614 | """ |
615 | extra_options = get_extra_options() |
616 | @@ -195,6 +212,7 @@ def get_base_inputs(): |
617 | config = hookenv.config() |
618 | str_disabled_plugins = config["disabled_plugins"] |
619 | disabled_plugins = str_disabled_plugins.split(":") if str_disabled_plugins else [] |
620 | + |
621 | return { |
622 | "extra_options": extra_options["inputs"], |
623 | "bcache": is_bcache(), |
624 | @@ -221,20 +239,25 @@ def get_extra_options(): |
625 | # to raw json |
626 | json_vals = {} |
627 | # kind level |
628 | + |
629 | for k, v in extra_options.items(): |
630 | json_vals[k] = {} |
631 | # plugins level |
632 | + |
633 | for plugin, values in v.items(): |
634 | json_vals[k][plugin] = {} |
635 | # inner plugin (aka key:value) |
636 | + |
637 | for key, val in values.items(): |
638 | if key in ("tagpass", "tagdrop"): |
639 | # this is a tagpass/drop, we need to go deeper |
640 | json_vals[k][plugin][key] = {} |
641 | + |
642 | for tag, tagvalue in val.items(): |
643 | json_vals[k][plugin][key][tag] = json.dumps(tagvalue) |
644 | else: |
645 | json_vals[k][plugin][key] = json.dumps(val) |
646 | + |
647 | return json_vals |
648 | |
649 | |
650 | @@ -323,13 +346,17 @@ def render_socket_listener_config(context): |
651 | def get_sysstat_config_with_sadc_xall(content): |
652 | """Get updated sysstat config content with `-S XALL` in `SADC_OPTIONS`. |
653 | |
654 | - `/etc/sysstat/systat` consists of a sequence of shell variable assignments used to configure sysstat logging. |
655 | + `/etc/sysstat/systat` consists of a sequence of shell variable assignments |
656 | + used to configure sysstat logging. |
657 | |
658 | Check the original config content. |
659 | + |
660 | If change needed, make the change and return new config content. |
661 | + |
662 | If no change, return None. |
663 | """ |
664 | - # if SADC_OPTIONS already exists with `-S XALL` in value, no need to change, return None |
665 | + # if SADC_OPTIONS already exists with `-S XALL` in value, no need to change, |
666 | + # return None |
667 | if re.search(r'^SADC_OPTIONS=".*-S\s+XALL.*"', content, flags=re.M): |
668 | return None |
669 | |
670 | @@ -365,6 +392,7 @@ def update_sysstat_config_with_sdac_xall(path="/etc/sysstat/sysstat"): |
671 | if os.path.isfile(path): |
672 | with open(path, mode="r", encoding="utf8") as f: |
673 | new_text = get_sysstat_config_with_sadc_xall(f.read()) |
674 | + |
675 | if new_text: |
676 | hookenv.log("updating {} to ensure `-S XALL` in SADC_OPTIONS".format(path)) |
677 | with open(path, mode="w", encoding="utf8") as f: |
678 | @@ -386,18 +414,23 @@ def configure_telegraf(): # noqa: C901 |
679 | "blocked", |
680 | "Wrong install_method provided: {!r}".format(config["install_method"]), |
681 | ) |
682 | + |
683 | return |
684 | + |
685 | if get_remote_unit_name() is None: |
686 | hookenv.status_set("waiting", "Waiting for juju-info relation") |
687 | # if UNIT_NAME in hostname config and relation not yet available, |
688 | # make telegraf unable to start to not get weird metrics names |
689 | + |
690 | if os.path.exists(config_path): |
691 | os.unlink(config_path) |
692 | + |
693 | return |
694 | |
695 | inputs = config.get("inputs_config", "") |
696 | outputs = config.get("outputs_config", "") |
697 | # just for the migration out of base64 |
698 | + |
699 | if inputs: |
700 | try: |
701 | inputs = base64.b64decode(inputs.encode("utf-8"), validate=True).decode( |
702 | @@ -406,6 +439,7 @@ def configure_telegraf(): # noqa: C901 |
703 | except binascii.Error: |
704 | # not bas64, probably already up to date configs |
705 | pass |
706 | + |
707 | if outputs: |
708 | try: |
709 | outputs = base64.b64decode(outputs.encode("utf-8"), validate=True).decode( |
710 | @@ -415,6 +449,7 @@ def configure_telegraf(): # noqa: C901 |
711 | # not bas64, probably already up to date configs |
712 | pass |
713 | tags = [] |
714 | + |
715 | if config["tags"]: |
716 | for tag in config["tags"].split(","): |
717 | key, value = tag.split("=") |
718 | @@ -424,11 +459,13 @@ def configure_telegraf(): # noqa: C901 |
719 | tags.append('juju_unit = "{}"'.format(get_remote_unit_name().replace("/", "-"))) |
720 | tags.append('juju_model = "{}"'.format(hookenv.model_name())) |
721 | context["tags"] = tags |
722 | + |
723 | if inputs: |
724 | context["inputs"] = inputs |
725 | else: |
726 | # use base inputs from charm templates |
727 | context["inputs"] = render_base_inputs() |
728 | + |
729 | if outputs: |
730 | context["outputs"] = outputs |
731 | else: |
732 | @@ -438,12 +475,13 @@ def configure_telegraf(): # noqa: C901 |
733 | context["hostname"] = get_hostname_label() |
734 | |
735 | logfile_path = os.path.normpath(context["logfile"]) |
736 | + |
737 | if ( |
738 | context["logfile"] |
739 | - and not logfile_path.startswith("/var/log/") |
740 | - and not ( |
741 | + and not logfile_path.startswith("/var/log/") # noqa W503 |
742 | + and not ( # noqa W503 |
743 | config["install_method"] == "snap" |
744 | - and logfile_path.startswith("/var/snap/telegraf/common/") |
745 | + and logfile_path.startswith("/var/snap/telegraf/common/") # noqa W503 |
746 | ) |
747 | ): |
748 | # only allow logging in /var/log, syslog, or /var/snap/telegraf/common |
749 | @@ -487,6 +525,7 @@ def configure_telegraf(): # noqa: C901 |
750 | ) |
751 | |
752 | # add sudoers file for telegraf if openvswitch is running |
753 | + |
754 | if host.service_running("openvswitch-switch"): |
755 | sudoers_filename = "telegraf_sudoers" |
756 | src = os.path.join(get_files_dir(), sudoers_filename) |
757 | @@ -508,6 +547,7 @@ def configure_telegraf(): # noqa: C901 |
758 | |
759 | set_flag("telegraf.configured") |
760 | set_flag("telegraf.needs_reload") |
761 | + |
762 | if config["install_method"] == "deb": |
763 | set_flag("telegraf.apt.configured") |
764 | else: |
765 | @@ -525,12 +565,15 @@ def install_telegraf(): |
766 | hookenv.status_set( |
767 | "blocked", "Wrong install_method provided. Expected either 'deb' or 'snap'." |
768 | ) |
769 | + |
770 | return |
771 | + |
772 | if install_method == "deb": |
773 | try: |
774 | snap.remove("telegraf") |
775 | except Exception: |
776 | - # the snap may already be absent, or snaps may not even be supported in this environment |
777 | + # the snap may already be absent, or snaps may not even be supported |
778 | + # in this environment |
779 | pass |
780 | apt.queue_install(["telegraf"]) |
781 | elif install_method == "snap": |
782 | @@ -538,6 +581,7 @@ def install_telegraf(): |
783 | config = hookenv.config() |
784 | snap_channel = config.get("snap_channel") |
785 | snap.install("telegraf", channel=snap_channel, classic=True) |
786 | + |
787 | if install_method: |
788 | set_flag("telegraf.installed") |
789 | |
790 | @@ -572,16 +616,19 @@ def upgrade_charm(): |
791 | @when("config.changed") |
792 | def handle_config_changes(): |
793 | config = hookenv.config() |
794 | + |
795 | if config.changed("extra_options"): |
796 | for plugin in list_supported_plugins(): |
797 | clear_flag("plugins.{}.configured".format(plugin)) |
798 | # if something else changed, let's reconfigure telegraf itself just in case |
799 | + |
800 | if config.changed("extra_plugins"): |
801 | clear_flag("extra_plugins.configured") |
802 | + |
803 | if ( |
804 | config.changed("install_method") |
805 | - or config.changed("snap_channel") |
806 | - or config.changed("install_sources") |
807 | + or config.changed("snap_channel") # noqa W503 |
808 | + or config.changed("install_sources") # noqa W503 |
809 | ): |
810 | clear_flag("telegraf.installed") |
811 | clear_flag("telegraf.configured") |
812 | @@ -595,6 +642,7 @@ def handle_config_changes(): |
813 | def configure_extra_plugins(): |
814 | config = hookenv.config() |
815 | plugins = config["extra_plugins"] |
816 | + |
817 | if plugins: |
818 | config_path = "{}/extra_plugins.conf".format(get_configs_dir()) |
819 | host.write_file(config_path, plugins.encode("utf-8")) |
820 | @@ -894,7 +942,7 @@ def redis_input(redis): |
821 | servers = ["tcp://{{ host }}:{{ port }}"] |
822 | # Until https://github.com/influxdata/telegraf/issues/5036 is fixed |
823 | fielddrop = ["aof_last_bgrewrite_status","aof_last_write_status","maxmemory_policy","rdb_last_bgsave_status","used_memory_dataset_perc","used_memory_peak_perc"] |
824 | -""" |
825 | +""" # noqa E501 (inline template) |
826 | config_path = "{}/{}.conf".format(get_configs_dir(), "redis") |
827 | |
828 | rels = hookenv.relations_of_type("redis") |
829 | @@ -1146,7 +1194,8 @@ def prometheus_client(prometheus): |
830 | |
831 | |
832 | def convert_days(time_string): |
833 | - """ |
834 | + """Convert string time descript to days. |
835 | + |
836 | Function to convert strings like 2w or 14d to a sting containing the number |
837 | of days. |
838 | |
839 | @@ -1302,8 +1351,8 @@ def start_or_restart(): |
840 | active_plugins_changed = helpers.data_changed("active_plugins", states or "") |
841 | if ( |
842 | not host.service_running(service) |
843 | - or config_files_changed |
844 | - or active_plugins_changed |
845 | + or config_files_changed # noqa W503 |
846 | + or active_plugins_changed # noqa W503 |
847 | ): |
848 | hookenv.log("Restarting telegraf") |
849 | host.service_restart(service) |
850 | @@ -1328,8 +1377,9 @@ def start_or_restart(): |
851 | |
852 | |
853 | def is_bcache(): |
854 | - """ |
855 | - return true if bcache is present, and this is not a container |
856 | + """Determine if this is a container. |
857 | + |
858 | + return true if bcache is present, and this is not a container. |
859 | """ |
860 | container = is_container() |
861 | return os.path.exists("/sys/fs/bcache") and not container |
862 | @@ -1352,9 +1402,10 @@ def update_status(): |
863 | @when_not("telegraf.nagios-setup.complete") |
864 | def configure_nagios(nagios): |
865 | """Configure nagios process check. |
866 | - the flag 'telegraf.nagios-setup.complete' is reset at the moment config is |
867 | - changed, so this should make sure that updates are handled.""" |
868 | |
869 | + The flag 'telegraf.nagios-setup.complete' is reset at the moment config is |
870 | + changed, so this should make sure that updates are handled. |
871 | + """ |
872 | # Use charmhelpers to handle the configuration of nrpe |
873 | hostname = nrpe.get_nagios_hostname() |
874 | nrpe_setup = nrpe.NRPE(hostname=hostname, primary=False) |
875 | diff --git a/src/tests/functional/tests/test_telegraf.py b/src/tests/functional/tests/test_telegraf.py |
876 | index 1b80661..3c4354d 100644 |
877 | --- a/src/tests/functional/tests/test_telegraf.py |
878 | +++ b/src/tests/functional/tests/test_telegraf.py |
879 | @@ -21,9 +21,8 @@ import unittest |
880 | |
881 | import requests |
882 | |
883 | -from zaza.utilities import juju |
884 | from zaza import model |
885 | - |
886 | +from zaza.utilities import juju |
887 | |
888 | DEFAULT_HTTPGET_TIMEOUT = 10 |
889 | DEFAULT_RETRIES = 12 |
890 | @@ -58,21 +57,24 @@ class TestTelegraf(BaseTelegrafTest): |
891 | model.get_units(app) |
892 | for app in juju.get_principle_applications(self.application_name) |
893 | ) |
894 | + |
895 | for unit in it.chain.from_iterable(principal_units): |
896 | if not unit.public_address: |
897 | continue |
898 | url = "http://{}:{}/metrics".format( |
899 | unit.public_address, DEFAULT_TELEGRAF_EXPORTER_PORT |
900 | ) |
901 | + |
902 | for retry in range(DEFAULT_RETRIES): |
903 | resp = requests.get(url, timeout=DEFAULT_HTTPGET_TIMEOUT) |
904 | self.assertEqual(resp.status_code, 200) |
905 | |
906 | if ( |
907 | unit.name.startswith("postgresql/") |
908 | - and "postgresql_blks_hit" not in resp.text |
909 | + and "postgresql_blks_hit" not in resp.text # noqa W503 |
910 | ) or "cpu_usage_idle" not in resp.text: |
911 | time.sleep(DEFAULT_RETRIES_TIMEOUT) |
912 | + |
913 | continue |
914 | |
915 | logging.info("test_service: Unit {} is reachable".format(unit.name)) |
916 | @@ -90,6 +92,7 @@ class TestTelegraf(BaseTelegrafTest): |
917 | r"^zoneinfo_", |
918 | r"^processes_", |
919 | ] |
920 | + |
921 | for re_pattern in re_patterns: |
922 | self.check_re_pattern(re_pattern, text) |
923 | |
924 | @@ -104,12 +107,14 @@ class TestTelegraf(BaseTelegrafTest): |
925 | install_method = model.get_application_config("telegraf")["install_method"][ |
926 | "value" |
927 | ] |
928 | + |
929 | if install_method == "deb": |
930 | telegraf_conf = DEB_TELEGRAF_CONF |
931 | else: |
932 | telegraf_conf = SNAP_TELEGRAF_CONF |
933 | cmd = "cat {}".format(telegraf_conf) |
934 | response = model.run_on_unit(self.lead_unit_name, cmd) |
935 | + |
936 | if response["Code"] != "0": |
937 | self.fail( |
938 | "test_02_telegraf_logfile: could not read file {}".format(telegraf_conf) |
939 | @@ -118,6 +123,7 @@ class TestTelegraf(BaseTelegrafTest): |
940 | for line in response["Stdout"].splitlines(): |
941 | if line.strip() == 'logfile = "/var/log/telegraf/telegraf.log"': |
942 | logging.info("test_02_telegraf_logfile: logfile config parameter found") |
943 | + |
944 | return |
945 | |
946 | self.fail( |
947 | @@ -127,25 +133,32 @@ class TestTelegraf(BaseTelegrafTest): |
948 | ) |
949 | |
950 | def test_03_system_service(self): |
951 | - """Check that the right service is running, e.g. either the deb's or the snap's.""" |
952 | + """Check that the right service is running. |
953 | + |
954 | + e.g. either the deb's or the snap's. |
955 | + """ |
956 | install_method = model.get_application_config("telegraf")["install_method"][ |
957 | "value" |
958 | ] |
959 | services = {"deb": "telegraf", "snap": "snap.telegraf.telegraf"} |
960 | + |
961 | for method in services.keys(): |
962 | service = services[method] |
963 | cmd = "service {} status".format(service) |
964 | response = model.run_on_unit(self.lead_unit_name, cmd) |
965 | + |
966 | if install_method == method and response["Code"] != "0": |
967 | self.fail( |
968 | - "test_03_system_service: service {} should be running on {} but is not. " |
969 | + "test_03_system_service: service {} should be running " |
970 | + "on {} but is not. " |
971 | "install_method is {}.".format( |
972 | service, self.lead_unit_name, install_method |
973 | ) |
974 | ) |
975 | elif install_method != method and response["Code"] == "0": |
976 | self.fail( |
977 | - "test_03_system_service: service {} is running on {} but shouldn't. " |
978 | + "test_03_system_service: service {} is running " |
979 | + "on {} but shouldn't. " |
980 | "install_method is {}.".format( |
981 | service, self.lead_unit_name, install_method |
982 | ) |
983 | diff --git a/src/tests/unit/__init__.py b/src/tests/unit/__init__.py |
984 | index 28e9795..5f22a2b 100644 |
985 | --- a/src/tests/unit/__init__.py |
986 | +++ b/src/tests/unit/__init__.py |
987 | @@ -1,3 +1,5 @@ |
988 | +"""Unit test module.""" |
989 | + |
990 | import sys |
991 | |
992 | sys.path.append(".") |
993 | diff --git a/src/tests/unit/test_mysql.py b/src/tests/unit/test_mysql.py |
994 | index 27f206d..9015600 100644 |
995 | --- a/src/tests/unit/test_mysql.py |
996 | +++ b/src/tests/unit/test_mysql.py |
997 | @@ -22,10 +22,11 @@ from unittest.mock import ANY, MagicMock, patch, sentinel |
998 | # Mock layer modules |
999 | import charms |
1000 | |
1001 | +import reactive |
1002 | + |
1003 | promreg = MagicMock() |
1004 | charms.promreg = promreg |
1005 | sys.modules["charms.promreg"] = promreg |
1006 | -import reactive |
1007 | |
1008 | |
1009 | class TestMySQL(unittest.TestCase): |
1010 | diff --git a/src/tests/unit/test_postgresql.py b/src/tests/unit/test_postgresql.py |
1011 | index 9192ea4..c011b32 100644 |
1012 | --- a/src/tests/unit/test_postgresql.py |
1013 | +++ b/src/tests/unit/test_postgresql.py |
1014 | @@ -17,7 +17,7 @@ |
1015 | import os |
1016 | import sys |
1017 | import unittest |
1018 | -from unittest.mock import ANY, call, MagicMock, patch, sentinel |
1019 | +from unittest.mock import ANY, MagicMock, call, patch, sentinel |
1020 | |
1021 | # Mock layer modules |
1022 | import charms |
1023 | @@ -32,8 +32,8 @@ sys.modules["charms.apt"] = apt |
1024 | sys.modules["charms.layer"] = layer |
1025 | sys.modules["charms.promreg"] = promreg |
1026 | |
1027 | -import reactive |
1028 | -from reactive import telegraf |
1029 | +import reactive # noqa E402 |
1030 | +from reactive import telegraf # noqa E402 |
1031 | |
1032 | |
1033 | class TestPostgreSQL(unittest.TestCase): |
1034 | @@ -123,7 +123,7 @@ class TestPostgreSQL(unittest.TestCase): |
1035 | get_base_dir.return_value = "/etc/telegraf" |
1036 | |
1037 | reactive.telegraf.render_postgresql_tmpl( |
1038 | - [{"replica": "master", "conn_str": "my_conn_str", "server": "my_server"},] |
1039 | + [{"replica": "master", "conn_str": "my_conn_str", "server": "my_server"}] |
1040 | ) |
1041 | |
1042 | write_file.assert_called_once_with( |
1043 | diff --git a/src/tests/unit/test_telegraf.py b/src/tests/unit/test_telegraf.py |
1044 | index 1825fa6..57e7e3c 100644 |
1045 | --- a/src/tests/unit/test_telegraf.py |
1046 | +++ b/src/tests/unit/test_telegraf.py |
1047 | @@ -14,36 +14,38 @@ |
1048 | # You should have received a copy of the GNU General Public License |
1049 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
1050 | |
1051 | -"""actions.py tests""" |
1052 | +"""Tests for actions.py.""" |
1053 | import base64 |
1054 | -import os |
1055 | import getpass |
1056 | import grp |
1057 | import json |
1058 | -import sys |
1059 | +import os |
1060 | import subprocess |
1061 | +import sys |
1062 | import unittest |
1063 | from textwrap import dedent |
1064 | -from unittest.mock import patch, MagicMock, call |
1065 | from unittest import mock |
1066 | +from unittest.mock import MagicMock, call, patch |
1067 | |
1068 | -import yaml |
1069 | -import pytest |
1070 | -import py |
1071 | - |
1072 | -from charms.reactive import bus, helpers, RelationBase, set_flag |
1073 | from charmhelpers.core.hookenv import Config |
1074 | from charmhelpers.core.templating import render |
1075 | |
1076 | -# Mock layer modules |
1077 | import charms |
1078 | +from charms.reactive import RelationBase, bus, helpers, set_flag |
1079 | + |
1080 | +import py |
1081 | |
1082 | +import pytest |
1083 | + |
1084 | +import yaml |
1085 | + |
1086 | +# Mock layer modules |
1087 | promreg = MagicMock() |
1088 | charms.promreg = promreg |
1089 | sys.modules["charms.promreg"] = promreg |
1090 | |
1091 | -import reactive |
1092 | -from reactive import telegraf |
1093 | +import reactive # noqa E402 |
1094 | +from reactive import telegraf # noqa E402 |
1095 | |
1096 | UNIT_TESTS_DIR = os.path.dirname(os.path.abspath(__file__)) |
1097 | UNIT_TESTS_DATA_DIR = os.path.join(UNIT_TESTS_DIR, "data") |
1098 | @@ -71,6 +73,7 @@ def setup(monkeypatch, tmpdir): |
1099 | # fix the args to use non-root, this is for callers that pass |
1100 | # owner/group as positional arguments like |
1101 | # charmhelpers.core.templating.render |
1102 | + |
1103 | if len(a) > 2: |
1104 | if a[2] == "root" and a[3] == "root": |
1105 | # make all files writable by owner, as we need don't run as root |
1106 | @@ -80,6 +83,7 @@ def setup(monkeypatch, tmpdir): |
1107 | kw["group"] = group |
1108 | # make all files writable by owner, as we need don't run as root |
1109 | kw["perms"] = 0o744 |
1110 | + |
1111 | return orig_write_file(*a, **kw) |
1112 | |
1113 | monkeypatch.setattr(telegraf.host, "write_file", intercept_write_file) |
1114 | @@ -94,6 +98,7 @@ def cleanup(request): |
1115 | unitdata._KV = None |
1116 | # rm unit-state.db file |
1117 | unit_state_db = os.path.join(telegraf.hookenv.charm_dir(), ".unit-state.db") |
1118 | + |
1119 | if os.path.exists(unit_state_db): |
1120 | os.unlink(unit_state_db) |
1121 | |
1122 | @@ -134,6 +139,7 @@ def config(monkeypatch, temp_charm_dir): |
1123 | data = dict((k, v["default"]) for k, v in raw_config["options"].items()) |
1124 | config = Config(data) |
1125 | monkeypatch.setattr(telegraf.hookenv, "config", lambda: config) |
1126 | + |
1127 | return config |
1128 | |
1129 | |
1130 | @@ -147,13 +153,14 @@ def configs_dir(): |
1131 | |
1132 | |
1133 | def persist_state(): |
1134 | - """Fake persistent state by calling helpers that modify unitdata.kv""" |
1135 | + """Fake persistent state by calling helpers that modify unitdata.kv.""" |
1136 | states = [ |
1137 | k |
1138 | for k in bus.get_states().keys() |
1139 | if k.startswith("plugins") or k.startswith("extra_plugins") |
1140 | ] |
1141 | helpers.any_file_changed(telegraf.list_config_files()) |
1142 | + |
1143 | if states: |
1144 | helpers.data_changed("active_plugins", states) |
1145 | |
1146 | @@ -169,7 +176,7 @@ def check_sysstat_config(original, expected): |
1147 | |
1148 | |
1149 | def test_sadc_options_correct(monkeypatch): |
1150 | - """If SADC_OPTIONS is already correct, should return None""" |
1151 | + """If SADC_OPTIONS is already correct, should return None.""" |
1152 | original = dedent( |
1153 | """ |
1154 | # some comment |
1155 | @@ -183,7 +190,7 @@ def test_sadc_options_correct(monkeypatch): |
1156 | |
1157 | |
1158 | def test_sadc_options_correct_included(monkeypatch): |
1159 | - """If SADC_OPTIONS already includes `-S XALL`, should return None""" |
1160 | + """If SADC_OPTIONS already includes `-S XALL`, should return None.""" |
1161 | original = dedent( |
1162 | """ |
1163 | # some comment |
1164 | @@ -197,7 +204,7 @@ def test_sadc_options_correct_included(monkeypatch): |
1165 | |
1166 | |
1167 | def test_sadc_options_non_exist(monkeypatch): |
1168 | - """If SADC_OPTIONS doesn't exist, should just append""" |
1169 | + """If SADC_OPTIONS doesn't exist, should just append.""" |
1170 | original = dedent( |
1171 | """ |
1172 | # some comment |
1173 | @@ -217,7 +224,7 @@ def test_sadc_options_non_exist(monkeypatch): |
1174 | |
1175 | |
1176 | def test_sadc_options_commented(monkeypatch): |
1177 | - """If SADC_OPTIONS exists but commented, should ignore and append""" |
1178 | + """If SADC_OPTIONS exists but commented, should ignore and append.""" |
1179 | original = dedent( |
1180 | """ |
1181 | # some comment |
1182 | @@ -243,7 +250,7 @@ def test_sadc_options_commented(monkeypatch): |
1183 | |
1184 | |
1185 | def test_sadc_options_incorrect(monkeypatch): |
1186 | - """If SADC_OPTIONS exists but not XALL, should replace""" |
1187 | + """If SADC_OPTIONS exists but not XALL, should replace.""" |
1188 | original = dedent( |
1189 | """ |
1190 | # some comment |
1191 | @@ -267,7 +274,7 @@ def test_sadc_options_incorrect(monkeypatch): |
1192 | |
1193 | |
1194 | def test_sadc_options_incorrect_included(monkeypatch): |
1195 | - """If SADC_OPTIONS exists but not XALL, should replace""" |
1196 | + """If SADC_OPTIONS exists but not XALL, should replace.""" |
1197 | original = dedent( |
1198 | """ |
1199 | # some comment |
1200 | @@ -291,7 +298,7 @@ def test_sadc_options_incorrect_included(monkeypatch): |
1201 | |
1202 | |
1203 | def test_sadc_options_commented_line_not_touched(monkeypatch): |
1204 | - """If SADC_OPTIONS exists but has no -S, should append""" |
1205 | + """If SADC_OPTIONS exists but has no -S, should append.""" |
1206 | original = dedent( |
1207 | """ |
1208 | # some comment |
1209 | @@ -318,7 +325,7 @@ def test_sadc_options_commented_line_not_touched(monkeypatch): |
1210 | |
1211 | |
1212 | def test_sadc_options_s_missing(monkeypatch): |
1213 | - """If SADC_OPTIONS exists but has no -S, should append""" |
1214 | + """If SADC_OPTIONS exists but has no -S, should append.""" |
1215 | original = dedent( |
1216 | """ |
1217 | # some comment |
1218 | @@ -351,6 +358,7 @@ def test_telegraf_exec_metrics(monkeypatch, temp_config_dir): |
1219 | metrics = set( |
1220 | ["sockstat", "sockstat6", "softnet_stat", "buddyinfo", "zoneinfo", "netns"] |
1221 | ) |
1222 | + |
1223 | for metric in metrics: |
1224 | run_telegraf_exec_metrics("--metric", metric) |
1225 | |
1226 | @@ -370,9 +378,8 @@ def test_telegraf_exec_metrics(monkeypatch, temp_config_dir): |
1227 | ) |
1228 | |
1229 | # ensure config files exists after render |
1230 | - run_telegraf_exec_metrics( |
1231 | - "--render-config-files", "--configs-dir", configs_dir(), |
1232 | - ) |
1233 | + run_telegraf_exec_metrics("--render-config-files", "--configs-dir", configs_dir()) |
1234 | + |
1235 | for metric in metrics: |
1236 | assert os.path.isfile(os.path.join(configs_dir(), "{}.conf".format(metric))) |
1237 | |
1238 | @@ -386,9 +393,11 @@ def test_telegraf_exec_metrics(monkeypatch, temp_config_dir): |
1239 | ":".join(disabled_metrics), |
1240 | ) |
1241 | # config files for disabled metrics should be removed. |
1242 | + |
1243 | for metric in disabled_metrics: |
1244 | assert not os.path.isfile(os.path.join(configs_dir(), "{}.conf".format(metric))) |
1245 | # config files for other metrics should still be there |
1246 | + |
1247 | for metric in metrics - disabled_metrics: |
1248 | assert os.path.isfile(os.path.join(configs_dir(), "{}.conf".format(metric))) |
1249 | |
1250 | @@ -619,7 +628,7 @@ inputs: |
1251 | |
1252 | |
1253 | def test_base_inputs_disabled_plugins(config): |
1254 | - """Check disabled_plugins option is working for builtin inputs""" |
1255 | + """Check disabled_plugins option is working for builtin inputs.""" |
1256 | config["disabled_plugins"] = "cpu:disk" |
1257 | content = telegraf.render_base_inputs() |
1258 | |
1259 | @@ -1246,7 +1255,7 @@ class TestGrafanaDashboard(unittest.TestCase): |
1260 | variable_end_string=">>", |
1261 | ) |
1262 | mock_grafana.register_dashboard.assert_called_once_with( |
1263 | - name=telegraf.GRAFANA_DASHBOARD_NAME, dashboard=mock_dashboard_dict, |
1264 | + name=telegraf.GRAFANA_DASHBOARD_NAME, dashboard=mock_dashboard_dict |
1265 | ) |
1266 | mock_set_flag.assert_called_once_with("grafana.configured") |
1267 | |
1268 | diff --git a/src/tox.ini b/src/tox.ini |
1269 | index 40c62d6..4977737 100644 |
1270 | --- a/src/tox.ini |
1271 | +++ b/src/tox.ini |
1272 | @@ -42,7 +42,8 @@ exclude = |
1273 | charmhelpers, |
1274 | mod, |
1275 | .build |
1276 | -ignore = I100, D101, D102, D103, I201, D205, W504, D400, D401, D403, D209, D100, E403, I101, E501, N803, E226, E128, D200, E741, D202, E261, E402, D104, W503, E231 # TODO |
1277 | +#ignore = I100, D101, D102, D103, I201, D205, W504, D400, D401, D403, D209, D100, E403, I101, E501, N803, E226, E128, D200, E741, D202, E261, E402, D104, W503, E231 # TODO |
1278 | +ignore = D100, D101, D102, D103 |
1279 | |
1280 | max-line-length = 88 |
1281 | max-complexity = 10 |
This merge proposal is being monitored by mergebot. Change the status to Approved to merge.