github.com/nats-io/nats-server/v2@v2.11.0-preview.2/server/split_test.go (about) 1 // Copyright 2012-2018 The NATS Authors 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package server 15 16 import ( 17 "bytes" 18 "net" 19 "testing" 20 ) 21 22 func TestSplitBufferSubOp(t *testing.T) { 23 cli, trash := net.Pipe() 24 defer cli.Close() 25 defer trash.Close() 26 27 s := &Server{gacc: NewAccount(globalAccountName)} 28 if err := s.newGateway(DefaultOptions()); err != nil { 29 t.Fatalf("Error creating gateways: %v", err) 30 } 31 s.registerAccount(s.gacc) 32 c := &client{srv: s, acc: s.gacc, msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription), nc: cli} 33 34 subop := []byte("SUB foo 1\r\n") 35 subop1 := subop[:6] 36 subop2 := subop[6:] 37 38 if err := c.parse(subop1); err != nil { 39 t.Fatalf("Unexpected parse error: %v\n", err) 40 } 41 if c.state != SUB_ARG { 42 t.Fatalf("Expected SUB_ARG state vs %d\n", c.state) 43 } 44 if err := c.parse(subop2); err != nil { 45 t.Fatalf("Unexpected parse error: %v\n", err) 46 } 47 if c.state != OP_START { 48 t.Fatalf("Expected OP_START state vs %d\n", c.state) 49 } 50 r := s.gacc.sl.Match("foo") 51 if r == nil || len(r.psubs) != 1 { 52 t.Fatalf("Did not match subscription properly: %+v\n", r) 53 } 54 sub := r.psubs[0] 55 if !bytes.Equal(sub.subject, []byte("foo")) { 56 t.Fatalf("Subject did not match expected 'foo' : '%s'\n", sub.subject) 57 } 58 if !bytes.Equal(sub.sid, []byte("1")) { 59 t.Fatalf("Sid did not match expected '1' : '%s'\n", sub.sid) 60 } 61 if sub.queue != nil { 62 t.Fatalf("Received a non-nil queue: '%s'\n", sub.queue) 63 } 64 } 65 66 func TestSplitBufferUnsubOp(t *testing.T) { 67 s := &Server{gacc: NewAccount(globalAccountName), gateway: &srvGateway{}} 68 s.registerAccount(s.gacc) 69 c := &client{srv: s, acc: s.gacc, msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)} 70 71 subop := []byte("SUB foo 1024\r\n") 72 if err := c.parse(subop); err != nil { 73 t.Fatalf("Unexpected parse error: %v\n", err) 74 } 75 if c.state != OP_START { 76 t.Fatalf("Expected OP_START state vs %d\n", c.state) 77 } 78 79 unsubop := []byte("UNSUB 1024\r\n") 80 unsubop1 := unsubop[:8] 81 unsubop2 := unsubop[8:] 82 83 if err := c.parse(unsubop1); err != nil { 84 t.Fatalf("Unexpected parse error: %v\n", err) 85 } 86 if c.state != UNSUB_ARG { 87 t.Fatalf("Expected UNSUB_ARG state vs %d\n", c.state) 88 } 89 if err := c.parse(unsubop2); err != nil { 90 t.Fatalf("Unexpected parse error: %v\n", err) 91 } 92 if c.state != OP_START { 93 t.Fatalf("Expected OP_START state vs %d\n", c.state) 94 } 95 r := s.gacc.sl.Match("foo") 96 if r != nil && len(r.psubs) != 0 { 97 t.Fatalf("Should be no subscriptions in results: %+v\n", r) 98 } 99 } 100 101 func TestSplitBufferPubOp(t *testing.T) { 102 c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)} 103 pub := []byte("PUB foo.bar INBOX.22 11\r\nhello world\r") 104 pub1 := pub[:2] 105 pub2 := pub[2:9] 106 pub3 := pub[9:15] 107 pub4 := pub[15:22] 108 pub5 := pub[22:25] 109 pub6 := pub[25:33] 110 pub7 := pub[33:] 111 112 if err := c.parse(pub1); err != nil { 113 t.Fatalf("Unexpected parse error: %v\n", err) 114 } 115 if c.state != OP_PU { 116 t.Fatalf("Expected OP_PU state vs %d\n", c.state) 117 } 118 if err := c.parse(pub2); err != nil { 119 t.Fatalf("Unexpected parse error: %v\n", err) 120 } 121 if c.state != PUB_ARG { 122 t.Fatalf("Expected OP_PU state vs %d\n", c.state) 123 } 124 if err := c.parse(pub3); err != nil { 125 t.Fatalf("Unexpected parse error: %v\n", err) 126 } 127 if c.state != PUB_ARG { 128 t.Fatalf("Expected OP_PU state vs %d\n", c.state) 129 } 130 if err := c.parse(pub4); err != nil { 131 t.Fatalf("Unexpected parse error: %v\n", err) 132 } 133 if c.state != PUB_ARG { 134 t.Fatalf("Expected PUB_ARG state vs %d\n", c.state) 135 } 136 if err := c.parse(pub5); err != nil { 137 t.Fatalf("Unexpected parse error: %v\n", err) 138 } 139 if c.state != MSG_PAYLOAD { 140 t.Fatalf("Expected MSG_PAYLOAD state vs %d\n", c.state) 141 } 142 143 // Check c.pa 144 if !bytes.Equal(c.pa.subject, []byte("foo.bar")) { 145 t.Fatalf("PUB arg subject incorrect: '%s'\n", c.pa.subject) 146 } 147 if !bytes.Equal(c.pa.reply, []byte("INBOX.22")) { 148 t.Fatalf("PUB arg reply subject incorrect: '%s'\n", c.pa.reply) 149 } 150 if c.pa.size != 11 { 151 t.Fatalf("PUB arg msg size incorrect: %d\n", c.pa.size) 152 } 153 if err := c.parse(pub6); err != nil { 154 t.Fatalf("Unexpected parse error: %v\n", err) 155 } 156 if c.state != MSG_PAYLOAD { 157 t.Fatalf("Expected MSG_PAYLOAD state vs %d\n", c.state) 158 } 159 if err := c.parse(pub7); err != nil { 160 t.Fatalf("Unexpected parse error: %v\n", err) 161 } 162 if c.state != MSG_END_N { 163 t.Fatalf("Expected MSG_END_N state vs %d\n", c.state) 164 } 165 } 166 167 func TestSplitBufferPubOp2(t *testing.T) { 168 c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)} 169 pub := []byte("PUB foo.bar INBOX.22 11\r\nhello world\r\n") 170 pub1 := pub[:30] 171 pub2 := pub[30:] 172 173 if err := c.parse(pub1); err != nil { 174 t.Fatalf("Unexpected parse error: %v\n", err) 175 } 176 if c.state != MSG_PAYLOAD { 177 t.Fatalf("Expected MSG_PAYLOAD state vs %d\n", c.state) 178 } 179 if err := c.parse(pub2); err != nil { 180 t.Fatalf("Unexpected parse error: %v\n", err) 181 } 182 if c.state != OP_START { 183 t.Fatalf("Expected OP_START state vs %d\n", c.state) 184 } 185 } 186 187 func TestSplitBufferPubOp3(t *testing.T) { 188 c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)} 189 pubAll := []byte("PUB foo bar 11\r\nhello world\r\n") 190 pub := pubAll[:16] 191 192 if err := c.parse(pub); err != nil { 193 t.Fatalf("Unexpected parse error: %v\n", err) 194 } 195 if !bytes.Equal(c.pa.subject, []byte("foo")) { 196 t.Fatalf("Unexpected subject: '%s' vs '%s'\n", c.pa.subject, "foo") 197 } 198 199 // Simulate next read of network, make sure pub state is saved 200 // until msg payload has cleared. 201 copy(pubAll, "XXXXXXXXXXXXXXXX") 202 if !bytes.Equal(c.pa.subject, []byte("foo")) { 203 t.Fatalf("Unexpected subject: '%s' vs '%s'\n", c.pa.subject, "foo") 204 } 205 if !bytes.Equal(c.pa.reply, []byte("bar")) { 206 t.Fatalf("Unexpected reply: '%s' vs '%s'\n", c.pa.reply, "bar") 207 } 208 if !bytes.Equal(c.pa.szb, []byte("11")) { 209 t.Fatalf("Unexpected size bytes: '%s' vs '%s'\n", c.pa.szb, "11") 210 } 211 } 212 213 func TestSplitBufferPubOp4(t *testing.T) { 214 c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)} 215 pubAll := []byte("PUB foo 11\r\nhello world\r\n") 216 pub := pubAll[:12] 217 218 if err := c.parse(pub); err != nil { 219 t.Fatalf("Unexpected parse error: %v\n", err) 220 } 221 if !bytes.Equal(c.pa.subject, []byte("foo")) { 222 t.Fatalf("Unexpected subject: '%s' vs '%s'\n", c.pa.subject, "foo") 223 } 224 225 // Simulate next read of network, make sure pub state is saved 226 // until msg payload has cleared. 227 copy(pubAll, "XXXXXXXXXXXX") 228 if !bytes.Equal(c.pa.subject, []byte("foo")) { 229 t.Fatalf("Unexpected subject: '%s' vs '%s'\n", c.pa.subject, "foo") 230 } 231 if !bytes.Equal(c.pa.reply, []byte("")) { 232 t.Fatalf("Unexpected reply: '%s' vs '%s'\n", c.pa.reply, "") 233 } 234 if !bytes.Equal(c.pa.szb, []byte("11")) { 235 t.Fatalf("Unexpected size bytes: '%s' vs '%s'\n", c.pa.szb, "11") 236 } 237 } 238 239 func TestSplitBufferPubOp5(t *testing.T) { 240 c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)} 241 pubAll := []byte("PUB foo 11\r\nhello world\r\n") 242 243 // Splits need to be on MSG_END_R now too, so make sure we check that. 244 // Split between \r and \n 245 pub := pubAll[:len(pubAll)-1] 246 247 if err := c.parse(pub); err != nil { 248 t.Fatalf("Unexpected parse error: %v\n", err) 249 } 250 if c.msgBuf == nil { 251 t.Fatalf("msgBuf should not be nil!\n") 252 } 253 if !bytes.Equal(c.msgBuf, []byte("hello world\r")) { 254 t.Fatalf("c.msgBuf did not snaphot the msg") 255 } 256 } 257 258 func TestSplitConnectArg(t *testing.T) { 259 c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)} 260 connectAll := []byte("CONNECT {\"verbose\":false,\"tls_required\":false," + 261 "\"user\":\"test\",\"pedantic\":true,\"pass\":\"pass\"}\r\n") 262 263 argJSON := connectAll[8:] 264 265 c1 := connectAll[:5] 266 c2 := connectAll[5:22] 267 c3 := connectAll[22 : len(connectAll)-2] 268 c4 := connectAll[len(connectAll)-2:] 269 270 if err := c.parse(c1); err != nil { 271 t.Fatalf("Unexpected parse error: %v\n", err) 272 } 273 if c.argBuf != nil { 274 t.Fatalf("Unexpected argBug placeholder.\n") 275 } 276 277 if err := c.parse(c2); err != nil { 278 t.Fatalf("Unexpected parse error: %v\n", err) 279 } 280 if c.argBuf == nil { 281 t.Fatalf("Expected argBug to not be nil.\n") 282 } 283 if !bytes.Equal(c.argBuf, argJSON[:14]) { 284 t.Fatalf("argBuf not correct, received %q, wanted %q\n", argJSON[:14], c.argBuf) 285 } 286 287 if err := c.parse(c3); err != nil { 288 t.Fatalf("Unexpected parse error: %v\n", err) 289 } 290 if c.argBuf == nil { 291 t.Fatalf("Expected argBug to not be nil.\n") 292 } 293 if !bytes.Equal(c.argBuf, argJSON[:len(argJSON)-2]) { 294 t.Fatalf("argBuf not correct, received %q, wanted %q\n", 295 argJSON[:len(argJSON)-2], c.argBuf) 296 } 297 298 if err := c.parse(c4); err != nil { 299 t.Fatalf("Unexpected parse error: %v\n", err) 300 } 301 if c.argBuf != nil { 302 t.Fatalf("Unexpected argBuf placeholder.\n") 303 } 304 } 305 306 func TestSplitDanglingArgBuf(t *testing.T) { 307 s := New(&defaultServerOptions) 308 c := &client{srv: s, acc: s.gacc, msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)} 309 310 // We test to make sure we do not dangle any argBufs after processing 311 // since that could lead to performance issues. 312 313 // SUB 314 subop := []byte("SUB foo 1\r\n") 315 c.parse(subop[:6]) 316 c.parse(subop[6:]) 317 if c.argBuf != nil { 318 t.Fatalf("Expected c.argBuf to be nil: %q\n", c.argBuf) 319 } 320 321 // UNSUB 322 unsubop := []byte("UNSUB 1024\r\n") 323 c.parse(unsubop[:8]) 324 c.parse(unsubop[8:]) 325 if c.argBuf != nil { 326 t.Fatalf("Expected c.argBuf to be nil: %q\n", c.argBuf) 327 } 328 329 // PUB 330 pubop := []byte("PUB foo.bar INBOX.22 11\r\nhello world\r\n") 331 c.parse(pubop[:22]) 332 c.parse(pubop[22:25]) 333 if c.argBuf == nil { 334 t.Fatal("Expected a non-nil argBuf!") 335 } 336 c.parse(pubop[25:]) 337 if c.argBuf != nil { 338 t.Fatalf("Expected c.argBuf to be nil: %q\n", c.argBuf) 339 } 340 341 // MINUS_ERR 342 errop := []byte("-ERR Too Long\r\n") 343 c.parse(errop[:8]) 344 c.parse(errop[8:]) 345 if c.argBuf != nil { 346 t.Fatalf("Expected c.argBuf to be nil: %q\n", c.argBuf) 347 } 348 349 // CONNECT_ARG 350 connop := []byte("CONNECT {\"verbose\":false,\"tls_required\":false," + 351 "\"user\":\"test\",\"pedantic\":true,\"pass\":\"pass\"}\r\n") 352 c.parse(connop[:22]) 353 c.parse(connop[22:]) 354 if c.argBuf != nil { 355 t.Fatalf("Expected c.argBuf to be nil: %q\n", c.argBuf) 356 } 357 358 // INFO_ARG 359 infoop := []byte("INFO {\"server_id\":\"id\"}\r\n") 360 c.parse(infoop[:8]) 361 c.parse(infoop[8:]) 362 if c.argBuf != nil { 363 t.Fatalf("Expected c.argBuf to be nil: %q\n", c.argBuf) 364 } 365 366 // MSG (the client has to be a ROUTE) 367 c = &client{msubs: -1, mpay: -1, subs: make(map[string]*subscription), kind: ROUTER, route: &route{}} 368 msgop := []byte("RMSG $foo foo 5\r\nhello\r\n") 369 c.parse(msgop[:5]) 370 c.parse(msgop[5:10]) 371 if c.argBuf == nil { 372 t.Fatal("Expected a non-nil argBuf") 373 } 374 if string(c.argBuf) != "$foo " { 375 t.Fatalf("Expected argBuf to be \"$foo \", got %q", string(c.argBuf)) 376 } 377 c.parse(msgop[10:]) 378 if c.argBuf != nil { 379 t.Fatalf("Expected argBuf to be nil: %q", c.argBuf) 380 } 381 if c.msgBuf != nil { 382 t.Fatalf("Expected msgBuf to be nil: %q", c.msgBuf) 383 } 384 385 c.state = OP_START 386 // Parse up-to somewhere in the middle of the payload. 387 // Verify that we have saved the MSG_ARG info 388 c.parse(msgop[:23]) 389 if c.argBuf == nil { 390 t.Fatal("Expected a non-nil argBuf") 391 } 392 if string(c.pa.account) != "$foo" { 393 t.Fatalf("Expected account to be \"$foo\", got %q", c.pa.account) 394 } 395 if string(c.pa.subject) != "foo" { 396 t.Fatalf("Expected subject to be \"foo\", got %q", c.pa.subject) 397 } 398 if string(c.pa.reply) != "" { 399 t.Fatalf("Expected reply to be \"\", got %q", c.pa.reply) 400 } 401 if c.pa.size != 5 { 402 t.Fatalf("Expected sid to 5, got %v", c.pa.size) 403 } 404 // msg buffer should be 405 if c.msgBuf == nil || string(c.msgBuf) != "hello\r" { 406 t.Fatalf("Expected msgBuf to be \"hello\r\", got %q", c.msgBuf) 407 } 408 c.parse(msgop[23:]) 409 // At the end, we should have cleaned-up both arg and msg buffers. 410 if c.argBuf != nil { 411 t.Fatalf("Expected argBuf to be nil: %q", c.argBuf) 412 } 413 if c.msgBuf != nil { 414 t.Fatalf("Expected msgBuf to be nil: %q", c.msgBuf) 415 } 416 } 417 418 func TestSplitRoutedMsgArg(t *testing.T) { 419 _, c, _ := setupClient() 420 defer c.close() 421 // Allow parser to process RMSG 422 c.kind = ROUTER 423 c.route = &route{} 424 425 b := make([]byte, 1024) 426 427 copy(b, []byte("RMSG $G hello.world 6040\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")) 428 c.parse(b) 429 430 copy(b, []byte("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\r\n")) 431 c.parse(b) 432 433 wantAccount := "$G" 434 wantSubject := "hello.world" 435 wantSzb := "6040" 436 437 if string(c.pa.account) != wantAccount { 438 t.Fatalf("Incorrect account: want %q, got %q", wantAccount, c.pa.account) 439 } 440 if string(c.pa.subject) != wantSubject { 441 t.Fatalf("Incorrect subject: want %q, got %q", wantSubject, c.pa.subject) 442 } 443 if string(c.pa.szb) != wantSzb { 444 t.Fatalf("Incorrect szb: want %q, got %q", wantSzb, c.pa.szb) 445 } 446 } 447 448 func TestSplitBufferMsgOp(t *testing.T) { 449 c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription), kind: ROUTER, route: &route{}} 450 msg := []byte("RMSG $G foo.bar _INBOX.22 11\r\nhello world\r") 451 msg1 := msg[:2] 452 msg2 := msg[2:9] 453 msg3 := msg[9:15] 454 msg4 := msg[15:22] 455 msg5 := msg[22:25] 456 msg6 := msg[25:37] 457 msg7 := msg[37:40] 458 msg8 := msg[40:] 459 460 if err := c.parse(msg1); err != nil { 461 t.Fatalf("Unexpected parse error: %v\n", err) 462 } 463 if c.state != OP_M { 464 t.Fatalf("Expected OP_M state vs %d\n", c.state) 465 } 466 if err := c.parse(msg2); err != nil { 467 t.Fatalf("Unexpected parse error: %v\n", err) 468 } 469 if c.state != MSG_ARG { 470 t.Fatalf("Expected MSG_ARG state vs %d\n", c.state) 471 } 472 if err := c.parse(msg3); err != nil { 473 t.Fatalf("Unexpected parse error: %v\n", err) 474 } 475 if c.state != MSG_ARG { 476 t.Fatalf("Expected MSG_ARG state vs %d\n", c.state) 477 } 478 if err := c.parse(msg4); err != nil { 479 t.Fatalf("Unexpected parse error: %v\n", err) 480 } 481 if c.state != MSG_ARG { 482 t.Fatalf("Expected MSG_ARG state vs %d\n", c.state) 483 } 484 if err := c.parse(msg5); err != nil { 485 t.Fatalf("Unexpected parse error: %v\n", err) 486 } 487 if c.state != MSG_ARG { 488 t.Fatalf("Expected MSG_ARG state vs %d\n", c.state) 489 } 490 if err := c.parse(msg6); err != nil { 491 t.Fatalf("Unexpected parse error: %v\n", err) 492 } 493 if c.state != MSG_PAYLOAD { 494 t.Fatalf("Expected MSG_PAYLOAD state vs %d\n", c.state) 495 } 496 497 // Check c.pa 498 if !bytes.Equal(c.pa.subject, []byte("foo.bar")) { 499 t.Fatalf("MSG arg subject incorrect: '%s'\n", c.pa.subject) 500 } 501 if !bytes.Equal(c.pa.reply, []byte("_INBOX.22")) { 502 t.Fatalf("MSG arg reply subject incorrect: '%s'\n", c.pa.reply) 503 } 504 if c.pa.size != 11 { 505 t.Fatalf("MSG arg msg size incorrect: %d\n", c.pa.size) 506 } 507 if err := c.parse(msg7); err != nil { 508 t.Fatalf("Unexpected parse error: %v\n", err) 509 } 510 if c.state != MSG_PAYLOAD { 511 t.Fatalf("Expected MSG_PAYLOAD state vs %d\n", c.state) 512 } 513 if err := c.parse(msg8); err != nil { 514 t.Fatalf("Unexpected parse error: %v\n", err) 515 } 516 if c.state != MSG_END_N { 517 t.Fatalf("Expected MSG_END_N state vs %d\n", c.state) 518 } 519 } 520 521 func TestSplitBufferLeafMsgArg(t *testing.T) { 522 c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription), kind: LEAF} 523 msg := []byte("LMSG foo + bar baz 11\r\n") 524 if err := c.parse(msg); err != nil { 525 t.Fatalf("Unexpected parse error: %v\n", err) 526 } 527 if c.state != MSG_PAYLOAD { 528 t.Fatalf("Expected MSG_PAYLOAD state vs %d\n", c.state) 529 } 530 checkPA := func(t *testing.T) { 531 t.Helper() 532 if !bytes.Equal(c.pa.subject, []byte("foo")) { 533 t.Fatalf("Expected subject to be %q, got %q", "foo", c.pa.subject) 534 } 535 if !bytes.Equal(c.pa.reply, []byte("bar")) { 536 t.Fatalf("Expected reply to be %q, got %q", "bar", c.pa.reply) 537 } 538 if n := len(c.pa.queues); n != 1 { 539 t.Fatalf("Expected 1 queue, got %v", n) 540 } 541 if !bytes.Equal(c.pa.queues[0], []byte("baz")) { 542 t.Fatalf("Expected queues to be %q, got %q", "baz", c.pa.queues) 543 } 544 } 545 checkPA(t) 546 547 // overwrite msg with payload 548 n := copy(msg, []byte("fffffffffff")) 549 if err := c.parse(msg[:n]); err != nil { 550 t.Fatalf("Unexpected parse error: %v\n", err) 551 } 552 if c.state != MSG_END_R { 553 t.Fatalf("Expected MSG_END_R state vs %d\n", c.state) 554 } 555 checkPA(t) 556 557 // Finish processing 558 copy(msg, []byte("\r\n")) 559 if err := c.parse(msg[:2]); err != nil { 560 t.Fatalf("Unexpected parse error: %v\n", err) 561 } 562 if c.state != OP_START { 563 t.Fatalf("Expected OP_START state vs %d\n", c.state) 564 } 565 if c.pa.subject != nil || c.pa.reply != nil || c.pa.queues != nil || c.pa.size != 0 || 566 c.pa.szb != nil || c.pa.arg != nil { 567 t.Fatalf("parser state not cleaned-up properly: %+v", c.pa) 568 } 569 }