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
| | #! /usr/bin/python3
# SPDX-License-Identifier: GPL-2.0-or-later
#
# tasst - Test A Simple Socket Transport
# library of test helpers for passt & pasta
#
# tasst/dhcpv6.py - Helpers for testing DHCPv6
#
# Copyright Red Hat
# Author: David Gibson <david@gibson.dropbear.id.au>
import ipaddress
import os
from tasst import Tasst, TasstSubData
from tasst.address import IpiAllocator, TEST_NET6_TASST_A
from tasst.nstool import UnshareSite
class BaseDhcpv6Tasst(Tasst):
"""
Test DHCPv6 behaviour.
:avocado: disable
"""
DHCLIENT = '/sbin/dhclient'
def subsetup(self, site, ifname, addr):
site.require_cmds(self.DHCLIENT)
pidfile = os.path.join(self.workdir, 'dhclient.pid')
leasefile = os.path.join(self.workdir, 'dhclient.leases')
# We need '-nc' because we may be running with capabilities
# but not UID 0. Without -nc dhclient drops capabilities
# before invoking dhclient-script, so it's unable to actually
# configure the interface
site.fg('{} -6 -v -nc -pf {} -lf {} {}'
.format(self.DHCLIENT, pidfile, leasefile, ifname), sudo=True)
Tasst.subsetup(self, BaseDhcpv6Tasst,
TasstSubData(site=site, ifname=ifname, addr=addr))
def test_addr(self):
sub = self.get_subsetup(BaseDhcpv6Tasst)
addrs = [a.ip for a in sub.site.addrs(sub.ifname, family='inet6', scope='global')]
self.assertIn(sub.addr, addrs) # Might also have a SLAAC address
class MetaDhcpv6Tasst(BaseDhcpv6Tasst):
"""Ugly workaround for
https://github.com/avocado-framework/avocado/issues/5680.
Explicitly apply the "meta" tag to inherited tests
:avocado: disable
:avocado: tags=meta
"""
def test_addr(self):
super().test_addr()
class Dhcpd6Tasst(MetaDhcpv6Tasst):
"""
:avocado: tags=meta
"""
DHCPD = 'dhcpd'
SUBNET = TEST_NET6_TASST_A
def setUp(self):
super().setUp()
ifname = 'clientif'
server_ifname = 'serverif'
self.client = UnshareSite(self.__class__.__name__ + '.client', '-Un')
self.server = UnshareSite(self.__class__.__name__ + '.server', '-n',
parent=self.client, sudo=True)
self.server.require_cmds(self.DHCPD)
self.client.veth(ifname, server_ifname, self.server)
# Allocate IPs, and sort out link local addressing
ipa = IpiAllocator(self.SUBNET)
(server_ip6,) = ipa.next_ipis()
(client_ip6,) = ipa.next_ipis()
self.server.ifup('lo')
self.server.ifup(server_ifname, server_ip6)
self.client.ifup('lo')
self.client.ifup(ifname)
(server_ip6_ll,) = self.server.addr_wait(server_ifname, family='inet6', scope='link')
# Configure the DHCP server
confpath = os.path.join(self.workdir, 'dhcpd.conf')
open(confpath, 'w').write('''
subnet6 {} {{
range6 {} {};
}}
'''.format(self.SUBNET, client_ip6.ip, client_ip6.ip))
self.pidpath = os.path.join(self.workdir, 'dhcpd.pid')
leasepath = os.path.join(self.workdir, 'dhcpd.leases')
open(leasepath, 'w').write('')
opts = ('-f -d -6 -cf {} -lf {} -pf {}'.format(confpath, leasepath, self.pidpath))
self.server.fg('{} -t {}'.format(self.DHCPD, opts)) # test config
self.dhcpd = self.server.bg('{} {}'.format(self.DHCPD, opts), sudo=True)
# Configure the client
BaseDhcpv6Tasst.subsetup(self, self.client, ifname, client_ip6.ip)
def tearDown(self):
pid = int(open(self.pidpath).read())
self.server.fg('kill {}'.format(pid))
status = self.dhcpd.wait()
self.server.close()
self.client.close()
super().tearDown()
|