Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lima-vm
GitHub Repository: lima-vm/lima
Path: blob/master/pkg/driver/vz/network_darwin_test.go
2611 views
1
//go:build darwin && !no_vz
2
3
// SPDX-FileCopyrightText: Copyright The Lima Authors
4
// SPDX-License-Identifier: Apache-2.0
5
6
package vz
7
8
import (
9
"encoding/binary"
10
"fmt"
11
"net"
12
"path/filepath"
13
"testing"
14
15
"gotest.tools/v3/assert"
16
)
17
18
const (
19
vmnetMaxPacketSize = 1514
20
packetsCount = 1000
21
)
22
23
func TestDialQemu(t *testing.T) {
24
listener, err := listenUnix(t.TempDir())
25
assert.NilError(t, err)
26
defer listener.Close()
27
t.Logf("Listening at %q", listener.Addr())
28
29
errc := make(chan error, 2)
30
31
// Start the fake vmnet server.
32
go func() {
33
t.Log("Fake vmnet started")
34
errc <- serveOneClient(listener)
35
t.Log("Fake vmnet finished")
36
}()
37
38
// Connect to the fake vmnet server.
39
client, err := DialQemu(t.Context(), listener.Addr().String())
40
assert.NilError(t, err)
41
t.Log("Connected to fake vment server")
42
43
dgramConn, err := net.FileConn(client)
44
assert.NilError(t, err)
45
46
vzConn := packetConn{Conn: dgramConn}
47
defer vzConn.Close()
48
49
go func() {
50
t.Log("Sender started")
51
buf := make([]byte, vmnetMaxPacketSize)
52
for i := range vmnetMaxPacketSize {
53
buf[i] = 0x55
54
}
55
56
// data packet format:
57
// 0-4 packet number
58
// 4-1514 0x55 ...
59
for i := range packetsCount {
60
binary.BigEndian.PutUint32(buf, uint32(i))
61
if _, err := vzConn.Write(buf); err != nil {
62
errc <- err
63
return
64
}
65
}
66
t.Logf("Sent %d data packets", packetsCount)
67
68
// quit packet format:
69
// 0-4: "quit"
70
copy(buf[:4], "quit")
71
if _, err := vzConn.Write(buf[:4]); err != nil {
72
errc <- err
73
return
74
}
75
76
errc <- nil
77
t.Log("Sender finished")
78
}()
79
80
// Read and verify packets to the server.
81
82
buf := make([]byte, vmnetMaxPacketSize)
83
84
t.Log("Receiving and verifying data packets...")
85
for i := range packetsCount {
86
n, err := vzConn.Read(buf)
87
assert.NilError(t, err)
88
assert.Assert(t, n >= vmnetMaxPacketSize, "unexpected number of bytes")
89
90
number := binary.BigEndian.Uint32(buf[:4])
91
assert.Equal(t, number, uint32(i), "unexpected packet")
92
93
for j := 4; j < vmnetMaxPacketSize; j++ {
94
assert.Equal(t, buf[j], byte(0x55), "unexpected byte at offset %d", j)
95
}
96
}
97
t.Logf("Received and verified %d data packets", packetsCount)
98
99
for range 2 {
100
err := <-errc
101
assert.NilError(t, err)
102
}
103
}
104
105
// serveOneClient accepts one client and echo back received packets until a
106
// "quit" packet is sent.
107
func serveOneClient(listener *net.UnixListener) error {
108
conn, err := listener.Accept()
109
if err != nil {
110
return err
111
}
112
qemuConn := qemuPacketConn{Conn: conn}
113
defer qemuConn.Close()
114
115
buf := make([]byte, vmnetMaxPacketSize)
116
for {
117
nr, err := qemuConn.Read(buf)
118
if err != nil {
119
return err
120
}
121
if string(buf[:4]) == "quit" {
122
return nil
123
}
124
nw, err := qemuConn.Write(buf[:nr])
125
if err != nil {
126
return err
127
}
128
if nw != nr {
129
return fmt.Errorf("incomplete write: expected: %d, wrote: %d", nr, nw)
130
}
131
}
132
}
133
134
// listenUnix creates and listen to unix socket under dir
135
func listenUnix(dir string) (*net.UnixListener, error) {
136
sock := filepath.Join(dir, "sock")
137
addr, err := net.ResolveUnixAddr("unix", sock)
138
if err != nil {
139
return nil, err
140
}
141
return net.ListenUnix("unix", addr)
142
}
143
144