@@ -17,12 +17,15 @@ import (
1717 "runtime"
1818 "slices"
1919 "strings"
20+ "sync"
2021 "syscall"
2122 "testing"
2223 "text/template"
2324
2425 "github.com/Code-Hex/vz/v3"
2526 "github.com/Code-Hex/vz/v3/vmnet"
27+ "github.com/Code-Hex/vz/v3/vmnet/fileadapter/datagram"
28+ "github.com/Code-Hex/vz/v3/vmnet/fileadapter/datagramx"
2629 "github.com/Code-Hex/vz/v3/xpc"
2730)
2831
@@ -44,7 +47,6 @@ func TestVmnetSharedModeAllowsCommunicationBetweenMultipleVMs(t *testing.T) {
4447 if err != nil {
4548 t .Fatal (err )
4649 }
47- macaddress1 := randomMACAddress (t )
4850
4951 // Create another VmnetNetwork instance from serialization of the first one
5052 serialization , err := network1 .CopySerialization ()
@@ -55,17 +57,58 @@ func TestVmnetSharedModeAllowsCommunicationBetweenMultipleVMs(t *testing.T) {
5557 if err != nil {
5658 t .Fatal (err )
5759 }
58- macaddress2 := randomMACAddress (t )
60+ // Test *FileAdaptorForInterface
61+ var startFuncsWG sync.WaitGroup
62+ var file3 * os.File
63+ var start3 func ()
64+ // Create DatagramFileAdaptorForInterface instances
65+ if network , err := vmnet .NewNetworkWithSerialization (serialization ); err != nil {
66+ t .Fatal (err )
67+ } else if iface , err := vmnet .StartInterfaceWithNetwork (network , xpc .NewDictionary ()); err != nil {
68+ t .Fatal (err )
69+ } else if file3 , start3 , _ , err = datagram .FileAdaptorForInterface (t .Context (), iface ); err != nil {
70+ t .Fatal (err )
71+ }
72+ startFuncsWG .Add (1 )
73+ go func () {
74+ defer startFuncsWG .Done ()
75+ start3 ()
76+ }()
5977
60- container1 := newVirtualizationMachine (t , configureNetworkDevice (network1 , macaddress1 ))
61- container2 := newVirtualizationMachine (t , configureNetworkDevice (network2 , macaddress2 ))
78+ // Create DatagramNextFileAdaptorForInterface instances
79+ var file4 * os.File
80+ var start4 func ()
81+ if network4 , err := vmnet .NewNetworkWithSerialization (serialization ); err != nil {
82+ t .Fatal (err )
83+ } else if iface , err := vmnet .StartInterfaceWithNetwork (network4 , xpc .NewDictionary ()); err != nil {
84+ t .Fatal (err )
85+ } else if file4 , start4 , _ , err = datagramx .FileAdaptorForInterface (t .Context (), iface ); err != nil {
86+ t .Fatal (err )
87+ }
88+ startFuncsWG .Add (1 )
89+ go func () {
90+ defer startFuncsWG .Done ()
91+ start4 ()
92+ }()
93+
94+ container1 := newVirtualizationMachine (t , configureVmnetNetworkDevice (network1 , randomMACAddress (t )))
95+ container2 := newVirtualizationMachine (t , configureVmnetNetworkDevice (network2 , randomMACAddress (t )))
96+ container3 := newVirtualizationMachine (t , configureFileHandleNetworkDevice (file3 , randomMACAddress (t )))
97+ container4 := newVirtualizationMachine (t , configureFileHandleNetworkDevice (file4 , randomMACAddress (t )))
6298 t .Cleanup (func () {
6399 if err := container1 .Shutdown (); err != nil {
64100 log .Println (err )
65101 }
66102 if err := container2 .Shutdown (); err != nil {
67103 log .Println (err )
68104 }
105+ if err := container3 .Shutdown (); err != nil {
106+ log .Println (err )
107+ }
108+ if err := container4 .Shutdown (); err != nil {
109+ log .Println (err )
110+ }
111+ startFuncsWG .Wait ()
69112 })
70113
71114 // Log network information
@@ -85,8 +128,14 @@ func TestVmnetSharedModeAllowsCommunicationBetweenMultipleVMs(t *testing.T) {
85128 t .Logf ("Container 1 IPv4: %s" , container1IPv4 )
86129 container2IPv4 := container2 .DetectIPv4 (t , "eth0" )
87130 t .Logf ("Container 2 IPv4: %s" , container2IPv4 )
131+ container3IPv4 := container3 .DetectIPv4 (t , "eth0" )
132+ t .Logf ("Container 3 IPv4: %s" , container3IPv4 )
133+ container4IPv4 := container4 .DetectIPv4 (t , "eth0" )
134+ t .Logf ("Container 4 IPv4: %s" , container4IPv4 )
88135 container1 .exec (t , "ping " + container2IPv4 )
89- container2 .exec (t , "ping " + container1IPv4 )
136+ container2 .exec (t , "ping " + container3IPv4 )
137+ container3 .exec (t , "ping " + container4IPv4 )
138+ container4 .exec (t , "ping " + container1IPv4 )
90139}
91140
92141// TestVmnetSharedModeWithConfiguringIPv4 tests VmnetNetwork in SharedMode
@@ -121,7 +170,7 @@ func TestVmnetSharedModeWithConfiguringIPv4(t *testing.T) {
121170 }
122171
123172 // Create VirtualizationMachine instance
124- container := newVirtualizationMachine (t , configureNetworkDevice (network , macaddress ))
173+ container := newVirtualizationMachine (t , configureVmnetNetworkDevice (network , macaddress ))
125174 t .Cleanup (func () {
126175 if err := container .Shutdown (); err != nil {
127176 log .Println (err )
@@ -203,7 +252,7 @@ func TestVmnetNetworkShareModeSharingOverXpc(t *testing.T) {
203252 if err != nil {
204253 t .Fatal (err )
205254 }
206- container := newVirtualizationMachine (t , configureNetworkDevice (network , randomMACAddress (t )))
255+ container := newVirtualizationMachine (t , configureVmnetNetworkDevice (network , randomMACAddress (t )))
207256 t .Cleanup (func () {
208257 if err := container .Shutdown (); err != nil {
209258 log .Println (err )
@@ -217,9 +266,9 @@ func TestVmnetNetworkShareModeSharingOverXpc(t *testing.T) {
217266 }
218267}
219268
220- // configureNetworkDevice returns a function that configures a network device
269+ // configureVmnetNetworkDevice returns a function that configures a network device
221270// with the given VmnetNetwork and MAC address.
222- func configureNetworkDevice (network * vmnet.Network , macAddress * vz.MACAddress ) func (cfg * vz.VirtualMachineConfiguration ) error {
271+ func configureVmnetNetworkDevice (network * vmnet.Network , macAddress * vz.MACAddress ) func (cfg * vz.VirtualMachineConfiguration ) error {
223272 return func (cfg * vz.VirtualMachineConfiguration ) error {
224273 var configurations []* vz.VirtioNetworkDeviceConfiguration
225274 attachment , err := vz .NewVmnetNetworkDeviceAttachment (network )
@@ -237,6 +286,26 @@ func configureNetworkDevice(network *vmnet.Network, macAddress *vz.MACAddress) f
237286 }
238287}
239288
289+ // configureFileHandleNetworkDevice returns a function that configures a network device
290+ // with the given file handle and MAC address.
291+ func configureFileHandleNetworkDevice (file * os.File , macAddress * vz.MACAddress ) func (cfg * vz.VirtualMachineConfiguration ) error {
292+ return func (cfg * vz.VirtualMachineConfiguration ) error {
293+ var configurations []* vz.VirtioNetworkDeviceConfiguration
294+ attachment , err := vz .NewFileHandleNetworkDeviceAttachment (file )
295+ if err != nil {
296+ return err
297+ }
298+ config , err := vz .NewVirtioNetworkDeviceConfiguration (attachment )
299+ if err != nil {
300+ return err
301+ }
302+ config .SetMACAddress (macAddress )
303+ configurations = append (configurations , config )
304+ cfg .SetNetworkDevicesVirtualMachineConfiguration (configurations )
305+ return nil
306+ }
307+ }
308+
240309// detectFreeIPv4Subnet detects a free IPv4 subnet on the host machine.
241310func detectFreeIPv4Subnet (t * testing.T , prefer netip.Prefix ) netip.Prefix {
242311 targetPrefix := netip .MustParsePrefix ("192.168.0.0/16" )
@@ -436,7 +505,7 @@ func xpcServerProvidingSubnet(t *testing.T, machServiceName string) (*xpc.Listen
436505 } else if serialization , err := network .CopySerialization (); err != nil {
437506 reply = createErrorReply ("failed to copy serialization: %v" , err )
438507 } else {
439- container := newVirtualizationMachine (t , configureNetworkDevice (network , randomMACAddress (t )))
508+ container := newVirtualizationMachine (t , configureVmnetNetworkDevice (network , randomMACAddress (t )))
440509 t .Cleanup (func () {
441510 if err := container .Shutdown (); err != nil {
442511 log .Println (err )
0 commit comments