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") } }) }