-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_dhcp_to_hosts.py
executable file
·134 lines (114 loc) · 5.96 KB
/
test_dhcp_to_hosts.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python
import pytest
import os
import types
from mock import mock_open, patch, call
import dhcp_to_hosts
from dhcp_to_hosts import DHCPRecord, Dhcp2Hosts
class DHCPHostsTestData(object):
"""Test data to represent DHCP hosts file"""
record1 = DHCPRecord(host='family-room', ip='172.30.50.22')
record2 = DHCPRecord(host='appletv', ip='172.30.50.2')
records = [record1, record2]
contents = "dhcp-range=172.30.50.51,172.30.50.99,12h\n" + \
"dhcp-host=00:0c:1e:02:b3:a3,{},{}\n".format(record1.ip, record1.host) + \
"dhcp-host=10:40:f3:ec:90:1c,{},{}\n".format(record2.ip, record2.host) + \
"dhcp-host=18:b4:30:00:48:b1,nest-thermostat"
class HostsTestData(object):
"""Test data to represent hosts file"""
record1 = DHCPHostsTestData.record1
record2 = DHCPHostsTestData.record2
contents_before = "127.0.0.1 localhost\n" + \
"::1 localhost ip6-localhost ip6-loopback\n" + \
"ff02::1 ip6-allnodes\n" + \
"ff02::2 ip6-allrouters\n\n" + \
"127.0.1.1 pi-hole"
new_block = "{}".format(Dhcp2Hosts.SECTION_HEADER) + \
"{}\t{}\n".format(record1.ip, record1.host) + \
"{}\t{}\n".format(record2.ip, record2.host) + \
"{}".format(Dhcp2Hosts.SECTION_FOOTER)
contents_after = contents_before + new_block
@pytest.fixture
def dhcp2hosts():
return Dhcp2Hosts('simulated_file')
def test_dns_record_eq():
record1 = DHCPRecord(host='host1', ip='192.168.1.1')
record1_same = DHCPRecord(host='host1', ip='192.168.1.1')
assert record1 == record1_same
assert record1 == record1
def test_dns_record_ne():
assert not (DHCPRecord(host='host1', ip='192.168.1.1') != DHCPRecord(host='host1', ip='192.168.1.1'))
assert DHCPRecord(host='host1', ip='192.168.1.2') != DHCPRecord(host='host1', ip='192.168.1.1')
assert DHCPRecord(host='host2', ip='192.168.1.1') != DHCPRecord(host='host1', ip='192.168.1.1')
def test_get_ip_host_from_dhcp_hostfile(dhcp2hosts):
with patch('dhcp_to_hosts.open', mock_open(read_data=DHCPHostsTestData.contents)) as mock_open_cm:
dhcp2hosts.read_dhcp_records()
mock_open_cm.assert_called_with('simulated_file', 'r')
assert len(dhcp2hosts.dhcp_records) == 2
assert dhcp2hosts.dhcp_records[0] == DHCPHostsTestData.record1
assert dhcp2hosts.dhcp_records[1] == DHCPHostsTestData.record2
def test_get_generated_block(dhcp2hosts):
dhcp2hosts.dhcp_records = DHCPHostsTestData.records
assert dhcp2hosts._get_generated_block() == HostsTestData.new_block
@patch('dhcp_to_hosts.os.utime')
@patch('dhcp_to_hosts.os.stat')
def test_update_hosts_opens_files(_mock_utime, _mock_stat, dhcp2hosts):
with patch('dhcp_to_hosts.open', mock_open(read_data='')) as mock_open_cm:
dhcp2hosts.update()
mock_open_cm.assert_any_call(Dhcp2Hosts.HOSTS_FILE, 'r')
mock_open_cm.assert_any_call(Dhcp2Hosts.HOSTS_FILE, 'w')
@patch('dhcp_to_hosts.os.utime')
@patch('dhcp_to_hosts.os.stat')
def test_update_hosts(_mock_utime, _mock_stat, dhcp2hosts):
def fake_read_dhcp_records(self):
self.dhcp_records = DHCPHostsTestData.records
with patch.object(Dhcp2Hosts, 'read_dhcp_records', autospec=True, side_effect=fake_read_dhcp_records):
with patch('dhcp_to_hosts.open', mock_open(read_data=HostsTestData.contents_before)) as mock_open_cm:
mock_open_cm().read.return_value = HostsTestData.contents_before
dhcp2hosts.update()
mock_open_cm().write.assert_called_once_with(HostsTestData.contents_after)
@patch('dhcp_to_hosts.os.utime')
@patch('dhcp_to_hosts.os.stat')
def test_update_hosts_idempotent(_mock_utime, _mock_stat, dhcp2hosts):
"""Make sure already updated contents aren't changed."""
def fake_read_dhcp_records(self):
self.dhcp_records = DHCPHostsTestData.records
with patch.object(Dhcp2Hosts, 'read_dhcp_records', autospec=True, side_effect=fake_read_dhcp_records):
with patch('dhcp_to_hosts.open', mock_open(read_data=HostsTestData.contents_before)) as mock_open_cm:
mock_open_cm().read.return_value = HostsTestData.contents_after
dhcp2hosts.update()
mock_open_cm().write.assert_called_once_with(HostsTestData.contents_after)
@patch('dhcp_to_hosts.os.utime')
def test_update_modifies_hosts_modification_time(mock_utime, dhcp2hosts):
stat_result = os.stat(os.path.realpath(__file__))
with patch('dhcp_to_hosts.open', mock_open(read_data='no_data')) as mock_open_cm:
with patch('dhcp_to_hosts.os.stat', return_value=stat_result):
dhcp2hosts.update()
mock_utime.assert_called_once_with(dhcp2hosts.HOSTS_FILE, (stat_result.st_atime, stat_result.st_mtime))
def test_needs_update_false(dhcp2hosts):
with patch('dhcp_to_hosts.os.path.getmtime', return_value=1330712292):
assert dhcp2hosts.needs_update() == False
def test_needs_update_true(dhcp2hosts):
with patch('dhcp_to_hosts.os.path.getmtime', side_effect=[1330712292, 1230712293]):
assert dhcp2hosts.needs_update() == True
def test_get_args_no_args():
with pytest.raises(SystemExit):
dhcp_to_hosts.get_args([])
def test_get_args_help():
with pytest.raises(SystemExit):
dhcp_to_hosts.get_args(['--help'])
@patch.object(Dhcp2Hosts, 'needs_update', autospec=True, return_value=True)
@patch.object(Dhcp2Hosts, 'update', autospec=True)
def test_run_needs_update(mock_needs_update, mock_update):
fake_file = 'fake_file'
def verify_fake_file_passed_in(self):
assert self.dhcp_hostsfile == fake_file
mock_update.side_effect = verify_fake_file_passed_in
dhcp_to_hosts.run(['--dhcp_hostsfile', fake_file])
assert mock_update.called
@patch.object(Dhcp2Hosts, 'needs_update', autospec=True, return_value=False)
def test_run_no_update_needed(mock_needs_update):
dhcp_to_hosts.run(['--dhcp_hostsfile', 'fake_file'])
assert mock_needs_update.called
if __name__ == '__main__':
pytest.main()