From 9585f74c5a5bc5abdeb3b0a3a74c2ef8d5983a5b Mon Sep 17 00:00:00 2001 From: DimVlas Date: Mon, 6 Jan 2025 23:36:56 +0300 Subject: [PATCH] hw11. is comleted --- hw11_telnet_client/main.go | 2 - hw11_telnet_client/telnet.go | 4 -- hw11_telnet_client/telnet_test.go | 103 ++++++++++++++++++++++++++++-- hw11_telnet_client/test.sh | 2 +- 4 files changed, 97 insertions(+), 14 deletions(-) diff --git a/hw11_telnet_client/main.go b/hw11_telnet_client/main.go index 7f185c0..ec0439f 100644 --- a/hw11_telnet_client/main.go +++ b/hw11_telnet_client/main.go @@ -73,7 +73,6 @@ func main() { clientErr <- ErrServerExit }() - //for { select { case <-c: log.Println("...Connection was closed by", path.Base(os.Args[0])) @@ -90,5 +89,4 @@ func main() { log.Println(err) return } - //} } diff --git a/hw11_telnet_client/telnet.go b/hw11_telnet_client/telnet.go index 21c3651..bbe86f6 100644 --- a/hw11_telnet_client/telnet.go +++ b/hw11_telnet_client/telnet.go @@ -24,9 +24,6 @@ func NewTelnetClient(address string, timeout time.Duration, in io.ReadCloser, ou } } -// Place your code here. -// P.S. Author's solution takes no more than 50 lines. - type telnetClient struct { timeout time.Duration addr string @@ -55,7 +52,6 @@ func (tc *telnetClient) Send() error { scanner := bufio.NewScanner(tc.in) for scanner.Scan() { mess := append(scanner.Bytes(), '\n') - if _, err := tc.conn.Write(mess); err != nil { return err } diff --git a/hw11_telnet_client/telnet_test.go b/hw11_telnet_client/telnet_test.go index a517547..972518b 100644 --- a/hw11_telnet_client/telnet_test.go +++ b/hw11_telnet_client/telnet_test.go @@ -62,6 +62,49 @@ func TestTelnetClient(t *testing.T) { wg.Wait() }) + + t.Run("bad_connect", func(t *testing.T) { + in := &bytes.Buffer{} + out := &bytes.Buffer{} + client := NewTelnetClient("localhost:4242", 1*time.Second, io.NopCloser(in), out) + + require.EqualError(t, client.Connect(), "dial tcp [::1]:4242: connect: connection refused") + }) + + t.Run("without_connect", func(t *testing.T) { + in := &bytes.Buffer{} + out := &bytes.Buffer{} + client := NewTelnetClient("localhost:4242", 5*time.Second, io.NopCloser(in), out) + + require.ErrorIs(t, client.Send(), ErrConnNotEstablish) + require.ErrorIs(t, client.Receive(), ErrConnNotEstablish) + require.NoError(t, client.Close()) + }) + + t.Run("close_listen", func(t *testing.T) { + l, err := net.Listen("tcp", "127.0.0.1:") + require.NoError(t, err) + + in := &bytes.Buffer{} + out := &bytes.Buffer{} + + timeout, err := time.ParseDuration("1s") + require.NoError(t, err) + + client := NewTelnetClient(l.Addr().String(), timeout, io.NopCloser(in), out) + require.NoError(t, client.Connect()) + defer func() { require.NoError(t, client.Close()) }() + + l.Close() + + conn := client.(*telnetClient).conn + + in.WriteString("hello\n") + require.EqualError(t, client.Send(), "write tcp "+conn.LocalAddr().String()+"->"+conn.RemoteAddr().String()+": write: connection reset by peer") + + // при получении возращает EOF, который перехватывается т.к. трактуется как корректное окончание + require.NoError(t, client.Receive()) + }) } var testParamData = []struct { @@ -70,10 +113,10 @@ var testParamData = []struct { timeout time.Duration host string port int - err error + err string }{ { - name: "parseArgs success", + name: "parseArgs_success", args: []string{ "--timeout=5s", "localhost", @@ -82,10 +125,21 @@ var testParamData = []struct { timeout: 5 * time.Second, host: "localhost", port: 12345, - err: nil, + err: "", + }, + { + name: "parseArgs_success_without_timeout", + args: []string{ + "localhost", + "12345", + }, + timeout: 10 * time.Second, + host: "localhost", + port: 12345, + err: "", }, { - name: "parseArgs bad timeout", + name: "parseArgs_bad_timeout", args: []string{ "--timeout=5ass", "localhost", @@ -94,7 +148,42 @@ var testParamData = []struct { timeout: 5 * time.Second, host: "", port: 0, - err: ErrParseArgs, + err: `parse args error: invalid value "5ass" for flag -timeout: parse error`, + }, + { + name: "parseArgs_bad_args_count", + args: []string{ + "--timeout=5s", + "localhost", + }, + timeout: 5 * time.Second, + host: "", + port: 0, + err: "parse args error: not enough arguments", + }, + { + name: "parseArgs_invalid_host", + args: []string{ + "--timeout=5s", + "domain/localhost", + "123", + }, + timeout: 5 * time.Second, + host: "", + port: 0, + err: "parse args error host: string \"domain/localhost\" cannot be a host name or address", + }, + { + name: "parseArgs_invalid_port", + args: []string{ + "--timeout=5s", + "localhost", + "a123", + }, + timeout: 5 * time.Second, + host: "localhost", + port: 0, + err: "parse args error port: strconv.Atoi: parsing \"a123\": invalid syntax", }, } @@ -110,8 +199,8 @@ func TestParseArgs(t *testing.T) { err := parseArgs(data.args, &timeout, &host, &port) - if data.err != nil { - require.ErrorIs(t, err, data.err) + if data.err != "" { + require.EqualError(t, err, data.err) } else { require.NoError(t, err) } diff --git a/hw11_telnet_client/test.sh b/hw11_telnet_client/test.sh index 422b594..ae4ed75 100755 --- a/hw11_telnet_client/test.sh +++ b/hw11_telnet_client/test.sh @@ -3,7 +3,7 @@ set -xeuo pipefail go build -o go-telnet -(echo -e "Hello\nFrom\nNC\n" && cat 2>/dev/null) | nc -l localhost 4242 >/tmp/nc.out & +(echo -e "Hello\nFrom\nNC\n" && cat 2>/dev/null) | nc -l 127.0.0.1 -p 4242 >/tmp/nc.out & NC_PID=$! sleep 1