mirror of
https://github.com/slackhq/nebula.git
synced 2026-11-15 22:36:52 +01:00
overlay/darwin: test tun framing and zero-alloc Read/Write (#1906)
smoke-extra / freebsd-amd64 (push) Failing after 16s
smoke-extra / linux-amd64-ipv6disable (push) Failing after 16s
smoke-extra / netbsd-amd64 (push) Failing after 17s
smoke-extra / openbsd-amd64 (push) Failing after 17s
smoke-extra / linux-386 (push) Failing after 16s
smoke / Run multi node smoke test (push) Failing after 1m41s
Build and test / Static checks (push) Successful in 45s
Build and test / Test linux (push) Failing after 1m47s
Build and test / Test linux-pkcs11 (push) Failing after 2m6s
Build and test / Test linux-boringcrypto (push) Failing after 2m57s
Build and test / Test linux-fips140 (push) Failing after 2m53s
Build and test / Cross-build linux-arm (push) Successful in 3m7s
Build and test / Cross-build linux-mips (push) Successful in 3m55s
Build and test / Cross-build linux-other (push) Successful in 3m13s
Build and test / Cross-build windows (push) Successful in 1m4s
Build and test / Cross-build freebsd (push) Successful in 1m35s
Build and test / Cross-build netbsd (push) Successful in 1m35s
Build and test / Cross-build openbsd (push) Successful in 1m34s
Build and test / Cross-build mobile (push) Successful in 3m26s
smoke-extra / Run windows smoke test (push) Canceled after 0s
smoke / Run self traffic smoke test on macOS (push) Canceled after 0s
Build and test / Test macos (push) Canceled after 0s
Build and test / Test windows (push) Canceled after 0s
Build and test / CI status (push) Canceled after 0s
smoke-extra / freebsd-amd64 (push) Failing after 16s
smoke-extra / linux-amd64-ipv6disable (push) Failing after 16s
smoke-extra / netbsd-amd64 (push) Failing after 17s
smoke-extra / openbsd-amd64 (push) Failing after 17s
smoke-extra / linux-386 (push) Failing after 16s
smoke / Run multi node smoke test (push) Failing after 1m41s
Build and test / Static checks (push) Successful in 45s
Build and test / Test linux (push) Failing after 1m47s
Build and test / Test linux-pkcs11 (push) Failing after 2m6s
Build and test / Test linux-boringcrypto (push) Failing after 2m57s
Build and test / Test linux-fips140 (push) Failing after 2m53s
Build and test / Cross-build linux-arm (push) Successful in 3m7s
Build and test / Cross-build linux-mips (push) Successful in 3m55s
Build and test / Cross-build linux-other (push) Successful in 3m13s
Build and test / Cross-build windows (push) Successful in 1m4s
Build and test / Cross-build freebsd (push) Successful in 1m35s
Build and test / Cross-build netbsd (push) Successful in 1m35s
Build and test / Cross-build openbsd (push) Successful in 1m34s
Build and test / Cross-build mobile (push) Successful in 3m26s
smoke-extra / Run windows smoke test (push) Canceled after 0s
smoke / Run self traffic smoke test on macOS (push) Canceled after 0s
Build and test / Test macos (push) Canceled after 0s
Build and test / Test windows (push) Canceled after 0s
Build and test / CI status (push) Canceled after 0s
This commit is contained in:
1 parent
428dad94b3
commit
7daacc6a48
1 file changed
+121
@@ -0,0 +1,121 @@
|
||||
//go:build !ios && !e2e_testing
|
||||
|
||||
package overlay
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestTun_WriteFraming(t *testing.T) {
|
||||
r, w, err := os.Pipe()
|
||||
require.NoError(t, err)
|
||||
defer r.Close()
|
||||
defer w.Close()
|
||||
tn := &tun{f: w}
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
pkt []byte
|
||||
af byte
|
||||
}{
|
||||
// Literal families rather than syscall.AF_*, so a wrong constant in Write can't also fix the expectation.
|
||||
{"ipv4", []byte{0x45, 1, 2, 3, 4, 5}, 2},
|
||||
{"ipv6", []byte{0x60, 1, 2, 3, 4, 5}, 30},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
n, err := tn.Write(tc.pkt)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(tc.pkt), n)
|
||||
|
||||
got := make([]byte, 64)
|
||||
n, err = r.Read(got)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, append([]byte{0, 0, 0, tc.af}, tc.pkt...), got[:n])
|
||||
})
|
||||
}
|
||||
|
||||
_, err = tn.Write([]byte{0x10, 1, 2, 3})
|
||||
require.Error(t, err)
|
||||
_, err = tn.Write([]byte{})
|
||||
require.ErrorIs(t, err, syscall.EIO)
|
||||
|
||||
// The rejected writes must not have put anything on the fd, so the next read sees only this packet.
|
||||
pkt := []byte{0x45, 9, 9}
|
||||
_, err = tn.Write(pkt)
|
||||
require.NoError(t, err)
|
||||
got := make([]byte, 64)
|
||||
n, err := r.Read(got)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, append([]byte{0, 0, 0, 2}, pkt...), got[:n])
|
||||
}
|
||||
|
||||
func TestTun_ReadStripsHeader(t *testing.T) {
|
||||
r, w, err := os.Pipe()
|
||||
require.NoError(t, err)
|
||||
defer r.Close()
|
||||
defer w.Close()
|
||||
tn := &tun{f: r}
|
||||
|
||||
pkt := []byte{0x45, 1, 2, 3, 4, 5}
|
||||
_, err = w.Write(append([]byte{0, 0, 0, syscall.AF_INET}, pkt...))
|
||||
require.NoError(t, err)
|
||||
|
||||
got := make([]byte, 64)
|
||||
n, err := tn.Read(got)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, pkt, got[:n])
|
||||
}
|
||||
|
||||
func TestTun_ReadShort(t *testing.T) {
|
||||
r, w, err := os.Pipe()
|
||||
require.NoError(t, err)
|
||||
defer r.Close()
|
||||
defer w.Close()
|
||||
tn := &tun{f: r}
|
||||
|
||||
// Fewer bytes than the protocol header is not a packet.
|
||||
_, err = w.Write([]byte{0, 0})
|
||||
require.NoError(t, err)
|
||||
n, err := tn.Read(make([]byte, 64))
|
||||
require.NoError(t, err)
|
||||
require.Zero(t, n)
|
||||
|
||||
// The next packet reads cleanly only if the short read consumed exactly what was written.
|
||||
pkt := []byte{0x45, 1, 2, 3}
|
||||
_, err = w.Write(append([]byte{0, 0, 0, syscall.AF_INET}, pkt...))
|
||||
require.NoError(t, err)
|
||||
got := make([]byte, 64)
|
||||
n, err = tn.Read(got)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, pkt, got[:n])
|
||||
}
|
||||
|
||||
// A heap allocation per packet rarely shows in a short throughput run, only across GC pauses, so
|
||||
// this pins Read and Write to zero allocations directly.
|
||||
func TestTun_ReadWriteDoNotAllocate(t *testing.T) {
|
||||
r, w, err := os.Pipe()
|
||||
require.NoError(t, err)
|
||||
defer r.Close()
|
||||
defer w.Close()
|
||||
tw := &tun{f: w}
|
||||
tr := &tun{f: r}
|
||||
|
||||
pkts := [][]byte{bytes.Repeat([]byte{0x45}, 1300), bytes.Repeat([]byte{0x60}, 1300)}
|
||||
buf := make([]byte, 1500)
|
||||
i := 0
|
||||
allocs := testing.AllocsPerRun(1000, func() {
|
||||
i++
|
||||
if _, err := tw.Write(pkts[i%len(pkts)]); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := tr.Read(buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
require.Zero(t, allocs)
|
||||
}
|
||||
Reference in new issue
Block a user