Skip to content

Commit be614e0

Browse files
FabianEckermanncodebot
authored andcommitted
cu_cp: add unittest for initial context setup routine
1 parent 3159ea5 commit be614e0

File tree

6 files changed

+366
-41
lines changed

6 files changed

+366
-41
lines changed

tests/test_doubles/ngap/ngap_test_message_validators.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ bool srsran::test_helpers::is_valid_initial_context_setup_response(const srs_cu_
3434
return true;
3535
}
3636

37+
bool srsran::test_helpers::is_valid_initial_context_setup_failure(const srs_cu_cp::ngap_message& msg)
38+
{
39+
TRUE_OR_RETURN(msg.pdu.type() == asn1::ngap::ngap_pdu_c::types_opts::unsuccessful_outcome);
40+
TRUE_OR_RETURN(msg.pdu.unsuccessful_outcome().proc_code == ASN1_NGAP_ID_INIT_CONTEXT_SETUP);
41+
return true;
42+
}
43+
3744
bool srsran::test_helpers::is_valid_ue_context_release_request(const srs_cu_cp::ngap_message& msg)
3845
{
3946
TRUE_OR_RETURN(msg.pdu.type() == asn1::ngap::ngap_pdu_c::types_opts::init_msg);

tests/test_doubles/ngap/ngap_test_message_validators.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ bool is_valid_init_ue_message(const srs_cu_cp::ngap_message& msg);
2424

2525
bool is_valid_initial_context_setup_response(const srs_cu_cp::ngap_message& msg);
2626

27+
bool is_valid_initial_context_setup_failure(const srs_cu_cp::ngap_message& msg);
28+
2729
bool is_valid_ue_context_release_request(const srs_cu_cp::ngap_message& msg);
2830

2931
bool is_valid_ue_radio_capability_info_indication(const srs_cu_cp::ngap_message& msg);

tests/unittests/cu_cp/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ target_include_directories(cu_cp_test_helpers PRIVATE ${CMAKE_SOURCE_DIR})
3232
target_link_libraries(cu_cp_test_helpers srsran_cu_cp srsran_support srslog f1ap_test_helpers e1ap_test_helpers f1ap_asn1 ngap_asn1 e1ap_asn1)
3333

3434

35-
add_executable(cu_cp_test cu_cp_test.cpp cu_cp_connectivity_test.cpp cu_cp_setup_test.cpp cu_cp_reestablishment_test.cpp)
35+
add_executable(cu_cp_test cu_cp_test.cpp cu_cp_connectivity_test.cpp cu_cp_setup_test.cpp cu_cp_reestablishment_test.cpp cu_cp_initial_context_setup_test.cpp)
3636
set_target_properties(cu_cp_test PROPERTIES UNITY_BUILD ON)
3737
target_link_libraries(cu_cp_test
3838
cu_cp_test_helpers
Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
/*
2+
*
3+
* Copyright 2021-2024 Software Radio Systems Limited
4+
*
5+
* By using this file, you agree to the terms and conditions set
6+
* forth in the LICENSE file which can be found at the top level of
7+
* the distribution.
8+
*
9+
*/
10+
11+
#include "cu_cp_test_environment.h"
12+
#include "tests/test_doubles/f1ap/f1ap_test_message_validators.h"
13+
#include "tests/test_doubles/f1ap/f1ap_test_messages.h"
14+
#include "tests/test_doubles/ngap/ngap_test_message_validators.h"
15+
#include "tests/test_doubles/rrc/rrc_test_message_validators.h"
16+
#include "tests/test_doubles/rrc/rrc_test_messages.h"
17+
#include "tests/unittests/e1ap/common/e1ap_cu_cp_test_messages.h"
18+
#include "tests/unittests/f1ap/common/f1ap_cu_test_messages.h"
19+
#include "tests/unittests/ngap/ngap_test_messages.h"
20+
#include "srsran/e1ap/common/e1ap_types.h"
21+
#include "srsran/f1ap/common/f1ap_message.h"
22+
#include "srsran/ngap/ngap_message.h"
23+
#include <gtest/gtest.h>
24+
25+
using namespace srsran;
26+
using namespace srs_cu_cp;
27+
28+
class cu_cp_initial_context_setup_test : public cu_cp_test_environment, public ::testing::Test
29+
{
30+
public:
31+
cu_cp_initial_context_setup_test() : cu_cp_test_environment(cu_cp_test_env_params{8, 8, 8192, create_mock_amf()})
32+
{
33+
// Run NG setup to completion.
34+
run_ng_setup();
35+
36+
// Setup DU.
37+
std::optional<unsigned> ret = connect_new_du();
38+
EXPECT_TRUE(ret.has_value());
39+
du_idx = ret.value();
40+
EXPECT_TRUE(this->run_f1_setup(du_idx));
41+
42+
// Setup CU-UP.
43+
ret = connect_new_cu_up();
44+
EXPECT_TRUE(ret.has_value());
45+
cu_up_idx = ret.value();
46+
EXPECT_TRUE(this->run_e1_setup(cu_up_idx));
47+
48+
// Connect UE 0x4601.
49+
EXPECT_TRUE(connect_new_ue(du_idx, du_ue_id, crnti));
50+
EXPECT_TRUE(authenticate_ue(du_idx, du_ue_id, amf_ue_id_t::min));
51+
52+
ue_ctx = this->find_ue_context(du_idx, du_ue_id);
53+
54+
EXPECT_NE(ue_ctx, nullptr);
55+
}
56+
57+
void send_initial_context_setup_request(bool with_pdu_sessions = false)
58+
{
59+
srsran_assert(not this->get_amf().try_pop_rx_pdu(ngap_pdu), "there are still NGAP messages to pop from AMF");
60+
srsran_assert(not this->get_du(du_idx).try_pop_dl_pdu(f1ap_pdu), "there are still F1AP DL messages to pop from DU");
61+
62+
// Inject NGAP Initial Context Setup Request
63+
ngap_message init_ctxt_setup_req;
64+
if (with_pdu_sessions) {
65+
init_ctxt_setup_req = generate_valid_initial_context_setup_request_message_with_pdu_session(
66+
ue_ctx->amf_ue_id.value(), ue_ctx->ran_ue_id.value());
67+
} else {
68+
init_ctxt_setup_req =
69+
generate_valid_initial_context_setup_request_message(ue_ctx->amf_ue_id.value(), ue_ctx->ran_ue_id.value());
70+
}
71+
72+
get_amf().push_tx_pdu(init_ctxt_setup_req);
73+
}
74+
75+
void send_ue_context_setup_request_and_await_response()
76+
{
77+
// Wait for F1AP UE Context Setup Request (containing Security Mode Command).
78+
bool result = this->wait_for_f1ap_tx_pdu(du_idx, f1ap_pdu);
79+
report_fatal_error_if_not(result, "Failed to receive Security Mode Command");
80+
report_fatal_error_if_not(test_helpers::is_valid_ue_context_setup_request(f1ap_pdu),
81+
"Invalid UE Context Setup Request");
82+
const byte_buffer& rrc_container = test_helpers::get_rrc_container(f1ap_pdu);
83+
report_fatal_error_if_not(
84+
test_helpers::is_valid_rrc_security_mode_command(test_helpers::extract_dl_dcch_msg(rrc_container)),
85+
"Invalid Security Mode command");
86+
87+
// Inject UE Context Setup Response
88+
f1ap_message ue_ctxt_setup_response = generate_ue_context_setup_response(ue_ctx->cu_ue_id.value(), du_ue_id);
89+
get_du(du_idx).push_ul_pdu(ue_ctxt_setup_response);
90+
}
91+
92+
void send_security_mode_complete_and_await_ue_capability_enquiry()
93+
{
94+
// Inject Security Mode Complete
95+
f1ap_message ul_rrc_msg_transfer = generate_ul_rrc_message_transfer(
96+
ue_ctx->cu_ue_id.value(), du_ue_id, srb_id_t::srb1, make_byte_buffer("00032a00fd5ec7ff").value());
97+
get_du(du_idx).push_ul_pdu(ul_rrc_msg_transfer);
98+
99+
// Wait for UE Capability Enquiry
100+
bool result = this->wait_for_f1ap_tx_pdu(du_idx, f1ap_pdu);
101+
report_fatal_error_if_not(result, "Failed to receive DL RRC Message, containing RRC UE Capability Enquiry");
102+
report_fatal_error_if_not(test_helpers::is_valid_dl_rrc_message_transfer(f1ap_pdu),
103+
"Invalid DL RRC Message Transfer");
104+
}
105+
106+
void send_ue_capability_info_and_await_registration_accept_and_initial_context_setup_response()
107+
{
108+
// Inject UL RRC Message Transfer (containing UE Capability Info)
109+
get_du(du_idx).push_ul_pdu(test_helpers::create_ul_rrc_message_transfer(
110+
du_ue_id,
111+
ue_ctx->cu_ue_id.value(),
112+
srb_id_t::srb1,
113+
make_byte_buffer(
114+
"00044c821930680ce811d1968097e360e1480005824c5c00060fc2c00637fe002e00131401a0000000880058d006007"
115+
"a071e439f0000240400e0300000000100186c0000700809df000000000000030368000800004b2ca000a07143c001c0"
116+
"03c000000100200409028098a8660c")
117+
.value()));
118+
119+
// Wait for DL RRC Message Transfer (containing NAS Registration Accept)
120+
bool result = this->wait_for_f1ap_tx_pdu(du_idx, f1ap_pdu);
121+
report_fatal_error_if_not(result, "Failed to receive DL RRC Message, containing NAS Registration Accept");
122+
report_fatal_error_if_not(test_helpers::is_valid_dl_rrc_message_transfer(f1ap_pdu),
123+
"Invalid DL RRC Message Transfer");
124+
125+
// Wait for Initial Context Setup Response
126+
result = this->wait_for_ngap_tx_pdu(ngap_pdu);
127+
report_fatal_error_if_not(result, "Failed to receive Initial Context Setup Response");
128+
report_fatal_error_if_not(test_helpers::is_valid_initial_context_setup_response(ngap_pdu),
129+
"Invalid init ctxt setup");
130+
}
131+
132+
void send_ue_capability_info_and_handle_pdu_session_resource_setup_request()
133+
{
134+
// Inject UL RRC Message Transfer (containing UE Capability Info)
135+
get_du(du_idx).push_ul_pdu(test_helpers::create_ul_rrc_message_transfer(
136+
du_ue_id,
137+
ue_ctx->cu_ue_id.value(),
138+
srb_id_t::srb1,
139+
make_byte_buffer(
140+
"00044c821930680ce811d1968097e360e1480005824c5c00060fc2c00637fe002e00131401a0000000880058d006007"
141+
"a071e439f0000240400e0300000000100186c0000700809df000000000000030368000800004b2ca000a07143c001c0"
142+
"03c000000100200409028098a8660c")
143+
.value()));
144+
145+
// Wait for E1AP Bearer Context Setup Request
146+
bool result = this->wait_for_e1ap_tx_pdu(0, e1ap_pdu);
147+
report_fatal_error_if_not(result, "Failed to receive E1AP Bearer Context Setup Request");
148+
149+
cu_cp_e1ap_id =
150+
int_to_gnb_cu_cp_ue_e1ap_id(e1ap_pdu.pdu.init_msg().value.bearer_context_setup_request()->gnb_cu_cp_ue_e1ap_id);
151+
cu_up_e1ap_id = int_to_gnb_cu_up_ue_e1ap_id(0);
152+
153+
// Inject Bearer Context Setup Response and wait for F1AP UE Context Modification Request.
154+
get_cu_up(0).push_tx_pdu(generate_bearer_context_setup_response(cu_cp_e1ap_id, cu_up_e1ap_id));
155+
result = this->wait_for_f1ap_tx_pdu(du_idx, f1ap_pdu);
156+
report_fatal_error_if_not(result, "Failed to receive F1AP UE Context Modification Request");
157+
report_fatal_error_if_not(test_helpers::is_valid_ue_context_modification_request(f1ap_pdu),
158+
"Invalid UE Context Modification");
159+
160+
// Inject UE Context Modification Response and wait for Bearer Context Modification to be sent to CU-UP.
161+
get_du(du_idx).push_ul_pdu(
162+
test_helpers::generate_ue_context_modification_response(du_ue_id, ue_ctx->cu_ue_id.value(), crnti));
163+
result = this->wait_for_e1ap_tx_pdu(0, e1ap_pdu);
164+
report_fatal_error_if_not(result, "Failed to receive E1AP Bearer Context Modification");
165+
166+
// Inject E1AP Bearer Context Modification Response and wait for DL RRC Message (containing RRC Reconfiguration)
167+
get_cu_up(0).push_tx_pdu(generate_bearer_context_modification_response(cu_cp_e1ap_id, cu_up_e1ap_id));
168+
result = this->wait_for_f1ap_tx_pdu(du_idx, f1ap_pdu);
169+
report_fatal_error_if_not(result, "Failed to receive F1AP DL RRC Message (containing RRC Reconfiguration)");
170+
report_fatal_error_if_not(test_helpers::is_valid_dl_rrc_message_transfer(f1ap_pdu),
171+
"Invalid DL RRC Message Transfer");
172+
}
173+
174+
void send_rrc_reconfiguration_complete_and_await_initial_context_setup_response()
175+
{
176+
// Inject UL RRC Message Transfer (containing RRC Reconfiguration Complete)
177+
f1ap_message ul_rrc_msg_transfer = generate_ul_rrc_message_transfer(
178+
ue_ctx->cu_ue_id.value(), du_ue_id, srb_id_t::srb1, make_byte_buffer("00050e00a18bc2b3").value());
179+
get_du(du_idx).push_ul_pdu(ul_rrc_msg_transfer);
180+
181+
// Wait for Initial Context Setup Response
182+
bool result = this->wait_for_ngap_tx_pdu(ngap_pdu);
183+
report_fatal_error_if_not(result, "Failed to receive Initial Context Setup Response");
184+
report_fatal_error_if_not(test_helpers::is_valid_initial_context_setup_response(ngap_pdu),
185+
"Invalid init ctxt setup");
186+
}
187+
188+
void await_initial_context_setup_failure()
189+
{
190+
// Wait for NGAP Initial Context Setup Failure
191+
bool result = this->wait_for_ngap_tx_pdu(ngap_pdu);
192+
report_fatal_error_if_not(result, "Failed to receive Initial Context Setup Failure");
193+
report_fatal_error_if_not(test_helpers::is_valid_initial_context_setup_failure(ngap_pdu),
194+
"Invalid Initial Context Setup Failure");
195+
}
196+
197+
void await_ue_capability_info_indication()
198+
{
199+
// Wait for UE Capability Info Indication
200+
bool result = this->wait_for_ngap_tx_pdu(ngap_pdu);
201+
report_fatal_error_if_not(result, "Failed to receive UE Radio Capability Info Indication");
202+
report_fatal_error_if_not(test_helpers::is_valid_ue_radio_capability_info_indication(ngap_pdu),
203+
"Invalid UE Radio Capability Info Indication");
204+
}
205+
206+
void await_ue_context_release_request()
207+
{
208+
// Wait for UE Context Release Request
209+
bool result = this->wait_for_ngap_tx_pdu(ngap_pdu);
210+
report_fatal_error_if_not(result, "Failed to receive UE Context Release Request");
211+
report_fatal_error_if_not(test_helpers::is_valid_ue_context_release_request(ngap_pdu),
212+
"Invalid UE Context Release Request");
213+
}
214+
215+
unsigned du_idx = 0;
216+
unsigned cu_up_idx = 0;
217+
218+
gnb_du_ue_f1ap_id_t du_ue_id = int_to_gnb_du_ue_f1ap_id(0);
219+
rnti_t crnti = to_rnti(0x4601);
220+
gnb_cu_cp_ue_e1ap_id_t cu_cp_e1ap_id;
221+
gnb_cu_up_ue_e1ap_id_t cu_up_e1ap_id;
222+
223+
const ue_context* ue_ctx = nullptr;
224+
225+
ngap_message ngap_pdu;
226+
f1ap_message f1ap_pdu;
227+
e1ap_message e1ap_pdu;
228+
};
229+
230+
TEST_F(cu_cp_initial_context_setup_test, when_ue_context_setup_fails_then_initial_context_setup_fails)
231+
{
232+
// Inject Initial Context Setup Request
233+
send_initial_context_setup_request();
234+
235+
// Inject UE Context Setup Failure
236+
f1ap_message ue_ctxt_setup_failure =
237+
generate_ue_context_setup_failure(find_ue_context(du_idx, du_ue_id)->cu_ue_id.value(), du_ue_id);
238+
get_du(du_idx).push_ul_pdu(ue_ctxt_setup_failure);
239+
240+
// Wait for NGAP Initial Context Setup Failure
241+
await_initial_context_setup_failure();
242+
}
243+
244+
TEST_F(cu_cp_initial_context_setup_test, when_security_mode_command_fails_then_initial_context_setup_fails)
245+
{
246+
// Inject Initial Context Setup Request
247+
send_initial_context_setup_request();
248+
249+
// Wait for F1AP UE Context Setup Request (containing Security Mode Command) and inject UE Context Setup Response
250+
send_ue_context_setup_request_and_await_response();
251+
252+
// Inject Security Mode Failure
253+
f1ap_message ul_rrc_msg_transfer = generate_ul_rrc_message_transfer(
254+
ue_ctx->cu_ue_id.value(), du_ue_id, srb_id_t::srb1, make_byte_buffer("00033200c1bf019d").value());
255+
get_du(du_idx).push_ul_pdu(ul_rrc_msg_transfer);
256+
257+
// Wait for NGAP Initial Context Setup Failure
258+
await_initial_context_setup_failure();
259+
}
260+
261+
TEST_F(cu_cp_initial_context_setup_test, when_ue_capability_enquiry_fails_then_initial_context_setup_fails)
262+
{
263+
// Inject Initial Context Setup Request
264+
send_initial_context_setup_request();
265+
266+
// Wait for F1AP UE Context Setup Request (containing Security Mode Command) and inject UE Context Setup Response
267+
send_ue_context_setup_request_and_await_response();
268+
269+
// Inject Security Mode Complete and await UE Capability Enquiry
270+
send_security_mode_complete_and_await_ue_capability_enquiry();
271+
272+
// Fail UE Capability Enquiry (UE doesn't respond)
273+
ASSERT_FALSE(tick_until(std::chrono::milliseconds(this->get_cu_cp_cfg().rrc_config.rrc_procedure_timeout_ms),
274+
[&]() { return false; }));
275+
276+
// Wait for NGAP Initial Context Setup Failure
277+
await_initial_context_setup_failure();
278+
}
279+
280+
TEST_F(cu_cp_initial_context_setup_test, when_ue_capability_enquiry_successful_then_initial_context_setup_succeeds)
281+
{
282+
// Inject Initial Context Setup Request
283+
send_initial_context_setup_request();
284+
285+
// Wait for F1AP UE Context Setup Request (containing Security Mode Command) and inject UE Context Setup Response
286+
send_ue_context_setup_request_and_await_response();
287+
288+
// Inject Security Mode Complete and await UE Capability Enquiry
289+
send_security_mode_complete_and_await_ue_capability_enquiry();
290+
291+
// Inject UE Capability Info and await DL RRC Message (Registration Accept) and Initial Context Setup Response
292+
send_ue_capability_info_and_await_registration_accept_and_initial_context_setup_response();
293+
294+
// Wait for UE Capability Info Indication
295+
await_ue_capability_info_indication();
296+
}
297+
298+
TEST_F(cu_cp_initial_context_setup_test,
299+
when_initial_context_setup_contains_valid_pdu_sessions_to_setup_then_initial_context_setup_succeeds)
300+
{
301+
// Inject Initial Context Setup Request
302+
send_initial_context_setup_request(true);
303+
304+
// Wait for F1AP UE Context Setup Request (containing Security Mode Command) and inject UE Context Setup Response
305+
send_ue_context_setup_request_and_await_response();
306+
307+
// Inject Security Mode Complete and await UE Capability Enquiry
308+
send_security_mode_complete_and_await_ue_capability_enquiry();
309+
310+
// Inject UE Capability Info and handle PDU Session Resource Setup List Context Request
311+
send_ue_capability_info_and_handle_pdu_session_resource_setup_request();
312+
313+
// Inject RRC Reconfiguration Complete and await Initial Context Setup Response
314+
send_rrc_reconfiguration_complete_and_await_initial_context_setup_response();
315+
316+
// Wait for UE Capability Info Indication
317+
await_ue_capability_info_indication();
318+
}

0 commit comments

Comments
 (0)