Support multiple subscription identifiers in received messages.

Summary:
- refactor property encoding
- change user property type to be std::pair<std::string, std::string>

Reviewers: ivica

Reviewed By: ivica

Subscribers: korina

Differential Revision: https://repo.mireo.local/D27867
This commit is contained in:
Bruno Iljazovic
2024-02-16 10:36:26 +01:00
parent b40ddb3ced
commit 1acdd99f28
35 changed files with 469 additions and 380 deletions

View File

@@ -80,7 +80,14 @@ inline std::string to_readable_props(Props props) {
if (v.has_value())
stream << *v << " ";
if constexpr (is_vector<decltype(v)>)
stream << boost::algorithm::join(v, ",");
for (size_t i = 0; i < v.size(); i++) {
if constexpr (is_pair<decltype(v[i])>)
stream << "(" << v[i].first << ", " << v[i].second << ")";
else
stream << v[i];
if (i + 1 < v.size())
stream << ", ";
}
return true;
});
return stream.str();

View File

@@ -191,7 +191,8 @@ struct shared_connect_prop_test_data : shared_test_data {
const uint16_t topic_alias_maximum = 12345;
const uint8_t request_response_information = 1;
const uint8_t request_problem_information = 0;
const std::vector<std::string> user_properties = std::vector<std::string>{ "key", "val" };
const std::vector<std::pair<std::string, std::string>> user_properties =
{ { "key", "val" } };
connect_props cprops = create_connect_props();
@@ -300,7 +301,8 @@ struct shared_connack_prop_test_data {
const std::string assigned_client_id = "client_id";
const uint16_t topic_alias_max = 128;
const std::string reason_string = "reason string";
const std::vector<std::string> user_properties = std::vector<std::string>{ "key", "val" };
const std::vector<std::pair<std::string, std::string>> user_properties =
{ { "key", "val" } };
const uint8_t wildcard_sub = 1;
const uint8_t sub_id = 1;
const uint8_t shared_sub = 0;

View File

@@ -125,6 +125,82 @@ BOOST_FIXTURE_TEST_CASE(receive_publish_qos2, shared_test_data) {
run_test(std::move(broker_side));
}
BOOST_FIXTURE_TEST_CASE(receive_publish_properties, shared_test_data) {
constexpr int expected_handlers_called = 1;
int handlers_called = 0;
publish_props pprops;
pprops[prop::payload_format_indicator] = uint8_t(0);
pprops[prop::message_expiry_interval] = 102u;
pprops[prop::content_type] = "content/type";
pprops[prop::response_topic] = "response/topic";
pprops[prop::correlation_data] = std::string {
static_cast<char>(0x00), static_cast<char>(0x01), static_cast<char>(0xFF)
};
pprops[prop::subscription_identifier] = { 40, 41, 42 };
pprops[prop::topic_alias] = uint16_t(103);
pprops[prop::user_property] = { { "name1", "value1" }, { "name2", "value2 "} };
auto publish = encoders::encode_publish(
1, topic, payload,
qos_e::at_most_once, retain_e::no, dup_e::no,
pprops
);
test::msg_exchange broker_side;
broker_side
.expect(connect)
.complete_with(success, after(0ms))
.reply_with(connack, after(0ms))
.send(publish, after(10ms));
asio::io_context ioc;
auto executor = ioc.get_executor();
auto& broker = asio::make_service<test::test_broker>(
ioc, executor, std::move(broker_side)
);
using client_type = mqtt_client<test::test_stream>;
client_type c(executor);
c.brokers("127.0.0.1")
.async_run(asio::detached);
c.async_receive([&handlers_called, &pprops, &c](
error_code ec, std::string rec_topic, std::string rec_payload,
publish_props rec_pprops
){
++handlers_called;
auto data = shared_test_data();
BOOST_TEST(!ec);
BOOST_TEST(data.topic == rec_topic);
BOOST_TEST(data.payload == rec_payload);
BOOST_TEST(*pprops[prop::payload_format_indicator]
== *rec_pprops[prop::payload_format_indicator]);
BOOST_TEST(*pprops[prop::message_expiry_interval]
== *rec_pprops[prop::message_expiry_interval]);
BOOST_TEST(*pprops[prop::content_type]
== *rec_pprops[prop::content_type]);
BOOST_TEST(*pprops[prop::response_topic]
== *rec_pprops[prop::response_topic]);
BOOST_TEST(*pprops[prop::correlation_data]
== *rec_pprops[prop::correlation_data]);
BOOST_TEST(pprops[prop::subscription_identifier]
== rec_pprops[prop::subscription_identifier]);
BOOST_TEST(*pprops[prop::topic_alias]
== *rec_pprops[prop::topic_alias]);
BOOST_TEST(pprops[prop::user_property]
== rec_pprops[prop::user_property]);
c.cancel();
}
);
ioc.run();
BOOST_TEST(handlers_called == expected_handlers_called);
BOOST_TEST(broker.received_all_expected());
}
BOOST_FIXTURE_TEST_CASE(receive_malformed_publish, shared_test_data) {
// packets
auto malformed_publish = encoders::encode_publish(
@@ -322,8 +398,10 @@ BOOST_FIXTURE_TEST_CASE(receive_big_publish, shared_test_data) {
cprops[prop::maximum_packet_size] = 10'000'000;
publish_props big_props;
for (int i = 0; i < 100; i++)
big_props[prop::user_property].push_back(std::string(65534, 'u'));
for (int i = 0; i < 50; i++)
big_props[prop::user_property].emplace_back(
std::string(65534, 'u'), std::string(65534, 'v')
);
// packets
auto connect_big_packets = encoders::encode_connect(

View File

@@ -545,16 +545,12 @@ BOOST_FIXTURE_TEST_CASE(send_big_publish, shared_test_data) {
const std::string big_topic = std::string(65534, 't');
const std::string big_payload = std::string(65534, 'p');
publish_props big_props;
for (int i = 0; i < 1; i++)
big_props[prop::user_property].push_back(std::string(65534, 'u'));
// packets
auto allow_big_connack = encoders::encode_connack(false, uint8_t(0x00), cprops);
auto big_publish = encoders::encode_publish(
1, big_topic, big_payload,
qos_e::at_least_once, retain_e::no, dup_e::no,
big_props
publish_props{}
);
auto pingreq = encoders::encode_pingreq();
auto pingresp = encoders::encode_pingresp();
@@ -590,7 +586,7 @@ BOOST_FIXTURE_TEST_CASE(send_big_publish, shared_test_data) {
.async_run(asio::detached);
c.async_publish<qos_e::at_least_once>(
big_topic, big_payload, retain_e::no, big_props,
big_topic, big_payload, retain_e::no, publish_props{},
[&handlers_called, &c](error_code ec, reason_code rc, puback_props) {
++handlers_called;

View File

@@ -50,9 +50,16 @@ BOOST_AUTO_TEST_CASE(malformed_reason_string) {
run_malformed_props_test(dprops);
}
BOOST_AUTO_TEST_CASE(malformed_user_property) {
BOOST_AUTO_TEST_CASE(malformed_user_property_key) {
disconnect_props dprops;
dprops[prop::user_property].push_back(std::string { 0x01 });
dprops[prop::user_property].emplace_back(std::string { 0x01 }, "value");
run_malformed_props_test(dprops);
}
BOOST_AUTO_TEST_CASE(malformed_user_property_value) {
disconnect_props dprops;
dprops[prop::user_property].emplace_back("key", std::string { 0x01 });
run_malformed_props_test(dprops);
}

View File

@@ -110,7 +110,7 @@ BOOST_AUTO_TEST_CASE(malformed_props_1) {
BOOST_AUTO_TEST_CASE(malformed_props_2) {
publish_props pprops;
pprops[prop::user_property].push_back(std::string { 0x01 });
pprops[prop::user_property].emplace_back(std::string { 0x01 }, "value");
run_malformed_props_test(pprops);
}
@@ -134,7 +134,7 @@ BOOST_AUTO_TEST_CASE(malformed_props_4) {
BOOST_AUTO_TEST_CASE(malformed_props_5) {
publish_props pprops;
pprops[prop::subscription_identifier] = 300'000'000;
pprops[prop::subscription_identifier].push_back(40);
run_malformed_props_test(pprops);
}

View File

@@ -50,8 +50,7 @@ BOOST_AUTO_TEST_CASE(test_connect) {
cprops[prop::topic_alias_maximum] = topic_alias_max;
cprops[prop::request_response_information] = request_response_information;
cprops[prop::request_problem_information] = request_problem_information;
cprops[prop::user_property].emplace_back(user_property_1);
cprops[prop::user_property].emplace_back(user_property_2);
cprops[prop::user_property].emplace_back(user_property_1, user_property_2);
cprops[prop::authentication_method] = auth_method;
cprops[prop::authentication_data] = auth_data;
@@ -62,8 +61,7 @@ BOOST_AUTO_TEST_CASE(test_connect) {
w[prop::content_type] = will_content_type;
w[prop::response_topic] = will_response_topic;
w[prop::correlation_data] = will_correlation_data;
w[prop::user_property].emplace_back(will_user_property_1);
w[prop::user_property].emplace_back(will_user_property_2);
w[prop::user_property].emplace_back(will_user_property_1, will_user_property_2);
std::optional<will> will_opt { std::move(w) };
auto msg = encoders::encode_connect(
@@ -96,9 +94,9 @@ BOOST_AUTO_TEST_CASE(test_connect) {
BOOST_CHECK_EQUAL(*cprops_[prop::topic_alias_maximum], topic_alias_max);
BOOST_CHECK_EQUAL(*cprops_[prop::request_response_information], request_response_information);
BOOST_CHECK_EQUAL(*cprops_[prop::request_problem_information], request_problem_information);
BOOST_ASSERT(cprops_[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL(cprops_[prop::user_property][0], user_property_1);
BOOST_CHECK_EQUAL(cprops_[prop::user_property][1], user_property_2);
BOOST_ASSERT(cprops_[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL(cprops_[prop::user_property][0].first, user_property_1);
BOOST_CHECK_EQUAL(cprops_[prop::user_property][0].second, user_property_2);
BOOST_CHECK_EQUAL(*cprops_[prop::authentication_method], auth_method);
BOOST_CHECK_EQUAL(*cprops_[prop::authentication_data], auth_data);
@@ -114,9 +112,9 @@ BOOST_AUTO_TEST_CASE(test_connect) {
BOOST_CHECK_EQUAL(*(*w_)[prop::content_type], will_content_type);
BOOST_CHECK_EQUAL(*(*w_)[prop::response_topic], will_response_topic);
BOOST_CHECK_EQUAL(*(*w_)[prop::correlation_data], will_correlation_data);
BOOST_ASSERT((*w_)[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL((*w_)[prop::user_property][0], will_user_property_1);
BOOST_CHECK_EQUAL((*w_)[prop::user_property][1], will_user_property_2);
BOOST_ASSERT((*w_)[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL((*w_)[prop::user_property][0].first, will_user_property_1);
BOOST_CHECK_EQUAL((*w_)[prop::user_property][0].second, will_user_property_2);
}
BOOST_AUTO_TEST_CASE(test_connack) {
@@ -152,8 +150,7 @@ BOOST_AUTO_TEST_CASE(test_connack) {
cprops[prop::assigned_client_identifier] = assigned_client_id;
cprops[prop::topic_alias_maximum] = topic_alias_max;
cprops[prop::reason_string] = reason_string;
cprops[prop::user_property].push_back(user_property_1);
cprops[prop::user_property].push_back(user_property_2);
cprops[prop::user_property].emplace_back(user_property_1, user_property_2);
cprops[prop::wildcard_subscription_available] = wildcard_sub;
cprops[prop::subscription_identifier_available] = sub_id;
cprops[prop::shared_subscription_available] = shared_sub;
@@ -186,9 +183,9 @@ BOOST_AUTO_TEST_CASE(test_connack) {
BOOST_CHECK_EQUAL(*cprops_[prop::assigned_client_identifier], assigned_client_id);
BOOST_CHECK_EQUAL(*cprops_[prop::topic_alias_maximum], topic_alias_max);
BOOST_CHECK_EQUAL(*cprops_[prop::reason_string], reason_string);
BOOST_ASSERT(cprops_[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL(cprops_[prop::user_property][0], user_property_1);
BOOST_CHECK_EQUAL(cprops_[prop::user_property][1], user_property_2);
BOOST_ASSERT(cprops_[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL(cprops_[prop::user_property][0].first, user_property_1);
BOOST_CHECK_EQUAL(cprops_[prop::user_property][0].second, user_property_2);
BOOST_CHECK_EQUAL(*cprops_[prop::wildcard_subscription_available], wildcard_sub);
BOOST_CHECK_EQUAL(*cprops_[prop::subscription_identifier_available], sub_id);
BOOST_CHECK_EQUAL(*cprops_[prop::shared_subscription_available], shared_sub);
@@ -221,9 +218,8 @@ BOOST_AUTO_TEST_CASE(test_publish) {
pprops[prop::topic_alias] = topic_alias;
pprops[prop::response_topic] = response_topic;
pprops[prop::correlation_data] = correlation_data;
pprops[prop::user_property].emplace_back(publish_prop_1);
pprops[prop::user_property].emplace_back(publish_prop_2);
pprops[prop::subscription_identifier] = subscription_identifier;
pprops[prop::user_property].emplace_back(publish_prop_1, publish_prop_2);
pprops[prop::subscription_identifier].push_back(subscription_identifier);
pprops[prop::content_type] = content_type;
auto msg = encoders::encode_publish(
@@ -252,10 +248,11 @@ BOOST_AUTO_TEST_CASE(test_publish) {
BOOST_CHECK_EQUAL(*pprops_[prop::topic_alias], topic_alias);
BOOST_CHECK_EQUAL(*pprops_[prop::response_topic], response_topic);
BOOST_CHECK_EQUAL(*pprops_[prop::correlation_data], correlation_data);
BOOST_ASSERT(pprops_[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0], publish_prop_1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][1], publish_prop_2);
BOOST_CHECK_EQUAL(*pprops_[prop::subscription_identifier], subscription_identifier);
BOOST_ASSERT(pprops_[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0].first, publish_prop_1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0].second, publish_prop_2);
BOOST_ASSERT(pprops_[prop::subscription_identifier].size() == 1);
BOOST_CHECK_EQUAL(pprops_[prop::subscription_identifier][0], subscription_identifier);
BOOST_CHECK_EQUAL(*pprops_[prop::content_type], content_type);
}
@@ -297,8 +294,7 @@ BOOST_AUTO_TEST_CASE(test_puback) {
puback_props pprops;
pprops[prop::reason_string] = reason_string;
pprops[prop::user_property].emplace_back(user_property_1);
pprops[prop::user_property].emplace_back(user_property_2);
pprops[prop::user_property].emplace_back(user_property_1, user_property_2);
auto msg = encoders::encode_puback(packet_id, reason_code, pprops);
@@ -318,9 +314,9 @@ BOOST_AUTO_TEST_CASE(test_puback) {
pprops_.visit([](const auto& p, const auto&) { (void)p; BOOST_ASSERT(p); return true; });
BOOST_CHECK_EQUAL(reason_code_, reason_code);
BOOST_CHECK_EQUAL(*pprops_[prop::reason_string], reason_string);
BOOST_ASSERT(pprops_[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0], user_property_1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][1], user_property_2);
BOOST_ASSERT(pprops_[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0].first, user_property_1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0].second, user_property_2);
}
BOOST_AUTO_TEST_CASE(test_pubrec) {
@@ -334,8 +330,7 @@ BOOST_AUTO_TEST_CASE(test_pubrec) {
pubrec_props pprops;
pprops[prop::reason_string] = reason_string;
pprops[prop::user_property].emplace_back(user_property_1);
pprops[prop::user_property].emplace_back(user_property_2);
pprops[prop::user_property].emplace_back(user_property_1, user_property_2);
auto msg = encoders::encode_pubrec(packet_id, reason_code, pprops);
@@ -355,9 +350,9 @@ BOOST_AUTO_TEST_CASE(test_pubrec) {
pprops_.visit([](const auto& p, const auto&) { (void)p; BOOST_ASSERT(p); return true; });
BOOST_CHECK_EQUAL(reason_code_, reason_code);
BOOST_CHECK_EQUAL(*pprops_[prop::reason_string], reason_string);
BOOST_ASSERT(pprops_[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0], user_property_1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][1], user_property_2);
BOOST_ASSERT(pprops_[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0].first, user_property_1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0].second, user_property_2);
}
BOOST_AUTO_TEST_CASE(test_pubrel) {
@@ -371,8 +366,7 @@ BOOST_AUTO_TEST_CASE(test_pubrel) {
pubrel_props pprops;
pprops[prop::reason_string] = reason_string;
pprops[prop::user_property].emplace_back(user_property_1);
pprops[prop::user_property].emplace_back(user_property_2);
pprops[prop::user_property].emplace_back(user_property_1, user_property_2);
auto msg = encoders::encode_pubrel(packet_id, reason_code, pprops);
@@ -392,9 +386,9 @@ BOOST_AUTO_TEST_CASE(test_pubrel) {
pprops_.visit([](const auto& p, const auto&) { (void)p; BOOST_ASSERT(p); return true; });
BOOST_CHECK_EQUAL(reason_code_, reason_code);
BOOST_CHECK_EQUAL(*pprops_[prop::reason_string], reason_string);
BOOST_ASSERT(pprops_[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0], user_property_1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][1], user_property_2);
BOOST_ASSERT(pprops_[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0].first, user_property_1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0].second, user_property_2);
}
BOOST_AUTO_TEST_CASE(test_pubcomp) {
@@ -408,8 +402,7 @@ BOOST_AUTO_TEST_CASE(test_pubcomp) {
pubcomp_props pprops;
pprops[prop::reason_string] = reason_string;
pprops[prop::user_property].emplace_back(user_property_1);
pprops[prop::user_property].emplace_back(user_property_2);
pprops[prop::user_property].emplace_back(user_property_1, user_property_2);
auto msg = encoders::encode_pubcomp(packet_id, reason_code, pprops);
@@ -429,9 +422,9 @@ BOOST_AUTO_TEST_CASE(test_pubcomp) {
pprops_.visit([](const auto& p, const auto&) { (void)p; BOOST_ASSERT(p); return true; });
BOOST_CHECK_EQUAL(reason_code_, reason_code);
BOOST_CHECK_EQUAL(*pprops_[prop::reason_string], reason_string);
BOOST_ASSERT(pprops_[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0], user_property_1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][1], user_property_2);
BOOST_ASSERT(pprops_[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0].first, user_property_1);
BOOST_CHECK_EQUAL(pprops_[prop::user_property][0].second, user_property_2);
}
BOOST_AUTO_TEST_CASE(test_subscribe) {
@@ -447,8 +440,7 @@ BOOST_AUTO_TEST_CASE(test_subscribe) {
subscribe_props sprops;
sprops[prop::subscription_identifier] = sub_id;
sprops[prop::user_property].push_back(user_property_1);
sprops[prop::user_property].push_back(user_property_2);
sprops[prop::user_property].emplace_back(user_property_1, user_property_2);
std::vector<subscribe_topic> filters {
{
@@ -484,9 +476,9 @@ BOOST_AUTO_TEST_CASE(test_subscribe) {
sprops_.visit([](const auto& p, const auto&) { (void)p; BOOST_ASSERT(p); return true; });
BOOST_CHECK_EQUAL(*sprops_[prop::subscription_identifier], sub_id);
BOOST_ASSERT(sprops_[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL(sprops_[prop::user_property][0], user_property_1);
BOOST_CHECK_EQUAL(sprops_[prop::user_property][1], user_property_2);
BOOST_ASSERT(sprops_[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL(sprops_[prop::user_property][0].first, user_property_1);
BOOST_CHECK_EQUAL(sprops_[prop::user_property][0].second, user_property_2);
}
BOOST_AUTO_TEST_CASE(test_suback) {
@@ -500,8 +492,7 @@ BOOST_AUTO_TEST_CASE(test_suback) {
suback_props sprops;
sprops[prop::reason_string] = reason_string;
sprops[prop::user_property].push_back(user_property_1);
sprops[prop::user_property].push_back(user_property_2);
sprops[prop::user_property].emplace_back(user_property_1, user_property_2);
auto msg = encoders::encode_suback(packet_id, reason_codes, sprops);
@@ -521,9 +512,9 @@ BOOST_AUTO_TEST_CASE(test_suback) {
sprops_.visit([](const auto& p, const auto&) { (void)p; BOOST_ASSERT(p); return true; });
BOOST_CHECK_EQUAL(*sprops_[prop::reason_string], reason_string);
BOOST_ASSERT(sprops_[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL(sprops_[prop::user_property][0], user_property_1);
BOOST_CHECK_EQUAL(sprops_[prop::user_property][1], user_property_2);
BOOST_ASSERT(sprops_[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL(sprops_[prop::user_property][0].first, user_property_1);
BOOST_CHECK_EQUAL(sprops_[prop::user_property][0].second, user_property_2);
}
BOOST_AUTO_TEST_CASE(test_unsubscribe) {
@@ -535,8 +526,7 @@ BOOST_AUTO_TEST_CASE(test_unsubscribe) {
std::string user_property_2 = "UNSUBSCRIBE user prop val";
unsubscribe_props uprops;
uprops[prop::user_property].push_back(user_property_1);
uprops[prop::user_property].push_back(user_property_2);
uprops[prop::user_property].emplace_back(user_property_1, user_property_2);
auto msg = encoders::encode_unsubscribe(packet_id, topics, uprops);
@@ -555,9 +545,9 @@ BOOST_AUTO_TEST_CASE(test_unsubscribe) {
BOOST_CHECK(topics_ == topics);
uprops_.visit([](const auto& p, const auto&) { (void)p; BOOST_ASSERT(p); return true; });
BOOST_ASSERT(uprops_[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL(uprops_[prop::user_property][0], user_property_1);
BOOST_CHECK_EQUAL(uprops_[prop::user_property][1], user_property_2);
BOOST_ASSERT(uprops_[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL(uprops_[prop::user_property][0].first, user_property_1);
BOOST_CHECK_EQUAL(uprops_[prop::user_property][0].second, user_property_2);
}
BOOST_AUTO_TEST_CASE(test_unsuback) {
@@ -571,8 +561,7 @@ BOOST_AUTO_TEST_CASE(test_unsuback) {
unsuback_props uprops;
uprops[prop::reason_string] = reason_string;
uprops[prop::user_property].push_back(user_property_1);
uprops[prop::user_property].push_back(user_property_2);
uprops[prop::user_property].emplace_back(user_property_1, user_property_2);
auto msg = encoders::encode_unsuback(packet_id, reason_codes, uprops);
@@ -592,9 +581,9 @@ BOOST_AUTO_TEST_CASE(test_unsuback) {
uprops_.visit([](const auto& p, const auto&) { (void)p; BOOST_ASSERT(p); return true; });
BOOST_CHECK_EQUAL(*uprops_[prop::reason_string], reason_string);
BOOST_ASSERT(uprops_[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL(uprops_[prop::user_property][0], user_property_1);
BOOST_CHECK_EQUAL(uprops_[prop::user_property][1], user_property_2);
BOOST_ASSERT(uprops_[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL(uprops_[prop::user_property][0].first, user_property_1);
BOOST_CHECK_EQUAL(uprops_[prop::user_property][0].second, user_property_2);
}
BOOST_AUTO_TEST_CASE(test_disconnect) {
@@ -610,8 +599,7 @@ BOOST_AUTO_TEST_CASE(test_disconnect) {
disconnect_props dprops;
dprops[prop::session_expiry_interval] = session_expiry_interval;
dprops[prop::reason_string] = reason_string;
dprops[prop::user_property].emplace_back(user_property_1);
dprops[prop::user_property].emplace_back(user_property_2);
dprops[prop::user_property].emplace_back(user_property_1, user_property_2);
dprops[prop::server_reference] = server_reference;
auto msg = encoders::encode_disconnect(reason_code, dprops);
@@ -630,9 +618,9 @@ BOOST_AUTO_TEST_CASE(test_disconnect) {
dprops_.visit([](const auto& p, const auto&) { (void)p; BOOST_ASSERT(p); return true; });
BOOST_CHECK_EQUAL(*dprops_[prop::session_expiry_interval], session_expiry_interval);
BOOST_CHECK_EQUAL(*dprops_[prop::reason_string], reason_string);
BOOST_ASSERT(dprops_[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL(dprops_[prop::user_property][0], user_property_1);
BOOST_CHECK_EQUAL(dprops_[prop::user_property][1], user_property_2);
BOOST_ASSERT(dprops_[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL(dprops_[prop::user_property][0].first, user_property_1);
BOOST_CHECK_EQUAL(dprops_[prop::user_property][0].second, user_property_2);
BOOST_CHECK_EQUAL(*dprops_[prop::server_reference], server_reference);
}
@@ -651,8 +639,7 @@ BOOST_AUTO_TEST_CASE(test_auth) {
aprops[prop::authentication_method] = authentication_method;
aprops[prop::authentication_data] = authentication_data;
aprops[prop::reason_string] = reason_string;
aprops[prop::user_property].emplace_back(user_property_1);
aprops[prop::user_property].emplace_back(user_property_2);
aprops[prop::user_property].emplace_back(user_property_1, user_property_2);
auto msg = encoders::encode_auth(reason_code, aprops);
@@ -671,9 +658,9 @@ BOOST_AUTO_TEST_CASE(test_auth) {
BOOST_CHECK_EQUAL(*aprops_[prop::authentication_method], authentication_method);
BOOST_CHECK_EQUAL(*aprops_[prop::authentication_data], authentication_data);
BOOST_CHECK_EQUAL(*aprops_[prop::reason_string], reason_string);
BOOST_ASSERT(aprops_[prop::user_property].size() == 2);
BOOST_CHECK_EQUAL(aprops_[prop::user_property][0], user_property_1);
BOOST_CHECK_EQUAL(aprops_[prop::user_property][1], user_property_2);
BOOST_ASSERT(aprops_[prop::user_property].size() == 1);
BOOST_CHECK_EQUAL(aprops_[prop::user_property][0].first, user_property_1);
BOOST_CHECK_EQUAL(aprops_[prop::user_property][0].second, user_property_2);
}
BOOST_AUTO_TEST_CASE(test_pingreq) {
@@ -692,8 +679,7 @@ BOOST_AUTO_TEST_CASE(test_pingresp) {
BOOST_AUTO_TEST_CASE(empty_user_property) {
publish_props pprops;
pprops[prop::user_property].emplace_back("");
pprops[prop::user_property].emplace_back("");
pprops[prop::user_property].emplace_back("", "");
auto msg = encoders::encode_publish(
1, "topic", "payload",
@@ -712,69 +698,9 @@ BOOST_AUTO_TEST_CASE(empty_user_property) {
const auto& [topic_, packet_id_, flags, pprops_, payload_] = *rv;
auto user_props_ = pprops_[prop::user_property];
BOOST_ASSERT(user_props_.size() == 2);
BOOST_CHECK_EQUAL(user_props_[0], "");
BOOST_CHECK_EQUAL(user_props_[1], "");
}
BOOST_AUTO_TEST_CASE(omit_invalid_user_property) {
// testing variables
std::string_view user_property_1 = "key";
std::string_view user_property_2 = "val";
std::string_view user_property_3 = "lone key";
publish_props pprops;
pprops[prop::user_property].emplace_back(user_property_1);
pprops[prop::user_property].emplace_back(user_property_2);
pprops[prop::user_property].emplace_back(user_property_3);
auto msg = encoders::encode_publish(
1, "topic", "payload",
qos_e::at_least_once, retain_e::yes, dup_e::no,
pprops
);
byte_citer it = msg.cbegin(), last = msg.cend();
auto header = decoders::decode_fixed_header(it, last);
BOOST_ASSERT(header);
const auto& [control_byte, remain_length] = *header;
auto rv = decoders::decode_publish(control_byte, remain_length, it);
BOOST_ASSERT(rv);
const auto& [topic_, packet_id_, flags, pprops_, payload_] = *rv;
auto user_props_ = pprops_[prop::user_property];
BOOST_ASSERT(user_props_.size() == 2);
BOOST_CHECK_EQUAL(user_props_[0], user_property_1);
BOOST_CHECK_EQUAL(user_props_[1], user_property_2);
}
BOOST_AUTO_TEST_CASE(omit_all_user_property) {
// testing variables
std::string_view user_property_1 = "key";
publish_props pprops;
pprops[prop::user_property].emplace_back(user_property_1);
auto msg = encoders::encode_publish(
1, "topic", "payload",
qos_e::at_least_once, retain_e::yes, dup_e::no,
pprops
);
byte_citer it = msg.cbegin(), last = msg.cend();
auto header = decoders::decode_fixed_header(it, last);
BOOST_ASSERT(header);
const auto& [control_byte, remain_length] = *header;
auto rv = decoders::decode_publish(control_byte, remain_length, it);
BOOST_ASSERT(rv);
const auto& [topic_, packet_id_, flags, pprops_, payload_] = *rv;
auto user_props_ = pprops_[prop::user_property];
BOOST_CHECK(user_props_.size() == 0);
BOOST_ASSERT(user_props_.size() == 1);
BOOST_CHECK_EQUAL(user_props_[0].first, "");
BOOST_CHECK_EQUAL(user_props_[0].second, "");
}
BOOST_AUTO_TEST_CASE(deserialize_user_property) {
@@ -795,9 +721,9 @@ BOOST_AUTO_TEST_CASE(deserialize_user_property) {
const auto& [reason_code_, pprops_] = *rv;
auto user_props_ = pprops_[prop::user_property];
BOOST_ASSERT(user_props_.size() == 2);
BOOST_CHECK_EQUAL(user_props_[0], "key");
BOOST_CHECK_EQUAL(user_props_[1], "val");
BOOST_ASSERT(user_props_.size() == 1);
BOOST_CHECK_EQUAL(user_props_[0].first, "key");
BOOST_CHECK_EQUAL(user_props_[0].second, "val");
}
BOOST_AUTO_TEST_CASE(deserialize_empty_user_property) {
@@ -818,9 +744,9 @@ BOOST_AUTO_TEST_CASE(deserialize_empty_user_property) {
const auto& [reason_code_, pprops_] = *rv;
auto user_props_ = pprops_[prop::user_property];
BOOST_ASSERT(user_props_.size() == 2);
BOOST_CHECK_EQUAL(user_props_[0], "");
BOOST_CHECK_EQUAL(user_props_[1], "");
BOOST_ASSERT(user_props_.size() == 1);
BOOST_CHECK_EQUAL(user_props_[0].first, "");
BOOST_CHECK_EQUAL(user_props_[0].second, "");
}
BOOST_AUTO_TEST_CASE(malformed_user_property) {

View File

@@ -105,14 +105,14 @@ BOOST_AUTO_TEST_CASE(invalid_topic_filter_6) {
BOOST_AUTO_TEST_CASE(malformed_user_property_1) {
subscribe_props sprops;
sprops[prop::user_property].push_back(std::string(10, char(0x01)));
sprops[prop::user_property].emplace_back("key", std::string(10, char(0x01)));
run_test(client::error::malformed_packet, "topic", sprops);
}
BOOST_AUTO_TEST_CASE(malformed_user_property_2) {
subscribe_props sprops;
sprops[prop::user_property].push_back(std::string(75000, 'a'));
sprops[prop::user_property].emplace_back("key", std::string(75000, 'a'));
run_test(client::error::malformed_packet, "topic", sprops);
}

View File

@@ -100,14 +100,14 @@ BOOST_AUTO_TEST_CASE(invalid_topic_filter_6) {
BOOST_AUTO_TEST_CASE(malformed_user_property_1) {
unsubscribe_props uprops;
uprops[prop::user_property].push_back(std::string(10, char(0x01)));
uprops[prop::user_property].emplace_back("key", std::string(10, char(0x01)));
run_test(client::error::malformed_packet, "topic", uprops);
}
BOOST_AUTO_TEST_CASE(malformed_user_property_2) {
unsubscribe_props uprops;
uprops[prop::user_property].push_back(std::string(75000, 'a'));
uprops[prop::user_property].emplace_back("key", std::string(75000, 'a'));
run_test(client::error::malformed_packet, "topic", uprops);
}