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