summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYuya Kusakabe <yuya.kusakabe@gmail.com>2018-05-17 10:35:33 +0900
committerGitHub <noreply@github.com>2018-05-17 10:35:33 +0900
commited6b92064e26a0c875e8825622a0e34f8475268f (patch)
tree9f190b37f22114a135ec3b62a3756a44659639a9 /src
parent3d6619b39b6f4eaad006e073a643e653827a3d1f (diff)
parent09d4f3d93fe272b12b5fae5de36e2c5c47206133 (diff)
downloadvyos-1x-ed6b92064e26a0c875e8825622a0e34f8475268f.tar.gz
vyos-1x-ed6b92064e26a0c875e8825622a0e34f8475268f.zip
Merge pull request #12 from higebu/more-tests
Add tests for hostname
Diffstat (limited to 'src')
-rwxr-xr-xsrc/conf_mode/host_name.py27
-rw-r--r--src/tests/test_host_name.py136
2 files changed, 157 insertions, 6 deletions
diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py
index 2a245b211..f6d091ac2 100755
--- a/src/conf_mode/host_name.py
+++ b/src/conf_mode/host_name.py
@@ -16,17 +16,26 @@
#
#
+"""
+conf-mode script for 'system host-name' and 'system domain-name'.
+"""
+
import os
import re
import sys
import subprocess
from vyos.config import Config
-from vyos.util import ConfigError
+from vyos import ConfigError
+
+hosts_file = '/etc/hosts'
hostname_regex = re.compile("^[A-Za-z0-9][-.A-Za-z0-9]*[A-Za-z0-9]$")
+local_addr = '127.0.1.1' # NOSONAR
+
def get_config():
+ """Get configuration"""
conf = Config()
hostname = conf.return_value("system host-name")
@@ -44,9 +53,11 @@ def get_config():
return {"hostname": hostname, "domain": domain, "fqdn": fqdn}
+
def verify(config):
+ """Verify configuration"""
# check for invalid host
-
+
# pattern $VAR(@) "^[[:alnum:]][-.[:alnum:]]*[[:alnum:]]$" ; "invalid host name $VAR(@)"
if not hostname_regex.match(config["hostname"]):
raise ConfigError('Invalid host name ' + config["hostname"])
@@ -54,29 +65,33 @@ def verify(config):
# pattern $VAR(@) "^.{1,63}$" ; "invalid host-name length"
length = len(config["hostname"])
if length < 1 or length > 63:
- raise ConfigError('Invalid host-name length, must be less than 63 characters')
+ raise ConfigError(
+ 'Invalid host-name length, must be less than 63 characters')
return None
def generate(config):
+ """Generate configuration files"""
# read the hosts file
- with open('/etc/hosts', 'r') as f:
+ with open(hosts_file, 'r') as f:
hosts = f.read()
# get the current hostname
old_hostname = subprocess.check_output(['hostname']).decode().strip()
# replace the local host line
- hosts = re.sub(r"(127.0.1.1\s+{0}.*)".format(old_hostname), r"127.0.1.1\t{0} # VyOS entry\n".format(config["fqdn"]), hosts)
+ hosts = re.sub(r"({}\s+{}.*)".format(local_addr, old_hostname),
+ r"{}\t{} # VyOS entry\n".format(local_addr, config["fqdn"]), hosts)
- with open('/etc/hosts', 'w') as f:
+ with open(hosts_file, 'w') as f:
f.write(hosts)
return None
def apply(config):
+ """Apply configuration"""
os.system("hostnamectl set-hostname {0}".format(config["fqdn"]))
# restart services that use the hostname
diff --git a/src/tests/test_host_name.py b/src/tests/test_host_name.py
new file mode 100644
index 000000000..3df1f975c
--- /dev/null
+++ b/src/tests/test_host_name.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2018 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty 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, see <http://www.gnu.org/licenses/>.
+#
+#
+
+import os
+import tempfile
+import unittest
+from unittest import TestCase, mock
+
+from vyos import ConfigError
+try:
+ from src.conf_mode import host_name
+except ModuleNotFoundError: # for unittest.main()
+ import sys
+ sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
+ from src.conf_mode import host_name
+
+
+class TestHostName(TestCase):
+
+ def test_get_config(self):
+ tests = [
+ {'name': 'empty_hostname_and_domain',
+ 'host-name': '',
+ 'domain-name': '',
+ 'expected': {"hostname": 'vyos', "domain": '', "fqdn": 'vyos'}},
+ {'name': 'empty_hostname',
+ 'host-name': '',
+ 'domain-name': 'localdomain',
+ 'expected': {"hostname": 'vyos', "domain": 'localdomain', "fqdn": 'vyos.localdomain'}},
+ {'name': 'has_hostname',
+ 'host-name': 'router',
+ 'domain-name': '',
+ 'expected': {"hostname": 'router', "domain": '', "fqdn": 'router'}},
+ {'name': 'has_hostname_and_domain',
+ 'host-name': 'router',
+ 'domain-name': 'localdomain',
+ 'expected': {"hostname": 'router', "domain": 'localdomain', "fqdn": 'router.localdomain'}},
+ ]
+ for t in tests:
+ def mocked_return_value(path, default=None):
+ return t[path.split()[1]]
+
+ with self.subTest(msg=t['name'], hostname=t['host-name'], domain=t['domain-name'], expected=t['expected']):
+ with mock.patch('vyos.config.Config.return_value', side_effect=mocked_return_value):
+ actual = host_name.get_config()
+ self.assertEqual(actual, t['expected'])
+
+
+ def test_verify(self):
+ tests = [
+ {'name': 'valid_hostname',
+ 'config': {"hostname": 'vyos', "domain": 'localdomain', "fqdn": 'vyos.localdomain'},
+ 'expected': None},
+ {'name': 'invalid_hostname',
+ 'config': {"hostname": 'vyos..', "domain": '', "fqdn": ''},
+ 'expected': ConfigError},
+ {'name': 'invalid_hostname_length',
+ 'config': {"hostname": 'a'*64, "domain": '', "fqdn": ''},
+ 'expected': ConfigError}
+ ]
+ for t in tests:
+ with self.subTest(msg=t['name'], config=t['config'], expected=t['expected']):
+ if t['expected'] is not None:
+ with self.assertRaises(t['expected']):
+ host_name.verify(t['config'])
+ else:
+ host_name.verify(t['config'])
+
+ def test_generate(self):
+ tests = [
+ {'name': 'valid_hostname',
+ 'config': {"hostname": 'router', "domain": 'localdomain', "fqdn": 'vyos.localdomain'},
+ 'expected': ['127.0.0.1 localhost debian',
+ '::1 localhost ip6-localhost ip6-loopback',
+ 'fe00::0 ip6-localnet',
+ 'ff00::0 ip6-mcastprefix',
+ 'ff02::1 ip6-allnodes',
+ 'ff02::2 ip6-allrouters',
+ '127.0.1.1 vyos #vyatta entry']}
+ ]
+ for t in tests:
+ with self.subTest(msg=t['name'], tasks=t['config'], expected=t['expected']):
+ m = mock.MagicMock(return_value=b'localhost')
+ with mock.patch('subprocess.check_output', m):
+ host_name.hosts_file = tempfile.mkstemp()[1]
+ with open(host_name.hosts_file, 'w') as f:
+ f.writelines(['127.0.0.1 localhost debian\n',
+ '::1 localhost ip6-localhost ip6-loopback\n',
+ 'fe00::0 ip6-localnet\n',
+ 'ff00::0 ip6-mcastprefix\n',
+ 'ff02::1 ip6-allnodes\n',
+ 'ff02::2 ip6-allrouters\n',
+ '127.0.1.1 vyos #vyatta entry'])
+ host_name.generate(t['config'])
+ if len(t['expected']) > 0:
+ self.assertTrue(os.path.isfile(host_name.hosts_file))
+ with open(host_name.hosts_file) as f:
+ actual = f.read()
+ self.assertEqual(
+ t['expected'], actual.splitlines())
+ os.remove(host_name.hosts_file)
+ else:
+ self.assertFalse(os.path.isfile(host_name.hosts_file))
+
+
+ def test_apply(self):
+ tests = [
+ {'name': 'valid_hostname',
+ 'config': {"hostname": 'router', "domain": 'localdomain', "fqdn": 'vyos.localdomain'},
+ 'expected': [mock.call('hostnamectl set-hostname vyos.localdomain'),
+ mock.call('systemctl restart rsyslog.service')]}
+ ]
+ for t in tests:
+ with self.subTest(msg=t['name'], c=t['config'], expected=t['expected']):
+ with mock.patch('os.system') as os_system:
+ host_name.apply(t['config'])
+ os_system.assert_has_calls(t['expected'])
+
+
+if __name__ == "__main__":
+ unittest.main()