Skip to content

Commit d431d22

Browse files
test(ip-recognizer): add ::1 loopback and mixed :: / ::1 test cases (#1940)
* test(ip-recognizer): add ::1 loopback and mixed :: / ::1 test cases After #1941 added IPv6_loopback pattern, these tests verify: - ::1 (loopback) is detected at 0.6 score, not confused with bare :: - bare :: and ::1 coexisting in one string each match independently * test(ip-recognizer): normalize result ordering in assertions Signed-off-by: Extra Small <littleshuai.bot@gmail.com> --------- Signed-off-by: Extra Small <littleshuai.bot@gmail.com> Co-authored-by: extrasmall0 <extrasmall0@users.noreply.github.com> Co-authored-by: Sharon Hart <sharonh.dev@gmail.com>
1 parent c14d9d8 commit d431d22

1 file changed

Lines changed: 56 additions & 88 deletions

File tree

presidio-analyzer/tests/test_ip_recognizer.py

Lines changed: 56 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,24 @@ def entities():
1414
return ["IP_ADDRESS"]
1515

1616

17+
def assert_results_match(
18+
results,
19+
expected_positions,
20+
expected_score_ranges,
21+
entities,
22+
max_score,
23+
):
24+
ordered_results = sorted(results, key=lambda result: (result.start, result.end))
25+
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
26+
ordered_results, expected_positions, expected_score_ranges
27+
):
28+
if fn_score == "max":
29+
fn_score = max_score
30+
assert_result_within_score_range(
31+
res, entities[0], st_pos, fn_pos, st_score, fn_score
32+
)
33+
34+
1735
@pytest.mark.parametrize(
1836
"text, expected_len, expected_positions, expected_score_ranges",
1937
[
@@ -29,6 +47,11 @@ def entities():
2947
("2345:0425:2CA1::0567:5673:23b5", 1, (), (),),
3048
("2400:c401::5054:ff:fe1b:b031", 1, (), (),),
3149
("Use local ipv6 ::", 1, ((15, 17),), ((0.05, 0.15),),),
50+
# IPv6 loopback (::1) should match at high confidence
51+
("my ip: ::1", 1, ((7, 10),), ((0.6, 0.81),),),
52+
("connecting from ::1", 1, ((16, 19),), ((0.6, 0.81),),),
53+
# bare :: and ::1 in same string should each match once
54+
("src=:: dst=::1", 2, ((4, 6), (11, 14)), ((0.05, 0.15), (0.6, 0.81)),),
3255
# fmt: on
3356
],
3457
)
@@ -43,14 +66,9 @@ def test_when_all_ips_then_succeed(
4366
):
4467
results = recognizer.analyze(text, entities)
4568
assert len(results) == expected_len
46-
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
47-
results, expected_positions, expected_score_ranges
48-
):
49-
if fn_score == "max":
50-
fn_score = max_score
51-
assert_result_within_score_range(
52-
res, entities[0], st_pos, fn_pos, st_score, fn_score
53-
)
69+
assert_results_match(
70+
results, expected_positions, expected_score_ranges, entities, max_score
71+
)
5472

5573

5674
@pytest.mark.parametrize(
@@ -77,14 +95,9 @@ def test_when_ipv6_compression_then_succeed(
7795
):
7896
results = recognizer.analyze(text, entities)
7997
assert len(results) == expected_len
80-
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
81-
results, expected_positions, expected_score_ranges
82-
):
83-
if fn_score == "max":
84-
fn_score = max_score
85-
assert_result_within_score_range(
86-
res, entities[0], st_pos, fn_pos, st_score, fn_score
87-
)
98+
assert_results_match(
99+
results, expected_positions, expected_score_ranges, entities, max_score
100+
)
88101

89102

90103
@pytest.mark.parametrize(
@@ -112,14 +125,9 @@ def test_when_ipv6_in_context_then_succeed(
112125
):
113126
results = recognizer.analyze(text, entities)
114127
assert len(results) == expected_len
115-
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
116-
results, expected_positions, expected_score_ranges
117-
):
118-
if fn_score == "max":
119-
fn_score = max_score
120-
assert_result_within_score_range(
121-
res, entities[0], st_pos, fn_pos, st_score, fn_score
122-
)
128+
assert_results_match(
129+
results, expected_positions, expected_score_ranges, entities, max_score
130+
)
123131

124132

125133
@pytest.mark.parametrize(
@@ -162,14 +170,9 @@ def test_when_ipv4_mapped_then_full_span_redacted(
162170
):
163171
results = recognizer.analyze(text, entities)
164172
assert len(results) == expected_len
165-
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
166-
results, expected_positions, expected_score_ranges
167-
):
168-
if fn_score == "max":
169-
fn_score = max_score
170-
assert_result_within_score_range(
171-
res, entities[0], st_pos, fn_pos, st_score, fn_score
172-
)
173+
assert_results_match(
174+
results, expected_positions, expected_score_ranges, entities, max_score
175+
)
173176

