Skip to content

Commit d71be37

Browse files
frankistcodebot
authored andcommitted
sched: implement unit test that ensures DL/UL scheduling in all slots for different TDD patterns
1 parent 8cebd85 commit d71be37

File tree

6 files changed

+206
-18
lines changed

6 files changed

+206
-18
lines changed

lib/scheduler/config/scheduler_cell_config_validator.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,12 @@ static error_type<std::string> validate_rach_cfg_common(const sched_cell_configu
7777
const unsigned start_slot_idx =
7878
subframe_idx * (1U << to_numerology_value(pusch_scs)) + prach_duration_info.start_slot_pusch_scs;
7979
for (unsigned sl = 0; sl < prach_duration_info.prach_length_slots; ++sl) {
80-
VERIFY(cell_cfg.is_fully_ul_enabled(slot_point{to_numerology_value(pusch_scs), sl + start_slot_idx}),
81-
"PRACH configuration index {} not supported with current TDD pattern. PRACH fall outside UL slots",
82-
rach_cfg_cmn.rach_cfg_generic.prach_config_index);
80+
VERIFY(
81+
cell_cfg.is_fully_ul_enabled(slot_point{to_numerology_value(pusch_scs), sl + start_slot_idx}),
82+
"PRACH configuration index {} not supported with current TDD pattern. Slot indexes used for PRACH {} fall "
83+
"outside TDD UL slots",
84+
rach_cfg_cmn.rach_cfg_generic.prach_config_index,
85+
interval<unsigned>{start_slot_idx, start_slot_idx + prach_duration_info.prach_length_slots});
8386
}
8487
}
8588
}

