|
1 | | -from dataclasses import dataclass |
| 1 | +from dataclasses import dataclass, replace |
| 2 | +from itertools import chain |
2 | 3 |
|
3 | 4 | import IPy |
4 | 5 | import pytest |
5 | 6 |
|
6 | | -from nav.dhcpstats.common import DhcpPath |
| 7 | +from nav.dhcpstats.common import DhcpPath, drop_groups_not_in_prefixes, group_paths |
7 | 8 | from nav.metrics.templates import metric_path_for_dhcp |
8 | 9 |
|
9 | 10 | @dataclass |
@@ -131,3 +132,181 @@ def test_from_external_info_should_fail_when_given_invalid_arguments(self, serve |
131 | 132 | with pytest.raises(ValueError): |
132 | 133 | DhcpPath.from_external_info(server_name, allocation_type, group_name, first_ip, last_ip) |
133 | 134 | pytest.fail(f"Didn't fail when {reason!r}") |
| 135 | + |
| 136 | + |
| 137 | +def test_group_paths_should_group_special_standalone_groups_paths_individually(): |
| 138 | + path0 = DhcpPath( |
| 139 | + ip_version=6, |
| 140 | + server_name="server1", |
| 141 | + allocation_type="range", |
| 142 | + group_name="standalone", |
| 143 | + group_name_source="special_groups", |
| 144 | + first_ip=IPy.IP("::0:1"), |
| 145 | + last_ip=IPy.IP("::0:ffff"), |
| 146 | + ) |
| 147 | + path1 = replace(path0, first_ip=IPy.IP("::1:1"), last_ip=IPy.IP("::1:ffff")) |
| 148 | + path2 = replace(path0, first_ip=IPy.IP("::2:1"), last_ip=IPy.IP("::2:ffff")) |
| 149 | + assert sorted(group_paths([path0, path1, path2])) == sorted([[path0], [path1], [path2]]) |
| 150 | + |
| 151 | + |
| 152 | +def test_group_paths_should_group_special_groups_paths_separately_from_custom_groups_paths(): |
| 153 | + path0 = DhcpPath( |
| 154 | + ip_version=6, |
| 155 | + server_name="server1", |
| 156 | + allocation_type="range", |
| 157 | + group_name="standalone", |
| 158 | + group_name_source="special_groups", |
| 159 | + first_ip=IPy.IP("::0:1"), |
| 160 | + last_ip=IPy.IP("::0:ffff"), |
| 161 | + ) |
| 162 | + path1 = replace(path0, first_ip=IPy.IP("::1:1"), last_ip=IPy.IP("::1:ffff")) |
| 163 | + path2 = replace(path0, first_ip=IPy.IP("::2:1"), last_ip=IPy.IP("::2:ffff"), group_name_source="custom_groups") |
| 164 | + path3 = replace(path0, first_ip=IPy.IP("::3:1"), last_ip=IPy.IP("::3:ffff"), group_name_source="custom_groups") |
| 165 | + assert sorted(group_paths([path0, path1, path2, path3])) == sorted([[path0], [path1], [path2, path3]]) |
| 166 | + |
| 167 | + |
| 168 | +def test_group_paths_should_group_custom_groups_paths_together_when_only_ip_addresses_differ(): |
| 169 | + path0 = DhcpPath( |
| 170 | + ip_version=6, |
| 171 | + server_name="server1", |
| 172 | + allocation_type="range", |
| 173 | + group_name="group1", |
| 174 | + group_name_source="custom_groups", |
| 175 | + first_ip=IPy.IP("::0:1"), |
| 176 | + last_ip=IPy.IP("::0:ffff"), |
| 177 | + ) |
| 178 | + path1 = replace(path0, first_ip=IPy.IP("::1:1"), last_ip=IPy.IP("::1:ffff")) |
| 179 | + path2 = replace(path0, first_ip=IPy.IP("::2:1"), last_ip=IPy.IP("::2:ffff"), group_name="different") |
| 180 | + path3 = replace(path0, first_ip=IPy.IP("::3:1"), last_ip=IPy.IP("::3:ffff"), allocation_type="pool") |
| 181 | + path4 = replace(path0, first_ip=IPy.IP("::4:1"), last_ip=IPy.IP("::4:ffff"), server_name="different") |
| 182 | + path5 = replace(path0, first_ip=IPy.IP("0.0.5.1"), last_ip=IPy.IP("0.0.5.255"), ip_version=4) |
| 183 | + assert sorted(group_paths([path0, path1, path2, path3, path4, path5])) == sorted([[path0, path1], [path2], [path3], [path4], [path5]]) |
| 184 | + |
| 185 | + |
| 186 | +def test_group_paths_should_group_custom_groups_paths_separately_when_other_than_ip_addresses_differ(): |
| 187 | + path0 = DhcpPath( |
| 188 | + ip_version=6, |
| 189 | + server_name="server1", |
| 190 | + allocation_type="range", |
| 191 | + group_name="group1", |
| 192 | + group_name_source="custom_groups", |
| 193 | + first_ip=IPy.IP("::1"), |
| 194 | + last_ip=IPy.IP("::ff"), |
| 195 | + ) |
| 196 | + path1 = replace(path0, group_name="different") |
| 197 | + path2 = replace(path0, server_name="different") |
| 198 | + path3 = replace(path0, allocation_type="subnet") |
| 199 | + path4 = replace(path0, first_ip=IPy.IP("0.0.0.1"), last_ip=IPy.IP("0.0.0.255"), ip_version=4) |
| 200 | + assert sorted(group_paths([path0, path1, path2, path3, path4])) == sorted([[path0], [path1], [path2], [path3], [path4]]) |
| 201 | + |
| 202 | +@pytest.mark.parametrize( |
| 203 | + "prefixes,test_input,expected_output", |
| 204 | + [ |
| 205 | + ( |
| 206 | + [IPy.IP("0.0.0.0/0")], |
| 207 | + [ |
| 208 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_0.1_1_252_12.foo", # Inside |
| 209 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_64.1_1_252_127.foo", # Inside |
| 210 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_253_1.1_1_253_8.foo", # Inside |
| 211 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_254_0.1_1_254_15.foo", # Inside |
| 212 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_100_0.1_1_101_0.foo", # Inside |
| 213 | + "nav.dhcp.4.server1.range.custom_groups.group3.1_1_100_0.1_1_101_0.foo", # Inside |
| 214 | + "nav.dhcp.4.server2.range.custom_groups.group1.1_1_100_0.1_1_101_0.foo", # Inside |
| 215 | + "nav.dhcp.4.server2.range.custom_groups.group2.1_1_254_0.1_1_254_15.foo", # Inside |
| 216 | + "nav.dhcp.4.server2.range.custom_groups.group3.1_1_253_1.1_1_253_8.foo", # Inside |
| 217 | + "nav.dhcp.4.server3.range.custom_groups.group1.1_1_250_1.1_1_255_1.foo", # Inside |
| 218 | + "nav.dhcp.4.server4.range.custom_groups.group1.1_1_253_1.1_1_255_1.foo", # Inside |
| 219 | + "nav.dhcp.4.server5.range.custom_groups.group1.1_1_250_1.1_1_253_1.foo", # Inside |
| 220 | + ], |
| 221 | + [ |
| 222 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_0.1_1_252_12.foo", # Inside |
| 223 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_64.1_1_252_127.foo", # Inside |
| 224 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_253_1.1_1_253_8.foo", # Inside |
| 225 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_254_0.1_1_254_15.foo", # Inside |
| 226 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_100_0.1_1_101_0.foo", # Inside |
| 227 | + "nav.dhcp.4.server1.range.custom_groups.group3.1_1_100_0.1_1_101_0.foo", # Inside |
| 228 | + "nav.dhcp.4.server2.range.custom_groups.group1.1_1_100_0.1_1_101_0.foo", # Inside |
| 229 | + "nav.dhcp.4.server2.range.custom_groups.group2.1_1_254_0.1_1_254_15.foo", # Inside |
| 230 | + "nav.dhcp.4.server2.range.custom_groups.group3.1_1_253_1.1_1_253_8.foo", # Inside |
| 231 | + "nav.dhcp.4.server3.range.custom_groups.group1.1_1_250_1.1_1_255_1.foo", # Inside |
| 232 | + "nav.dhcp.4.server4.range.custom_groups.group1.1_1_253_1.1_1_255_1.foo", # Inside |
| 233 | + "nav.dhcp.4.server5.range.custom_groups.group1.1_1_250_1.1_1_253_1.foo", # Inside |
| 234 | + ], |
| 235 | + ), |
| 236 | + ( |
| 237 | + [IPy.IP("1.1.252.0/24"), IPy.IP("1.1.253.0/24")], |
| 238 | + [ |
| 239 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_0.1_1_252_12.foo", # Inside |
| 240 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_64.1_1_252_127.foo", # Inside |
| 241 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_253_1.1_1_253_8.foo", # Inside |
| 242 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_254_0.1_1_254_15.foo", # Another path in the group is inside |
| 243 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_100_0.1_1_101_0.foo", # Another path in the group is inside |
| 244 | + "nav.dhcp.4.server1.range.custom_groups.group3.1_1_100_0.1_1_101_0.foo", # Outside |
| 245 | + "nav.dhcp.4.server2.range.custom_groups.group1.1_1_100_0.1_1_101_0.foo", # Outside |
| 246 | + "nav.dhcp.4.server2.range.custom_groups.group2.1_1_254_0.1_1_254_15.foo", # Outside |
| 247 | + "nav.dhcp.4.server2.range.custom_groups.group3.1_1_253_1.1_1_253_8.foo", # Inside |
| 248 | + "nav.dhcp.4.server3.range.custom_groups.group1.1_1_250_1.1_1_255_1.foo", # Partially Inside |
| 249 | + "nav.dhcp.4.server4.range.custom_groups.group1.1_1_253_1.1_1_255_1.foo", # Partially Inside |
| 250 | + "nav.dhcp.4.server5.range.custom_groups.group1.1_1_250_1.1_1_253_1.foo", # Partially Inside |
| 251 | + ], |
| 252 | + [ |
| 253 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_0.1_1_252_12.foo", # Inside |
| 254 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_64.1_1_252_127.foo", # Inside |
| 255 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_253_1.1_1_253_8.foo", # Inside |
| 256 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_254_0.1_1_254_15.foo", # Another path in the group is inside |
| 257 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_100_0.1_1_101_0.foo", # Another path in the group inside |
| 258 | + "nav.dhcp.4.server2.range.custom_groups.group3.1_1_253_1.1_1_253_8.foo", # Inside |
| 259 | + "nav.dhcp.4.server3.range.custom_groups.group1.1_1_250_1.1_1_255_1.foo", # Partially Inside |
| 260 | + "nav.dhcp.4.server4.range.custom_groups.group1.1_1_253_1.1_1_255_1.foo", # Partially Inside |
| 261 | + "nav.dhcp.4.server5.range.custom_groups.group1.1_1_250_1.1_1_253_1.foo", # Partially Inside |
| 262 | + ], |
| 263 | + ), |
| 264 | + ( |
| 265 | + [IPy.IP("1.1.252.0/24")], |
| 266 | + [ |
| 267 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_0.1_1_252_12.foo", # Inside |
| 268 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_64.1_1_252_127.foo", # Inside |
| 269 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_253_1.1_1_253_8.foo", # Outside |
| 270 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_254_0.1_1_254_15.foo", # Outside |
| 271 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_100_0.1_1_101_0.foo", # Outside |
| 272 | + "nav.dhcp.4.server1.range.custom_groups.group3.1_1_100_0.1_1_101_0.foo", # Outside |
| 273 | + "nav.dhcp.4.server2.range.custom_groups.group1.1_1_100_0.1_1_101_0.foo", # Outside |
| 274 | + "nav.dhcp.4.server2.range.custom_groups.group2.1_1_254_0.1_1_254_15.foo", # Outside |
| 275 | + "nav.dhcp.4.server2.range.custom_groups.group3.1_1_253_1.1_1_253_8.foo", # Outside |
| 276 | + "nav.dhcp.4.server3.range.custom_groups.group1.1_1_250_1.1_1_255_1.foo", # Partially Inside |
| 277 | + "nav.dhcp.4.server4.range.custom_groups.group1.1_1_253_1.1_1_255_1.foo", # Outside |
| 278 | + "nav.dhcp.4.server5.range.custom_groups.group1.1_1_250_1.1_1_253_1.foo", # Partially Inside |
| 279 | + ], |
| 280 | + [ |
| 281 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_0.1_1_252_12.foo", # Inside |
| 282 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_64.1_1_252_127.foo", # Inside |
| 283 | + "nav.dhcp.4.server3.range.custom_groups.group1.1_1_250_1.1_1_255_1.foo", # Partially Inside |
| 284 | + "nav.dhcp.4.server5.range.custom_groups.group1.1_1_250_1.1_1_253_1.foo", # Partially Inside |
| 285 | + ], |
| 286 | + ), |
| 287 | + ( |
| 288 | + [], |
| 289 | + [ |
| 290 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_0.1_1_252_12.foo", # Outside |
| 291 | + "nav.dhcp.4.server1.range.custom_groups.group1.1_1_252_64.1_1_252_127.foo", # Outside |
| 292 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_253_1.1_1_253_8.foo", # Outside |
| 293 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_254_0.1_1_254_15.foo", # Outside |
| 294 | + "nav.dhcp.4.server1.range.custom_groups.group2.1_1_100_0.1_1_101_0.foo", # Outside |
| 295 | + "nav.dhcp.4.server1.range.custom_groups.group3.1_1_100_0.1_1_101_0.foo", # Outside |
| 296 | + "nav.dhcp.4.server2.range.custom_groups.group1.1_1_100_0.1_1_101_0.foo", # Outside |
| 297 | + "nav.dhcp.4.server2.range.custom_groups.group2.1_1_254_0.1_1_254_15.foo", # Outside |
| 298 | + "nav.dhcp.4.server2.range.custom_groups.group3.1_1_253_1.1_1_253_8.foo", # Outside |
| 299 | + "nav.dhcp.4.server3.range.custom_groups.group1.1_1_250_1.1_1_255_1.foo", # Outside |
| 300 | + "nav.dhcp.4.server4.range.custom_groups.group1.1_1_253_1.1_1_255_1.foo", # Outside |
| 301 | + "nav.dhcp.4.server5.range.custom_groups.group1.1_1_250_1.1_1_253_1.foo", # Outside |
| 302 | + ], |
| 303 | + [], |
| 304 | + ) |
| 305 | + ] |
| 306 | +) |
| 307 | +def test_drop_groups_not_in_prefixes_should_work_as_expected(prefixes, test_input, expected_output): |
| 308 | + native_paths = [DhcpPath.from_graphite_path(path) for path in test_input] |
| 309 | + grouped_paths = group_paths(native_paths) |
| 310 | + remaining_grouped_paths = drop_groups_not_in_prefixes(grouped_paths, prefixes) |
| 311 | + remaining_graphite_paths = [path.to_graphite_path("foo") for path in chain.from_iterable(remaining_grouped_paths)] |
| 312 | + assert sorted(remaining_graphite_paths) == sorted(expected_output) |
0 commit comments