github.com/vmware/transport-go@v1.3.4/stompserver/stomp_connection_test.go (about) 1 // Copyright 2019-2020 VMware, Inc. 2 // SPDX-License-Identifier: BSD-2-Clause 3 4 package stompserver 5 6 import ( 7 "errors" 8 "fmt" 9 "github.com/go-stomp/stomp/v3/frame" 10 "github.com/stretchr/testify/assert" 11 "sync" 12 "testing" 13 "time" 14 ) 15 16 type MockRawConnection struct { 17 connected bool 18 incomingFrames chan interface{} 19 lock sync.Mutex 20 currentDeadline time.Time 21 sentFrames []*frame.Frame 22 nextWriteErr error 23 nextReadErr error 24 writeWg *sync.WaitGroup 25 } 26 27 func NewMockRawConnection() *MockRawConnection { 28 return &MockRawConnection{ 29 connected: true, 30 incomingFrames: make(chan interface{}), 31 sentFrames: []*frame.Frame{}, 32 nextWriteErr: nil, 33 } 34 } 35 36 func (con *MockRawConnection) ReadFrame() (*frame.Frame, error) { 37 obj := <-con.incomingFrames 38 39 if obj == nil { 40 // heart-beat 41 return nil, nil 42 } 43 44 f, ok := obj.(*frame.Frame) 45 if ok { 46 return f, nil 47 } 48 49 return nil, obj.(error) 50 } 51 52 func (con *MockRawConnection) WriteFrame(frame *frame.Frame) error { 53 defer func() { con.nextWriteErr = nil }() 54 if con.nextWriteErr != nil { 55 return con.nextWriteErr 56 } 57 58 con.lock.Lock() 59 con.sentFrames = append(con.sentFrames, frame) 60 if con.writeWg != nil { 61 con.writeWg.Done() 62 } 63 con.lock.Unlock() 64 return nil 65 } 66 67 func (con *MockRawConnection) LastSentFrame() *frame.Frame { 68 return con.sentFrames[len(con.sentFrames)-1] 69 } 70 71 func (con *MockRawConnection) SetReadDeadline(t time.Time) { 72 con.lock.Lock() 73 con.currentDeadline = t 74 con.lock.Unlock() 75 } 76 77 func (con *MockRawConnection) getCurrentReadDeadline() time.Time { 78 con.lock.Lock() 79 defer con.lock.Unlock() 80 return con.currentDeadline 81 } 82 83 func (con *MockRawConnection) Close() error { 84 con.connected = false 85 return nil 86 } 87 88 func (con *MockRawConnection) SendConnectFrame() { 89 con.incomingFrames <- frame.New( 90 frame.CONNECT, 91 frame.AcceptVersion, "1.2") 92 } 93 94 func getTestStompConn(conf StompConfig, events chan *ConnEvent) (*stompConn, *MockRawConnection, chan *ConnEvent) { 95 if events == nil { 96 events = make(chan *ConnEvent, 1000) 97 } 98 99 rawConn := NewMockRawConnection() 100 return NewStompConn(rawConn, conf, events).(*stompConn), rawConn, events 101 } 102 103 func TestStompConn_Connect(t *testing.T) { 104 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 105 106 assert.NotNil(t, stompConn.GetId()) 107 108 assert.Equal(t, stompConn.state, connecting) 109 110 rawConn.incomingFrames <- frame.New(frame.CONNECT, frame.AcceptVersion, "1.0,1.2,1.1,1.3") 111 112 e := <-events 113 114 assert.Equal(t, e.eventType, ConnectionEstablished) 115 assert.Equal(t, e.conn, stompConn) 116 117 assert.Equal(t, len(rawConn.sentFrames), 1) 118 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.CONNECTED, 119 frame.Version, "1.2", 120 frame.HeartBeat, "0,0", 121 frame.Server, "stompServer/0.0.1"), true) 122 123 assert.Equal(t, stompConn.state, connected) 124 } 125 126 func TestStompConn_ConnectStomp10(t *testing.T) { 127 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 128 129 assert.Equal(t, stompConn.state, connecting) 130 131 rawConn.incomingFrames <- frame.New(frame.CONNECT, frame.AcceptVersion, "1.0") 132 133 e := <-events 134 135 assert.Equal(t, e.eventType, ConnectionClosed) 136 assert.Equal(t, e.conn, stompConn) 137 138 assert.Equal(t, len(rawConn.sentFrames), 1) 139 140 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.ERROR, 141 frame.Message, unsupportedStompVersionError.Error()), true) 142 143 assert.Equal(t, stompConn.state, closed) 144 assert.Equal(t, rawConn.connected, false) 145 } 146 147 func TestStompConn_ConnectInvalidStompVersion(t *testing.T) { 148 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 149 150 assert.Equal(t, stompConn.state, connecting) 151 152 rawConn.incomingFrames <- frame.New(frame.CONNECT, frame.AcceptVersion, "5.0") 153 154 e := <-events 155 156 assert.Equal(t, e.eventType, ConnectionClosed) 157 assert.Equal(t, e.conn, stompConn) 158 159 assert.Equal(t, len(rawConn.sentFrames), 1) 160 161 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.ERROR, 162 frame.Message, unsupportedStompVersionError.Error()), true) 163 164 assert.Equal(t, stompConn.state, closed) 165 assert.Equal(t, rawConn.connected, false) 166 } 167 168 func TestStompConn_ConnectWithReceiptHeader(t *testing.T) { 169 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 170 171 assert.Equal(t, stompConn.state, connecting) 172 173 rawConn.incomingFrames <- frame.New(frame.CONNECT, 174 frame.AcceptVersion, "1.2", 175 frame.Receipt, "receipt-id") 176 177 e := <-events 178 179 assert.Equal(t, e.eventType, ConnectionClosed) 180 assert.Equal(t, e.conn, stompConn) 181 182 assert.Equal(t, len(rawConn.sentFrames), 1) 183 184 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.ERROR, 185 frame.Message, invalidHeaderError.Error()), true) 186 187 assert.Equal(t, stompConn.state, closed) 188 assert.Equal(t, rawConn.connected, false) 189 } 190 191 func TestStompConn_ConnectMissingStompVersionHeader(t *testing.T) { 192 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 193 194 assert.Equal(t, stompConn.state, connecting) 195 196 rawConn.incomingFrames <- frame.New(frame.CONNECT) 197 198 e := <-events 199 assert.Equal(t, e.eventType, ConnectionClosed) 200 assert.Equal(t, e.conn, stompConn) 201 202 assert.Equal(t, len(rawConn.sentFrames), 1) 203 204 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.ERROR, 205 frame.Message, unsupportedStompVersionError.Error()), true) 206 207 assert.Equal(t, stompConn.state, closed) 208 } 209 210 func TestStompConn_ConnectInvalidHeartbeatHeader(t *testing.T) { 211 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 212 213 assert.Equal(t, stompConn.state, connecting) 214 215 rawConn.incomingFrames <- frame.New(frame.CONNECT, 216 frame.AcceptVersion, "1.2", 217 frame.HeartBeat, "12,asd") 218 219 e := <-events 220 221 assert.Equal(t, e.eventType, ConnectionClosed) 222 assert.Equal(t, e.conn, stompConn) 223 224 assert.Equal(t, len(rawConn.sentFrames), 1) 225 226 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.ERROR, 227 frame.Message, frame.ErrInvalidHeartBeat.Error()), true) 228 229 assert.Equal(t, stompConn.state, closed) 230 assert.Equal(t, rawConn.connected, false) 231 } 232 233 func TestStompConn_InvalidStompCommand(t *testing.T) { 234 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 235 236 assert.Equal(t, stompConn.state, connecting) 237 238 rawConn.incomingFrames <- frame.New("invalid-stomp-command", 239 frame.AcceptVersion, "1.2") 240 241 e := <-events 242 243 assert.Equal(t, e.eventType, ConnectionClosed) 244 assert.Equal(t, e.conn, stompConn) 245 246 assert.Equal(t, len(rawConn.sentFrames), 1) 247 248 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.ERROR, 249 frame.Message, unsupportedStompCommandError.Error()), true) 250 251 assert.Equal(t, stompConn.state, closed) 252 assert.Equal(t, rawConn.connected, false) 253 } 254 255 func TestStompConn_ConnectNoServerHeartbeat(t *testing.T) { 256 _, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 257 258 rawConn.incomingFrames <- frame.New( 259 frame.CONNECT, 260 frame.AcceptVersion, "1.1,1.0", 261 frame.HeartBeat, "4000,4000") 262 263 <-events 264 265 assert.Equal(t, len(rawConn.sentFrames), 1) 266 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.CONNECTED, 267 frame.Version, "1.1", 268 frame.HeartBeat, "0,0"), false) 269 } 270 271 func TestStompConn_ConnectServerHeartbeat(t *testing.T) { 272 _, rawConn, events := getTestStompConn(NewStompConfig(9999999991, []string{}), nil) 273 rawConn.incomingFrames <- frame.New( 274 frame.CONNECT, 275 frame.AcceptVersion, "1.1,1.0", 276 frame.HeartBeat, "4000,4000") 277 278 <-events 279 280 assert.Equal(t, len(rawConn.sentFrames), 1) 281 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.CONNECTED, 282 frame.Version, "1.1", 283 frame.HeartBeat, "999999999,999999999"), false) 284 } 285 286 func TestStompConn_ConnectClientHeartbeat(t *testing.T) { 287 _, rawConn, events := getTestStompConn(NewStompConfig(7000, []string{}), nil) 288 289 rawConn.incomingFrames <- frame.New( 290 frame.CONNECT, 291 frame.AcceptVersion, "1.2", 292 frame.HeartBeat, "8000,9000") 293 294 <-events 295 296 assert.Equal(t, len(rawConn.sentFrames), 1) 297 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.CONNECTED, 298 frame.HeartBeat, "9000,8000"), false) 299 } 300 301 func TestStompConn_ConnectWhenConnected(t *testing.T) { 302 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 303 304 rawConn.SendConnectFrame() 305 306 e := <-events 307 assert.Equal(t, e.eventType, ConnectionEstablished) 308 309 assert.Equal(t, len(rawConn.sentFrames), 1) 310 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.CONNECTED), false) 311 312 rawConn.SendConnectFrame() 313 314 e = <-events 315 assert.Equal(t, e.eventType, ConnectionClosed) 316 317 assert.Equal(t, len(rawConn.sentFrames), 2) 318 verifyFrame(t, rawConn.sentFrames[1], frame.New(frame.ERROR, 319 frame.Message, unexpectedStompCommandError.Error()), true) 320 321 assert.Equal(t, stompConn.state, closed) 322 } 323 324 func TestStompConn_SubscribeNotConnected(t *testing.T) { 325 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 326 327 rawConn.incomingFrames <- frame.New( 328 frame.SUBSCRIBE, 329 frame.Destination, "/topic/test") 330 331 e := <-events 332 assert.Equal(t, e.eventType, ConnectionClosed) 333 assert.Equal(t, e.conn, stompConn) 334 335 assert.Equal(t, len(rawConn.sentFrames), 1) 336 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.ERROR, 337 frame.Message, notConnectedStompError.Error()), true) 338 assert.Equal(t, stompConn.state, closed) 339 } 340 341 func TestStompConn_SubscribeMissingIdHeader(t *testing.T) { 342 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 343 344 rawConn.SendConnectFrame() 345 346 e := <-events 347 assert.Equal(t, e.eventType, ConnectionEstablished) 348 349 rawConn.incomingFrames <- frame.New( 350 frame.SUBSCRIBE, 351 frame.Destination, "/topic/test") 352 353 e = <-events 354 assert.Equal(t, e.eventType, ConnectionClosed) 355 356 assert.Equal(t, len(rawConn.sentFrames), 2) 357 verifyFrame(t, rawConn.sentFrames[1], frame.New(frame.ERROR, 358 frame.Message, invalidSubscriptionError.Error()), true) 359 assert.Equal(t, stompConn.state, closed) 360 } 361 362 func TestStompConn_SubscribeMissingDestinationHeader(t *testing.T) { 363 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 364 365 rawConn.SendConnectFrame() 366 367 e := <-events 368 assert.Equal(t, e.eventType, ConnectionEstablished) 369 370 rawConn.incomingFrames <- frame.New( 371 frame.SUBSCRIBE, 372 frame.Id, "sub-id") 373 374 e = <-events 375 assert.Equal(t, e.eventType, ConnectionClosed) 376 377 assert.Equal(t, len(rawConn.sentFrames), 2) 378 verifyFrame(t, rawConn.sentFrames[1], frame.New(frame.ERROR, 379 frame.Message, invalidFrameError.Error()), true) 380 assert.Equal(t, stompConn.state, closed) 381 } 382 383 func TestStompConn_Subscribe(t *testing.T) { 384 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 385 386 rawConn.SendConnectFrame() 387 388 e := <-events 389 assert.Equal(t, e.eventType, ConnectionEstablished) 390 391 assert.Equal(t, len(rawConn.sentFrames), 1) 392 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.CONNECTED), false) 393 394 rawConn.incomingFrames <- frame.New( 395 frame.SUBSCRIBE, 396 frame.Id, "sub-id", 397 frame.Destination, "/topic/test") 398 399 e = <-events 400 assert.Equal(t, e.eventType, SubscribeToTopic) 401 assert.Equal(t, e.conn, stompConn) 402 assert.Equal(t, e.destination, "/topic/test") 403 assert.Equal(t, e.sub.destination, "/topic/test") 404 assert.Equal(t, e.sub.id, "sub-id") 405 assert.Equal(t, e.frame.Command, frame.SUBSCRIBE) 406 407 assert.Equal(t, len(rawConn.sentFrames), 1) 408 assert.Equal(t, stompConn.state, connected) 409 410 assert.Equal(t, stompConn.subscriptions["sub-id"].destination, "/topic/test") 411 412 // trigger send subscribe request with the same id 413 rawConn.incomingFrames <- frame.New( 414 frame.SUBSCRIBE, 415 frame.Id, "sub-id", 416 frame.Destination, "/topic/test") 417 418 // verify that there was no second subscription created for the same subscription id 419 assert.Equal(t, e.sub, stompConn.subscriptions["sub-id"]) 420 } 421 422 func TestStompConn_SendNotConnected(t *testing.T) { 423 _, rawConn, events := getTestStompConn(NewStompConfig(0, []string{"/pub/"}), nil) 424 425 rawConn.incomingFrames <- frame.New( 426 frame.SEND, 427 frame.Destination, "/pub/test") 428 429 e := <-events 430 assert.Equal(t, e.eventType, ConnectionClosed) 431 432 assert.Equal(t, len(rawConn.sentFrames), 1) 433 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.ERROR, 434 frame.Message, notConnectedStompError.Error()), true) 435 } 436 437 func TestStompConn_SendMissingDestinationHeader(t *testing.T) { 438 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{"/pub/"}), nil) 439 440 rawConn.SendConnectFrame() 441 442 e := <-events 443 assert.Equal(t, e.eventType, ConnectionEstablished) 444 445 rawConn.incomingFrames <- frame.New( 446 frame.SEND) 447 448 e = <-events 449 assert.Equal(t, e.eventType, ConnectionClosed) 450 451 assert.Equal(t, len(rawConn.sentFrames), 2) 452 verifyFrame(t, rawConn.sentFrames[1], frame.New(frame.ERROR, 453 frame.Message, invalidFrameError.Error()), true) 454 assert.Equal(t, stompConn.state, closed) 455 } 456 457 func TestStompConn_Send_InvalidSend(t *testing.T) { 458 _, rawConn, events := getTestStompConn(NewStompConfig(0, []string{"/pub/"}), nil) 459 460 rawConn.SendConnectFrame() 461 462 e := <-events 463 assert.Equal(t, e.eventType, ConnectionEstablished) 464 assert.Equal(t, len(rawConn.sentFrames), 1) 465 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.CONNECTED), false) 466 467 // try sending a frame to a topic channel directly not request channel 468 rawConn.incomingFrames <- frame.New(frame.SEND, 469 frame.Destination, "/topic/test") 470 e = <-events 471 472 assert.Equal(t, e.eventType, ConnectionClosed) 473 assert.Equal(t, len(rawConn.sentFrames), 2) 474 verifyFrame(t, rawConn.sentFrames[1], frame.New(frame.ERROR, 475 frame.Message, invalidSendDestinationError.Error()), true) 476 } 477 478 func TestStompConn_Send(t *testing.T) { 479 _, rawConn, events := getTestStompConn(NewStompConfig(0, []string{"/pub/"}), nil) 480 481 rawConn.SendConnectFrame() 482 483 e := <-events 484 assert.Equal(t, e.eventType, ConnectionEstablished) 485 486 msgF := frame.New(frame.SEND, frame.Destination, "/pub/test") 487 488 rawConn.incomingFrames <- msgF 489 490 e = <-events 491 assert.Equal(t, e.eventType, IncomingMessage) 492 assert.Equal(t, e.frame, msgF) 493 assert.Equal(t, e.frame.Command, frame.MESSAGE) 494 495 rawConn.incomingFrames <- frame.New(frame.SEND, 496 frame.Destination, "/pub/test", frame.Receipt, "receipt-id") 497 498 e = <-events 499 assert.Equal(t, e.eventType, IncomingMessage) 500 501 assert.Equal(t, len(rawConn.sentFrames), 2) 502 verifyFrame(t, rawConn.sentFrames[1], frame.New(frame.RECEIPT, 503 frame.ReceiptId, "receipt-id"), true) 504 } 505 506 func TestStompConn_UnsubscribeNotConnected(t *testing.T) { 507 _, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 508 509 rawConn.incomingFrames <- frame.New( 510 frame.UNSUBSCRIBE, 511 frame.Destination, "/topic/test") 512 513 e := <-events 514 assert.Equal(t, e.eventType, ConnectionClosed) 515 516 assert.Equal(t, len(rawConn.sentFrames), 1) 517 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.ERROR, 518 frame.Message, notConnectedStompError.Error()), true) 519 } 520 521 func TestStompConn_UnsubscribeMissingIdHeader(t *testing.T) { 522 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 523 524 rawConn.SendConnectFrame() 525 526 e := <-events 527 assert.Equal(t, e.eventType, ConnectionEstablished) 528 529 rawConn.incomingFrames <- frame.New( 530 frame.UNSUBSCRIBE) 531 532 e = <-events 533 assert.Equal(t, e.eventType, ConnectionClosed) 534 535 assert.Equal(t, len(rawConn.sentFrames), 2) 536 verifyFrame(t, rawConn.sentFrames[1], frame.New(frame.ERROR, 537 frame.Message, invalidSubscriptionError.Error()), true) 538 assert.Equal(t, stompConn.state, closed) 539 } 540 541 func TestStompConn_Unsubscribe(t *testing.T) { 542 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 543 544 rawConn.SendConnectFrame() 545 546 e := <-events 547 assert.Equal(t, e.eventType, ConnectionEstablished) 548 549 rawConn.incomingFrames <- frame.New( 550 frame.UNSUBSCRIBE, 551 frame.Id, "invalid-sub-id", 552 frame.Receipt, "receipt-id") 553 554 rawConn.incomingFrames <- frame.New( 555 frame.SUBSCRIBE, 556 frame.Id, "sub-id", 557 frame.Destination, "/topic/test") 558 559 e = <-events 560 assert.Equal(t, e.eventType, SubscribeToTopic) 561 562 assert.Equal(t, len(rawConn.sentFrames), 2) 563 verifyFrame(t, rawConn.sentFrames[1], frame.New(frame.RECEIPT, 564 frame.ReceiptId, "receipt-id"), true) 565 566 rawConn.incomingFrames <- frame.New( 567 frame.UNSUBSCRIBE, 568 frame.Id, "sub-id") 569 570 e = <-events 571 assert.Equal(t, e.eventType, UnsubscribeFromTopic) 572 assert.Equal(t, e.conn, stompConn) 573 assert.Equal(t, e.destination, "/topic/test") 574 assert.Equal(t, e.sub.destination, "/topic/test") 575 assert.Equal(t, e.sub.id, "sub-id") 576 577 assert.Equal(t, len(stompConn.subscriptions), 0) 578 assert.Equal(t, stompConn.state, connected) 579 } 580 581 func TestStompConn_DisconnectNotConnected(t *testing.T) { 582 _, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 583 584 rawConn.incomingFrames <- frame.New( 585 frame.DISCONNECT) 586 587 e := <-events 588 assert.Equal(t, e.eventType, ConnectionClosed) 589 590 assert.Equal(t, len(rawConn.sentFrames), 1) 591 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.ERROR, 592 frame.Message, notConnectedStompError.Error()), true) 593 } 594 595 func TestStompConn_Disconnect(t *testing.T) { 596 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 597 598 rawConn.SendConnectFrame() 599 600 e := <-events 601 assert.Equal(t, e.eventType, ConnectionEstablished) 602 603 assert.Equal(t, len(rawConn.sentFrames), 1) 604 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.CONNECTED), false) 605 606 rawConn.incomingFrames <- frame.New( 607 frame.DISCONNECT) 608 609 e = <-events 610 assert.Equal(t, e.eventType, ConnectionClosed) 611 612 assert.Equal(t, len(rawConn.sentFrames), 1) 613 assert.Equal(t, stompConn.state, closed) 614 } 615 616 func TestStompConn_DisconnectWithReceipt(t *testing.T) { 617 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 618 619 rawConn.SendConnectFrame() 620 621 e := <-events 622 assert.Equal(t, e.eventType, ConnectionEstablished) 623 624 assert.Equal(t, len(rawConn.sentFrames), 1) 625 verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.CONNECTED), false) 626 627 rawConn.incomingFrames <- frame.New( 628 frame.DISCONNECT, 629 frame.Receipt, "test-receipt") 630 631 e = <-events 632 assert.Equal(t, e.eventType, ConnectionClosed) 633 634 assert.Equal(t, len(rawConn.sentFrames), 2) 635 verifyFrame(t, rawConn.sentFrames[1], 636 frame.New(frame.RECEIPT, frame.ReceiptId, "test-receipt"), true) 637 assert.Equal(t, stompConn.state, closed) 638 } 639 640 func TestStompConn_Close(t *testing.T) { 641 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 642 643 stompConn.Close() 644 645 e := <-events 646 assert.Equal(t, e.eventType, ConnectionClosed) 647 648 assert.Equal(t, len(rawConn.sentFrames), 0) 649 assert.Equal(t, stompConn.state, closed) 650 assert.Equal(t, rawConn.connected, false) 651 } 652 653 func TestStompConn_SendFrameToSubscription(t *testing.T) { 654 stompConn, rawConn, _ := getTestStompConn(NewStompConfig(0, []string{}), nil) 655 656 sub := &subscription{ 657 id: "sub-id", 658 destination: "/topic/test", 659 } 660 661 f := frame.New(frame.MESSAGE, frame.Destination, "/topic/test") 662 663 rawConn.writeWg = &sync.WaitGroup{} 664 rawConn.writeWg.Add(1) 665 666 stompConn.SendFrameToSubscription(f, sub) 667 668 rawConn.writeWg.Wait() 669 assert.Equal(t, len(rawConn.sentFrames), 1) 670 671 assert.Equal(t, rawConn.sentFrames[0], f) 672 assert.Equal(t, rawConn.sentFrames[0].Header.Get(frame.MessageId), "1") 673 674 rawConn.writeWg.Add(1) 675 stompConn.SendFrameToSubscription(f, sub) 676 rawConn.writeWg.Wait() 677 assert.Equal(t, len(rawConn.sentFrames), 2) 678 assert.Equal(t, rawConn.sentFrames[1].Header.Get(frame.MessageId), "2") 679 680 rawConn.writeWg.Add(50) 681 for i := 0; i < 50; i++ { 682 go stompConn.SendFrameToSubscription(f.Clone(), sub) 683 } 684 685 rawConn.writeWg.Wait() 686 assert.Equal(t, len(rawConn.sentFrames), 52) 687 } 688 689 func TestStompConn_SendErrorFrameToSubscription(t *testing.T) { 690 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 691 692 sub := &subscription{ 693 id: "sub-id", 694 destination: "/topic/test", 695 } 696 697 f := frame.New(frame.ERROR, frame.Destination, "/topic/test") 698 stompConn.SendFrameToSubscription(f, sub) 699 700 e := <-events 701 702 assert.Equal(t, e.eventType, ConnectionClosed) 703 assert.Equal(t, len(rawConn.sentFrames), 1) 704 } 705 706 func TestStompConn_ReadError(t *testing.T) { 707 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 708 709 rawConn.incomingFrames <- errors.New("read error") 710 711 e := <-events 712 assert.Equal(t, e.eventType, ConnectionClosed) 713 714 assert.Equal(t, len(rawConn.sentFrames), 0) 715 assert.Equal(t, stompConn.state, closed) 716 } 717 718 func TestStompConn_WriteErrorDuringConnect(t *testing.T) { 719 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil) 720 721 rawConn.nextWriteErr = errors.New("write error") 722 rawConn.SendConnectFrame() 723 724 e := <-events 725 assert.Equal(t, e.eventType, ConnectionClosed) 726 assert.Equal(t, stompConn.state, closed) 727 } 728 729 func TestStompConn_WriteErrorDuringSend(t *testing.T) { 730 stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{"/pub/"}), nil) 731 732 rawConn.SendConnectFrame() 733 734 e := <-events 735 assert.Equal(t, e.eventType, ConnectionEstablished) 736 737 rawConn.nextWriteErr = errors.New("write error") 738 rawConn.incomingFrames <- frame.New( 739 frame.SEND, 740 frame.Destination, "/pub/", 741 frame.Receipt, "receipt-id") 742 743 e = <-events 744 745 assert.Equal(t, e.eventType, ConnectionClosed) 746 assert.Equal(t, stompConn.state, closed) 747 } 748 749 func TestStompConn_SetReadDeadline(t *testing.T) { 750 stompConn, rawConn, events := getTestStompConn(NewStompConfig(20000, []string{}), nil) 751 752 infiniteTimeout := time.Time{} 753 754 assert.Equal(t, rawConn.getCurrentReadDeadline(), infiniteTimeout) 755 756 rawConn.incomingFrames <- frame.New( 757 frame.CONNECT, 758 frame.AcceptVersion, "1.2", 759 frame.HeartBeat, "200,200") 760 761 <-events 762 763 // verify timeout is set to 20 seconds 764 assert.Equal(t, stompConn.readTimeoutMs, int64(20000)) 765 766 rawConn.incomingFrames <- nil 767 rawConn.incomingFrames <- nil 768 769 diff := rawConn.getCurrentReadDeadline().Sub(time.Now()) 770 771 // verify the read deadline for the connection is 772 // between 15 and 21 seconds 773 assert.Greater(t, diff.Seconds(), float64(15)) 774 assert.Greater(t, float64(21), diff.Seconds()) 775 } 776 777 func TestStompConn_WriteHeartbeat(t *testing.T) { 778 stompConn, rawConn, events := getTestStompConn(NewStompConfig(100, []string{}), nil) 779 780 rawConn.incomingFrames <- frame.New( 781 frame.CONNECT, 782 frame.AcceptVersion, "1.2", 783 frame.HeartBeat, "50,50") 784 785 <-events 786 787 rawConn.lock.Lock() 788 rawConn.writeWg = new(sync.WaitGroup) 789 rawConn.writeWg.Add(2) 790 rawConn.lock.Unlock() 791 792 rawConn.writeWg.Wait() 793 794 // verify the last frame is heartbeat (nil) 795 rawConn.lock.Lock() 796 assert.Nil(t, rawConn.LastSentFrame()) 797 rawConn.lock.Unlock() 798 799 rawConn.writeWg.Add(3) 800 stompConn.SendFrameToSubscription(frame.New(frame.MESSAGE), &subscription{id: "sub-1"}) 801 rawConn.writeWg.Wait() 802 803 // verify the last frame is heartbeat (nil) 804 rawConn.lock.Lock() 805 rawConn.writeWg = nil 806 assert.Nil(t, rawConn.LastSentFrame()) 807 rawConn.lock.Unlock() 808 } 809 810 func verifyFrame(t *testing.T, actualFrame *frame.Frame, expectedFrame *frame.Frame, exactHeaderMatch bool) { 811 assert.Equal(t, expectedFrame.Command, actualFrame.Command) 812 if exactHeaderMatch { 813 assert.Equal(t, expectedFrame.Header.Len(), actualFrame.Header.Len()) 814 } 815 816 for i := 0; i < expectedFrame.Header.Len(); i++ { 817 key, value := expectedFrame.Header.GetAt(i) 818 assert.Equal(t, actualFrame.Header.Get(key), value) 819 } 820 } 821 822 func printFrame(f *frame.Frame) { 823 if f == nil { 824 fmt.Println("HEARTBEAT FRAME") 825 } else { 826 fmt.Println("FRAME:", f.Command) 827 for i := 0; i < f.Header.Len(); i++ { 828 key, value := f.Header.GetAt(i) 829 fmt.Println(key+":", value) 830 } 831 fmt.Println("BODY:", string(f.Body)) 832 } 833 }