ooni-probe-cli/internal/engine/experiment/tlsmiddlebox/conn_test.go

164 lines
3.5 KiB
Go

package tlsmiddlebox
import (
"context"
"errors"
"io"
"syscall"
"testing"
"github.com/ooni/probe-cli/v3/internal/model/mocks"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
func TestDialerTTLWrapperConn(t *testing.T) {
t.Run("Read", func(t *testing.T) {
t.Run("on success", func(t *testing.T) {
b := make([]byte, 128)
conn := &dialerTTLWrapperConn{
Conn: &mocks.Conn{
MockRead: func(b []byte) (int, error) {
return len(b), nil
},
},
}
count, err := conn.Read(b)
if err != nil {
t.Fatal(err)
}
if count != len(b) {
t.Fatal("unexpected count")
}
})
t.Run("on failure", func(t *testing.T) {
b := make([]byte, 128)
expectedErr := io.EOF
conn := &dialerTTLWrapperConn{
Conn: &mocks.Conn{
MockRead: func(b []byte) (int, error) {
return 0, expectedErr
},
},
}
count, err := conn.Read(b)
if err == nil || err.Error() != netxlite.FailureEOFError {
t.Fatal("unexpected err", err)
}
if count != 0 {
t.Fatal("unexpected count")
}
})
})
t.Run("Write", func(t *testing.T) {
t.Run("on success", func(t *testing.T) {
b := make([]byte, 128)
conn := &dialerTTLWrapperConn{
Conn: &mocks.Conn{
MockWrite: func(b []byte) (int, error) {
return len(b), nil
},
},
}
count, err := conn.Write(b)
if err != nil {
t.Fatal(err)
}
if count != len(b) {
t.Fatal("unexpected count")
}
})
t.Run("on failure", func(t *testing.T) {
b := make([]byte, 128)
expectedErr := io.EOF
conn := &dialerTTLWrapperConn{
Conn: &mocks.Conn{
MockWrite: func(b []byte) (int, error) {
return 0, expectedErr
},
},
}
count, err := conn.Write(b)
if err == nil || err.Error() != netxlite.FailureEOFError {
t.Fatal("unexpected err", err)
}
if count != 0 {
t.Fatal("unexpected count")
}
})
})
}
func TestSetTTL(t *testing.T) {
t.Run("success case", func(t *testing.T) {
if testing.Short() {
t.Skip("skip test in short mode")
}
d := NewDialerTTLWrapper()
ctx := context.Background()
conn, err := d.DialContext(ctx, "tcp", "1.1.1.1:80")
if err != nil {
t.Fatal("expected non-nil conn")
}
// test TTL set
err = setConnTTL(conn, 1)
if err != nil {
t.Fatal("unexpected error in setting TTL", err)
}
var buf [512]byte
_, err = conn.Write([]byte("1111"))
if err != nil {
t.Fatal("error writing", err)
}
r, _ := conn.Read(buf[:])
if r != 0 {
t.Fatal("unexpected output size", r)
}
setConnTTL(conn, 64) // reset TTL to ensure conn closes successfully
conn.Close()
_, err = conn.Read(buf[:])
if err == nil || err.Error() != netxlite.FailureConnectionAlreadyClosed {
t.Fatal("failed to reset TTL")
}
})
t.Run("failure case", func(t *testing.T) {
conn := &mocks.Conn{}
err := setConnTTL(conn, 1)
if !errors.Is(err, errInvalidConnWrapper) {
t.Fatal("unexpected error")
}
})
}
func TestGetSoErr(t *testing.T) {
t.Run("success case", func(t *testing.T) {
d := NewDialerTTLWrapper()
ctx := context.Background()
conn, err := d.DialContext(ctx, "tcp", "1.1.1.1:80")
if err != nil {
t.Fatal(err)
}
errno, err := getSoErr(conn)
if err != nil {
t.Fatal("unexpected error", err)
}
if !errors.Is(errno, syscall.Errno(0)) {
t.Fatal("unexpected errno")
}
})
t.Run("failure case", func(t *testing.T) {
conn := &mocks.Conn{}
errno, err := getSoErr(conn)
if !errors.Is(err, errInvalidConnWrapper) {
t.Fatal("unexpected error")
}
if errno != nil {
t.Fatal("expected nil errorno")
}
})
}