From 79715578883ea62684ff1a69f7879a0daf997637 Mon Sep 17 00:00:00 2001 From: c8ef Date: Thu, 14 May 2026 18:42:22 +0800 Subject: [PATCH] use std::optional Signed-off-by: c8ef --- README.md | 2 +- proto/frontend/src/action_prof_mgr.h | 2 +- proto/frontend/src/table_info_store.h | 2 +- proto/tests/matchers.cpp | 3 +- proto/tests/matchers.h | 12 +- proto/tests/mock_switch.cpp | 13 +- proto/tests/server/test_gnmi.cpp | 19 ++- proto/tests/stream_receiver.h | 9 +- proto/tests/test_proto_fe.cpp | 199 +++++++++++--------------- proto/tests/test_proto_fe_digest.cpp | 50 +++---- 10 files changed, 137 insertions(+), 174 deletions(-) diff --git a/README.md b/README.md index 6eb24d31..bcf670f4 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ to install different dependencies. required to run some of the generated binaries uner valgrind - valgrind, as some tests use it to check for memory errors - Boost library, for some of the C++ tests: we currently require - `boost/optional.hpp` and `boost/functional/hash.hpp` + `boost/functional/hash.hpp` ### Installing dependencies from package repositories diff --git a/proto/frontend/src/action_prof_mgr.h b/proto/frontend/src/action_prof_mgr.h index b65e97ac..621ff08a 100644 --- a/proto/frontend/src/action_prof_mgr.h +++ b/proto/frontend/src/action_prof_mgr.h @@ -280,7 +280,7 @@ class ActionProfAccessManual : public ActionProfAccessBase { bool get_member_info(const Id &group_id, const Id &member_id, int *weight, WatchPort *watch_port) const; - // would be nice to be able to use boost::optional for the retrieve functions; + // would be nice to be able to use std::optional for the retrieve functions; // we cannot return a pointer (that would be null if the key couldn't be // found) because some other thread may come in and remove the corresponding // group / member, thus invalidating the pointer. diff --git a/proto/frontend/src/table_info_store.h b/proto/frontend/src/table_info_store.h index 50db7377..aabae743 100644 --- a/proto/frontend/src/table_info_store.h +++ b/proto/frontend/src/table_info_store.h @@ -64,7 +64,7 @@ class TableInfoStore { uint64_t controller_metadata{0}; std::string metadata; int64_t idle_timeout_ns{0}; - // wish I could use boost::optional here + // wish I could use std::optional here bool is_oneshot{false}; pi_indirect_handle_t oneshot_group_handle{0}; }; diff --git a/proto/tests/matchers.cpp b/proto/tests/matchers.cpp index e2a7b665..14eeda01 100644 --- a/proto/tests/matchers.cpp +++ b/proto/tests/matchers.cpp @@ -300,8 +300,7 @@ TableEntryMatcher_Base::add_direct_counter(pi_p4_id_t counter_id, CounterDataMatcher(data, check_bytes, check_packets)); } -void -TableEntryMatcher_Base::set_ttl(boost::optional ttl_ns) { +void TableEntryMatcher_Base::set_ttl(std::optional ttl_ns) { ttl = ttl_ns; } diff --git a/proto/tests/matchers.h b/proto/tests/matchers.h index 53406713..503c242c 100644 --- a/proto/tests/matchers.h +++ b/proto/tests/matchers.h @@ -25,15 +25,13 @@ #include #include +#include #include #include -#include - -#include "p4/v1/p4runtime.pb.h" - #include "PI/pi.h" #include "PI/pi_clone.h" +#include "p4/v1/p4runtime.pb.h" namespace pi { namespace proto { @@ -224,8 +222,8 @@ class TableEntryMatcher_Base { const p4::v1::CounterData &data, bool check_bytes, bool check_packets); - // boost:none means to TTL expected in the entry properties - void set_ttl(boost::optional ttl_ns); + // std::nullopt means to TTL expected in the entry properties + void set_ttl(std::optional ttl_ns); protected: TableEntryMatcher_Base(); @@ -235,7 +233,7 @@ class TableEntryMatcher_Base { std::unordered_map meters; std::unordered_map counters; - boost::optional ttl; + std::optional ttl; }; class TableEntryMatcher_Direct diff --git a/proto/tests/mock_switch.cpp b/proto/tests/mock_switch.cpp index 8205aa14..3cae4813 100644 --- a/proto/tests/mock_switch.cpp +++ b/proto/tests/mock_switch.cpp @@ -25,6 +25,7 @@ #include // std::copy, std::for_each, std::count #include +#include #include #include #include @@ -32,9 +33,6 @@ #include // std::move #include -#include -#include - #include "PI/frontends/cpp/tables.h" #include "PI/frontends/proto/device_mgr.h" #include "PI/int/pi_int.h" @@ -44,6 +42,7 @@ #include "PI/target/pi_imp.h" #include "PI/target/pi_learn_imp.h" #include "PI/target/pi_tables_imp.h" +#include "boost/functional/hash.hpp" namespace pi { namespace proto { @@ -800,7 +799,7 @@ class DummyPRE { pi_mc_node_handle_t node_handle) { auto it = mc_nodes.find(node_handle); if (it == mc_nodes.end()) return PI_STATUS_TARGET_ERROR; - if (it->second.attached_to.is_initialized()) return PI_STATUS_TARGET_ERROR; + if (it->second.attached_to) return PI_STATUS_TARGET_ERROR; it->second.attached_to = grp_handle; return PI_STATUS_SUCCESS; } @@ -810,8 +809,8 @@ class DummyPRE { (void)grp_handle; auto it = mc_nodes.find(node_handle); if (it == mc_nodes.end()) return PI_STATUS_TARGET_ERROR; - if (!it->second.attached_to.is_initialized()) return PI_STATUS_TARGET_ERROR; - it->second.attached_to = boost::none; + if (!it->second.attached_to) return PI_STATUS_TARGET_ERROR; + it->second.attached_to = std::nullopt; return PI_STATUS_SUCCESS; } @@ -833,7 +832,7 @@ class DummyPRE { pi_mc_node_handle_t node_handle; pi_mc_rid_t rid; std::vector eg_ports; - boost::optional attached_to; + std::optional attached_to; McNode(pi_mc_node_handle_t node_handle, pi_mc_rid_t rid, diff --git a/proto/tests/server/test_gnmi.cpp b/proto/tests/server/test_gnmi.cpp index 9d371f3d..7a212618 100644 --- a/proto/tests/server/test_gnmi.cpp +++ b/proto/tests/server/test_gnmi.cpp @@ -20,7 +20,6 @@ */ #include - #include #include @@ -30,17 +29,15 @@ #include #include #include +#include #include #include #include #include #include -#include - -#include "gnmi/gnmi.grpc.pb.h" - #include "gnmi.h" +#include "gnmi/gnmi.grpc.pb.h" using grpc::Server; using grpc::ServerBuilder; @@ -191,9 +188,9 @@ std::ostream &operator <<(std::ostream &os, const Event &e) { return os; } -std::ostream &operator <<(std::ostream &os, const boost::optional &e) { - if (e.is_initialized()) - os << e.get(); +std::ostream& operator<<(std::ostream& os, const std::optional& e) { + if (e) + os << e.value(); else os << "NONE"; return os; @@ -559,11 +556,11 @@ class TestGNMISysrepo : public TestGNMI { return event_queue.empty(); } - boost::optional wait_for_event(const std::string &xpath) { + std::optional wait_for_event(const std::string& xpath) { Event event; event.xpath = xpath; if (!event_queue.pop_back(&event, std::chrono::milliseconds(500))) - return boost::none; + return std::nullopt; return event; } @@ -623,7 +620,7 @@ class TestGNMISysrepo : public TestGNMI { auto xpath = gNMI_path_to_XPath(notification.prefix(), update.path()); if (xpath == expected_xpath) return update.val().string_val(); } - return ""; // use boost::optional instead ? + return ""; // use std::optional instead ? } static constexpr char iface_type[] = "iana-if-type:ethernetCsmacd"; diff --git a/proto/tests/stream_receiver.h b/proto/tests/stream_receiver.h index 86518138..87e6b4d8 100644 --- a/proto/tests/stream_receiver.h +++ b/proto/tests/stream_receiver.h @@ -19,10 +19,9 @@ #include #include #include +#include #include -#include - #include "p4/v1/p4runtime.pb.h" namespace p4v1 = ::p4::v1; @@ -102,8 +101,8 @@ class StreamReceiver { } template - boost::optional get(const std::chrono::duration &timeout) { - using Clock = std::chrono::steady_clock; + std::optional get(const std::chrono::duration& timeout) { + using Clock = std::chrono::steady_clock; Lock lock(mutex); // using wait_until and not wait_for to account for spurious awakenings. if (cvar.wait_until(lock, Clock::now() + timeout, @@ -112,7 +111,7 @@ class StreamReceiver { msgs.pop(); return msg; } - return boost::none; + return std::nullopt; } private: diff --git a/proto/tests/test_proto_fe.cpp b/proto/tests/test_proto_fe.cpp index 9792aa00..2da768e0 100644 --- a/proto/tests/test_proto_fe.cpp +++ b/proto/tests/test_proto_fe.cpp @@ -21,7 +21,6 @@ */ #include - #include #include #include @@ -36,6 +35,7 @@ #include // std::distance #include #include +#include #include #include #include @@ -44,22 +44,17 @@ #include #include -#include - #include "PI/frontends/cpp/tables.h" #include "PI/frontends/proto/device_mgr.h" #include "PI/int/pi_int.h" #include "PI/p4info.h" #include "PI/pi.h" #include "PI/proto/util.h" - -#include "src/report_error.h" -#include "src/statusor.h" - #include "google/rpc/code.pb.h" - #include "matchers.h" #include "mock_switch.h" +#include "src/report_error.h" +#include "src/statusor.h" #include "stream_receiver.h" #include "test_proto_fe_base.h" @@ -456,34 +451,28 @@ class MatchTableTest } p4v1::TableEntry generic_make(pi_p4_id_t t_id, - boost::optional mf, - const std::string ¶m_v, - int priority = 0, + std::optional mf, + const std::string& param_v, int priority = 0, uint64_t controller_metadata = 0); - boost::optional default_mf() const; + std::optional default_mf() const; pi_p4_id_t t_id; pi_p4_id_t mf_id; pi_p4_id_t a_id; }; -p4v1::TableEntry -MatchTableTest::generic_make(pi_p4_id_t t_id, - boost::optional mf, - const std::string ¶m_v, - int priority, - uint64_t controller_metadata) { +p4v1::TableEntry MatchTableTest::generic_make( + pi_p4_id_t t_id, std::optional mf, + const std::string& param_v, int priority, uint64_t controller_metadata) { p4v1::TableEntry table_entry; table_entry.set_table_id(t_id); table_entry.set_controller_metadata(controller_metadata); table_entry.set_metadata(std::to_string(controller_metadata)); table_entry.set_priority(priority); - // not supported by older versions of boost - // if (mf != boost::none) { - if (mf.is_initialized()) { + if (mf) { auto mf_ptr = table_entry.add_match(); - *mf_ptr = mf.get(); + *mf_ptr = mf.value(); } auto entry = table_entry.mutable_action(); auto action = entry->mutable_action(); @@ -496,12 +485,11 @@ MatchTableTest::generic_make(pi_p4_id_t t_id, return table_entry; } -boost::optional -MatchTableTest::default_mf() const { +std::optional MatchTableTest::default_mf() const { auto mk_input = std::get<1>(GetParam()); switch (mk_input.get_type()) { case MatchKeyInput::Type::EXACT: - return boost::none; + return std::nullopt; case MatchKeyInput::Type::LPM: return MatchKeyInput::make_lpm(std::string(4, '\x00'), 0); case MatchKeyInput::Type::TERNARY: @@ -514,7 +502,7 @@ MatchTableTest::default_mf() const { return MatchKeyInput::make_range( std::string(4, '\x00'), std::string(4, '\xff'), PRIORITY); } - return boost::none; // unreachable + return std::nullopt; // unreachable } TEST_P(MatchTableTest, AddAndRead) { @@ -605,7 +593,7 @@ TEST_P(MatchTableTest, SetDefault) { std::string adata(6, '\xcd'); auto entry_matcher = CorrectTableEntryDirect(a_id, adata); EXPECT_CALL(*mock, table_default_action_set(t_id, entry_matcher)).Times(2); - auto entry = generic_make(t_id, boost::none, adata); + auto entry = generic_make(t_id, std::nullopt, adata); entry.set_is_default_action(true); { auto status = add_entry(&entry); @@ -644,7 +632,7 @@ TEST_P(MatchTableTest, GetDefault) { std::string adata(6, '\xcd'); auto entry_matcher = CorrectTableEntryDirect(a_id, adata); - auto entry = generic_make(t_id, boost::none, adata); + auto entry = generic_make(t_id, std::nullopt, adata); entry.set_is_default_action(true); EXPECT_CALL(*mock, table_default_action_set(t_id, entry_matcher)); EXPECT_OK(modify_entry(&entry)); @@ -754,16 +742,16 @@ TEST_P(MatchTableTest, InvalidActionId) { TEST_P(MatchTableTest, MissingMatchField) { std::string adata(6, '\xcd'); auto mk_input = default_mf(); - if (mk_input.is_initialized()) { // omitting field supported for match type - auto mk_matcher = CorrectMatchKey(t_id, mk_input.get().get_match_key()); + if (mk_input) { // omitting field supported for match type + auto mk_matcher = CorrectMatchKey(t_id, mk_input.value().get_match_key()); auto entry_matcher = CorrectTableEntryDirect(a_id, adata); EXPECT_CALL(*mock, table_entry_add(t_id, mk_matcher, entry_matcher, _)); - auto entry = generic_make( - t_id, boost::none, adata, mk_input->get_priority()); + auto entry = + generic_make(t_id, std::nullopt, adata, mk_input->get_priority()); auto status = add_entry(&entry); ASSERT_EQ(status.code(), Code::OK); } else { // omitting field not supported for match type - auto entry = generic_make(t_id, boost::none, adata, 0); + auto entry = generic_make(t_id, std::nullopt, adata, 0); auto status = add_entry(&entry); EXPECT_EQ(status, OneExpectedError(Code::INVALID_ARGUMENT)); } @@ -919,14 +907,13 @@ class ActionProfTest member->set_watch(watch_port); } - void add_member_to_group_new(p4v1::ActionProfileGroup *group, - uint32_t member_id, - int weight, - const boost::optional &watch_port) { + void add_member_to_group_new(p4v1::ActionProfileGroup* group, + uint32_t member_id, int weight, + const std::optional& watch_port) { auto member = group->add_members(); member->set_member_id(member_id); member->set_weight(weight); - if (watch_port.is_initialized()) member->set_watch_port(*watch_port); + if (watch_port) member->set_watch_port(*watch_port); } template @@ -1762,13 +1749,12 @@ class MatchTableIndirectTest template p4v1::TableEntry make_indirect_entry_one_shot( - const boost::optional &mf_v, - It params_begin, It params_end, + const std::optional& mf_v, It params_begin, It params_end, int weight = 1, int watch_port = 0) { p4v1::TableEntry table_entry; auto t_id = pi_p4info_table_id_from_name(p4info, "IndirectWS"); table_entry.set_table_id(t_id); - if (mf_v.is_initialized()) { + if (mf_v) { auto mf = table_entry.add_match(); mf->set_field_id(pi_p4info_table_match_field_id_from_name( p4info, t_id, "header_test.field32")); @@ -1788,13 +1774,12 @@ class MatchTableIndirectTest template p4v1::TableEntry make_indirect_entry_one_shot_new( - const boost::optional &mf_v, - It params_begin, It params_end, - int weight, const boost::optional &watch_port) { + const std::optional& mf_v, It params_begin, It params_end, + int weight, const std::optional& watch_port) { p4v1::TableEntry table_entry; auto t_id = pi_p4info_table_id_from_name(p4info, "IndirectWS"); table_entry.set_table_id(t_id); - if (mf_v.is_initialized()) { + if (mf_v) { auto mf = table_entry.add_match(); mf->set_field_id(pi_p4info_table_match_field_id_from_name( p4info, t_id, "header_test.field32")); @@ -1807,7 +1792,7 @@ class MatchTableIndirectTest auto ap_action = ap_action_set->add_action_profile_actions(); set_action(ap_action->mutable_action(), *param_it); ap_action->set_weight(weight); - if (watch_port.is_initialized()) ap_action->set_watch_port(*watch_port); + if (watch_port) ap_action->set_watch_port(*watch_port); } return table_entry; } @@ -2278,8 +2263,8 @@ TEST_P(MatchTableIndirectTest, SetDefault) { std::vector params; params.emplace_back(6, '\x00'); params.emplace_back(6, '\x01'); - auto entry = make_indirect_entry_one_shot( - boost::none /* no match */, params.begin(), params.end()); + auto entry = make_indirect_entry_one_shot(std::nullopt /* no match */, + params.begin(), params.end()); entry.set_is_default_action(true); // Cannot set default entry for indirect table EXPECT_EQ( @@ -2312,11 +2297,11 @@ class ExactOneTest : public DeviceMgrTest { ExactOneTest() : ExactOneTest("ExactOne", "header_test.field32") { } - p4v1::TableEntry make_entry(const boost::optional &mf_v, - const std::string ¶m_v) { + p4v1::TableEntry make_entry(const std::optional& mf_v, + const std::string& param_v) { p4v1::TableEntry table_entry; table_entry.set_table_id(t_id); - if (mf_v.is_initialized()) { + if (mf_v) { auto mf = table_entry.add_match(); mf->set_field_id(pi_p4info_table_match_field_id_from_name( p4info, t_id, f_name.c_str())); @@ -2360,7 +2345,7 @@ TEST_F(ExactOneTest, ZeroKeyAndDefaultEntry) { EXPECT_CALL(*mock, table_entry_add(t_id, _, _, _)); EXPECT_CALL(*mock, table_default_action_set(t_id, _)).Times(2); { - auto entry = make_entry(boost::none, adata); + auto entry = make_entry(std::nullopt, adata); entry.set_is_default_action(true); auto status = modify_entry(&entry); EXPECT_EQ(status.code(), Code::OK); @@ -2371,7 +2356,7 @@ TEST_F(ExactOneTest, ZeroKeyAndDefaultEntry) { EXPECT_EQ(status.code(), Code::OK); } { - auto entry = make_entry(boost::none, adata); + auto entry = make_entry(std::nullopt, adata); entry.set_is_default_action(true); auto status = modify_entry(&entry); EXPECT_EQ(status.code(), Code::OK); @@ -2551,7 +2536,7 @@ TEST_F(DirectMeterTest, ReadAllFromTable) { // default entry direct meter access with DirectMeterEntry message TEST_F(DirectMeterTest, DefaultEntry) { std::string adata(6, '\xcd'); - auto entry = make_entry(boost::none, adata); + auto entry = make_entry(std::nullopt, adata); entry.set_is_default_action(true); auto config = make_meter_config(); auto meter_entry = make_meter_entry(entry, config); @@ -2574,7 +2559,7 @@ TEST_F(DirectMeterTest, DefaultEntry) { // default entry direct meter access with TableEntry message TEST_F(DirectMeterTest, WriteInTableEntryDefault) { std::string adata(6, '\xcd'); - auto entry = make_entry(boost::none, adata); + auto entry = make_entry(std::nullopt, adata); entry.set_is_default_action(true); auto *meter_config = entry.mutable_meter_config(); *meter_config = make_meter_config(); @@ -2883,7 +2868,7 @@ TEST_F(DirectCounterTest, WriteInTableEntry) { // default entry direct counter access with DirectCounterEntry message TEST_F(DirectCounterTest, DefaultEntry) { std::string adata(6, '\xcd'); - auto entry = make_entry(boost::none, adata); + auto entry = make_entry(std::nullopt, adata); entry.set_is_default_action(true); auto counter_entry = make_counter_entry(&entry); auto *counter_data = counter_entry.mutable_data(); @@ -2906,7 +2891,7 @@ TEST_F(DirectCounterTest, DefaultEntry) { // default entry direct counter access with TableEntry message TEST_F(DirectCounterTest, WriteInTableEntryDefault) { std::string adata(6, '\xcd'); - auto entry = make_entry(boost::none, adata); + auto entry = make_entry(std::nullopt, adata); entry.set_is_default_action(true); auto counter_data = entry.mutable_counter_data(); counter_data->set_packet_count(3); @@ -3123,16 +3108,14 @@ class TernaryOneTest : public DeviceMgrTest { TernaryOneTest() : TernaryOneTest("TernaryOne", "header_test.field32") { } - p4v1::TableEntry make_entry(const boost::optional &mf_v, - const boost::optional &mask_v, - const std::string ¶m_v, + p4v1::TableEntry make_entry(const std::optional& mf_v, + const std::optional& mask_v, + const std::string& param_v, int priority = PRIORITY) { p4v1::TableEntry table_entry; table_entry.set_table_id(t_id); table_entry.set_priority(priority); - // not supported by older versions of boost - // if (mf_v != boost::none) { - if (mf_v.is_initialized()) { + if (mf_v) { auto mf = table_entry.add_match(); mf->set_field_id(pi_p4info_table_match_field_id_from_name( p4info, t_id, f_name.c_str())); @@ -3179,7 +3162,7 @@ TEST_F(TernaryOneTest, ValueEqValueAndMask) { TEST_F(TernaryOneTest, DontCare) { std::string adata(6, '\xcd'); { // omitting match field: valid - auto entry = make_entry(boost::none, boost::none, adata); + auto entry = make_entry(std::nullopt, std::nullopt, adata); EXPECT_CALL(*mock, table_entry_add(t_id, _, _, _)); auto status = add_entry(&entry); ASSERT_EQ(status.code(), Code::OK); @@ -3204,7 +3187,7 @@ TEST_F(TernaryOneTest, DontCare) { TEST_F(TernaryOneTest, ZeroPriority) { std::string adata(6, '\xcd'); - auto entry = make_entry(boost::none, boost::none, adata, 0); + auto entry = make_entry(std::nullopt, std::nullopt, adata, 0); EXPECT_CALL(*mock, table_entry_add(t_id, _, _, _)).Times(0); auto status = add_entry(&entry); EXPECT_EQ(status, OneExpectedError(Code::INVALID_ARGUMENT)); @@ -3221,15 +3204,13 @@ class RangeOneTest : public DeviceMgrTest { RangeOneTest() : RangeOneTest("RangeOne", "header_test.field32") { } - p4v1::TableEntry make_entry(const boost::optional &low_v, - const boost::optional &high_v, - const std::string ¶m_v) { + p4v1::TableEntry make_entry(const std::optional& low_v, + const std::optional& high_v, + const std::string& param_v) { p4v1::TableEntry table_entry; table_entry.set_table_id(t_id); table_entry.set_priority(PRIORITY); - // not supported by older versions of boost - // if (low_v != boost::none) { - if (low_v.is_initialized()) { + if (low_v) { auto mf = table_entry.add_match(); mf->set_field_id(pi_p4info_table_match_field_id_from_name( p4info, t_id, f_name.c_str())); @@ -3284,7 +3265,7 @@ TEST_F(RangeOneTest, LowLeHigh) { TEST_F(RangeOneTest, DontCare) { std::string adata(6, '\xcd'); { // omitting match field: valid - auto entry = make_entry(boost::none, boost::none, adata); + auto entry = make_entry(std::nullopt, std::nullopt, adata); EXPECT_CALL(*mock, table_entry_add(t_id, _, _, _)); auto status = add_entry(&entry); ASSERT_EQ(status.code(), Code::OK); @@ -3318,14 +3299,11 @@ class LpmOneTest : public DeviceMgrTest { LpmOneTest() : LpmOneTest("LpmOne", "header_test.field32") { } - p4v1::TableEntry make_entry(const boost::optional &mf_v, - int pLen, - const std::string ¶m_v) { + p4v1::TableEntry make_entry(const std::optional& mf_v, int pLen, + const std::string& param_v) { p4v1::TableEntry table_entry; table_entry.set_table_id(t_id); - // not supported by older versions of boost - // if (mf_v != boost::none) { - if (mf_v.is_initialized()) { + if (mf_v) { auto mf = table_entry.add_match(); mf->set_field_id(pi_p4info_table_match_field_id_from_name( p4info, t_id, f_name.c_str())); @@ -3386,7 +3364,7 @@ TEST_F(LpmOneTest, DontCare) { std::string adata(6, '\xcd'); int pLen(0); { // omitting match field: valid - auto entry = make_entry(boost::none, pLen, adata); + auto entry = make_entry(std::nullopt, pLen, adata); EXPECT_CALL(*mock, table_entry_add(t_id, _, _, _)); auto status = add_entry(&entry); ASSERT_EQ(status.code(), Code::OK); @@ -4218,14 +4196,14 @@ class MatchTableConstDefaultActionTest : public DeviceMgrTest { } p4v1::TableEntry make_entry(pi_p4_id_t a_id, - const boost::optional ¶m_v) { + const std::optional& param_v) { p4v1::TableEntry table_entry; table_entry.set_table_id(t_id); table_entry.set_is_default_action(true); auto entry = table_entry.mutable_action(); auto action = entry->mutable_action(); action->set_action_id(a_id); - if (param_v.is_initialized()) { + if (param_v) { auto param = action->add_params(); param->set_param_id( pi_p4info_action_param_id_from_name(p4info, a_id, "param")); @@ -4235,7 +4213,7 @@ class MatchTableConstDefaultActionTest : public DeviceMgrTest { } DeviceMgr::Status set_default(pi_p4_id_t a_id, - const boost::optional ¶m_v) { + const std::optional& param_v) { auto table_entry = make_entry(a_id, param_v); return modify_entry(&table_entry); } @@ -4251,7 +4229,7 @@ TEST_F(MatchTableConstDefaultActionTest, MutateParam) { } TEST_F(MatchTableConstDefaultActionTest, MutateAction) { - EXPECT_EQ(set_default(aC_id, boost::none), + EXPECT_EQ(set_default(aC_id, std::nullopt), OneExpectedError(Code::PERMISSION_DENIED, "const default action")); } @@ -4286,7 +4264,7 @@ class MatchTableActionAnnotationsTest : public DeviceMgrTest { } DeviceMgr::Status set_default(pi_p4_id_t a_id, - const boost::optional ¶m_v) { + const std::optional& param_v) { p4v1::TableEntry table_entry; table_entry.set_table_id(t_id); table_entry.set_is_default_action(true); @@ -4294,9 +4272,8 @@ class MatchTableActionAnnotationsTest : public DeviceMgrTest { return modify_entry(&table_entry); } - DeviceMgr::Status insert_entry(const std::string &mf_v, - pi_p4_id_t a_id, - const boost::optional ¶m_v) { + DeviceMgr::Status insert_entry(const std::string& mf_v, pi_p4_id_t a_id, + const std::optional& param_v) { p4v1::TableEntry table_entry; table_entry.set_table_id(t_id); auto mf = table_entry.add_match(); @@ -4314,13 +4291,12 @@ class MatchTableActionAnnotationsTest : public DeviceMgrTest { pi_p4_id_t aC_id; // DEFAULT_ONLY scope private: - void set_action(p4v1::TableEntry *table_entry, - pi_p4_id_t a_id, - const boost::optional ¶m_v) const { + void set_action(p4v1::TableEntry* table_entry, pi_p4_id_t a_id, + const std::optional& param_v) const { auto entry = table_entry->mutable_action(); auto action = entry->mutable_action(); action->set_action_id(a_id); - if (param_v.is_initialized()) { + if (param_v) { auto param = action->add_params(); param->set_param_id( pi_p4info_action_param_id_from_name(p4info, a_id, "param")); @@ -4348,9 +4324,9 @@ TEST_F(MatchTableActionAnnotationsTest, TableOnly) { TEST_F(MatchTableActionAnnotationsTest, DefaultOnly) { EXPECT_CALL(*mock, table_default_action_set(t_id, _)); - EXPECT_OK(set_default(aC_id, boost::none)); + EXPECT_OK(set_default(aC_id, std::nullopt)); EXPECT_CALL(*mock, table_entry_add(t_id, _, _, _)).Times(Exactly(0)); - EXPECT_EQ(insert_entry(std::string("\x01\x02"), aC_id, boost::none), + EXPECT_EQ(insert_entry(std::string("\x01\x02"), aC_id, std::nullopt), OneExpectedError(Code::PERMISSION_DENIED, "Cannot use DEFAULT_ONLY action in table entry")); } @@ -4369,24 +4345,23 @@ class IdleTimeoutTest : public ExactOneTest { // prevent name hiding using ExactOneTest::make_entry; - template + template p4v1::TableEntry make_entry( - const boost::optional &mf_v, - const std::string ¶m_v, - const std::chrono::duration &timeout) { + const std::optional& mf_v, const std::string& param_v, + const std::chrono::duration& timeout) { auto table_entry = make_entry(mf_v, param_v); table_entry.set_idle_timeout_ns( std::chrono::duration_cast(timeout).count()); return table_entry; } - template - boost::optional notification_receive( - const std::chrono::duration &timeout) { + template + std::optional notification_receive( + const std::chrono::duration& timeout) { return stream_receiver.get(timeout); } - boost::optional notification_receive() { + std::optional notification_receive() { return notification_receive(defaultTimeout); } @@ -4421,12 +4396,12 @@ TEST_F(IdleTimeoutTest, EntryAgeing) { auto entry_handle = mock->get_table_entry_handle(); EXPECT_EQ(mock->age_entry(t_id, entry_handle), PI_STATUS_SUCCESS); auto notification = notification_receive(); - ASSERT_NE(notification, boost::none); + ASSERT_NE(notification, std::nullopt); ASSERT_EQ(notification->table_entry_size(), 1); const auto &table_entry = notification->table_entry(0); entry.clear_action(); EXPECT_PROTO_EQ(table_entry, entry); - EXPECT_EQ(notification_receive(negativeTimeout), boost::none); + EXPECT_EQ(notification_receive(negativeTimeout), std::nullopt); } // Checks that idle notifications which are close to each other in time are @@ -4446,9 +4421,9 @@ TEST_F(IdleTimeoutTest, Buffering) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); } auto notification = notification_receive(); - ASSERT_NE(notification, boost::none); + ASSERT_NE(notification, std::nullopt); EXPECT_EQ(notification->table_entry_size(), static_cast(num_entries)); - EXPECT_EQ(notification_receive(negativeTimeout), boost::none); + EXPECT_EQ(notification_receive(negativeTimeout), std::nullopt); } // Checks that notifications are not buffered for too long. @@ -4465,7 +4440,7 @@ TEST_F(IdleTimeoutTest, MaxBuffering) { std::this_thread::sleep_for(notificationMaxDelay); } int num_notifications = 0; - while (notification_receive() != boost::none) num_notifications++; + while (notification_receive() != std::nullopt) num_notifications++; EXPECT_GT(num_notifications, 1); } @@ -4489,7 +4464,7 @@ TEST_F(IdleTimeoutTest, ModifyTTL) { EXPECT_CALL(*mock, table_entry_modify_wkey(t_id, _, entry_matcher)); EXPECT_OK(modify_entry(&entry)); - entry_matcher_->set_ttl(boost::none); + entry_matcher_->set_ttl(std::nullopt); EXPECT_CALL(*mock, table_entry_modify_wkey(t_id, _, entry_matcher)); EXPECT_OK(modify_entry(&entry)); @@ -4540,9 +4515,9 @@ class StreamErrorTest : public DeviceMgrTest { return mgr.stream_message_request_handle(request); } - template - boost::optional error_receive( - const std::chrono::duration &timeout) { + template + std::optional error_receive( + const std::chrono::duration& timeout) { return stream_receiver.get(timeout); } @@ -4562,7 +4537,7 @@ TEST_F(StreamErrorTest, StreamErrorDisabled) { .WillOnce(Return(PI_STATUS_TARGET_ERROR)); auto status = send_packet(); EXPECT_NE(status.code(), Code::OK); - EXPECT_EQ(error_receive(negativeTimeout), boost::none); + EXPECT_EQ(error_receive(negativeTimeout), std::nullopt); } TEST_F(StreamErrorTest, StreamErrorEnabled) { @@ -4577,7 +4552,7 @@ TEST_F(StreamErrorTest, StreamErrorEnabled) { auto status = send_packet(); EXPECT_NE(status.code(), Code::OK); auto stream_error = error_receive(defaultTimeout); - EXPECT_NE(stream_error, boost::none); + EXPECT_NE(stream_error, std::nullopt); EXPECT_TRUE(stream_error->has_packet_out()); } diff --git a/proto/tests/test_proto_fe_digest.cpp b/proto/tests/test_proto_fe_digest.cpp index d317d0b2..89cdfcc8 100644 --- a/proto/tests/test_proto_fe_digest.cpp +++ b/proto/tests/test_proto_fe_digest.cpp @@ -21,7 +21,6 @@ */ #include - #include #include @@ -31,20 +30,17 @@ #include // std::ifstream #include // std::back_inserter #include +#include #include #include #include #include -#include - -#include "src/common.h" -#include "src/digest_mgr.h" - #include "google/rpc/code.pb.h" - #include "matchers.h" #include "mock_switch.h" +#include "src/common.h" +#include "src/digest_mgr.h" #include "test_proto_fe_base.h" namespace pi { @@ -134,9 +130,9 @@ class DigestMgrTest : public DeviceMgrBaseTest { return mock->digest_inject(digest_id, ++msg_id, samples_); } - template - boost::optional digest_receive( - const std::chrono::duration &timeout) { + template + std::optional digest_receive( + const std::chrono::duration& timeout) { Lock lock(mutex); // using wait_until and not wait_for to account for spurious awakenings. // if (cvar.wait_for(lock, timeout, [this] { return !digests.empty(); })) { @@ -146,10 +142,10 @@ class DigestMgrTest : public DeviceMgrBaseTest { digests.pop(); return digest; } - return boost::none; + return std::nullopt; } - boost::optional digest_receive() { + std::optional digest_receive() { return digest_receive(defaultTimeout); } @@ -221,7 +217,7 @@ TEST_F(DigestMgrTest, Default) { EXPECT_CALL(*mock, learn_msg_done(_)); ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); auto digest = digest_receive(); - ASSERT_NE(digest, boost::none); + ASSERT_NE(digest, std::nullopt); EXPECT_EQ(digest->digest_id(), digest_id); EXPECT_EQ(digest->data_size(), 1); EXPECT_TRUE(s.eq(digest->data(0))); @@ -235,7 +231,7 @@ TEST_F(DigestMgrTest, DefaultCanonical) { EXPECT_CALL(*mock, learn_msg_done(_)); ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); auto digest = digest_receive(); - ASSERT_NE(digest, boost::none); + ASSERT_NE(digest, std::nullopt); EXPECT_EQ(digest->digest_id(), digest_id); EXPECT_EQ(digest->data_size(), 1); EXPECT_TRUE(s.eq(digest->data(0))); @@ -253,8 +249,8 @@ TEST_F(DigestMgrTest, Cache) { ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); - ASSERT_NE(digest_receive(), boost::none); - ASSERT_NE(digest_receive(), boost::none); // default config: no cache + ASSERT_NE(digest_receive(), std::nullopt); + ASSERT_NE(digest_receive(), std::nullopt); // default config: no cache p4v1::DigestEntry config; config.set_digest_id(digest_id); @@ -263,11 +259,11 @@ TEST_F(DigestMgrTest, Cache) { ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); - ASSERT_NE(digest_receive(), boost::none); - ASSERT_EQ(digest_receive(3 * ack_timeout), boost::none); // cache hit + ASSERT_NE(digest_receive(), std::nullopt); + ASSERT_EQ(digest_receive(3 * ack_timeout), std::nullopt); // cache hit // we have waited 3 * ack_timeout, cache should be clear ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); - ASSERT_NE(digest_receive(), boost::none); + ASSERT_NE(digest_receive(), std::nullopt); } TEST_F(DigestMgrTest, Ack) { @@ -287,9 +283,9 @@ TEST_F(DigestMgrTest, Ack) { ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); auto digest = digest_receive(); - ASSERT_NE(digest, boost::none); + ASSERT_NE(digest, std::nullopt); // cache hit - ASSERT_EQ(digest_receive(std::chrono::milliseconds(200)), boost::none); + ASSERT_EQ(digest_receive(std::chrono::milliseconds(200)), std::nullopt); p4v1::DigestListAck ack; ack.set_digest_id(digest_id); ack.set_list_id(digest->list_id()); @@ -297,7 +293,7 @@ TEST_F(DigestMgrTest, Ack) { ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); // the ack call is asynchronous and there is no way to get completion // information, but we assume that 200ms is long enough for it to complete - ASSERT_NE(digest_receive(std::chrono::milliseconds(200)), boost::none); + ASSERT_NE(digest_receive(std::chrono::milliseconds(200)), std::nullopt); } TEST_F(DigestMgrTest, MaxListSize) { @@ -318,7 +314,7 @@ TEST_F(DigestMgrTest, MaxListSize) { ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); } auto digest = digest_receive(std::chrono::milliseconds(500)); - ASSERT_NE(digest, boost::none); + ASSERT_NE(digest, std::nullopt); EXPECT_EQ(digest->data_size(), 2); } @@ -334,7 +330,7 @@ TEST_F(DigestMgrTest, MaxTimeout) { s << "\x11\x22\x33\x44\x55\x66" << "\x01\x23"; ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); auto sent_at = Clock::now(); - ASSERT_NE(digest_receive(std::chrono::milliseconds(1000)), boost::none); + ASSERT_NE(digest_receive(std::chrono::milliseconds(1000)), std::nullopt); auto received_at = Clock::now(); auto diff = received_at - sent_at; EXPECT_GT(diff, max_timeout / 2); @@ -358,17 +354,17 @@ TEST_F(DigestMgrTest, Reset) { ASSERT_OK(config_write(config, p4v1::Update::INSERT)); ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); - ASSERT_NE(digest_receive(), boost::none); + ASSERT_NE(digest_receive(), std::nullopt); ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); - ASSERT_EQ(digest_receive(), boost::none); // cache hit + ASSERT_EQ(digest_receive(), std::nullopt); // cache hit // deleting the config should reset the state of the DigestMgr, so it should // clear the cache ASSERT_OK(config_delete()); ASSERT_OK(config_write(config, p4v1::Update::INSERT)); ASSERT_EQ(digest_inject({s}), PI_STATUS_SUCCESS); - ASSERT_NE(digest_receive(), boost::none); + ASSERT_NE(digest_receive(), std::nullopt); } } // namespace