tests/unittests/scheduler/CMakeLists.txt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,15 @@ add_executable(pdcch_resource_allocator_test pdcch/pdcch_resource_allocator_test
3131
target_link_libraries(pdcch_resource_allocator_test srsran_sched srslog mac_configuration_helpers sched_config gtest gtest_main)
3232
add_test(pdcch_resource_allocator_test pdcch_resource_allocator_test)
3333

34-
add_executable(scheduler_test scheduler_retx_test.cpp scheduler_ue_removal_test.cpp)
35-
target_link_libraries(scheduler_test srsran_sched sched_config
34+
add_executable(scheduler_test scheduler_retx_test.cpp scheduler_ue_removal_test.cpp scheduler_tdd_test.cpp)
35+
target_link_libraries(scheduler_test
36+
srsran_sched
37+
sched_config
3638
scheduler_test_suite
37-
gtest gtest_main)
39+
gtest
40+
gtest_main)
3841
gtest_discover_tests(scheduler_test)
42+
add_test(scheduler_test scheduler_test)
3943

4044
add_executable(multiple_ue_sched_test multiple_ue_sched_test.cpp)
4145
target_link_libraries(multiple_ue_sched_test

tests/unittests/scheduler/scheduler_retx_test.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,3 @@ TEST_F(scheduler_missing_ack_tester, when_no_crc_arrives_then_ul_harq_eventually
231231
INSTANTIATE_TEST_SUITE_P(msg3_retx,
232232
scheduler_retx_tester,
233233
testing::Values(test_params{0}, test_params{1}, test_params{2}, test_params{3}));
234-
235-
int main(int argc, char** argv)
236-
{
237-
srslog::fetch_basic_logger("SCHED", true).set_level(srslog::basic_levels::info);
238-
srslog::init();
239-
240-
::testing::InitGoogleTest(&argc, argv);
241-
return RUN_ALL_TESTS();
242-
}
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
*
3+
* Copyright 2021-2023 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+
/// \file
12+
/// \brief Unit test for scheduler using different TDD patterns.
13+
14+
#include "test_utils/config_generators.h"
15+
#include "test_utils/indication_generators.h"
16+
#include "test_utils/result_test_helpers.h"
17+
#include "test_utils/scheduler_test_bench.h"
18+
#include <gtest/gtest.h>
19+
20+
using namespace srsran;
21+
22+
class base_scheduler_tdd_tester : public scheduler_test_bench
23+
{
24+
protected:
25+
base_scheduler_tdd_tester(
26+
const tdd_ul_dl_config_common& tdd_cfg = config_helpers::make_default_tdd_ul_dl_config_common()) :
27+
scheduler_test_bench(4, tdd_cfg.ref_scs)
28+
{
29+
// Add Cell.
30+
this->add_cell([this, &tdd_cfg]() {
31+
params.scs_common = tdd_cfg.ref_scs;
32+
params.dl_arfcn = 520002;
33+
params.band = nr_band::n41;
34+
params.channel_bw_mhz = bs_channel_bandwidth_fr1::MHz20;
35+
const unsigned nof_crbs = band_helper::get_n_rbs_from_bw(
36+
params.channel_bw_mhz, params.scs_common, band_helper::get_freq_range(*params.band));
37+
static const uint8_t ss0_idx = 0;
38+
optional<band_helper::ssb_coreset0_freq_location> ssb_freq_loc = band_helper::get_ssb_coreset0_freq_location(
39+
params.dl_arfcn, *params.band, nof_crbs, params.scs_common, params.scs_common, ss0_idx);
40+
if (!ssb_freq_loc.has_value()) {
41+
report_error("Unable to derive a valid SSB pointA and k_SSB for cell id ({}).\n", params.pci);
42+
}
43+
params.offset_to_point_a = (*ssb_freq_loc).offset_to_point_A;
44+
params.k_ssb = (*ssb_freq_loc).k_ssb;
45+
params.coreset0_index = (*ssb_freq_loc).coreset0_idx;
46+
47+
sched_cell_configuration_request_message sched_cfg =
48+
test_helpers::make_default_sched_cell_configuration_request(params);
49+
// TDD params.
50+
sched_cfg.tdd_ul_dl_cfg_common = tdd_cfg;
51+
52+
return sched_cfg;
53+
}());
54+
55+
// Add UE
56+
auto ue_cfg = test_helpers::create_default_sched_ue_creation_request(params, {ue_drb_lcid});
57+
ue_cfg.ue_index = ue_idx;
58+
ue_cfg.crnti = ue_rnti;
59+
this->add_ue(ue_cfg);
60+
}
61+
62+
const du_ue_index_t ue_idx = to_du_ue_index(0);
63+
const rnti_t ue_rnti = to_rnti(0x4601);
64+
const lcid_t ue_drb_lcid = LCID_MIN_DRB;
65+
66+
cell_config_builder_params params;
67+
};
68+
69+
using test_params = tdd_ul_dl_config_common;
70+
71+
class scheduler_tdd_tester : public base_scheduler_tdd_tester, public ::testing::TestWithParam<test_params>
72+
{
73+
public:
74+
scheduler_tdd_tester() : base_scheduler_tdd_tester(GetParam()) {}
75+
};
76+
77+
TEST_P(scheduler_tdd_tester, all_dl_slots_are_scheduled)
78+
{
79+
// Enqueue enough bytes for continuous DL tx.
80+
dl_buffer_state_indication_message dl_buf_st{ue_idx, ue_drb_lcid, 10000000};
81+
this->push_dl_buffer_state(dl_buf_st);
82+
83+
const unsigned MAX_COUNT = 1000;
84+
for (unsigned count = 0; count != MAX_COUNT; ++count) {
85+
this->run_slot();
86+
ASSERT_TRUE(this->last_sched_res->success);
87+
88+
// For every DL slot.
89+
// Note: Skip special slots in test for now.
90+
if (cell_cfg_list[0].is_fully_dl_enabled(this->last_result_slot())) {
91+
// Ensure UE PDSCH allocations are made.
92+
ASSERT_FALSE(this->last_sched_res->dl.ue_grants.empty())
93+
<< "The UE configuration is leading to some DL slots staying empty";
94+
}
95+
96+
for (const pucch_info& pucch : this->last_sched_res->ul.pucchs) {
97+
if (pucch.format == pucch_format::FORMAT_1 and pucch.format_1.sr_bits != sr_nof_bits::no_sr) {
98+
// Skip SRs for this test.
99+
continue;
100+
}
101+
102+
uci_indication uci_ind = create_uci_indication(this->last_result_slot(), ue_idx, pucch);
103+
this->sched->handle_uci_indication(uci_ind);
104+
}
105+
}
106+
}
107+
108+
TEST_P(scheduler_tdd_tester, all_ul_slots_are_scheduled)
109+
{
110+
// Enqueue enough bytes for continuous UL tx.
111+
ul_bsr_indication_message bsr{
112+
to_du_cell_index(0), ue_idx, ue_rnti, bsr_format::SHORT_BSR, {ul_bsr_lcg_report{uint_to_lcg_id(0), 10000000}}};
113+
this->push_bsr(bsr);
114+
115+
// Run some slots to ensure PDCCH can be scheduled.
116+
for (unsigned i = 0; i != cell_cfg_list[0].tdd_cfg_common->pattern1.nof_ul_symbols; ++i) {
117+
run_slot();
118+
}
119+
120+
const unsigned MAX_COUNT = 1000;
121+
for (unsigned count = 0; count != MAX_COUNT; ++count) {
122+
this->run_slot();
123+
ASSERT_TRUE(this->last_sched_res->success);
124+
125+
// For every UL slot.
126+
// Note: Skip special slots in test for now.
127+
if (cell_cfg_list[0].is_fully_ul_enabled(this->last_result_slot())) {
128+
// Ensure UE PUSCH allocations are made.
129+
ASSERT_FALSE(this->last_sched_res->ul.puschs.empty())
130+
<< "The UE configuration is leading to some UL slots staying empty";
131+
}
132+
133+
for (const ul_sched_info& pusch : this->last_sched_res->ul.puschs) {
134+
ul_crc_indication crc{};
135+
crc.cell_index = to_du_cell_index(0);
136+
crc.sl_rx = this->last_result_slot();
137+
crc.crcs.resize(1);
138+
crc.crcs[0].ue_index = ue_idx;
139+
crc.crcs[0].rnti = ue_rnti;
140+
crc.crcs[0].harq_id = to_harq_id(pusch.pusch_cfg.harq_id);
141+
crc.crcs[0].tb_crc_success = true;
142+
this->sched->handle_crc_indication(crc);
143+
}
144+
}
145+
}
146+
147+
INSTANTIATE_TEST_SUITE_P(
148+
scheduler_tdd_test,
149+
scheduler_tdd_tester,
150+
testing::Values(
151+
// clang-format off
152+
// test_params{ref_scs, pattern1={slot_period, DL_slots, DL_symbols, UL_slots, UL_symbols}, pattern2={...}}
153+
test_params{subcarrier_spacing::kHz30, {10, 6, 4, 3, 4}, nullopt}));
154+
// Note: Not working because some PDSCHs fail due to insufficient PUCCH resources.
155+
//test_params{subcarrier_spacing::kHz30, {10, 7, 4, 2, 4}, nullopt},
156+
// Note: Not working because PRACH configuration needs to be adjusted.
157+
//test_params{subcarrier_spacing::kHz30, {6, 3, 4, 2, 4}, tdd_ul_dl_pattern{4, 4, 0, 0, 0}}));
158+
// clang-format on

tests/unittests/scheduler/test_utils/indication_generators.h

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
namespace srsran {
1616

17-
rach_indication_message::preamble create_preamble(unsigned preamble_id, rnti_t tc_rnti)
17+
inline rach_indication_message::preamble create_preamble(unsigned preamble_id, rnti_t tc_rnti)
1818
{
1919
rach_indication_message::preamble preamble{};
2020
preamble.preamble_id = preamble_id;
@@ -23,8 +23,8 @@ rach_indication_message::preamble create_preamble(unsigned preamble_id, rnti_t t
2323
return preamble;
2424
}
2525

26-
rach_indication_message create_rach_indication(slot_point next_slot_rx,
27-
std::initializer_list<rach_indication_message::preamble> preambles)
26+
inline rach_indication_message
27+
create_rach_indication(slot_point next_slot_rx, std::initializer_list<rach_indication_message::preamble> preambles)
2828
{
2929
rach_indication_message rach_ind{};
3030
rach_ind.cell_index = to_du_cell_index(0);
@@ -42,4 +42,35 @@ rach_indication_message create_rach_indication(slot_point
4242
return rach_ind;
4343
}
4444

45+
inline uci_indication create_uci_indication(slot_point uci_sl, du_ue_index_t ue_idx, const pucch_info& pucch_pdu)
46+
{
47+
uci_indication uci_ind{};
48+
uci_ind.cell_index = to_du_cell_index(0);
49+
uci_ind.slot_rx = uci_sl;
50+
uci_ind.ucis.resize(1);
51+
uci_ind.ucis[0].crnti = pucch_pdu.crnti;
52+
uci_ind.ucis[0].ue_index = ue_idx;
53+
switch (pucch_pdu.format) {
54+
case pucch_format::FORMAT_1: {
55+
uci_indication::uci_pdu::uci_pucch_f0_or_f1_pdu f1{};
56+
f1.harqs.resize(pucch_pdu.format_1.harq_ack_nof_bits);
57+
std::fill(f1.harqs.begin(), f1.harqs.end(), mac_harq_ack_report_status::ack);
58+
uci_ind.ucis[0].pdu = f1;
59+
} break;
60+
case pucch_format::FORMAT_2: {
61+
uci_indication::uci_pdu::uci_pucch_f2_or_f3_or_f4_pdu f2{};
62+
f2.harqs.resize(pucch_pdu.format_2.harq_ack_nof_bits);
63+
std::fill(f2.harqs.begin(), f2.harqs.end(), mac_harq_ack_report_status::ack);
64+
uci_ind.ucis[0].pdu = f2;
65+
if (pucch_pdu.format_2.csi_part1_bits > 0) {
66+
f2.csi.emplace();
67+
f2.csi->first_tb_wideband_cqi = 15;
68+
}
69+
} break;
70+
default:
71+
report_fatal_error("Unsupported PUCCH format");
72+
}
73+
return uci_ind;
74+
}
75+
4576
} // namespace srsran

tests/unittests/scheduler/test_utils/scheduler_test_bench.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class scheduler_test_bench
2727
explicit scheduler_test_bench(unsigned tx_rx_delay_ = 4, subcarrier_spacing max_scs = subcarrier_spacing::kHz15) :
2828
tx_rx_delay(tx_rx_delay_),
2929
logger([]() -> srslog::basic_logger& {
30+
srslog::init();
3031
auto& l = srslog::fetch_basic_logger("SCHED", true);
3132
l.set_level(srslog::basic_levels::debug);
3233
return l;

0 commit comments

Comments
 (0)