github.com/matrixorigin/matrixone@v1.2.0/pkg/frontend/iopackage_test.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package frontend 16 17 import ( 18 "context" 19 "fmt" 20 "sync" 21 "sync/atomic" 22 "testing" 23 "time" 24 25 "github.com/fagongzi/goetty/v2" 26 "github.com/fagongzi/goetty/v2/codec" 27 "github.com/fagongzi/goetty/v2/codec/simple" 28 "github.com/smartystreets/goconvey/convey" 29 30 "github.com/matrixorigin/matrixone/pkg/common/moerr" 31 "github.com/matrixorigin/matrixone/pkg/logutil" 32 ) 33 34 func TestBasicIOPackage_WriteUint8(t *testing.T) { 35 var buffer = make([]byte, 256) 36 var pos = 0 37 var IO IOPackageImpl 38 var prePos int 39 for i := 0; i < 256; i++ { 40 prePos = pos 41 pos = IO.WriteUint8(buffer, pos, uint8(i)) 42 if pos != prePos+1 { 43 t.Errorf("WriteUint8 value %d failed.", i) 44 break 45 } 46 if buffer[i] != uint8(i) { 47 t.Errorf("WriteUint8 value %d failed.", i) 48 break 49 } 50 } 51 } 52 53 func TestBasicIOPackage_WriteUint16(t *testing.T) { 54 var buffer = make([]byte, 65536*2) 55 var pos = 0 56 var IO IOPackageImpl 57 var prePos int 58 for i := 0; i < 65536; i++ { 59 value := uint16(i) 60 prePos = pos 61 pos = IO.WriteUint16(buffer, pos, value) 62 if pos != prePos+2 { 63 t.Errorf("WriteUint16 value %d failed.", value) 64 break 65 } 66 67 var b1, b2 uint8 68 if IO.IsLittleEndian() { 69 b1 = uint8(value & 0xff) 70 b2 = uint8((value >> 8) & 0xff) 71 } else { 72 b1 = uint8((value >> 8) & 0xff) 73 b2 = uint8(value & 0xff) 74 } 75 76 p := 2 * i 77 if !(buffer[p] == b1 && buffer[p+1] == b2) { 78 t.Errorf("WriteUint16 value %d failed.", value) 79 break 80 } 81 } 82 } 83 84 func TestBasicIOPackage_WriteUint32(t *testing.T) { 85 var buffer = make([]byte, 65536*4) 86 var pos = 0 87 var IO IOPackageImpl 88 var prePos int 89 for i := 0; i < 65536; i++ { 90 value := uint32(0x01010101 + i) 91 prePos = pos 92 pos = IO.WriteUint32(buffer, pos, value) 93 if pos != prePos+4 { 94 t.Errorf("WriteUint32 value %d failed.", value) 95 break 96 } 97 var b1, b2, b3, b4 uint8 98 if IO.IsLittleEndian() { 99 b1 = uint8(value & 0xff) 100 b2 = uint8((value >> 8) & 0xff) 101 b3 = uint8((value >> 16) & 0xff) 102 b4 = uint8((value >> 24) & 0xff) 103 } else { 104 b4 = uint8(value & 0xff) 105 b3 = uint8((value >> 8) & 0xff) 106 b2 = uint8((value >> 16) & 0xff) 107 b1 = uint8((value >> 24) & 0xff) 108 } 109 110 p := 4 * i 111 if !(buffer[p] == b1 && buffer[p+1] == b2 && buffer[p+2] == b3 && buffer[p+3] == b4) { 112 t.Errorf("WriteUint32 value %d failed.", value) 113 break 114 } 115 } 116 } 117 118 func TestBasicIOPackage_WriteUint64(t *testing.T) { 119 var buffer = make([]byte, 65536*8) 120 var pos = 0 121 var IO IOPackageImpl 122 var prePos int 123 for i := 0; i < 65536; i++ { 124 value := uint64(0x0101010101010101 + i) 125 prePos = pos 126 pos = IO.WriteUint64(buffer, pos, value) 127 if pos != prePos+8 { 128 t.Errorf("WriteUint64 value %d failed.", value) 129 break 130 } 131 var b1, b2, b3, b4, b5, b6, b7, b8 uint8 132 if IO.IsLittleEndian() { 133 b1 = uint8(value & 0xff) 134 b2 = uint8((value >> 8) & 0xff) 135 b3 = uint8((value >> 16) & 0xff) 136 b4 = uint8((value >> 24) & 0xff) 137 b5 = uint8((value >> 32) & 0xff) 138 b6 = uint8((value >> 40) & 0xff) 139 b7 = uint8((value >> 48) & 0xff) 140 b8 = uint8((value >> 56) & 0xff) 141 } else { 142 b8 = uint8(value & 0xff) 143 b7 = uint8((value >> 8) & 0xff) 144 b6 = uint8((value >> 16) & 0xff) 145 b5 = uint8((value >> 24) & 0xff) 146 b4 = uint8((value >> 32) & 0xff) 147 b3 = uint8((value >> 40) & 0xff) 148 b2 = uint8((value >> 48) & 0xff) 149 b1 = uint8((value >> 56) & 0xff) 150 } 151 152 p := 8 * i 153 if !(buffer[p] == b1 && buffer[p+1] == b2 && buffer[p+2] == b3 && buffer[p+3] == b4 && 154 buffer[p+4] == b5 && buffer[p+5] == b6 && buffer[p+6] == b7 && buffer[p+7] == b8) { 155 t.Errorf("WriteUint64 value %d failed.", value) 156 break 157 } 158 } 159 } 160 161 func TestBasicIOPackage_ReadUint8(t *testing.T) { 162 var buffer = make([]byte, 256) 163 var pos = 0 164 var IO IOPackageImpl 165 var prePos int 166 for i := 0; i < 256; i++ { 167 prePos = pos 168 IO.WriteUint8(buffer, pos, uint8(i)) 169 rValue, pos, ok := IO.ReadUint8(buffer, pos) 170 if !ok || rValue != uint8(i) || pos != prePos+1 { 171 t.Errorf("ReadUint8 value %d failed.", i) 172 break 173 } 174 } 175 } 176 177 func TestBasicIOPackage_ReadUint16(t *testing.T) { 178 var buffer = make([]byte, 65536*2) 179 var pos = 0 180 var IO IOPackageImpl 181 var prePos int 182 for i := 0; i < 65536; i++ { 183 value := uint16(i) 184 prePos = pos 185 IO.WriteUint16(buffer, pos, value) 186 rValue, pos, ok := IO.ReadUint16(buffer, pos) 187 if !ok || pos != prePos+2 || rValue != value { 188 t.Errorf("ReadUint16 value %d failed.", value) 189 break 190 } 191 } 192 } 193 194 func TestBasicIOPackage_ReadUint32(t *testing.T) { 195 var buffer = make([]byte, 65536*4) 196 var pos = 0 197 var IO IOPackageImpl 198 var prePos int 199 for i := 0; i < 65536; i++ { 200 value := uint32(0x01010101 + i) 201 prePos = pos 202 IO.WriteUint32(buffer, pos, value) 203 rValue, pos, ok := IO.ReadUint32(buffer, pos) 204 if !ok || pos != prePos+4 || rValue != value { 205 t.Errorf("ReadUint32 value %d failed.", value) 206 break 207 } 208 } 209 } 210 211 func TestBasicIOPackage_ReadUint64(t *testing.T) { 212 var buffer = make([]byte, 65536*8) 213 var pos = 0 214 var IO IOPackageImpl 215 var prePos int 216 for i := 0; i < 65536; i++ { 217 value := uint64(0x0101010101010101 + i) 218 prePos = pos 219 IO.WriteUint64(buffer, pos, value) 220 rValue, pos, ok := IO.ReadUint64(buffer, pos) 221 if !ok || pos != prePos+8 || rValue != value { 222 t.Errorf("ReadUint64 value %d failed.", value) 223 break 224 } 225 } 226 } 227 228 var svrRun int32 229 230 func isClosed() bool { 231 return atomic.LoadInt32(&svrRun) != 0 232 } 233 234 func setServer(val int32) { 235 atomic.StoreInt32(&svrRun, val) 236 } 237 238 func echoHandler(session goetty.IOSession, msg interface{}, received uint64) error { 239 value, ok := msg.(string) 240 if !ok { 241 return moerr.NewInternalError(context.TODO(), "convert to string failed") 242 } 243 244 err := session.Write(value, goetty.WriteOptions{Flush: true}) 245 if err != nil { 246 return err 247 } 248 return nil 249 } 250 251 func echoServer(handler func(goetty.IOSession, interface{}, uint64) error, aware goetty.IOSessionAware, 252 codec codec.Codec) { 253 echoServer, err := goetty.NewApplication("127.0.0.1:6001", handler, 254 goetty.WithAppSessionOptions( 255 goetty.WithSessionCodec(codec), 256 goetty.WithSessionLogger(logutil.GetGlobalLogger())), 257 goetty.WithAppSessionAware(aware)) 258 if err != nil { 259 panic(err) 260 } 261 err = echoServer.Start() 262 if err != nil { 263 panic(err) 264 } 265 setServer(0) 266 267 fmt.Println("Server started") 268 to := NewTimeout(5*time.Minute, false) 269 for !isClosed() && !to.isTimeout() { 270 } 271 err = echoServer.Stop() 272 if err != nil { 273 return 274 } 275 fmt.Println("Server exited") 276 } 277 278 func echoClient() { 279 addrPort := "localhost:6001" 280 io := goetty.NewIOSession(goetty.WithSessionCodec(simple.NewStringCodec())) 281 err := io.Connect(addrPort, time.Second*3) 282 if err != nil { 283 fmt.Println("connect server failed.", err.Error()) 284 return 285 } 286 287 alphabet := [10]string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"} 288 289 for i := 0; i < 10; i++ { 290 err := io.Write(alphabet[i], goetty.WriteOptions{Flush: true}) 291 if err != nil { 292 fmt.Println("client writes packet failed.", err.Error()) 293 break 294 } 295 fmt.Printf("client writes %s.\n", alphabet[i]) 296 data, err := io.Read(goetty.ReadOptions{}) 297 if err != nil { 298 fmt.Println("client reads packet failed.", err.Error()) 299 break 300 } 301 value, ok := data.(string) 302 if !ok { 303 fmt.Println("convert to string failed.") 304 break 305 } 306 fmt.Printf("client reads %s.\n", value) 307 if value != alphabet[i] { 308 fmt.Printf("echo failed. send %s but response %s\n", alphabet[i], value) 309 break 310 } 311 } 312 err = io.Close() 313 if err != nil { 314 return 315 } 316 } 317 318 func TestIOPackageImpl_ReadPacket(t *testing.T) { 319 wg := sync.WaitGroup{} 320 wg.Add(1) 321 go func() { 322 defer wg.Done() 323 echoServer(echoHandler, nil, simple.NewStringCodec()) 324 }() 325 326 to := NewTimeout(1*time.Minute, false) 327 for isClosed() && !to.isTimeout() { 328 } 329 time.Sleep(15 * time.Second) 330 echoClient() 331 setServer(1) 332 wg.Wait() 333 } 334 335 func Test_AppendUint(t *testing.T) { 336 convey.Convey("AppendUint succ", t, func() { 337 var io IOPackageImpl 338 var data, data2 = []byte{'a'}, []byte{'a', 'b'} 339 var value uint8 = 'b' 340 data = io.AppendUint8(data, value) 341 convey.So(data, convey.ShouldResemble, data2) 342 343 var value2 uint16 = 'c' 344 data = io.AppendUint16(data, value2) 345 data2 = append(data2, []byte{0, 'c'}...) 346 convey.So(data, convey.ShouldResemble, data2) 347 348 var value3 uint32 = 'd' 349 data = io.AppendUint32(data, value3) 350 data2 = append(data2, []byte{0, 0, 0, 'd'}...) 351 convey.So(data, convey.ShouldResemble, data2) 352 353 var value4 uint64 = 'e' 354 data = io.AppendUint64(data, value4) 355 data2 = append(data2, []byte{0, 0, 0, 0, 0, 0, 0, 'e'}...) 356 convey.So(data, convey.ShouldResemble, data2) 357 358 var pos = 9 359 u, i, b := io.ReadUint64(data, pos) 360 convey.So(u, convey.ShouldEqual, 0) 361 convey.So(i, convey.ShouldEqual, 0) 362 convey.So(b, convey.ShouldEqual, false) 363 364 io.endian = true 365 pos = 0 366 _, i, b = io.ReadUint64(data, pos) 367 convey.So(i, convey.ShouldEqual, 8) 368 convey.So(b, convey.ShouldEqual, true) 369 }) 370 }