174177

175178
@pytest.mark.parametrize(
@@ -205,14 +208,9 @@ def test_when_ipv4_embedded_then_full_span_redacted(
205208
):
206209
results = recognizer.analyze(text, entities)
207210
assert len(results) == expected_len
208-
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
209-
results, expected_positions, expected_score_ranges
210-
):
211-
if fn_score == "max":
212-
fn_score = max_score
213-
assert_result_within_score_range(
214-
res, entities[0], st_pos, fn_pos, st_score, fn_score
215-
)
211+
assert_results_match(
212+
results, expected_positions, expected_score_ranges, entities, max_score
213+
)
216214

217215

218216
@pytest.mark.parametrize(
@@ -237,14 +235,9 @@ def test_when_multiple_ips_then_all_found(
237235
):
238236
results = recognizer.analyze(text, entities)
239237
assert len(results) == expected_len
240-
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
241-
results, expected_positions, expected_score_ranges
242-
):
243-
if fn_score == "max":
244-
fn_score = max_score
245-
assert_result_within_score_range(
246-
res, entities[0], st_pos, fn_pos, st_score, fn_score
247-
)
238+
assert_results_match(
239+
results, expected_positions, expected_score_ranges, entities, max_score
240+
)
248241

249242

250243
@pytest.mark.parametrize(
@@ -278,14 +271,9 @@ def test_when_non_ip_pattern_then_no_match(
278271
):
279272
results = recognizer.analyze(text, entities)
280273
assert len(results) == expected_len
281-
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
282-
results, expected_positions, expected_score_ranges
283-
):
284-
if fn_score == "max":
285-
fn_score = max_score
286-
assert_result_within_score_range(
287-
res, entities[0], st_pos, fn_pos, st_score, fn_score
288-
)
274+
assert_results_match(
275+
results, expected_positions, expected_score_ranges, entities, max_score
276+
)
289277

290278

291279
@pytest.mark.parametrize(
@@ -321,14 +309,9 @@ def test_when_ip_at_boundary_then_correct_span(
321309
):
322310
results = recognizer.analyze(text, entities)
323311
assert len(results) == expected_len
324-
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
325-
results, expected_positions, expected_score_ranges
326-
):
327-
if fn_score == "max":
328-
fn_score = max_score
329-
assert_result_within_score_range(
330-
res, entities[0], st_pos, fn_pos, st_score, fn_score
331-
)
312+
assert_results_match(
313+
results, expected_positions, expected_score_ranges, entities, max_score
314+
)
332315

333316

334317
@pytest.mark.parametrize(
@@ -364,14 +347,9 @@ def test_when_invalid_ip_then_no_match(
364347
):
365348
results = recognizer.analyze(text, entities)
366349
assert len(results) == expected_len
367-
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
368-
results, expected_positions, expected_score_ranges
369-
):
370-
if fn_score == "max":
371-
fn_score = max_score
372-
assert_result_within_score_range(
373-
res, entities[0], st_pos, fn_pos, st_score, fn_score
374-
)
350+
assert_results_match(
351+
results, expected_positions, expected_score_ranges, entities, max_score
352+
)
375353

376354

377355
@pytest.mark.parametrize(
@@ -403,14 +381,9 @@ def test_when_special_ip_variants_then_succeed(
403381
):
404382
results = recognizer.analyze(text, entities)
405383
assert len(results) == expected_len
406-
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
407-
results, expected_positions, expected_score_ranges
408-
):
409-
if fn_score == "max":
410-
fn_score = max_score
411-
assert_result_within_score_range(
412-
res, entities[0], st_pos, fn_pos, st_score, fn_score
413-
)
384+
assert_results_match(
385+
results, expected_positions, expected_score_ranges, entities, max_score
386+
)
414387

415388

416389
@pytest.mark.parametrize(
@@ -457,11 +430,6 @@ def test_when_cidr_notation_then_largest_span_redacted(
457430
):
458431
results = recognizer.analyze(text, entities)
459432
assert len(results) == expected_len
460-
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
461-
results, expected_positions, expected_score_ranges
462-
):
463-
if fn_score == "max":
464-
fn_score = max_score
465-
assert_result_within_score_range(
466-
res, entities[0], st_pos, fn_pos, st_score, fn_score
467-
)
433+
assert_results_match(
434+
results, expected_positions, expected_score_ranges, entities, max_score
435+
)

0 commit comments

Comments
 (0)