1
|
|
|
import logging |
2
|
|
|
from unittest import TestCase |
3
|
|
|
|
4
|
|
|
from hypothesis import example, given, strategies as st, assume |
5
|
|
|
from hypothesis.provisional import domains, urls |
6
|
|
|
|
7
|
|
|
from kibana_prometheus_exporter import config |
8
|
|
|
|
9
|
|
|
|
10
|
|
|
def _everything_except(excluded_types): |
11
|
|
|
return st.from_type(type).flatmap(st.from_type).filter(lambda x: not isinstance(x, excluded_types)) |
12
|
|
|
|
13
|
|
|
|
14
|
|
|
def _everything_except_int_like(): |
15
|
|
|
def _not_convertible_to_int(val): |
16
|
|
|
try: |
17
|
|
|
int_val = int(str(val)) |
18
|
|
|
except Exception: |
19
|
|
|
return True |
20
|
|
|
else: |
21
|
|
|
return str(int_val) != str(val) |
22
|
|
|
|
23
|
|
|
return _everything_except(int).filter(_not_convertible_to_int) |
24
|
|
|
|
25
|
|
|
|
26
|
|
|
MIN_PORT = 0 |
27
|
|
|
MAX_PORT = 2**16 - 1 |
28
|
|
|
PORTS_VALID = st.integers(min_value=MIN_PORT, max_value=MAX_PORT) |
29
|
|
|
PORTS_INVALID = st.integers().filter(lambda x: x < MIN_PORT or x > MAX_PORT) |
30
|
|
|
|
31
|
|
|
|
32
|
|
|
@st.composite |
33
|
|
|
def _urls_with_out_of_bounds_port(draw): |
34
|
|
|
domain = draw(domains()) |
35
|
|
|
port = draw(PORTS_INVALID) |
36
|
|
|
return "http://%s:%d" % (domain, port) |
37
|
|
|
|
38
|
|
|
|
39
|
|
|
@st.composite |
40
|
|
|
def _urls_with_bogus_port(draw): |
41
|
|
|
domain = draw(domains()) |
42
|
|
|
port = draw(_everything_except_int_like) |
43
|
|
|
return "http://%s:%s" % (domain, port) |
44
|
|
|
|
45
|
|
|
|
46
|
|
|
class TestCheckURL(TestCase): |
47
|
|
|
@given(urls()) |
48
|
|
|
@example("http://example.com/some/path?x=2") |
49
|
|
|
@example("http://example.com/some/path") |
50
|
|
|
@example("http://example.com/") |
51
|
|
|
@example("http://example.com") |
52
|
|
|
def test_full_url_is_ok(self, url): |
53
|
|
|
self.assertEqual(config._check_url(url), url) |
54
|
|
|
|
55
|
|
|
@given(domains()) |
56
|
|
|
@example(None) |
57
|
|
|
@example("example.com") |
58
|
|
|
@example("://example.com") |
59
|
|
|
def test_raises_for_missing_or_wrong_scheme(self, url): |
60
|
|
|
self.assertRaises(ValueError, config._check_url, url) |
61
|
|
|
|
62
|
|
|
@given(_urls_with_out_of_bounds_port()) |
63
|
|
|
def test_raises_for_out_of_bounds_port_number(self, url): |
64
|
|
|
self.assertRaises(ValueError, config._check_url, url) |
65
|
|
|
|
66
|
|
|
@given(domain=domains(), port=_everything_except_int_like()) |
67
|
|
|
def test_raises_for_bogus_port_number(self, domain, port): |
68
|
|
|
assume(str(port) not in ("[]", "")) # urllib bug: https://bugs.python.org/issue36338 |
69
|
|
|
assume(str(port) not in ("/")) # An empty port is allowed |
70
|
|
|
url = "http://%s:%s" % (domain, port) |
71
|
|
|
self.assertRaises(ValueError, config._check_url, url) |
72
|
|
|
|
73
|
|
|
|
74
|
|
|
class TestCheckPort(TestCase): |
75
|
|
|
@given(PORTS_VALID) |
76
|
|
|
def test_port_range_works(self, port): |
77
|
|
|
self.assertEqual(config._check_port(port), port) |
78
|
|
|
|
79
|
|
|
@given(PORTS_INVALID) |
80
|
|
|
def test_outside_port_range_fails(self, port): |
81
|
|
|
self.assertRaises(ValueError, config._check_port, port) |
82
|
|
|
|
83
|
|
|
@given(port=_everything_except_int_like()) |
84
|
|
|
def test_raises_for_text(self, port): |
85
|
|
|
assume(not str(port).isnumeric()) |
86
|
|
|
self.assertRaises(ValueError, config._check_port, port) |
87
|
|
|
|
88
|
|
|
|
89
|
|
|
class TestCheckLogLevel(TestCase): |
90
|
|
|
def test_check_log_level_works_for_expected_values(self): |
91
|
|
|
for level in config.LOG_LEVELS: |
92
|
|
|
with self.subTest(level): |
93
|
|
|
self.assertEqual(config._check_log_level(level), getattr(logging, level.upper())) |
94
|
|
|
|
95
|
|
|
@given(st.text().filter(lambda x: x.upper() not in config.LOG_LEVELS)) |
|
|
|
|
96
|
|
|
def test_check_log_level_raises_for_random_text(self, value): |
97
|
|
|
self.assertRaises(ValueError, config._check_log_level, value) |
98
|
|
|
|
99
|
|
|
@given(_everything_except(str)) |
100
|
|
|
def test_check_log_level_raises_for_random_non_text_stuff(self, value): |
101
|
|
|
self.assertRaises(ValueError, config._check_log_level, value) |
102
|
|
|
|