1
0
mirror of https://github.com/peeringdb/peeringdb.git synced 2024-05-11 05:55:09 +00:00
Files
peeringdb-peeringdb/tests/test_validators.py
Matt Griswold ea55c4dc38 July updates (#762)
* Change label from primary ASN to ASN

* Raise validation error when trying to update ASN

* first steps for dotf importer procotol (#697)

* migrations (#697)

* Add translation to error meessage

* Make ASN readonly in table

* Add test now that ASN should not be able to update

* Set fac.rencode to '' for all entries and make it readonly in serializer

* Add unique constraints to network ixlan ip addresses

* Add migration to null out duplicate ipaddresses for deleted netixlans

* Add unique constraints to network ixlan ip addresses

* Add migration to null out duplicate ipaddresses for deleted netixlans

* remove old migrations (#697)

* fix netixlan ipaddr dedupe migration (#268)
add netixlan ipaddr unique constraint migration (#268)

* ixf_member_data migrations (#697)

* fix table name (#697)

* importer protocol (#697)

* fix netixlan ipaddr dedupe migration (#268)
add netixlan ipaddr unique constraint migration (#268)

* ixf proposed changes notifications (#697)

* Delete repeated query

* Add a test to show rencode is readonly

* Blank out rencode when mocking data

* Remove validator now that constraint exists

* Add back unique field validator w Check Deleted true

* conflict resolving (#697)

* UniqueFieldValidator raise error with code "unique" (#268)

* conflict resolution (#697)

* Add fixme comment to tests

* conflict resolution (#697)

* Remove now invalid undelete tests

* UniqueFieldValidator raise error with code "unique" (#268)

* delete admin tools for duplicate ip addresses

* Make migration to delete duplicateipnetworkixlan

* Add ixlan-ixpfx status matching validation, add corresponding test

* delete redundant checking in test

* resolve conflict ui (#697)

* fix migrations hierarchy

* squash migrations for ixf member data

* clean up preview and post-mortem tools

* remove non-sensical permission check when undeleting soft-deleted objects through unique integrity error handling

* only include the ix-f data url in notifications to admincom (#697)

* resolve on --skip-import (#697)

* ac conflict resolution (#697)

* Define more accurately the incompatible statuses for ixlan and ixpfx

* Add another status test

* Preventing disrupting changes (#697)

* fix tests (#697)

* Stop allow_ixp_update from being write only and add a global stat for automated networks

* Add tests for global stats that appear in footer

* Change how timezone is called with datetime, to get test_stats.py/test_generate_for_current_date to pass

* test for protected entities (#697)

* admincom conflict resolution refine readonly fields (#697)
network notifications only if the problem is actually actionable by the network (#697)

* ixp / ac notifcation when ix-f source cannot be parsed (#697)
fix issue with ixlan prefix protection (#697)

* migrations (#697)

* code documentation (#697)

* ux tweaks (#697)

* UX tweaks (#697)

* Fix typo

* fix netixlan returned in IXFMemberData.apply when adding a new one (#697)

* fix import log incosistencies (#697)

* Add IXFMemberData to test

* Update test data

* Add protocol tests

* Add tests for views

* always persist changes to remote data on set_conflict (#697)

* More tests

* always persist changes to remote data on set_conflict (#697)

* suggest-add test

* net_present_at_ix should check status (#697)

* Add more protocol tests

* Edit language of some tests

* django-peeringdb to 2.1.1
relock pipfile, pin django-ratelimit to <3 as it breaks stuff

* Add net_count_ixf field to ix object (#683)

* Add the IX-F Member Export URL to the ixlan API endpoint (#249)

* Lock some objects from being deleted by the owner (#696)

* regenerate api docs (#249)

* always persist changes to remote data on set_add and set_update (#697)

* IXFMemberData: always persist remote data changes during set_add and set_update, also allow for saving without touching the updated field

* always persist changes to remote data on set_add and set_update (#697)

* Fix suggest-add tests

* IXFMemberData: always persist remote data changes during set_add and set_update, also allow for saving without touching the updated field

* IXFMemberData: always persist remote data changes during set_add and set_update, also allow for saving without touching the updated field

* fix issue with deletion when ixfmemberdata for entry existed previously (#697)

* fix test_suggest_delete_local_ixf_no_flag (#697 tests)

* fix issue with deletion when ixfmemberdata for entry existed previously (#697)

* invalid ips get logged and notified to the ix via notify_error (#697)

* Fix more tests

* issue with previous_data when running without save (#697)
properly track speed errors (#697)

* reset errors on ixfmemberdata that go into pending_save (#697)

* add remote_data to admin view (#697)

* fix error reset inconsistency (#697)

* Refine invalid data tests

* remove debug output

* for notifications to ac include contact points for net and ix in the message (#697)

* settings to toggle ix-f tickets / emails (#697)

* allow turning off ix-f notifications for net and ix separately (#697)

* add jsonschema test

* Add idempotent tests to updater

* remove old ixf member tests

* Invalid data tests when ixp_updates are enabled

* fix speed error validation (#697)

* fix issue with rollback (#697)

* fix migration hierarchy

* fix ixfmemberdata _email

* django-peeringdb to 2.2 and relock

* add ixf rollback tests

* ixf email notifications off by default

* black formatted

* pyupgrade

Co-authored-by: egfrank <egfrank@20c.com>
Co-authored-by: Stefan Pratter <stefan@20c.com>
2020-07-15 07:07:01 +00:00

304 lines
8.0 KiB
Python

import ipaddress
import os
import pytest
import requests
from django.test import override_settings
from django.core.exceptions import ValidationError
from django.core.management import call_command
from peeringdb_server.validators import (
validate_address_space,
validate_info_prefixes4,
validate_info_prefixes6,
validate_prefix_overlap,
validate_phonenumber,
validate_irr_as_set,
)
from peeringdb_server.models import (
Organization,
InternetExchange,
IXLan,
IXLanPrefix,
Network,
NetworkContact,
Facility,
ProtectedAction,
)
pytestmark = pytest.mark.django_db
INVALID_ADDRESS_SPACES = [
"0.0.0.0/1",
"0.0.0.0/8",
"10.0.0.0/8",
"127.0.0.0/8",
"169.254.0.0/16",
# FIXME: this fails still
#'172.0.0.0/11',
"172.16.0.0/12",
"192.0.2.0/24",
"192.168.0.0/16",
"198.18.0.0/15",
"198.51.100.0/24",
"203.0.113.0/24",
# FIXME: this fails still
#'224.0.0.0/3',
"224.0.0.0/4",
"240.0.0.0/4",
"100.64.0.0/10",
"0000::/8",
"0064:ff9b::/96",
"0100::/8",
"0200::/7",
"0400::/6",
"0800::/5",
"1000::/4",
"2001::/33",
"2001:0:8000::/33",
"2001:0002::/48",
"2001:0003::/32",
"2001:10::/28",
"2001:20::/28",
"2001:db8::/32",
"2002::/16",
"3ffe::/16",
"4000::/2",
"4000::/3",
"5f00::/8",
"6000::/3",
"8000::/3",
"a000::/3",
"c000::/3",
"e000::/4",
"f000::/5",
"f800::/6",
"fc00::/7",
"fe80::/10",
"fec0::/10",
"ff00::/8",
]
@pytest.fixture(params=INVALID_ADDRESS_SPACES)
def prefix(request):
return request.param
# @pytest.mark.django_db
def test_validate_address_space(prefix):
"""
Tests peeringdb_server.validators.validate_address_space
"""
with pytest.raises(ValidationError) as exc:
validate_address_space(ipaddress.ip_network(str(prefix)))
@override_settings(DATA_QUALITY_MAX_PREFIX_V4_LIMIT=500000)
def test_validate_info_prefixes4():
"""
Tests peeringdb_server.validators.validate_info_prefixes4
"""
with pytest.raises(ValidationError):
validate_info_prefixes4(500001)
with pytest.raises(ValidationError):
validate_info_prefixes4(-1)
validate_info_prefixes4(500000)
assert validate_info_prefixes4(None) == 0
assert validate_info_prefixes4("") == 0
@override_settings(DATA_QUALITY_MAX_PREFIX_V6_LIMIT=500000)
def test_validate_info_prefixes6():
"""
Tests peeringdb_server.validators.validate_info_prefixes6
"""
with pytest.raises(ValidationError):
validate_info_prefixes6(500001)
with pytest.raises(ValidationError):
validate_info_prefixes6(-1)
validate_info_prefixes6(500000)
assert validate_info_prefixes6(None) == 0
assert validate_info_prefixes6("") == 0
@override_settings(
DATA_QUALITY_MIN_PREFIXLEN_V4=24,
DATA_QUALITY_MAX_PREFIXLEN_V4=24,
DATA_QUALITY_MIN_PREFIXLEN_V6=48,
DATA_QUALITY_MAX_PREFIXLEN_V6=48,
)
def test_validate_prefixlen():
"""
Tests prefix length limits
"""
with pytest.raises(ValidationError):
validate_address_space("37.77.32.0/20")
with pytest.raises(ValidationError):
validate_address_space("131.72.77.240/28")
with pytest.raises(ValidationError):
validate_address_space("2403:c240::/32")
with pytest.raises(ValidationError):
validate_address_space("2001:504:0:2::/64")
@pytest.mark.django_db
def test_validate_prefix_overlap():
org = Organization.objects.create(name="Test org", status="ok")
ix = InternetExchange.objects.create(name="Text exchange", status="ok", org=org)
ixlan = ix.ixlan
pfx1 = IXLanPrefix.objects.create(
ixlan=ixlan,
protocol="IPv4",
prefix=ipaddress.ip_network("198.32.125.0/24"),
status="ok",
)
with pytest.raises(ValidationError) as exc:
validate_prefix_overlap("198.32.124.0/23")
@pytest.mark.parametrize(
"value,validated",
[
# success validation
("RIPE::AS-FOO", "RIPE::AS-FOO"),
("AS-FOO@RIPE", "AS-FOO@RIPE"),
("AS-FOO-BAR@RIPE", "AS-FOO-BAR@RIPE"),
("ripe::as-foo", "RIPE::AS-FOO"),
("as-foo@ripe", "AS-FOO@RIPE"),
("as-foo@ripe as-bar@ripe", "AS-FOO@RIPE AS-BAR@RIPE"),
("as-foo@ripe,as-bar@ripe", "AS-FOO@RIPE AS-BAR@RIPE"),
("as-foo@ripe, as-bar@ripe", "AS-FOO@RIPE AS-BAR@RIPE"),
(
"RIPE::AS12345:AS-FOO RIPE::AS12345:AS-FOO:AS9876",
"RIPE::AS12345:AS-FOO RIPE::AS12345:AS-FOO:AS9876",
),
("ripe::as-foo:as123:as345", "RIPE::AS-FOO:AS123:AS345"),
("RIPE::AS12345", "RIPE::AS12345"),
("AS12345@RIPE", "AS12345@RIPE"),
("RIPE::AS123456:RS-FOO", "RIPE::AS123456:RS-FOO"),
("as-foo", "AS-FOO"),
("rs-foo", "RS-FOO"),
("as-foo as-bar", "AS-FOO AS-BAR"),
("rs-foo as-bar", "RS-FOO AS-BAR"),
("rs-foo rs-bar", "RS-FOO RS-BAR"),
("AS15562", "AS15562"),
("AS-15562", "AS-15562"),
("AS15562 AS33333", "AS15562 AS33333"),
# fail validation
("UNKNOWN::AS-FOO", False),
("AS-FOO@UNKNOWN", False),
("ASFOO@UNKNOWN", False),
("UNKNOWN::ASFOO", False),
("RIPE:AS-FOO", False),
("RIPE::RS15562:RS-FOO", False),
("RIPE::AS123456:RS-FOO:AS-FOO", False),
('!"*([])?.=+/\\', False),
('RIPE::!"*([])?.=+/\\', False),
('!"*([])?.=+/\\@RIPE', False),
# > DATA_QUALITY_MAX_IRR_DEPTH
("ripe::as-foo:as123:as345:as678", False),
],
)
def test_validate_irr_as_set(value, validated):
if not validated:
with pytest.raises(ValidationError):
validate_irr_as_set(value)
else:
assert validate_irr_as_set(value) == validated
@pytest.mark.django_db
def test_validate_phonenumber():
# test standalone validator
validate_phonenumber("+1 206 555 0199")
validate_phonenumber("012065550199", "US")
with pytest.raises(ValidationError):
validate_phonenumber("invalid number")
with pytest.raises(ValidationError):
validate_phonenumber("012065550199")
# test model field validation
org = Organization.objects.create(name="Test org", status="ok")
ix = InternetExchange.objects.create(
name="Text exchange",
status="ok",
org=org,
country="US",
city="Some city",
region_continent="North America",
media="Ethernet",
)
net = Network.objects.create(name="Text network", asn=12345, status="ok", org=org)
poc = NetworkContact.objects.create(network=net, status="ok", role="Abuse")
# test poc phone validation
with pytest.raises(ValidationError):
poc.phone = "invalid"
poc.full_clean()
poc.phone = "+1 206 555 0199"
poc.full_clean()
# test ix phone validation
with pytest.raises(ValidationError):
ix.tech_phone = "invalid"
ix.full_clean()
ix.tech_phone = "+1 206 555 0199"
ix.full_clean()
with pytest.raises(ValidationError):
ix.policy_phone = "invalid"
ix.full_clean()
ix.policy_phone = "+1 206 555 0199"
ix.full_clean()
@pytest.mark.django_db
def test_validate_ixpfx_ixlan_status_match():
org = Organization.objects.create(name="Test org", status="ok")
ix = InternetExchange.objects.create(
name="Text exchange", status="pending", org=org
)
ixlan = ix.ixlan
pfx = IXLanPrefix.objects.create(
ixlan=ixlan,
protocol="IPv4",
prefix=ipaddress.ip_network("198.32.125.0/24"),
status="ok",
)
with pytest.raises(ValidationError) as exc1:
pfx.clean()
assert (
exc1.value.args[0]
== "IXLanPrefix with status 'ok' cannot be linked to a IXLan with status 'pending'."
)
ixlan.status = "deleted"
ixlan.save()
pfx.status = "pending"
pfx.save()
with pytest.raises(ValidationError) as exc2:
pfx.clean()
assert (
exc2.value.args[0]
== "IXLanPrefix with status 'pending' cannot be linked to a IXLan with status 'deleted'."
)