github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/deadlineconn/deadlineconn_test.go (about) 1 // Copyright (c) 2015-2022 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package deadlineconn 19 20 import ( 21 "bufio" 22 "io" 23 "net" 24 "sync" 25 "testing" 26 "time" 27 ) 28 29 // Test deadlineconn handles read timeout properly by reading two messages beyond deadline. 30 func TestBuffConnReadTimeout(t *testing.T) { 31 l, err := net.Listen("tcp", "localhost:0") 32 if err != nil { 33 t.Fatalf("unable to create listener. %v", err) 34 } 35 defer l.Close() 36 serverAddr := l.Addr().String() 37 38 tcpListener, ok := l.(*net.TCPListener) 39 if !ok { 40 t.Fatalf("failed to assert to net.TCPListener") 41 } 42 43 var wg sync.WaitGroup 44 wg.Add(1) 45 go func() { 46 defer wg.Done() 47 48 tcpConn, terr := tcpListener.AcceptTCP() 49 if terr != nil { 50 t.Errorf("failed to accept new connection. %v", terr) 51 return 52 } 53 deadlineconn := New(tcpConn) 54 deadlineconn.WithReadDeadline(time.Second) 55 deadlineconn.WithWriteDeadline(time.Second) 56 defer deadlineconn.Close() 57 58 // Read a line 59 b := make([]byte, 12) 60 _, terr = deadlineconn.Read(b) 61 if terr != nil { 62 t.Errorf("failed to read from client. %v", terr) 63 return 64 } 65 received := string(b) 66 if received != "message one\n" { 67 t.Errorf(`server: expected: "message one\n", got: %v`, received) 68 return 69 } 70 71 // Wait for more than read timeout to simulate processing. 72 time.Sleep(3 * time.Second) 73 74 _, terr = deadlineconn.Read(b) 75 if terr != nil { 76 t.Errorf("failed to read from client. %v", terr) 77 return 78 } 79 received = string(b) 80 if received != "message two\n" { 81 t.Errorf(`server: expected: "message two\n", got: %v`, received) 82 return 83 } 84 85 // Send a response. 86 _, terr = io.WriteString(deadlineconn, "messages received\n") 87 if terr != nil { 88 t.Errorf("failed to write to client. %v", terr) 89 return 90 } 91 }() 92 93 c, err := net.Dial("tcp", serverAddr) 94 if err != nil { 95 t.Fatalf("unable to connect to server. %v", err) 96 } 97 defer c.Close() 98 99 _, err = io.WriteString(c, "message one\n") 100 if err != nil { 101 t.Fatalf("failed to write to server. %v", err) 102 } 103 _, err = io.WriteString(c, "message two\n") 104 if err != nil { 105 t.Fatalf("failed to write to server. %v", err) 106 } 107 108 received, err := bufio.NewReader(c).ReadString('\n') 109 if err != nil { 110 t.Fatalf("failed to read from server. %v", err) 111 } 112 if received != "messages received\n" { 113 t.Fatalf(`client: expected: "messages received\n", got: %v`, received) 114 } 115 116 wg.Wait() 117 }