From 3852698ad955e6c46aebe4b6120221025c5543a5 Mon Sep 17 00:00:00 2001 From: Sergey Sukhanov Date: Mon, 20 Sep 2021 11:35:59 +0200 Subject: [PATCH] dcsctp: support handover state serialization testing dcSCTP library users can set their custom g_handover_state_transformer_for_test that can serialize and deserialize the state. All dcSCTP handover tests call g_handover_state_transformer_for_test. If some part of the state is serialized incorrectly or is forgotten, high chance that it will fail the tests. Bug: webrtc:13154 Change-Id: I251a099be04dda7611e9df868d36e3a76dc7d1e1 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232325 Commit-Queue: Sergey Sukhanov Reviewed-by: Mirko Bonadei Reviewed-by: Victor Boivie Cr-Commit-Position: refs/heads/main@{#35035} --- net/dcsctp/common/BUILD.gn | 9 ++++++ net/dcsctp/common/handover_testing.cc | 22 ++++++++++++++ net/dcsctp/common/handover_testing.h | 29 +++++++++++++++++++ net/dcsctp/rx/BUILD.gn | 1 + net/dcsctp/rx/data_tracker_test.cc | 2 ++ net/dcsctp/rx/reassembly_queue_test.cc | 3 ++ .../rx/traditional_reassembly_streams_test.cc | 4 +++ net/dcsctp/socket/BUILD.gn | 1 + net/dcsctp/socket/dcsctp_socket_test.cc | 2 ++ .../socket/stream_reset_handler_test.cc | 3 ++ net/dcsctp/tx/BUILD.gn | 1 + net/dcsctp/tx/retransmission_queue_test.cc | 2 ++ 12 files changed, 79 insertions(+) create mode 100644 net/dcsctp/common/handover_testing.cc create mode 100644 net/dcsctp/common/handover_testing.h diff --git a/net/dcsctp/common/BUILD.gn b/net/dcsctp/common/BUILD.gn index 591fa44207..80520132b0 100644 --- a/net/dcsctp/common/BUILD.gn +++ b/net/dcsctp/common/BUILD.gn @@ -54,3 +54,12 @@ if (rtc_include_tests) { ] } } + +rtc_library("handover_testing") { + deps = [ "../public:socket" ] + testonly = true + sources = [ + "handover_testing.cc", + "handover_testing.h", + ] +} diff --git a/net/dcsctp/common/handover_testing.cc b/net/dcsctp/common/handover_testing.cc new file mode 100644 index 0000000000..1081766ea5 --- /dev/null +++ b/net/dcsctp/common/handover_testing.cc @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include "net/dcsctp/common/handover_testing.h" + +namespace dcsctp { +namespace { +// Default transformer function does nothing - dcSCTP does not implement +// state serialization that could be tested by setting +// `g_handover_state_transformer_for_test`. +void NoTransformation(DcSctpSocketHandoverState*) {} +} // namespace + +void (*g_handover_state_transformer_for_test)(DcSctpSocketHandoverState*) = + NoTransformation; +} // namespace dcsctp diff --git a/net/dcsctp/common/handover_testing.h b/net/dcsctp/common/handover_testing.h new file mode 100644 index 0000000000..396016afec --- /dev/null +++ b/net/dcsctp/common/handover_testing.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#ifndef NET_DCSCTP_COMMON_HANDOVER_TESTING_H_ +#define NET_DCSCTP_COMMON_HANDOVER_TESTING_H_ + +#include "net/dcsctp/public/dcsctp_handover_state.h" + +namespace dcsctp { +// This global function is to facilitate testing of the socket handover state +// (`DcSctpSocketHandoverState`) serialization. dcSCTP library users have to +// implement state serialization if it's needed. To test the serialization one +// can set a custom `g_handover_state_transformer_for_test` at startup, link to +// the dcSCTP tests and run the resulting binary. Custom function can serialize +// and deserialize the passed state. All dcSCTP handover tests call +// `g_handover_state_transformer_for_test`. If some part of the state is +// serialized incorrectly or is forgotten, high chance that it will fail the +// tests. +extern void (*g_handover_state_transformer_for_test)( + DcSctpSocketHandoverState*); +} // namespace dcsctp + +#endif // NET_DCSCTP_COMMON_HANDOVER_TESTING_H_ diff --git a/net/dcsctp/rx/BUILD.gn b/net/dcsctp/rx/BUILD.gn index cdb465336b..c5023a5907 100644 --- a/net/dcsctp/rx/BUILD.gn +++ b/net/dcsctp/rx/BUILD.gn @@ -108,6 +108,7 @@ if (rtc_include_tests) { "../../../rtc_base:gunit_helpers", "../../../rtc_base:rtc_base_approved", "../../../test:test_support", + "../common:handover_testing", "../common:sequence_numbers", "../packet:chunk", "../packet:data", diff --git a/net/dcsctp/rx/data_tracker_test.cc b/net/dcsctp/rx/data_tracker_test.cc index e59f8a929d..6140241f4e 100644 --- a/net/dcsctp/rx/data_tracker_test.cc +++ b/net/dcsctp/rx/data_tracker_test.cc @@ -15,6 +15,7 @@ #include "absl/types/optional.h" #include "api/array_view.h" +#include "net/dcsctp/common/handover_testing.h" #include "net/dcsctp/packet/chunk/sack_chunk.h" #include "net/dcsctp/timer/fake_timeout.h" #include "net/dcsctp/timer/timer.h" @@ -54,6 +55,7 @@ class DataTrackerTest : public testing::Test { EXPECT_TRUE(tracker_->GetHandoverReadiness().IsReady()); DcSctpSocketHandoverState state; tracker_->AddHandoverState(state); + g_handover_state_transformer_for_test(&state); tracker_ = std::make_unique("log: ", timer_.get(), kInitialTSN, &state); } diff --git a/net/dcsctp/rx/reassembly_queue_test.cc b/net/dcsctp/rx/reassembly_queue_test.cc index 8f98ef1e08..d1e3bf6413 100644 --- a/net/dcsctp/rx/reassembly_queue_test.cc +++ b/net/dcsctp/rx/reassembly_queue_test.cc @@ -18,6 +18,7 @@ #include #include "api/array_view.h" +#include "net/dcsctp/common/handover_testing.h" #include "net/dcsctp/packet/chunk/forward_tsn_chunk.h" #include "net/dcsctp/packet/chunk/forward_tsn_common.h" #include "net/dcsctp/packet/chunk/iforward_tsn_chunk.h" @@ -367,6 +368,7 @@ TEST_F(ReassemblyQueueTest, HandoverInInitialState) { EXPECT_EQ(reasm1.GetHandoverReadiness(), HandoverReadinessStatus()); DcSctpSocketHandoverState state; reasm1.AddHandoverState(state); + g_handover_state_transformer_for_test(&state); ReassemblyQueue reasm2("log: ", TSN(100), kBufferSize, &state); reasm2.Add(TSN(10), gen_.Ordered({1, 2, 3, 4}, "BE")); @@ -381,6 +383,7 @@ TEST_F(ReassemblyQueueTest, HandoverAfterHavingAssembedOneMessage) { EXPECT_EQ(reasm1.GetHandoverReadiness(), HandoverReadinessStatus()); DcSctpSocketHandoverState state; reasm1.AddHandoverState(state); + g_handover_state_transformer_for_test(&state); ReassemblyQueue reasm2("log: ", TSN(100), kBufferSize, &state); reasm2.Add(TSN(11), gen_.Ordered({1, 2, 3, 4}, "BE")); diff --git a/net/dcsctp/rx/traditional_reassembly_streams_test.cc b/net/dcsctp/rx/traditional_reassembly_streams_test.cc index f58bfed4a4..3e6f560aba 100644 --- a/net/dcsctp/rx/traditional_reassembly_streams_test.cc +++ b/net/dcsctp/rx/traditional_reassembly_streams_test.cc @@ -13,6 +13,7 @@ #include #include +#include "net/dcsctp/common/handover_testing.h" #include "net/dcsctp/common/sequence_numbers.h" #include "net/dcsctp/packet/chunk/forward_tsn_chunk.h" #include "net/dcsctp/packet/chunk/forward_tsn_common.h" @@ -156,6 +157,7 @@ TEST_F(TraditionalReassemblyStreamsTest, NoStreamsCanBeHandedOver) { DcSctpSocketHandoverState state; streams1.AddHandoverState(state); + g_handover_state_transformer_for_test(&state); TraditionalReassemblyStreams streams2("", on_assembled.AsStdFunction(), &state); @@ -191,6 +193,7 @@ TEST_F(TraditionalReassemblyStreamsTest, DcSctpSocketHandoverState state; streams1.AddHandoverState(state); + g_handover_state_transformer_for_test(&state); TraditionalReassemblyStreams streams2("", on_assembled.AsStdFunction(), &state); EXPECT_EQ(streams2.Add(tsn(4), gen_.Ordered({7})), 1); @@ -223,6 +226,7 @@ TEST_F(TraditionalReassemblyStreamsTest, DcSctpSocketHandoverState state; streams1.AddHandoverState(state); + g_handover_state_transformer_for_test(&state); TraditionalReassemblyStreams streams2("", on_assembled.AsStdFunction(), &state); EXPECT_EQ(streams2.Add(tsn(4), gen_.Unordered({7})), 1); diff --git a/net/dcsctp/socket/BUILD.gn b/net/dcsctp/socket/BUILD.gn index 895292001c..69307ac6b4 100644 --- a/net/dcsctp/socket/BUILD.gn +++ b/net/dcsctp/socket/BUILD.gn @@ -225,6 +225,7 @@ if (rtc_include_tests) { "../../../rtc_base:gunit_helpers", "../../../rtc_base:rtc_base_approved", "../../../test:test_support", + "../common:handover_testing", "../common:internal_types", "../packet:chunk", "../packet:error_cause", diff --git a/net/dcsctp/socket/dcsctp_socket_test.cc b/net/dcsctp/socket/dcsctp_socket_test.cc index 2fadde8a21..9f5190b254 100644 --- a/net/dcsctp/socket/dcsctp_socket_test.cc +++ b/net/dcsctp/socket/dcsctp_socket_test.cc @@ -21,6 +21,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/array_view.h" +#include "net/dcsctp/common/handover_testing.h" #include "net/dcsctp/packet/chunk/chunk.h" #include "net/dcsctp/packet/chunk/cookie_echo_chunk.h" #include "net/dcsctp/packet/chunk/data_chunk.h" @@ -324,6 +325,7 @@ class DcSctpSocketTest : public testing::Test { absl::optional handover_state = sock_z_->GetHandoverStateAndClose(); EXPECT_TRUE(handover_state.has_value()); + g_handover_state_transformer_for_test(&*handover_state); cb_z_.Reset(); sock_z_ = std::make_unique("Z", cb_z_, GetPacketObserver("Z"), options_); diff --git a/net/dcsctp/socket/stream_reset_handler_test.cc b/net/dcsctp/socket/stream_reset_handler_test.cc index 4fa7e1b686..894f486388 100644 --- a/net/dcsctp/socket/stream_reset_handler_test.cc +++ b/net/dcsctp/socket/stream_reset_handler_test.cc @@ -17,6 +17,7 @@ #include "absl/types/optional.h" #include "api/array_view.h" +#include "net/dcsctp/common/handover_testing.h" #include "net/dcsctp/common/internal_types.h" #include "net/dcsctp/packet/chunk/reconfig_chunk.h" #include "net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.h" @@ -186,6 +187,8 @@ class StreamResetHandlerTest : public testing::Test { retransmission_queue_->AddHandoverState(state); + g_handover_state_transformer_for_test(&state); + data_tracker_ = std::make_unique( "log: ", delayed_ack_timer_.get(), kPeerInitialTsn, &state); reasm_ = std::make_unique("log: ", kPeerInitialTsn, kArwnd, diff --git a/net/dcsctp/tx/BUILD.gn b/net/dcsctp/tx/BUILD.gn index a02f5dc6ee..6bf439f955 100644 --- a/net/dcsctp/tx/BUILD.gn +++ b/net/dcsctp/tx/BUILD.gn @@ -121,6 +121,7 @@ if (rtc_include_tests) { "../../../rtc_base:gunit_helpers", "../../../rtc_base:rtc_base_approved", "../../../test:test_support", + "../common:handover_testing", "../packet:chunk", "../packet:data", "../public:socket", diff --git a/net/dcsctp/tx/retransmission_queue_test.cc b/net/dcsctp/tx/retransmission_queue_test.cc index 5f524de4bb..b34927a1bb 100644 --- a/net/dcsctp/tx/retransmission_queue_test.cc +++ b/net/dcsctp/tx/retransmission_queue_test.cc @@ -18,6 +18,7 @@ #include "absl/types/optional.h" #include "api/array_view.h" +#include "net/dcsctp/common/handover_testing.h" #include "net/dcsctp/packet/chunk/data_chunk.h" #include "net/dcsctp/packet/chunk/forward_tsn_chunk.h" #include "net/dcsctp/packet/chunk/forward_tsn_common.h" @@ -93,6 +94,7 @@ class RetransmissionQueueTest : public testing::Test { EXPECT_EQ(queue.GetHandoverReadiness(), HandoverReadinessStatus()); DcSctpSocketHandoverState state; queue.AddHandoverState(state); + g_handover_state_transformer_for_test(&state); return RetransmissionQueue( "", TSN(10), kArwnd, producer_, on_rtt_.AsStdFunction(), on_clear_retransmission_counter_.AsStdFunction(), *timer_, options_,