refactor(tracex): convert to unit testing (#781)
The exercise already allowed me to notice issues such as fields not being properly initialized by savers. This is one of the last steps before moving tracex away from the internal/netx package and into the internal package. See https://github.com/ooni/probe/issues/2121
This commit is contained in:
parent
6212daa54a
commit
d397036073
17 changed files with 1674 additions and 1111 deletions
|
|
@ -12,127 +12,268 @@ import (
|
|||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
||||
)
|
||||
|
||||
func TestSaverDialerFailure(t *testing.T) {
|
||||
expected := errors.New("mocked error")
|
||||
func TestDialerConnectObserver(t *testing.T) {
|
||||
saver := &Saver{}
|
||||
dlr := &SaverDialer{
|
||||
Dialer: &mocks.Dialer{
|
||||
MockDialContext: func(ctx context.Context, network string, address string) (net.Conn, error) {
|
||||
return nil, expected
|
||||
},
|
||||
},
|
||||
Saver: saver,
|
||||
obs := &dialerConnectObserver{
|
||||
saver: saver,
|
||||
}
|
||||
conn, err := dlr.DialContext(context.Background(), "tcp", "www.google.com:443")
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("expected another error here")
|
||||
dialer := &mocks.Dialer{}
|
||||
out := obs.WrapDialer(dialer)
|
||||
dialSaver := out.(*DialerSaver)
|
||||
if dialSaver.Dialer != dialer {
|
||||
t.Fatal("invalid dialer")
|
||||
}
|
||||
if conn != nil {
|
||||
t.Fatal("expected nil conn here")
|
||||
}
|
||||
ev := saver.Read()
|
||||
if len(ev) != 1 {
|
||||
t.Fatal("expected a single event here")
|
||||
}
|
||||
if ev[0].Value().Address != "www.google.com:443" {
|
||||
t.Fatal("unexpected Address")
|
||||
}
|
||||
if ev[0].Value().Duration <= 0 {
|
||||
t.Fatal("unexpected Duration")
|
||||
}
|
||||
if !errors.Is(ev[0].Value().Err, expected) {
|
||||
t.Fatal("unexpected Err")
|
||||
}
|
||||
if ev[0].Name() != netxlite.ConnectOperation {
|
||||
t.Fatal("unexpected Name")
|
||||
}
|
||||
if ev[0].Value().Proto != "tcp" {
|
||||
t.Fatal("unexpected Proto")
|
||||
}
|
||||
if !ev[0].Value().Time.Before(time.Now()) {
|
||||
t.Fatal("unexpected Time")
|
||||
if dialSaver.Saver != saver {
|
||||
t.Fatal("invalid saver")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSaverConnDialerFailure(t *testing.T) {
|
||||
expected := errors.New("mocked error")
|
||||
saver := &Saver{}
|
||||
dlr := &SaverConnDialer{
|
||||
Dialer: &mocks.Dialer{
|
||||
MockDialContext: func(ctx context.Context, network string, address string) (net.Conn, error) {
|
||||
return nil, expected
|
||||
},
|
||||
},
|
||||
Saver: saver,
|
||||
}
|
||||
conn, err := dlr.DialContext(context.Background(), "tcp", "www.google.com:443")
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("not the error we expected")
|
||||
}
|
||||
if conn != nil {
|
||||
t.Fatal("expected nil conn here")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSaverConnDialerSuccess(t *testing.T) {
|
||||
saver := &Saver{}
|
||||
dlr := &SaverConnDialer{
|
||||
Dialer: &SaverDialer{
|
||||
func TestDialerSaver(t *testing.T) {
|
||||
t.Run("on failure", func(t *testing.T) {
|
||||
expected := errors.New("mocked error")
|
||||
saver := &Saver{}
|
||||
dlr := &DialerSaver{
|
||||
Dialer: &mocks.Dialer{
|
||||
MockDialContext: func(ctx context.Context, network string, address string) (net.Conn, error) {
|
||||
return &mocks.Conn{
|
||||
MockRead: func(b []byte) (int, error) {
|
||||
return 0, io.EOF
|
||||
},
|
||||
MockWrite: func(b []byte) (int, error) {
|
||||
return 0, io.EOF
|
||||
},
|
||||
MockClose: func() error {
|
||||
return io.EOF
|
||||
},
|
||||
MockLocalAddr: func() net.Addr {
|
||||
return &net.TCPAddr{Port: 12345}
|
||||
},
|
||||
}, nil
|
||||
return nil, expected
|
||||
},
|
||||
},
|
||||
Saver: saver,
|
||||
},
|
||||
Saver: saver,
|
||||
}
|
||||
conn, err := dlr.DialContext(context.Background(), "tcp", "www.google.com:443")
|
||||
if err != nil {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
conn.Read(nil)
|
||||
conn.Write(nil)
|
||||
conn.Close()
|
||||
events := saver.Read()
|
||||
if len(events) != 3 {
|
||||
t.Fatal("unexpected number of events saved", len(events))
|
||||
}
|
||||
if events[0].Name() != "connect" {
|
||||
t.Fatal("expected a connect event")
|
||||
}
|
||||
saverCheckConnectEvent(t, &events[0])
|
||||
if events[1].Name() != "read" {
|
||||
t.Fatal("expected a read event")
|
||||
}
|
||||
saverCheckReadEvent(t, &events[1])
|
||||
if events[2].Name() != "write" {
|
||||
t.Fatal("expected a write event")
|
||||
}
|
||||
saverCheckWriteEvent(t, &events[2])
|
||||
}
|
||||
conn, err := dlr.DialContext(context.Background(), "tcp", "www.google.com:443")
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("expected another error here")
|
||||
}
|
||||
if conn != nil {
|
||||
t.Fatal("expected nil conn here")
|
||||
}
|
||||
ev := saver.Read()
|
||||
if len(ev) != 1 {
|
||||
t.Fatal("expected a single event here")
|
||||
}
|
||||
if ev[0].Value().Address != "www.google.com:443" {
|
||||
t.Fatal("unexpected Address")
|
||||
}
|
||||
if ev[0].Value().Duration <= 0 {
|
||||
t.Fatal("unexpected Duration")
|
||||
}
|
||||
if !errors.Is(ev[0].Value().Err, expected) {
|
||||
t.Fatal("unexpected Err")
|
||||
}
|
||||
if ev[0].Name() != netxlite.ConnectOperation {
|
||||
t.Fatal("unexpected Name")
|
||||
}
|
||||
if ev[0].Value().Proto != "tcp" {
|
||||
t.Fatal("unexpected Proto")
|
||||
}
|
||||
if !ev[0].Value().Time.Before(time.Now()) {
|
||||
t.Fatal("unexpected Time")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("CloseIdleConnections", func(t *testing.T) {
|
||||
var called bool
|
||||
child := &mocks.Dialer{
|
||||
MockCloseIdleConnections: func() {
|
||||
called = true
|
||||
},
|
||||
}
|
||||
dialer := &DialerSaver{
|
||||
Dialer: child,
|
||||
Saver: &Saver{},
|
||||
}
|
||||
dialer.CloseIdleConnections()
|
||||
if !called {
|
||||
t.Fatal("not called")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func saverCheckConnectEvent(t *testing.T, ev *Event) {
|
||||
// TODO(bassosimone): implement
|
||||
func TestDialerReadWriteObserver(t *testing.T) {
|
||||
saver := &Saver{}
|
||||
obs := &dialerReadWriteObserver{
|
||||
saver: saver,
|
||||
}
|
||||
dialer := &mocks.Dialer{}
|
||||
out := obs.WrapDialer(dialer)
|
||||
dialSaver := out.(*DialerConnSaver)
|
||||
if dialSaver.Dialer != dialer {
|
||||
t.Fatal("invalid dialer")
|
||||
}
|
||||
if dialSaver.Saver != saver {
|
||||
t.Fatal("invalid saver")
|
||||
}
|
||||
}
|
||||
|
||||
func saverCheckReadEvent(t *testing.T, ev *Event) {
|
||||
// TODO(bassosimone): implement
|
||||
func TestDialerConnSaver(t *testing.T) {
|
||||
t.Run("DialContext", func(t *testing.T) {
|
||||
t.Run("on failure", func(t *testing.T) {
|
||||
expected := errors.New("mocked error")
|
||||
saver := &Saver{}
|
||||
dlr := &DialerConnSaver{
|
||||
Dialer: &mocks.Dialer{
|
||||
MockDialContext: func(ctx context.Context, network string, address string) (net.Conn, error) {
|
||||
return nil, expected
|
||||
},
|
||||
},
|
||||
Saver: saver,
|
||||
}
|
||||
conn, err := dlr.DialContext(context.Background(), "tcp", "www.google.com:443")
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("not the error we expected")
|
||||
}
|
||||
if conn != nil {
|
||||
t.Fatal("expected nil conn here")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("on success", func(t *testing.T) {
|
||||
origConn := &mocks.Conn{}
|
||||
saver := &Saver{}
|
||||
dlr := &DialerConnSaver{
|
||||
Dialer: &DialerSaver{
|
||||
Dialer: &mocks.Dialer{
|
||||
MockDialContext: func(ctx context.Context, network string, address string) (net.Conn, error) {
|
||||
return origConn, nil
|
||||
},
|
||||
},
|
||||
Saver: saver,
|
||||
},
|
||||
Saver: saver,
|
||||
}
|
||||
conn, err := dlr.DialContext(context.Background(), "tcp", "www.google.com:443")
|
||||
if err != nil {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
cw := conn.(*dialerConnWrapper)
|
||||
if cw.Conn != origConn {
|
||||
t.Fatal("unexpected conn")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("CloseIdleConnections", func(t *testing.T) {
|
||||
var called bool
|
||||
child := &mocks.Dialer{
|
||||
MockCloseIdleConnections: func() {
|
||||
called = true
|
||||
},
|
||||
}
|
||||
dialer := &DialerConnSaver{
|
||||
Dialer: child,
|
||||
Saver: &Saver{},
|
||||
}
|
||||
dialer.CloseIdleConnections()
|
||||
if !called {
|
||||
t.Fatal("not called")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func saverCheckWriteEvent(t *testing.T, ev *Event) {
|
||||
// TODO(bassosimone): implement
|
||||
func TestDialerConnWrapper(t *testing.T) {
|
||||
t.Run("Read", func(t *testing.T) {
|
||||
baseConn := &mocks.Conn{
|
||||
MockRead: func(b []byte) (int, error) {
|
||||
return 0, io.EOF
|
||||
},
|
||||
MockRemoteAddr: func() net.Addr {
|
||||
return &mocks.Addr{
|
||||
MockString: func() string {
|
||||
return "www.google.com:443"
|
||||
},
|
||||
MockNetwork: func() string {
|
||||
return "tcp"
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
saver := &Saver{}
|
||||
conn := &dialerConnWrapper{
|
||||
Conn: baseConn,
|
||||
saver: saver,
|
||||
}
|
||||
data := make([]byte, 155)
|
||||
count, err := conn.Read(data)
|
||||
if !errors.Is(err, io.EOF) {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
if count != 0 {
|
||||
t.Fatal("unexpected count")
|
||||
}
|
||||
ev := saver.Read()
|
||||
if len(ev) != 1 {
|
||||
t.Fatal("expected a single event here")
|
||||
}
|
||||
if ev[0].Value().Address != "www.google.com:443" {
|
||||
t.Fatal("unexpected Address")
|
||||
}
|
||||
if ev[0].Value().Duration <= 0 {
|
||||
t.Fatal("unexpected Duration")
|
||||
}
|
||||
if !errors.Is(ev[0].Value().Err, io.EOF) {
|
||||
t.Fatal("unexpected Err")
|
||||
}
|
||||
if ev[0].Name() != netxlite.ReadOperation {
|
||||
t.Fatal("unexpected Name")
|
||||
}
|
||||
if ev[0].Value().Proto != "tcp" {
|
||||
t.Fatal("unexpected Proto")
|
||||
}
|
||||
if !ev[0].Value().Time.Before(time.Now()) {
|
||||
t.Fatal("unexpected Time")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Write", func(t *testing.T) {
|
||||
baseConn := &mocks.Conn{
|
||||
MockWrite: func(b []byte) (int, error) {
|
||||
return 0, io.EOF
|
||||
},
|
||||
MockRemoteAddr: func() net.Addr {
|
||||
return &mocks.Addr{
|
||||
MockString: func() string {
|
||||
return "www.google.com:443"
|
||||
},
|
||||
MockNetwork: func() string {
|
||||
return "tcp"
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
saver := &Saver{}
|
||||
conn := &dialerConnWrapper{
|
||||
Conn: baseConn,
|
||||
saver: saver,
|
||||
}
|
||||
data := make([]byte, 155)
|
||||
count, err := conn.Write(data)
|
||||
if !errors.Is(err, io.EOF) {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
if count != 0 {
|
||||
t.Fatal("unexpected count")
|
||||
}
|
||||
ev := saver.Read()
|
||||
if len(ev) != 1 {
|
||||
t.Fatal("expected a single event here")
|
||||
}
|
||||
if ev[0].Value().Address != "www.google.com:443" {
|
||||
t.Fatal("unexpected Address")
|
||||
}
|
||||
if ev[0].Value().Duration <= 0 {
|
||||
t.Fatal("unexpected Duration")
|
||||
}
|
||||
if !errors.Is(ev[0].Value().Err, io.EOF) {
|
||||
t.Fatal("unexpected Err")
|
||||
}
|
||||
if ev[0].Name() != netxlite.WriteOperation {
|
||||
t.Fatal("unexpected Name")
|
||||
}
|
||||
if ev[0].Value().Proto != "tcp" {
|
||||
t.Fatal("unexpected Proto")
|
||||
}
|
||||
if !ev[0].Value().Time.Before(time.Now()) {
|
||||
t.Fatal("unexpected Time")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue