github.com/GuanceCloud/cliutils@v1.1.21/logger/tcpudp_test.go (about) 1 // Unless explicitly stated otherwise all files in this repository are licensed 2 // under the MIT License. 3 // This product includes software developed at Guance Cloud (https://www.guance.com/). 4 // Copyright 2021-present Guance, Inc. 5 6 package logger 7 8 import ( 9 "bytes" 10 "fmt" 11 "net" 12 "net/url" 13 "testing" 14 "time" 15 16 tu "github.com/GuanceCloud/cliutils/testutil" 17 ) 18 19 type listener interface { 20 Close() error 21 } 22 23 var stopListenMsg = "__stop_server" 24 25 func serve(t *testing.T, 26 expectLogCnt int, 27 proto string, 28 listen string, 29 ch chan interface{}, 30 ) (listener, error) { 31 t.Helper() 32 switch proto { 33 case "udp": 34 l, err := net.ListenPacket("udp", listen) 35 if err != nil { 36 t.Logf("net.ListenPacket: %s", err) 37 return nil, err 38 } 39 40 go func() { 41 readBuf := make([]byte, 1024) 42 lines := []string{} 43 for { 44 n, _, err := l.ReadFrom(readBuf) 45 if err != nil { 46 t.Error(err) 47 ch <- nil 48 return 49 } 50 51 if bytes.Contains(readBuf, []byte(stopListenMsg)) { 52 for _, line := range lines { 53 t.Logf("log data: %s", line) 54 } 55 56 tu.Equals(t, expectLogCnt, len(lines)) 57 ch <- nil 58 return 59 } else { 60 t.Logf("get log data: %s", string(readBuf[:n])) 61 lines = append(lines, string(readBuf[:n])) 62 } 63 } 64 }() 65 return l, nil 66 67 case "tcp": 68 l, err := net.Listen("tcp", listen) 69 if err != nil { 70 return nil, err 71 } 72 73 t.Logf("listen to %s ok", listen) 74 75 go func() { 76 for { 77 conn, err := l.Accept() 78 if err != nil { 79 t.Logf("l.Accept: %s", err) 80 ch <- nil 81 return 82 } 83 84 go func(c net.Conn) { 85 lines := []string{} 86 readBuf := make([]byte, 1024) 87 defer c.Close() 88 89 for { 90 n, err := c.Read(readBuf) 91 if err != nil { 92 t.Error(err) 93 } 94 95 if bytes.Contains(readBuf, []byte(stopListenMsg)) { 96 for _, line := range lines { 97 t.Logf("log data: %s", line) 98 } 99 100 tu.Equals(t, expectLogCnt, len(lines)) 101 return 102 } else { 103 t.Logf("get log data: %s", string(readBuf[:n])) 104 lines = append(lines, string(readBuf[:n])) 105 } 106 } 107 }(conn) 108 } 109 }() 110 111 return l, nil 112 } 113 114 return nil, fmt.Errorf("should not been here") 115 } 116 117 func TestRemoteLogger(t *testing.T) { 118 cases := []struct { 119 name string 120 file string 121 level string 122 options int 123 logs [][2]string 124 expectLogCnt int 125 ch chan interface{} 126 fail bool 127 }{ 128 { 129 name: "tcp-logger-server", 130 file: "tcp://0.0.0.0:12345", 131 options: OPT_DEFAULT, 132 level: DEBUG, 133 logs: [][2]string{ 134 {DEBUG, "this is debug msg"}, 135 {INFO, "this is info msg"}, 136 }, 137 expectLogCnt: 2, 138 ch: make(chan interface{}), 139 }, 140 141 { 142 name: "udp-logger-server", 143 file: "udp://0.0.0.0:12345", 144 options: OPT_DEFAULT, 145 level: DEBUG, 146 logs: [][2]string{ 147 {DEBUG, "this is debug msg"}, 148 {INFO, "this is info msg"}, 149 }, 150 expectLogCnt: 2, 151 ch: make(chan interface{}), 152 }, 153 154 { 155 name: "udp-logger-server-with-color-log", 156 file: "udp://0.0.0.0:12345", 157 options: OPT_DEFAULT | OPT_COLOR, 158 level: DEBUG, 159 logs: [][2]string{ 160 {DEBUG, "this is debug msg"}, 161 {INFO, "this is info msg"}, 162 }, 163 expectLogCnt: 2, 164 ch: make(chan interface{}), 165 }, 166 167 { 168 name: "invalid-remote-logger", 169 file: "http://0.0.0.0:12345", 170 options: OPT_DEFAULT | OPT_COLOR, 171 fail: true, 172 }, 173 } 174 175 for _, tc := range cases { 176 t.Run(tc.name, func(t *testing.T) { 177 u, err := url.Parse(tc.file) 178 if err != nil { 179 t.Error(err) 180 } 181 182 var listen listener 183 184 switch u.Scheme { 185 case "tcp", "udp": 186 listen, err = serve(t, tc.expectLogCnt, u.Scheme, u.Host, tc.ch) 187 if err != nil { 188 t.Error(err) 189 } 190 time.Sleep(time.Second) // wait server ok 191 default: 192 t.Logf("invalid schema") 193 return 194 } 195 196 rs, err := newRemoteSync(u.Scheme, u.Host) 197 if err != nil { 198 t.Error(err) 199 } 200 201 rl, err := newCustomizeRootLogger(tc.level, tc.options, rs) 202 root = rl 203 204 if err != nil { 205 t.Error(err) 206 } 207 208 l := SLogger(tc.name) 209 210 for _, arr := range tc.logs { 211 if len(arr) != 2 { 212 t.Error("expect length 2") 213 } 214 215 switch arr[0] { 216 case DEBUG: 217 l.Debugf("-> %s", arr[1]) 218 case INFO: 219 l.Infof("-> %s", arr[1]) 220 } 221 222 time.Sleep(time.Millisecond * 10) 223 } 224 225 // end of log message: shutdown server 226 l.Info(stopListenMsg) 227 time.Sleep(time.Millisecond * 10) // wait server receive ok 228 229 listen.Close() 230 <-tc.ch 231 }) 232 } 233 }