From 57d5f3a02e5373b78f500a41818f89f35f3a69b5 Mon Sep 17 00:00:00 2001 From: jurraca Date: Sat, 1 Feb 2025 15:34:11 +0000 Subject: [PATCH] Add ASN tie breaks tests Test fallbacks based on valid_until, valid_since, and lower ASN if both timestamps match. Also fix duplicates in main roa parse test and remove counts assertions. --- tests/data/rpki_raw.csv | 28 +++++++++++------- tests/test_rpki_parser.py | 62 +++++++++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 26 deletions(-) diff --git a/tests/data/rpki_raw.csv b/tests/data/rpki_raw.csv index 13af26e..97de28d 100644 --- a/tests/data/rpki_raw.csv +++ b/tests/data/rpki_raw.csv @@ -1,12 +1,18 @@ aia,aki,cert_issuer,cert_serial,error,file,hash_id,sia,signing_time,ski,type,valid_since,valid_until,validation,prefix,asid,maxlen,test_case -rsync://rpki.arin.net/repository/arin-rpki-ta/1.cer,86:A9:90:76:61:0E:7C:08:AE:DD:CE:87:67:AA:5D:C4:52:8C:49:08,/CN=8f6916d463bfc5c35e4659c12889a337f3cc6f6b7fe978372b,2A789934ED3D1853C03BA192AFF9CBBE2A44E891,unable to get local issuer certificate,/home/kartograf/data/1730210400/rpki/cache/rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/1.roa,jJJsAMYzGpr8h9jrBTHvkZWOWQcbQsY6KFav/8MwBC4=,rsync://rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/1.roa,1721069362,C4:F5:41:EE:72:30:C9:A4:9E:76:FD:FB:C7:85:FE:C7:2B:EE:E6:CA,roa,1721069062,1752518962,OK,2602:fd60:11::/48,49134,48,valid -rsync://rpki.arin.net/repository/arin-rpki-ta/2,86:A9:90:76:61:0E:7C:08:AE:DD:CE:87:67:AA:5D:C4:52:8C:49:08,/CN=8f6916d463bfc5c35e4659c12889a337f3cc6f6b7fe978372b,618746799E365F8F63A3CAB2A372ABE6816EC3F6,unable to get local issuer certificate,/home/kartograf/data/1730210400/rpki/cache/rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/2.roa,JrIkZRssmOONk/CBI9A9neb6L4O1efvsso1ar/lUbHQ=,rsync://rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/2.roa,1721069361,5A:89:FE:EA:7D:A9:81:96:46:49:C5:25:07:37:B5:F4:AA:A5:96:91,roa,1721069061,1752518961,OK,2602:fd60::/44,396503,44,valid -rsync://rpki.arin.net/repository/arin-rpki-ta/3.cer,86:A9:90:76:61:0E:7C:08:AE:DD:CE:87:67:AA:5D:C4:52:8C:49:08,/CN=8f6916d463bfc5c35e4659c12889a337f3cc6f6b7fe978372b,4973C3937B8453A08847D3B995C1CA41BA28D153,unable to get local issuer certificate,/home/kartograf/data/1730210400/rpki/cache/rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/3.roa,18oKgF1Or7jXF1G/gggLM4BHgRLPSPi64hFZ2Z8UHk8=,rsync://rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/3.roa,1706756675,88:21:48:93:4E:7A:2C:6C:6F:F0:D2:0B:7B:3D:D2:BC:DA:80:84:4D,roa,1706756375,1738206275,OK,158.51.113.0/24,23470,24,valid -rsync://rpki.arin.net/repository/arin-rpki-ta/4.cer,86:A9:90:76:61:0E:7C:08:AE:DD:CE:87:67:AA:5D:C4:52:8C:49:08,/CN=8f6916d463bfc5c35e4659c12889a337f3cc6f6b7fe978372b,6BE1ADC656C88D467CBF06BB2E890B95BCA0B24E,unable to get local issuer certificate,/home/kartograf/data/1730210400/rpki/cache/rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/4.roa,EhQRnwfEIqL4rpYQmSzoByvQElLITMmNQmilR4MYPc4=,rsync://rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/4.roa,1721069361,DB:B0:C0:44:5D:A4:86:C2:55:E2:07:55:EE:30:85:E6:CB:59:31:84,roa,1721069061,1752518961,OK,2602:fd60:ff0::/48,137908,48,valid -rsync://rpki.arin.net/repository/arin-rpki-ta/5.cer,86:A9:90:76:61:0E:7C:08:AE:DD:CE:87:67:AA:5D:C4:52:8C:49:08,/CN=8f6916d463bfc5c35e4659c12889a337f3cc6f6b7fe978372b,45D9858BC753770DD894B50587AF74A5D61E238C,unable to get local issuer certificate,/home/kartograf/data/1730210400/rpki/cache/rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/5.roa,9BdIkUhCxm4K663U7LFp/tM71Hq0nDVSFP6NvT0pngQ=,rsync://rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/5.roa,1702699880,CF:BC:73:EE:A3:DB:A2:5E:7A:2B:AE:DF:2D:AE:0E:6E:89:70:1D:69,roa,1702699580,1734149480,OK,2602:fd60:e::/48,396503,48,valid -rsync://rpki.arin.net/repository/arin-rpki-ta/6.cer,86:A9:90:76:61:0E:7C:08:AE:DD:CE:87:67:AA:5D:C4:52:8C:49:08,/CN=8f6916d463bfc5c35e4659c12889a337f3cc6f6b7fe978372b,2AEA9B91583807D0CBBA0C4F0998FC56E89AAE7F,unable to get local issuer certificate,/home/kartograf/data/1730210400/rpki/cache/rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/6.roa,TAHubY+7GFPqIJIlhlmcQzM/eqNRhS0m4z1pEbe1cmQ=,rsync://rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/6.roa,1725124096,C0:F1:6A:8D:95:BE:AB:A0:96:A3:9C:04:02:65:8A:7D:9E:DE:EE:C4,roa,1725123796,1756573696,OK,2602:fd60:7::/48,396503,48,valid -rsync://rpki.arin.net/repository/arin-rpki-ta/7.cer,86:A9:90:76:61:0E:7C:08:AE:DD:CE:87:67:AA:5D:C4:52:8C:49:08,/CN=8f6916d463bfc5c35e4659c12889a337f3cc6f6b7fe978372b,2AEA9B91583807D0CBBA0C4F0998FC56E89AAE7F,unable to get local issuer certificate,/home/kartograf/data/1730210400/rpki/cache/rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/7.roa,TAHubY+7GFPqIJIlhlmcQzM/eqNRhS0m4z1pEbe1cmQ=,rsync://rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/7.roa,1725124096,C0:F1:6A:8D:95:BE:AB:A0:96:A3:9C:04:02:65:8A:7D:9E:DE:EE:C4,roa,1725123796,1756573696,OK,2602:fd60:7::/48,396503,48,duplicate of row above -rsync://rpki.arin.net/repository/arin-rpki-ta/8.cer,86:A9:90:76:61:0E:7C:08:AE:DD:CE:87:67:AA:5D:C4:52:8C:49:08,/CN=8f6916d463bfc5c35e4659c12889a337f3cc6f6b7fe978372b,775EA3FF97551B8DAB1870EE20B90C6D38AFE3F3,unable to get local issuer certificate,/home/kartograf/data/1730210400/rpki/cache/rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/8.roa,7pPxkgwX/p8qZcZ4U4B6r43qRmLaDzJ9eipWTWYXVgQ=,rsync://rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/8.roa,1702699880,98:23:C0:CD:73:C0:73:4B:88:4C:8E:A2:FE:FC:94:59:27:54:FC:CF,roa,1702699580,1734149480,OK,23.154.81.0/24,53356,24,valid -rsync://rpki.arin.net/repository/arin-rpki-ta/9.cer,86:A9:90:76:61:0E:7C:08:AE:DD:CE:87:67:AA:5D:C4:52:8C:49:08,/CN=8f6916d463bfc5c35e4659c12889a337f3cc6f6b7fe978372b,66D4203E6D324EDF7DB13F151CE102BE0DBE1200,unable to get local issuer certificate,/home/kartograf/data/1730210400/rpki/cache/rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/9.roa,Wfz/lTUfLoaYSWzIWHHqfxFY68pwclupNoh7qMD/dy4=,rsync://rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/9.roa,1721069363,EF:A6:FD:C7:47:52:EA:52:97:81:CB:E6:BC:08:E1:89:74:01:CE:54,roa,1721069063,1752518963,OK,23.154.81.0/24,396503,24,duplicate of row above -rsync://rpki.arin.net/repository/arin-rpki-ta/10.cer,86:A9:90:76:61:0E:7C:08:AE:DD:CE:87:67:AA:5D:C4:52:8C:49:08,/CN=8f6916d463bfc5c35e4659c12889a337f3cc6f6b7fe978372b,35802871A8C539AD5A498BEDDDEF0D3F70E27D85,unable to get local issuer certificate,/home/kartograf/data/1730210400/rpki/cache/rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/10.roa,5DOfCcd4V1zI0oWAJNiXnZVa/zwdfo+24eD0OBlrFy4=,rsync://rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/10.roa,1721921309,BA:47:CE:B1:56:FB:2F:78:B5:37:B4:63:10:F4:17:1F:BB:2C:6A:FB,err,1721921009,1753370909,OK,23.154.80.0/24,213186,24,type is not “roa” -rsync://rpki.arin.net/repository/arin-rpki-ta/11.cer,86:A9:90:76:61:0E:7C:08:AE:DD:CE:87:67:AA:5D:C4:52:8C:49:08,/CN=8f6916d463bfc5c35e4659c12889a337f3cc6f6b7fe978372b,77C98DB3245AF48F037FF77D087EB06EC63AAC8D,unable to get local issuer certificate,/home/kartograf/data/1730210400/rpki/cache/rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/11.roa,/pHsoAr4Krm+kx64aCsYjFRuk+JnfbiC6JA9UWV27TQ=,rsync://rpki.tools.westconnect.ca/repo/WestConnect-Pub/0/11.roa,1721069362,C5:65:B7:B3:AA:F9:59:32:0B:F5:50:24:70:01:09:71:4D:FC:20:24,roa,1721069062,1752518962,Failed,158.51.112.0/24,396503,24,failed validation +rsync://rpki.arin.net/repository/arin-rpki-ta/1.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/1.roa,1111111111,A1:B1:C1,roa,1721069062,1752518962,OK,2602:fd60:11::/48,49134,48,valid +rsync://rpki.arin.net/repository/arin-rpki-ta/2,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/1.roa,1111111111,A1:B1:C1,roa,1721069061,1752518961,OK,2602:fd60::/44,396503,44,valid +rsync://rpki.arin.net/repository/arin-rpki-ta/3.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/1.roa,1111111111,A1:B1:C1,roa,1706756375,1738206275,OK,158.51.113.0/24,23470,24,valid +rsync://rpki.arin.net/repository/arin-rpki-ta/4.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/1.roa,1111111111,A1:B1:C1,roa,1721069061,1752518961,OK,2602:fd60:ff0::/48,137908,48,valid +rsync://rpki.arin.net/repository/arin-rpki-ta/5.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/1.roa,1111111111,A1:B1:C1,roa,1702699580,1734149480,OK,2602:fd60:e::/48,396503,48,valid +rsync://rpki.arin.net/repository/arin-rpki-ta/6.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/1.roa,1111111111,A1:B1:C1,roa,1725123796,1756573696,OK,2602:fd60:7::/48,396503,48,valid +rsync://rpki.arin.net/repository/arin-rpki-ta/7.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/1.roa,1111111111,A1:B1:C1,roa,1725123796,1756573696,OK,2602:fd60:7::/48,396503,48,duplicate of row above +rsync://rpki.arin.net/repository/arin-rpki-ta/8.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/1.roa,1111111111,A1:B1:C1,roa,1702699580,1734149480,OK,23.154.81.0/24,53356,24,valid +rsync://rpki.arin.net/repository/arin-rpki-ta/9.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/1.roa,1111111111,A1:B1:C1,roa,1721069063,1752518963,OK,23.154.81.0/24,396503,24,duplicate of row above +rsync://rpki.arin.net/repository/arin-rpki-ta/10.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/1.roa,1111111111,A1:B1:C1,err,1721921009,1753370909,OK,23.154.80.0/24,213186,24,type is not “roa” +rsync://rpki.arin.net/repository/arin-rpki-ta/11.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/1.roa,1111111111,A1:B1:C1,roa,1721069062,1752518962,Failed,158.51.112.0/24,396503,24,failed validation +rsync://rpki.arin.net/repository/arin-rpki-ta/12.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/1.roa,1111111111,A1:B1:C1,roa,1111111000,1111112000,OK,101.0.1.0/24,11101,24,earlier validity +rsync://rpki.arin.net/repository/arin-rpki-ta/13.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/2.roa,2222222222,A2:B2:C2,roa,2222222000,2222223000,OK,101.0.1.0/24,11102,24,later validity wins +rsync://rpki.arin.net/repository/arin-rpki-ta/14.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/3.roa,3333333333,A3:B3:C3,roa,3333333000,3333334000,OK,102.0.100.0/24,11103,24,same valid_until earlier valid_since +rsync://rpki.arin.net/repository/arin-rpki-ta/15.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/4.roa,4444444444,A4:B4:C4,roa,3333333100,3333334000,OK,102.0.100.0/24,11104,24,same valid_until later valid_since wins +rsync://rpki.arin.net/repository/arin-rpki-ta/16.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/5.roa,5555555555,A5:B5:C5,roa,4444444000,4444445000,OK,103.0.1.0/24,11105,24,same timestamps higher ASN +rsync://rpki.arin.net/repository/arin-rpki-ta/17.cer,1:1:1:1,/CN=Test1,1111,none,/test1.roa,hash1,rsync://rpki.example.net/6.roa,6666666666,A6:B6:C6,roa,4444444000,4444445000,OK,103.0.1.0/24,11106,24,same timestamps lower ASN wins diff --git a/tests/test_rpki_parser.py b/tests/test_rpki_parser.py index d51543d..8f0f8a0 100644 --- a/tests/test_rpki_parser.py +++ b/tests/test_rpki_parser.py @@ -3,7 +3,6 @@ from kartograf.rpki.parse import parse_rpki from .context import create_test_context -from .util.helpers import flatten def prefixes_from_vrps(vrps): @@ -30,24 +29,15 @@ def test_roa_validations(tmp_path, capsys): final_path = os.path.join(context.out_dir_rpki, "rpki_final.txt") assert os.path.exists(final_path), "rpki_final.txt should exist" - # Read the raw JSON to compare counts - with open(os.path.join(context.out_dir_rpki, "rpki_raw.json"), "r") as f: - raw_data = json.load(f) - # Count entries in final output with open(final_path, "r") as f: - final_lines = f.readlines() - - # Count of duplicates should be the count of final output minus the count - # of unique prefixes in the raw data - prefixes = [prefixes_from_vrps(roa['vrps']) for roa in raw_data] - duplicates = len(set(flatten(prefixes))) - len(final_lines) + final_lines = [line.strip() for line in f.readlines()] captured = capsys.readouterr() - assert len(final_lines) == 7, "Should have found 7 valid ROAs" - assert duplicates == 2, "Should have found 2 duplicates" - assert "Result entries written: 7" in captured.out - assert "Duplicates found: 2" in captured.out + + assert len(final_lines) == 10, "Should have found 10 valid ROAs" + assert "Result entries written: 10" in captured.out + assert "Duplicates found: 5" in captured.out assert "Invalids found: 1" in captured.out assert "Incompletes: 0" in captured.out assert "Non-ROA files: 1" in captured.out @@ -95,3 +85,45 @@ def test_roa_incompletes(tmp_path, capsys): assert len(final_lines) == 0, "No rows should be written" captured = capsys.readouterr() assert "Incompletes: 2" in captured.out + + +def test_roa_valid_until_fallback(tmp_path): + '''Test ROA selection falls back to later valid_until''' + epoch = "111111111" + context = create_test_context(tmp_path, epoch) + parse_rpki(context) + + final_path = os.path.join(context.out_dir_rpki, "rpki_final.txt") + with open(final_path, "r") as f: + entries = [line.strip() for line in f.readlines()] + + assert "101.0.1.0/24 AS11102" in entries, "ROA with later valid_until should be selected" + assert not any("101.0.1.0/24 AS11101" in e for e in entries), "ROA with earlier valid_until should not be selected" + + +def test_roa_valid_since_fallback(tmp_path): + '''Test ROA selection falls back to later valid_since when valid_until matches''' + epoch = "111111111" + context = create_test_context(tmp_path, epoch) + parse_rpki(context) + + final_path = os.path.join(context.out_dir_rpki, "rpki_final.txt") + with open(final_path, "r") as f: + entries = [line.strip() for line in f.readlines()] + + assert "102.0.100.0/24 AS11104" in entries, "ROA with later valid_since should be selected" + assert not any("102.0.100.0/24 AS11103" in e for e in entries), "ROA with earlier valid_since should not be selected" + + +def test_roa_asn_fallback(tmp_path): + '''Test ROA selection falls back to lower ASN when timestamps match''' + epoch = "111111111" + context = create_test_context(tmp_path, epoch) + parse_rpki(context) + + final_path = os.path.join(context.out_dir_rpki, "rpki_final.txt") + with open(final_path, "r") as f: + entries = [line.strip() for line in f.readlines()] + + assert "103.0.1.0/24 AS11105" in entries, "ROA with lower ASN should be selected" + assert not any("103.0.1.0/24 AS11106" in e for e in entries), "ROA with higher ASN should not be selected"