package main import ( "bytes" "io/ioutil" "net" "sync" "testing" "time" "github.com/stretchr/testify/require" ) func TestTelnetClient(t *testing.T) { t.Run("basic", func(t *testing.T) { l, err := net.Listen("tcp", "127.0.0.1:") require.NoError(t, err) defer func() { require.NoError(t, l.Close()) }() var wg sync.WaitGroup wg.Add(2) go func() { defer wg.Done() in := &bytes.Buffer{} out := &bytes.Buffer{} timeout, err := time.ParseDuration("10s") require.NoError(t, err) client := NewTelnetClient(l.Addr().String(), timeout, ioutil.NopCloser(in), out) require.NoError(t, client.Connect()) defer func() { require.NoError(t, client.Close()) }() in.WriteString("hello\n") err = client.Send() require.NoError(t, err) err = client.Receive() require.NoError(t, err) require.Equal(t, "world\n", out.String()) }() go func() { defer wg.Done() conn, err := l.Accept() require.NoError(t, err) require.NotNil(t, conn) defer func() { require.NoError(t, conn.Close()) }() request := make([]byte, 1024) n, err := conn.Read(request) require.NoError(t, err) require.Equal(t, "hello\n", string(request)[:n]) n, err = conn.Write([]byte("world\n")) require.NoError(t, err) require.NotEqual(t, 0, n) }() wg.Wait() }) t.Run("bad host with timeout", func(t *testing.T) { timeout := time.Second * 5 client := NewTelnetClient("mail.ru:25", timeout, nil, nil) start := time.Now() err := client.Connect() require.Error(t, err, "Can't connect: dial tcp 94.100.180.201:25: i/o timeout") require.GreaterOrEqual(t, time.Since(start).Milliseconds(), timeout.Milliseconds()-time.Second.Milliseconds()) require.LessOrEqual(t, time.Since(start).Milliseconds(), timeout.Milliseconds()+time.Second.Milliseconds()) }) t.Run("close by peer", func(t *testing.T) { l, err := net.Listen("tcp", "127.0.0.1:") require.NoError(t, err) defer func() { require.NoError(t, l.Close()) }() var wg sync.WaitGroup wg.Add(2) go func() { defer wg.Done() in := &bytes.Buffer{} out := &bytes.Buffer{} timeout, err := time.ParseDuration("10s") require.NoError(t, err) client := NewTelnetClient(l.Addr().String(), timeout, ioutil.NopCloser(in), out) require.NoError(t, client.Connect()) defer func() { require.NoError(t, client.Close()) }() in.WriteString("hello\n") err = client.Send() require.NoError(t, err) err = client.Receive() require.Error(t, err, "...connection closed by peer") }() go func() { defer wg.Done() conn, err := l.Accept() require.NoError(t, err) require.NotNil(t, conn) request := make([]byte, 1024) n, err := conn.Read(request) require.NoError(t, err) require.Equal(t, "hello\n", string(request)[:n]) require.NoError(t, conn.Close()) }() wg.Wait() }) }