@@ -17,6 +17,7 @@ import (
1717 "runtime"
1818 "slices"
1919 "strings"
20+ "sync"
2021 "syscall"
2122 "testing"
2223 "text/template"
@@ -44,7 +45,6 @@ func TestVmnetSharedModeAllowsCommunicationBetweenMultipleVMs(t *testing.T) {
4445 if err != nil {
4546 t .Fatal (err )
4647 }
47- macaddress1 := randomMACAddress (t )
4848
4949 // Create another VmnetNetwork instance from serialization of the first one
5050 serialization , err := network1 .CopySerialization ()
@@ -55,17 +55,58 @@ func TestVmnetSharedModeAllowsCommunicationBetweenMultipleVMs(t *testing.T) {
5555 if err != nil {
5656 t .Fatal (err )
5757 }
58- macaddress2 := randomMACAddress (t )
58+ // Test *FileAdaptorForInterface
59+ var startFuncsWG sync.WaitGroup
60+ var file3 * os.File
61+ var start3 func ()
62+ // Create DatagramFileAdaptorForInterface instances
63+ if network , err := vmnet .NewNetworkWithSerialization (serialization ); err != nil {
64+ t .Fatal (err )
65+ } else if iface , err := vmnet .StartInterfaceWithNetwork (network , xpc .NewDictionary ()); err != nil {
66+ t .Fatal (err )
67+ } else if file3 , start3 , _ , err = vmnet .DatagramFileAdaptorForInterface (t .Context (), iface ); err != nil {
68+ t .Fatal (err )
69+ }
70+ startFuncsWG .Add (1 )
71+ go func () {
72+ defer startFuncsWG .Done ()
73+ start3 ()
74+ }()
5975
60- container1 := newVirtualizationMachine (t , configureNetworkDevice (network1 , macaddress1 ))
61- container2 := newVirtualizationMachine (t , configureNetworkDevice (network2 , macaddress2 ))
76+ // Create DatagramNextFileAdaptorForInterface instances
77+ var file4 * os.File
78+ var start4 func ()
79+ if network4 , err := vmnet .NewNetworkWithSerialization (serialization ); err != nil {
80+ t .Fatal (err )
81+ } else if iface , err := vmnet .StartInterfaceWithNetwork (network4 , xpc .NewDictionary ()); err != nil {
82+ t .Fatal (err )
83+ } else if file4 , start4 , _ , err = vmnet .DatagramNextFileAdaptorForInterface (t .Context (), iface ); err != nil {
84+ t .Fatal (err )
85+ }
86+ startFuncsWG .Add (1 )
87+ go func () {
88+ defer startFuncsWG .Done ()
89+ start4 ()
90+ }()
91+
92+ container1 := newVirtualizationMachine (t , configureVmnetNetworkDevice (network1 , randomMACAddress (t )))
93+ container2 := newVirtualizationMachine (t , configureVmnetNetworkDevice (network2 , randomMACAddress (t )))
94+ container3 := newVirtualizationMachine (t , configureFileHandleNetworkDevice (file3 , randomMACAddress (t )))
95+ container4 := newVirtualizationMachine (t , configureFileHandleNetworkDevice (file4 , randomMACAddress (t )))
6296 t .Cleanup (func () {
6397 if err := container1 .Shutdown (); err != nil {
6498 log .Println (err )
6599 }
66100 if err := container2 .Shutdown (); err != nil {
67101 log .Println (err )
68102 }
103+ if err := container3 .Shutdown (); err != nil {
104+ log .Println (err )
105+ }
106+ if err := container4 .Shutdown (); err != nil {
107+ log .Println (err )
108+ }
109+ startFuncsWG .Wait ()
69110 })
70111
71112 // Log network information
@@ -85,8 +126,14 @@ func TestVmnetSharedModeAllowsCommunicationBetweenMultipleVMs(t *testing.T) {
85126 t .Logf ("Container 1 IPv4: %s" , container1IPv4 )
86127 container2IPv4 := container2 .DetectIPv4 (t , "eth0" )
87128 t .Logf ("Container 2 IPv4: %s" , container2IPv4 )
129+ container3IPv4 := container3 .DetectIPv4 (t , "eth0" )
130+ t .Logf ("Container 3 IPv4: %s" , container3IPv4 )
131+ container4IPv4 := container4 .DetectIPv4 (t , "eth0" )
132+ t .Logf ("Container 4 IPv4: %s" , container4IPv4 )
88133 container1 .exec (t , "ping " + container2IPv4 )
89- container2 .exec (t , "ping " + container1IPv4 )
134+ container2 .exec (t , "ping " + container3IPv4 )
135+ container3 .exec (t , "ping " + container4IPv4 )
136+ container4 .exec (t , "ping " + container1IPv4 )
90137}
91138
92139// TestVmnetSharedModeWithConfiguringIPv4 tests VmnetNetwork in SharedMode
@@ -121,7 +168,7 @@ func TestVmnetSharedModeWithConfiguringIPv4(t *testing.T) {
121168 }
122169
123170 // Create VirtualizationMachine instance
124- container := newVirtualizationMachine (t , configureNetworkDevice (network , macaddress ))
171+ container := newVirtualizationMachine (t , configureVmnetNetworkDevice (network , macaddress ))
125172 t .Cleanup (func () {
126173 if err := container .Shutdown (); err != nil {
127174 log .Println (err )
@@ -203,7 +250,7 @@ func TestVmnetNetworkShareModeSharingOverXpc(t *testing.T) {
203250 if err != nil {
204251 t .Fatal (err )
205252 }
206- container := newVirtualizationMachine (t , configureNetworkDevice (network , randomMACAddress (t )))
253+ container := newVirtualizationMachine (t , configureVmnetNetworkDevice (network , randomMACAddress (t )))
207254 t .Cleanup (func () {
208255 if err := container .Shutdown (); err != nil {
209256 log .Println (err )
@@ -217,9 +264,9 @@ func TestVmnetNetworkShareModeSharingOverXpc(t *testing.T) {
217264 }
218265}
219266
220- // configureNetworkDevice returns a function that configures a network device
267+ // configureVmnetNetworkDevice returns a function that configures a network device
221268// with the given VmnetNetwork and MAC address.
222- func configureNetworkDevice (network * vmnet.Network , macAddress * vz.MACAddress ) func (cfg * vz.VirtualMachineConfiguration ) error {
269+ func configureVmnetNetworkDevice (network * vmnet.Network , macAddress * vz.MACAddress ) func (cfg * vz.VirtualMachineConfiguration ) error {
223270 return func (cfg * vz.VirtualMachineConfiguration ) error {
224271 var configurations []* vz.VirtioNetworkDeviceConfiguration
225272 attachment , err := vz .NewVmnetNetworkDeviceAttachment (network )
@@ -237,6 +284,26 @@ func configureNetworkDevice(network *vmnet.Network, macAddress *vz.MACAddress) f
237284 }
238285}
239286
287+ // configureFileHandleNetworkDevice returns a function that configures a network device
288+ // with the given file handle and MAC address.
289+ func configureFileHandleNetworkDevice (file * os.File , macAddress * vz.MACAddress ) func (cfg * vz.VirtualMachineConfiguration ) error {
290+ return func (cfg * vz.VirtualMachineConfiguration ) error {
291+ var configurations []* vz.VirtioNetworkDeviceConfiguration
292+ attachment , err := vz .NewFileHandleNetworkDeviceAttachment (file )
293+ if err != nil {
294+ return err
295+ }
296+ config , err := vz .NewVirtioNetworkDeviceConfiguration (attachment )
297+ if err != nil {
298+ return err
299+ }
300+ config .SetMACAddress (macAddress )
301+ configurations = append (configurations , config )
302+ cfg .SetNetworkDevicesVirtualMachineConfiguration (configurations )
303+ return nil
304+ }
305+ }
306+
240307// detectFreeIPv4Subnet detects a free IPv4 subnet on the host machine.
241308func detectFreeIPv4Subnet (t * testing.T , prefer netip.Prefix ) netip.Prefix {
242309 targetPrefix := netip .MustParsePrefix ("192.168.0.0/16" )
@@ -436,7 +503,7 @@ func xpcServerProvidingSubnet(t *testing.T, machServiceName string) (*xpc.Listen
436503 } else if serialization , err := network .CopySerialization (); err != nil {
437504 reply = createErrorReply ("failed to copy serialization: %v" , err )
438505 } else {
439- container := newVirtualizationMachine (t , configureNetworkDevice (network , randomMACAddress (t )))
506+ container := newVirtualizationMachine (t , configureVmnetNetworkDevice (network , randomMACAddress (t )))
440507 t .Cleanup (func () {
441508 if err := container .Shutdown (); err != nil {
442509 log .Println (err )
0 commit comments