264 lines
11 KiB
Python
264 lines
11 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
#
|
||
|
# Copyright (C) 2014 Red Hat, Inc.
|
||
|
#
|
||
|
# This copyrighted material is made available to anyone wishing to use,
|
||
|
# modify, copy, or redistribute it subject to the terms and conditions of
|
||
|
# the GNU General Public License v.2, or (at your option) any later version.
|
||
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||
|
# ANY WARRANTY expressed or implied, including the implied warranties of
|
||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||
|
# Public License for more details. You should have received a copy of the
|
||
|
# GNU General Public License along with this program; if not, write to the
|
||
|
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||
|
# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
|
||
|
# source code or documentation are not subject to the GNU General Public
|
||
|
# License and may only be used or replicated with the express permission of
|
||
|
# Red Hat, Inc.
|
||
|
|
||
|
from pyanaconda import network
|
||
|
import unittest
|
||
|
|
||
|
|
||
|
class NetworkTests(unittest.TestCase):
|
||
|
|
||
|
def test_is_valid_hostname(self):
|
||
|
"""Test hostname validation."""
|
||
|
|
||
|
assert not network.is_valid_hostname("")[0]
|
||
|
assert not network.is_valid_hostname(None)[0]
|
||
|
|
||
|
# section length < 64
|
||
|
assert network.is_valid_hostname("h"*63)[0]
|
||
|
assert not network.is_valid_hostname("h"*64)[0]
|
||
|
|
||
|
# length < 65
|
||
|
assert network.is_valid_hostname("section." * 7+"sectionx")[0]
|
||
|
assert not network.is_valid_hostname("section." * 7+"sectionxx")[0]
|
||
|
|
||
|
assert not network.is_valid_hostname(
|
||
|
"section.must.be..nonempty.")[0]
|
||
|
assert not network.is_valid_hostname(
|
||
|
".section.must.be.nonempty.")[0]
|
||
|
assert network.is_valid_hostname(
|
||
|
"section.can.contain.only.alphanums.012.or.hyp-hens")[0]
|
||
|
assert not network.is_valid_hostname(
|
||
|
"section.can.contain.only.alphanums.012.or.hyp-hens!!!")[0]
|
||
|
assert not network.is_valid_hostname(
|
||
|
"section.may.not.start.with.-hyphen")[0]
|
||
|
assert not network.is_valid_hostname(
|
||
|
"section.may.not.end.with.hyphen-")[0]
|
||
|
|
||
|
assert network.is_valid_hostname("0-0.")[0]
|
||
|
assert network.is_valid_hostname("0.")[0]
|
||
|
|
||
|
assert not network.is_valid_hostname("Lennart's Laptop")[0]
|
||
|
|
||
|
assert not network.is_valid_hostname("own.hostname.cannot.end.in.dot.",
|
||
|
local=True)[0]
|
||
|
|
||
|
def test_prefix2netmask2prefix(self):
|
||
|
"""Test netmask and prefix conversion."""
|
||
|
lore = [
|
||
|
(0, "0.0.0.0"),
|
||
|
(1, "128.0.0.0"),
|
||
|
(2, "192.0.0.0"),
|
||
|
(3, "224.0.0.0"),
|
||
|
(4, "240.0.0.0"),
|
||
|
(5, "248.0.0.0"),
|
||
|
(6, "252.0.0.0"),
|
||
|
(7, "254.0.0.0"),
|
||
|
(8, "255.0.0.0"),
|
||
|
(9, "255.128.0.0"),
|
||
|
(10, "255.192.0.0"),
|
||
|
(11, "255.224.0.0"),
|
||
|
(12, "255.240.0.0"),
|
||
|
(13, "255.248.0.0"),
|
||
|
(14, "255.252.0.0"),
|
||
|
(15, "255.254.0.0"),
|
||
|
(16, "255.255.0.0"),
|
||
|
(17, "255.255.128.0"),
|
||
|
(18, "255.255.192.0"),
|
||
|
(19, "255.255.224.0"),
|
||
|
(20, "255.255.240.0"),
|
||
|
(21, "255.255.248.0"),
|
||
|
(22, "255.255.252.0"),
|
||
|
(23, "255.255.254.0"),
|
||
|
(24, "255.255.255.0"),
|
||
|
(25, "255.255.255.128"),
|
||
|
(26, "255.255.255.192"),
|
||
|
(27, "255.255.255.224"),
|
||
|
(28, "255.255.255.240"),
|
||
|
(29, "255.255.255.248"),
|
||
|
(30, "255.255.255.252"),
|
||
|
(31, "255.255.255.254"),
|
||
|
(32, "255.255.255.255"),
|
||
|
]
|
||
|
for prefix, netmask in lore:
|
||
|
assert network.prefix_to_netmask(prefix) == netmask
|
||
|
assert network.netmask_to_prefix(netmask) == prefix
|
||
|
|
||
|
assert network.prefix_to_netmask(33) == "255.255.255.255"
|
||
|
|
||
|
def test_nm_check_ip_address(self,):
|
||
|
"""Test IPv4 and IPv6 address checks."""
|
||
|
good_IPv4_tests = [
|
||
|
'1.2.3.4',
|
||
|
'0.0.0.0',
|
||
|
'10.20.30.40',
|
||
|
'255.255.255.255',
|
||
|
'249.249.249.249'
|
||
|
]
|
||
|
good_IPv6_tests = [
|
||
|
'0000:0000:0000:0000:0000:0000:0000:0000',
|
||
|
'0000:0000:0000:0000:0000:0000:1.2.3.4',
|
||
|
'::a:b:c:d:e:f:1',
|
||
|
'::a:b:c:d:e:255.255.255.255',
|
||
|
'1::a:b:c:d:e:f',
|
||
|
'1::a:b:c:d:255.255.255.255',
|
||
|
'1:12::a:b:c:d:e',
|
||
|
'1:12::a:b:c:10.20.30.40',
|
||
|
'12::a:b:c:d:e',
|
||
|
'12::a:b:c:10.20.30.40',
|
||
|
'1:12:123::a:b:c:d',
|
||
|
'1:12:123::a:b:100.200.250.249',
|
||
|
'12:123::a:b:c:d',
|
||
|
'12:123::a:b:100.200.250.249',
|
||
|
'123::a:b:c:d',
|
||
|
'123::a:b:100.200.250.249',
|
||
|
'::a:b:c:d',
|
||
|
'::a:b:100.200.250.249',
|
||
|
'1:12:123:1234::a:b:c',
|
||
|
'1:12:123:1234::a:1.20.30.99',
|
||
|
'12:123:1234::a:b:c',
|
||
|
'12:123:1234::a:1.20.30.99',
|
||
|
'123:1234::a:b:c',
|
||
|
'123:1234::a:1.20.30.99',
|
||
|
'1234::a:b:c',
|
||
|
'1234::a:1.20.30.99',
|
||
|
'::a:b:c',
|
||
|
'::a:1.20.30.99',
|
||
|
'1:12:123:1234:abcd::a:b',
|
||
|
'1:12:123:1234:abcd::0.0.0.0',
|
||
|
'12:123:1234:abcd::a:b',
|
||
|
'12:123:1234:abcd::0.0.0.0',
|
||
|
'123:1234:abcd::a:b',
|
||
|
'123:1234:abcd::0.0.0.0',
|
||
|
'1234:abcd::a:b',
|
||
|
'1234:abcd::0.0.0.0',
|
||
|
'abcd::a:b',
|
||
|
'abcd::0.0.0.0',
|
||
|
'::a:b',
|
||
|
'::0.0.0.0',
|
||
|
'1:12:123:1234:dead:beef::aaaa',
|
||
|
'12:123:1234:dead:beef::aaaa',
|
||
|
'123:1234:dead:beef::aaaa',
|
||
|
'1234:dead:beef::aaaa',
|
||
|
'dead:beef::aaaa',
|
||
|
'beef::aaaa',
|
||
|
'::aaaa',
|
||
|
'::'
|
||
|
]
|
||
|
|
||
|
bad_IPv4_tests = [
|
||
|
'1.2.3.',
|
||
|
'1.2.3',
|
||
|
'256.2.3.4',
|
||
|
'a.b.c.d',
|
||
|
'1.2.3.400'
|
||
|
'....',
|
||
|
'1..2.3'
|
||
|
]
|
||
|
bad_IPv6_tests = [
|
||
|
# Too many bits
|
||
|
'0000:0000:0000:0000:0000:0000:0000:0000:0000'
|
||
|
'0000:0000:0000:0000:0000:0000:0000:1.2.3.4',
|
||
|
'0000:0000:0000:0000:0000:0000:1.2.3.4.5',
|
||
|
# Not enough bits
|
||
|
'0000:0000:0000:0000:0000:0000:0000',
|
||
|
'0000:0000:0000:0000:0000:1.2.3.4',
|
||
|
# zero-length contractions
|
||
|
'0000::0000:0000:0000:0000:0000:1.2.3.4',
|
||
|
'0000:0000::0000:0000:0000:0000:1.2.3.4',
|
||
|
'0000:0000:0000::0000:0000:0000:1.2.3.4',
|
||
|
'0000:0000:0000:0000::0000:0000:1.2.3.4',
|
||
|
'0000:0000:0000:0000:0000::0000:1.2.3.4',
|
||
|
'0000:0000:0000:0000:0000:0000::1.2.3.4',
|
||
|
'123::4567:89:a:bcde:f0f0:aaaa:8',
|
||
|
'123:4567::89:a:bcde:f0f0:aaaa:8',
|
||
|
'123:4567:89::a:bcde:f0f0:aaaa:8',
|
||
|
'123:4567:89:a:bcde::f0f0:aaaa:8',
|
||
|
'123:4567:89:a:bcde:f0f0::aaaa:8',
|
||
|
'123:4567:89:a:bcde:f0f0:aaaa::8',
|
||
|
# too many contractions
|
||
|
'a::b::c',
|
||
|
'::a::b',
|
||
|
'a::b::',
|
||
|
# invalid numbers
|
||
|
'00000::0000',
|
||
|
'defg::',
|
||
|
'12345::abcd',
|
||
|
'ffff::0x1e'
|
||
|
]
|
||
|
|
||
|
# test good IPv4
|
||
|
for i in good_IPv4_tests:
|
||
|
assert network.check_ip_address(i, version=4)
|
||
|
assert network.check_ip_address(i)
|
||
|
assert not network.check_ip_address(i, version=6)
|
||
|
|
||
|
# test bad Ipv4
|
||
|
for i in bad_IPv4_tests:
|
||
|
assert not network.check_ip_address(i)
|
||
|
assert not network.check_ip_address(i, version=4)
|
||
|
assert not network.check_ip_address(i, version=6)
|
||
|
|
||
|
# test good IPv6
|
||
|
for i in good_IPv6_tests:
|
||
|
assert network.check_ip_address(i, version=6)
|
||
|
assert network.check_ip_address(i)
|
||
|
assert not network.check_ip_address(i, version=4)
|
||
|
|
||
|
# test bad IPv6
|
||
|
for i in bad_IPv6_tests:
|
||
|
assert not network.check_ip_address(i)
|
||
|
assert not network.check_ip_address(i, version=6)
|
||
|
assert not network.check_ip_address(i, version=4)
|
||
|
|
||
|
def test_hostname_from_cmdline(self):
|
||
|
"""Test extraction of hostname from cmdline."""
|
||
|
cmdline = {"ip": "10.34.102.244::10.34.102.54:255.255.255.0:myhostname:ens9:none"}
|
||
|
assert network.hostname_from_cmdline(cmdline) == "myhostname"
|
||
|
# This case is not officially supported according to dracut.cmdline but
|
||
|
# the ip configuration is actually working and we care not to break
|
||
|
# hostname setting for it (#1988521)
|
||
|
cmdline = {"ip": "10.34.102.244::10.34.102.54:255.255.255.0:myhostname:"}
|
||
|
assert network.hostname_from_cmdline(cmdline) == "myhostname"
|
||
|
# ip takes precedence
|
||
|
cmdline = {"ip": "10.34.102.244::10.34.102.54:255.255.255.0:myhostname:ens9:none",
|
||
|
"hostname": "hostname_bootopt"}
|
||
|
assert network.hostname_from_cmdline(cmdline) == "myhostname"
|
||
|
cmdline = {"ip": "ens3:dhcp"}
|
||
|
assert network.hostname_from_cmdline(cmdline) == ""
|
||
|
cmdline = {"ip": "ens3:dhcp:1500"}
|
||
|
assert network.hostname_from_cmdline(cmdline) == ""
|
||
|
cmdline = {"ip": "ens3:dhcp",
|
||
|
"hostname": "hostname_bootopt"}
|
||
|
assert network.hostname_from_cmdline(cmdline) == "hostname_bootopt"
|
||
|
# two ip configurations
|
||
|
cmdline = {"ip": "ens3:dhcp 10.34.102.244::10.34.102.54:255.255.255.0:myhostname:ens9:none"}
|
||
|
assert network.hostname_from_cmdline(cmdline) == "myhostname"
|
||
|
# ipv6 configuration
|
||
|
cmdline = {"ip": "[fd00:10:100::84:5]::[fd00:10:100::86:49]:80:myhostname:ens50:none"}
|
||
|
assert network.hostname_from_cmdline(cmdline) == "myhostname"
|
||
|
cmdline = {"ip": "[fd00:10:100::84:5]:::80:myhostname:ens50:none"}
|
||
|
assert network.hostname_from_cmdline(cmdline) == "myhostname"
|
||
|
cmdline = {"ip": "[fd00:10:100::84:5]::[fd00:10:100::86:49]:80::ens50:none"}
|
||
|
assert network.hostname_from_cmdline(cmdline) == ""
|
||
|
cmdline = {"ip": "[fd00:10:100::84:5]::[fd00:10:100::86:49]:80::ens50:none "
|
||
|
"ens3:dhcp 10.34.102.244::10.34.102.54:255.255.255.0:myhostname:ens9:none"}
|
||
|
assert network.hostname_from_cmdline(cmdline) == "myhostname"
|
||
|
# automatic ip= whith MAC address set
|
||
|
cmdline = {"ip": "ens3:dhcp::52:54:00:12:34:56"}
|
||
|
assert network.hostname_from_cmdline(cmdline) == ""
|