1+ from __future__ import annotations
2+
13import pytest
24
35import logging
46
7+ from lib .bond import Bond
58from lib .host import Host
69from lib .network import Network
10+ from lib .tunnel import Tunnel
11+ from lib .vlan import VLAN
12+ from lib .xo import xo_cli
713
814from typing import Generator
915
@@ -14,15 +20,7 @@ def host_no_sdn_controller(host: Host):
1420 pytest .skip ("This test requires an XCP-ng with no SDN controller" )
1521
1622
17- @pytest .fixture (scope = 'module' )
18- def empty_network (host : Host ) -> Generator [Network , None , None ]:
19- try :
20- net = host .create_network (label = "empty_network for tests" )
21- yield net
22- finally :
23- if net is not None :
24- net .destroy ()
25-
23+ # ---- Bond ----
2624@pytest .fixture (params = [])
2725def bond_devices (request : pytest .FixtureRequest ) -> list [str ]:
2826 return request .param
@@ -32,7 +30,7 @@ def bond_mode(request: pytest.FixtureRequest) -> str:
3230 return request .param
3331
3432@pytest .fixture
35- def bond (host : Host , empty_network : Network , bond_devices : list [str ], bond_mode : str ):
33+ def bond (host : Host , empty_network : Network , bond_devices : list [str ], bond_mode : str ) -> Generator [ Bond , None , None ] :
3634 pifs = []
3735 logging .info (f"bond: resolve PIFs on { host .hostname_or_ip } using \
3836 { [(pif .network_uuid (), pif .param_get ('device' )) for pif in host .pifs ()]} " )
@@ -45,3 +43,107 @@ def bond(host: Host, empty_network: Network, bond_devices: list[str], bond_mode:
4543 yield bond
4644 finally :
4745 bond .destroy ()
46+
47+
48+ # ---- Network ----
49+ @pytest .fixture (scope = 'module' )
50+ def empty_network (host : Host ) -> Generator [Network , None , None ]:
51+ try :
52+ net = host .create_network (label = "empty_network for tests" )
53+ yield net
54+ finally :
55+ if net is not None :
56+ net .destroy ()
57+
58+
59+ # ---- Tunnel ----
60+ @pytest .fixture (params = ["eth0" ])
61+ def tunnel_device (request : pytest .FixtureRequest ) -> str :
62+ return request .param
63+
64+ @pytest .fixture (params = ["gre" , "vxlan" ])
65+ def tunnel_protocol (request : pytest .FixtureRequest ) -> str :
66+ return request .param
67+
68+ @pytest .fixture (params = [False , True ])
69+ def tunnel_encryption (request : pytest .FixtureRequest ) -> bool :
70+ return request .param
71+
72+ @pytest .fixture
73+ def tunnel (
74+ connected_hosts_with_xo : list [Host ],
75+ tunnel_device : str , tunnel_protocol : str , tunnel_encryption : bool ,
76+ ) -> Generator [Tunnel , None , None ]:
77+ host = connected_hosts_with_xo [0 ]
78+
79+ # check system requirements
80+ if not host .is_package_installed ("openvswitch-ipsec" ):
81+ pytest .skip ("'tunnel' fixture requires configuration, see https://docs.xen-orchestra.com/sdn_controller" )
82+
83+ logging .info (f"tunnel: resolve PIF on { host .hostname_or_ip } using \
84+ { [(pif .network_uuid (), pif .param_get ('device' )) for pif in host .pifs ()]} " )
85+
86+ [pif ] = host .pifs (device = tunnel_device )
87+ if pif .ip_configuration_mode () == "None" :
88+ pytest .skip (f"'tunnel' fixture requires tunnel_device={ tunnel_device } to have configured IP" )
89+
90+ xo_cli ('sdnController.createPrivateNetwork' , {
91+ 'poolIds' : f"json:[\" { host .pool .uuid } \" ]" ,
92+ 'pifIds' : f"json:[\" { pif .uuid } \" ]" ,
93+ 'name' : 'test-tunnel' ,
94+ 'description' : 'tunnel for test' ,
95+ 'encapsulation' : tunnel_protocol ,
96+ 'encrypted' : 'true' if tunnel_encryption else 'false' ,
97+ })
98+ tunnel = None
99+ network = None
100+ try :
101+ # get Tunnel from PIF
102+ tunnel_uuid = host .xe ('tunnel-list' , {
103+ 'transport-PIF' : pif .uuid ,
104+ }, minimal = True )
105+ tunnel = Tunnel (host , tunnel_uuid )
106+
107+ # get Network from Tunnel
108+ network_uuid = tunnel .access_PIF ().network_uuid ()
109+ network = Network (host , network_uuid )
110+
111+ yield tunnel
112+ finally :
113+ if tunnel is not None :
114+ tunnel .destroy ()
115+
116+ if network is not None :
117+ # sdnController.createPrivateNetwork might have create several Tunnel (one per host)
118+ # so get all Tunnel attached to Network and destroy them
119+ for pif_uuid in network .pif_uuids ():
120+ tunnel_uuid = host .xe ('tunnel-list' , {
121+ 'access-PIF' : pif_uuid ,
122+ }, minimal = True )
123+ tunnel = Tunnel (host , tunnel_uuid )
124+ tunnel .destroy ()
125+
126+ # finally destroy the Network
127+ network .destroy ()
128+
129+
130+ # ---- VLAN ----
131+ @pytest .fixture (params = ["eth0" ])
132+ def vlan_device (request : pytest .FixtureRequest ) -> str :
133+ return request .param
134+
135+ @pytest .fixture (params = [0 ])
136+ def vlan_tag (request : pytest .FixtureRequest ) -> int :
137+ return request .param
138+
139+ @pytest .fixture
140+ def vlan (host : Host , empty_network : Network , vlan_tag : int , vlan_device : str ) -> Generator [VLAN , None , None ]:
141+ logging .info (f"vlan: resolve PIF on { host .hostname_or_ip } using \
142+ { [(pif .network_uuid (), pif .param_get ('device' )) for pif in host .pifs ()]} " )
143+
144+ [pif ] = host .pifs (device = vlan_device )
145+ vlan = host .create_vlan (empty_network , pif , vlan_tag )
146+ try :
147+ yield vlan
148+ finally :
149+ vlan .destroy ()
0 commit comments