diff --git a/src/wifi/model/wifi-mac-queue.cc b/src/wifi/model/wifi-mac-queue.cc index 946988bab..8f67650c0 100644 --- a/src/wifi/model/wifi-mac-queue.cc +++ b/src/wifi/model/wifi-mac-queue.cc @@ -154,7 +154,16 @@ WifiMacQueue::Insert (ConstIterator pos, Ptr item) if (m_dropPolicy == DROP_OLDEST) { NS_LOG_DEBUG ("Remove the oldest item in the queue"); - DoRemove (begin ()); + if (pos == begin ()) + { + // Avoid invalidating pos + DoRemove (begin ()); + pos = begin (); + } + else + { + DoRemove (begin ()); + } } return DoEnqueue (pos, item); diff --git a/src/wifi/test/wifi-mac-queue.cc b/src/wifi/test/wifi-mac-queue.cc new file mode 100644 index 000000000..c006e897b --- /dev/null +++ b/src/wifi/test/wifi-mac-queue.cc @@ -0,0 +1,121 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2021 IITP RAS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Alexander Krotov + */ + +#include "ns3/test.h" +#include "ns3/wifi-mac-queue.h" + +using namespace ns3; + +/** + * \ingroup wifi-test + * \ingroup tests + * + * \brief Test DROP_OLDEST setting. + * + * This test verifies the correctness of DROP_OLDEST policy when packets + * are pushed into the front of the queue. This case is not handled + * by the underlying ns3::Queue. + */ +class WifiMacQueueDropOldestTest : public TestCase +{ +public: + /** + * \brief Constructor + */ + WifiMacQueueDropOldestTest (); + + void DoRun () override; +}; + +WifiMacQueueDropOldestTest::WifiMacQueueDropOldestTest() + : TestCase ("Test DROP_OLDEST setting") +{ +} + +void +WifiMacQueueDropOldestTest::DoRun () +{ + auto wifiMacQueue = CreateObject (); + wifiMacQueue->SetMaxSize (QueueSize ("5p")); + wifiMacQueue->SetAttribute ("DropPolicy", EnumValue (WifiMacQueue::DROP_OLDEST)); + + // Initialize the queue with 5 packets. + std::vector packetUids; + for (uint32_t i = 0; i < 5; i++) + { + WifiMacHeader header; + auto packet = Create (); + auto item = Create (packet, header); + wifiMacQueue->PushFront (item); + + packetUids.push_back (packet->GetUid ()); + } + + // Check that all elements are inserted successfully. + auto it = wifiMacQueue->begin (); + NS_TEST_EXPECT_MSG_EQ (wifiMacQueue->GetNPackets (), 5, "Queue has unexpected number of elements"); + for (uint32_t i = 5; i > 0; i--) + { + NS_TEST_EXPECT_MSG_EQ ((*it)->GetPacket ()->GetUid (), + packetUids.at (i - 1), + "Stored packet is not the expected one"); + it++; + } + + // Push another element in front of the queue. + WifiMacHeader header; + auto packet = Create (); + auto item = Create (packet, header); + wifiMacQueue->PushFront (item); + + // Update the vector of expected packet UIDs. + packetUids.at (4) = packet->GetUid (); + + // Check that front packet was replaced correctly. + it = wifiMacQueue->begin (); + NS_TEST_EXPECT_MSG_EQ (wifiMacQueue->GetNPackets (), 5, "Queue has unexpected number of elements"); + for (uint32_t i = 5; i > 0; i--) + { + NS_TEST_EXPECT_MSG_EQ ((*it)->GetPacket ()->GetUid (), + packetUids.at (i - 1), + "Stored packet is not the expected one"); + it++; + } +} + +/** + * \ingroup wifi-test + * \ingroup tests + * + * \brief Wifi MAC Queue Test Suite + */ +class WifiMacQueueTestSuite : public TestSuite +{ + public: + WifiMacQueueTestSuite (); +}; + +WifiMacQueueTestSuite::WifiMacQueueTestSuite () + : TestSuite ("wifi-mac-queue", UNIT) +{ + AddTestCase (new WifiMacQueueDropOldestTest, TestCase::QUICK); +} + +static WifiMacQueueTestSuite g_wifiMacQueueTestSuite; ///< the test suite diff --git a/src/wifi/wscript b/src/wifi/wscript index 069b5d95f..8fb7d375d 100644 --- a/src/wifi/wscript +++ b/src/wifi/wscript @@ -124,7 +124,8 @@ def build(bld): 'test/wifi-phy-thresholds-test.cc', 'test/wifi-phy-reception-test.cc', 'test/inter-bss-test-suite.cc', - 'test/wifi-phy-ofdma-test.cc' + 'test/wifi-phy-ofdma-test.cc', + 'test/wifi-mac-queue.cc', ] # Tests encapsulating example programs should be listed here