@@ -629,4 +629,200 @@ BOOST_AUTO_TEST_CASE( multi_client_qos1 ) {
629
629
th.join ();
630
630
}
631
631
632
+ BOOST_AUTO_TEST_CASE ( multi_client_nl ) {
633
+ boost::asio::io_context iocb;
634
+ test_broker b (iocb);
635
+ MQTT_NS::optional<test_server_no_tls> s;
636
+ std::promise<void > p;
637
+ auto f = p.get_future ();
638
+ std::thread th (
639
+ [&] {
640
+ s.emplace (iocb, b);
641
+ p.set_value ();
642
+ iocb.run ();
643
+ }
644
+ );
645
+ f.wait ();
646
+ auto finish =
647
+ [&] {
648
+ as::post (
649
+ iocb,
650
+ [&] {
651
+ s->close ();
652
+ }
653
+ );
654
+ };
655
+
656
+ int close_count = 0 ;
657
+ auto server_close = [&] {
658
+ if (++close_count == 2 ) finish ();
659
+ };
660
+
661
+ boost::asio::io_context ioc;
662
+
663
+ auto c1 = MQTT_NS::make_client (ioc, broker_url, broker_notls_port, MQTT_NS::protocol_version::v5);
664
+ c1->set_clean_start (true );
665
+ c1->set_client_id (" cid1" );
666
+
667
+ auto c2 = MQTT_NS::make_client (ioc, broker_url, broker_notls_port, MQTT_NS::protocol_version::v5);
668
+ c2->set_clean_start (true );
669
+ c2->set_client_id (" cid2" );
670
+
671
+ using packet_id_t = typename std::remove_reference_t <decltype (*c1)>::packet_id_t ;
672
+
673
+ checker chk = {
674
+ // connect
675
+ cont (" h_connack_1" ),
676
+ cont (" h_connack_2" ),
677
+
678
+ // subscribe topic1 QoS0 NL:yes
679
+ cont (" h_suback_1" ),
680
+ // subscribe topic1 QoS0 NL:no
681
+ cont (" h_suback_2" ),
682
+
683
+ // c1 publish topic1 QoS0
684
+ cont (" h_publish_2_1" ),
685
+ // c2 publish topic1 QoS0
686
+ cont (" h_publish_1" ),
687
+ deps (" h_publish_2_2" ," h_publish_2_1" ),
688
+
689
+ // disconnect
690
+ cont (" h_close_1" ),
691
+ cont (" h_close_2" ),
692
+ };
693
+
694
+ c1->set_v5_connack_handler (
695
+ [&]
696
+ (bool sp, MQTT_NS::v5::connect_reason_code connack_return_code, MQTT_NS::v5::properties /* props*/ ) {
697
+ MQTT_CHK (" h_connack_1" );
698
+ BOOST_TEST (sp == false );
699
+ BOOST_TEST (connack_return_code == MQTT_NS::v5::connect_reason_code::success);
700
+ c2->connect ();
701
+ return true ;
702
+ }
703
+ );
704
+
705
+ c2->set_v5_connack_handler (
706
+ [&]
707
+ (bool sp, MQTT_NS::v5::connect_reason_code connack_return_code, MQTT_NS::v5::properties /* props*/ ) {
708
+ MQTT_CHK (" h_connack_2" );
709
+ BOOST_TEST (sp == false );
710
+ BOOST_TEST (connack_return_code == MQTT_NS::v5::connect_reason_code::success);
711
+ c1->subscribe (" topic1" , MQTT_NS::qos::at_most_once | MQTT_NS::nl::yes);
712
+ return true ;
713
+ }
714
+ );
715
+
716
+ c1->set_v5_suback_handler (
717
+ [&]
718
+ (packet_id_t , std::vector<MQTT_NS::v5::suback_reason_code> reasons, MQTT_NS::v5::properties /* props*/ ) {
719
+ MQTT_CHK (" h_suback_1" );
720
+ BOOST_TEST (reasons.size () == 1U );
721
+ BOOST_TEST (reasons[0 ] == MQTT_NS::v5::suback_reason_code::granted_qos_0);
722
+ c2->subscribe (" topic1" , MQTT_NS::qos::at_most_once | MQTT_NS::nl::no);
723
+ return true ;
724
+ }
725
+ );
726
+
727
+ c2->set_v5_suback_handler (
728
+ [&]
729
+ (packet_id_t , std::vector<MQTT_NS::v5::suback_reason_code> reasons, MQTT_NS::v5::properties /* props*/ ) {
730
+ MQTT_CHK (" h_suback_2" );
731
+ BOOST_TEST (reasons.size () == 1U );
732
+ BOOST_TEST (reasons[0 ] == MQTT_NS::v5::suback_reason_code::granted_qos_0);
733
+ c1->publish (" topic1" , " topic1_contents1" , MQTT_NS::qos::at_most_once);
734
+ return true ;
735
+ }
736
+ );
737
+
738
+ c1->set_v5_publish_handler (
739
+ [&]
740
+ (MQTT_NS::optional<packet_id_t > packet_id,
741
+ MQTT_NS::publish_options pubopts,
742
+ MQTT_NS::buffer topic,
743
+ MQTT_NS::buffer contents,
744
+ MQTT_NS::v5::properties /* props*/ ) {
745
+ MQTT_CHK (" h_publish_1" );
746
+ BOOST_TEST (pubopts.get_dup () == MQTT_NS::dup ::no);
747
+ BOOST_TEST (pubopts.get_qos () == MQTT_NS::qos::at_most_once);
748
+ BOOST_TEST (pubopts.get_retain () == MQTT_NS::retain::no);
749
+ BOOST_CHECK (!packet_id);
750
+ BOOST_TEST (topic == " topic1" );
751
+ BOOST_TEST (contents == " topic1_contents2" );
752
+ c1->disconnect ();
753
+ return true ;
754
+ }
755
+ );
756
+
757
+ c2->set_v5_publish_handler (
758
+ [&]
759
+ (MQTT_NS::optional<packet_id_t > packet_id,
760
+ MQTT_NS::publish_options pubopts,
761
+ MQTT_NS::buffer topic,
762
+ MQTT_NS::buffer contents,
763
+ MQTT_NS::v5::properties /* props*/ ) {
764
+ auto ret = chk.match (
765
+ " h_suback_2" ,
766
+ [&] {
767
+ MQTT_CHK (" h_publish_2_1" );
768
+ BOOST_TEST (pubopts.get_dup () == MQTT_NS::dup ::no);
769
+ BOOST_TEST (pubopts.get_qos () == MQTT_NS::qos::at_most_once);
770
+ BOOST_TEST (pubopts.get_retain () == MQTT_NS::retain::no);
771
+ BOOST_CHECK (!packet_id);
772
+ BOOST_TEST (topic == " topic1" );
773
+ BOOST_TEST (contents == " topic1_contents1" );
774
+ c2->publish (" topic1" , " topic1_contents2" , MQTT_NS::qos::at_most_once);
775
+ },
776
+ " h_publish_2_1" ,
777
+ [&] {
778
+ MQTT_CHK (" h_publish_2_2" );
779
+ BOOST_TEST (pubopts.get_dup () == MQTT_NS::dup ::no);
780
+ BOOST_TEST (pubopts.get_qos () == MQTT_NS::qos::at_most_once);
781
+ BOOST_TEST (pubopts.get_retain () == MQTT_NS::retain::no);
782
+ BOOST_CHECK (!packet_id);
783
+ BOOST_TEST (topic == " topic1" );
784
+ BOOST_TEST (contents == " topic1_contents2" );
785
+ c2->disconnect ();
786
+ }
787
+ );
788
+ BOOST_TEST (ret);
789
+
790
+ return true ;
791
+ }
792
+ );
793
+
794
+ c1->set_close_handler (
795
+ [&]
796
+ () {
797
+ MQTT_CHK (" h_close_1" );
798
+ server_close ();
799
+ });
800
+ c2->set_close_handler (
801
+ [&]
802
+ () {
803
+ MQTT_CHK (" h_close_2" );
804
+ server_close ();
805
+ });
806
+
807
+ c1->set_error_handler (
808
+ []
809
+ (MQTT_NS::error_code) {
810
+ BOOST_CHECK (false );
811
+ });
812
+
813
+ c2->set_puback_handler (
814
+ []
815
+ (std::uint16_t ) {
816
+ BOOST_CHECK (false );
817
+ return true ;
818
+ });
819
+
820
+ c1->connect ();
821
+
822
+ ioc.run ();
823
+ BOOST_TEST (chk.all ());
824
+ th.join ();
825
+ }
826
+
827
+
632
828
BOOST_AUTO_TEST_SUITE_END ()
0 commit comments