A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
network-server-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 University of Padova
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Davide Magrin <magrinda@dei.unipd.it>
7 */
8
9/*
10 * This file includes testing for the following components:
11 * - NetworkServer
12 */
13
14// Include headers of classes to test
15#include "utilities.h"
16
17#include "ns3/callback.h"
18#include "ns3/core-module.h"
19#include "ns3/log.h"
20#include "ns3/network-server-helper.h"
21#include "ns3/network-server.h"
22
23// An essential include is test.h
24#include "ns3/test.h"
25
26using namespace ns3;
27using namespace lorawan;
28
29NS_LOG_COMPONENT_DEFINE("NetworkServerTestSuite");
30
31/**
32 * @ingroup lorawan
33 *
34 * It verifies that the NetworkServer application can receive packets sent in uplink by devices
35 */
37{
38 public:
39 UplinkPacketTest(); //!< Default constructor
40 ~UplinkPacketTest() override; //!< Destructor
41
42 /**
43 * Callback for tracing ReceivedPacket.
44 *
45 * @param packet The packet received.
46 */
48
49 /**
50 * Send a packet from the input end device.
51 *
52 * @param endDevice A pointer to the end device Node.
53 */
54 void SendPacket(Ptr<Node> endDevice);
55
56 private:
57 void DoRun() override;
58
59 bool m_receivedPacket = false; //!< Set to true if a packet is received by the server
60};
61
62// Add some help text to this case to describe what it is intended to test
64 : TestCase("Verify that the NetworkServer application can receive"
65 " packets sent in the uplink by devices")
66{
67}
68
69// Reminder that the test case should clean up after itself
73
74void
76{
77 NS_LOG_DEBUG("Received a packet at the network server");
78 m_receivedPacket = true;
79}
80
81void
83{
84 endDevice->GetDevice(0)->Send(Create<Packet>(20), Address(), 0);
85}
86
87// This method is the pure virtual method from class TestCase that every
88// TestCase must implement
89void
91{
92 NS_LOG_DEBUG("UplinkPacketTest");
93
94 // Create a bunch of actual devices
95 NetworkComponents components = InitializeNetwork(1, 1);
96
97 Ptr<LoraChannel> channel = components.channel;
98 NodeContainer endDevices = components.endDevices;
99 NodeContainer gateways = components.gateways;
100 Ptr<Node> nsNode = components.nsNode;
101
102 // Connect the trace source for received packets
103 nsNode->GetApplication(0)->TraceConnectWithoutContext(
104 "ReceivedPacket",
106
107 // Send a packet
109
113
114 // Check that we received the packet
116}
117
118/**
119 * @ingroup lorawan
120 *
121 * It verifies that devices requesting an acknowledgment receive a reply from the network server
122 */
124{
125 public:
126 DownlinkPacketTest(); //!< Default constructor
127 ~DownlinkPacketTest() override; //!< Destructor
128
129 /**
130 * Record the exit status of a MAC layer packet retransmission process of an end device.
131 *
132 * This trace sink is only used here to determine whether an ack was received by the end device
133 * after sending a package requiring an acknowledgement.
134 *
135 * @param requiredTransmissions Number of transmissions attempted during the process.
136 * @param success Whether the retransmission procedure was successful.
137 * @param time Timestamp of the initial transmission attempt.
138 * @param packet The packet being retransmitted.
139 */
140 void ReceivedPacketAtEndDevice(uint8_t requiredTransmissions,
141 bool success,
142 Time time,
143 Ptr<Packet> packet);
144
145 /**
146 * Send a packet from the input end device.
147 *
148 * @param endDevice A pointer to the end device Node.
149 * @param requestAck Whether to require an acknowledgement from the server.
150 */
151 void SendPacket(Ptr<Node> endDevice, bool requestAck);
152
153 private:
154 void DoRun() override;
155
156 bool m_receivedPacketAtEd = false; //!< Set to true if a packet is received by the end device
157};
158
159// Add some help text to this case to describe what it is intended to test
161 : TestCase("Verify that devices requesting an acknowledgment receive"
162 " a reply from the network server.")
163{
164}
165
166// Reminder that the test case should clean up after itself
170
171void
173 bool success,
174 Time time,
175 Ptr<Packet> packet)
176{
177 NS_LOG_DEBUG("Received a packet at the end device");
178 m_receivedPacketAtEd = success;
179}
180
181void
182DownlinkPacketTest::SendPacket(Ptr<Node> endDevice, bool requestAck)
183{
184 if (requestAck)
185 {
187 DynamicCast<LoraNetDevice>(endDevice->GetDevice(0))->GetMac())
189 }
190 endDevice->GetDevice(0)->Send(Create<Packet>(20), Address(), 0);
191}
192
193// This method is the pure virtual method from class TestCase that every
194// TestCase must implement
195void
197{
198 NS_LOG_DEBUG("DownlinkPacketTest");
199
200 // Create a bunch of actual devices
201 NetworkComponents components = InitializeNetwork(1, 1);
202
203 Ptr<LoraChannel> channel = components.channel;
204 NodeContainer endDevices = components.endDevices;
205 NodeContainer gateways = components.gateways;
206 Ptr<Node> nsNode = components.nsNode;
207
208 // Connect the end device's trace source for received packets
210 DynamicCast<LoraNetDevice>(endDevices.Get(0)->GetDevice(0))->GetMac())
212 "RequiredTransmissions",
214
215 // Send a packet in uplink
216 Simulator::Schedule(Seconds(1), &DownlinkPacketTest::SendPacket, this, endDevices.Get(0), true);
217
218 Simulator::Stop(Seconds(10)); // Allow for time to receive a downlink packet
221
223}
224
225/**
226 * @ingroup lorawan
227 *
228 * It verifies that the NetworkServer application correctly responds to LinkCheck requests
229 */
231{
232 public:
233 LinkCheckTest(); //!< Default constructor
234 ~LinkCheckTest() override; //!< Destructor
235
236 /**
237 * Trace changes in the last known gateway count variable (updated on reception of
238 * LinkCheckAns MAC commands) of an end device.
239 *
240 * @param newValue The updated value.
241 * @param oldValue The previous value.
242 */
243 void LastKnownGatewayCount(uint8_t newValue, uint8_t oldValue);
244
245 /**
246 * Send a packet containing a LinkCheckReq MAC command from the input end device.
247 *
248 * @param endDevice A pointer to the end device Node.
249 * @param requestAck Whether to require an acknowledgement from the server.
250 */
251 void SendPacket(Ptr<Node> endDevice, bool requestAck);
252
253 private:
254 void DoRun() override;
255 bool m_receivedPacketAtEd = false; //!< Set to true if a packet containing a LinkCheckAns MAC
256 //!< command is received by the end device
258 0; //!< Stores the number of gateways that received the last packet carrying a
259 //!< LinkCheckReq MAC command
260};
261
262// Add some help text to this case to describe what it is intended to test
264 : TestCase("Verify that the NetworkServer application correctly responds to "
265 "LinkCheck requests")
266{
267}
268
269// Reminder that the test case should clean up after itself
273
274void
275LinkCheckTest::LastKnownGatewayCount(uint8_t newValue, uint8_t oldValue)
276{
277 NS_LOG_DEBUG("Updated gateway count");
279
281}
282
283void
284LinkCheckTest::SendPacket(Ptr<Node> endDevice, bool requestAck)
285{
287 DynamicCast<LoraNetDevice>(endDevice->GetDevice(0))->GetMac());
288
289 if (requestAck)
290 {
291 macLayer->SetMType(LorawanMacHeader::CONFIRMED_DATA_UP);
292 }
293
294 macLayer->AddMacCommand(Create<LinkCheckReq>());
295
296 endDevice->GetDevice(0)->Send(Create<Packet>(20), Address(), 0);
297}
298
299// This method is the pure virtual method from class TestCase that every
300// TestCase must implement
301void
303{
304 NS_LOG_DEBUG("LinkCheckTest");
305
306 // Create a bunch of actual devices
307 NetworkComponents components = InitializeNetwork(1, 1);
308
309 Ptr<LoraChannel> channel = components.channel;
310 NodeContainer endDevices = components.endDevices;
311 NodeContainer gateways = components.gateways;
312 Ptr<Node> nsNode = components.nsNode;
313
314 // Connect the end device's trace source for last known gateway count
316 DynamicCast<LoraNetDevice>(endDevices.Get(0)->GetDevice(0))->GetMac())
317 ->TraceConnectWithoutContext("LastKnownGatewayCount",
319
320 // Send a packet in uplink
321 Simulator::Schedule(Seconds(1), &LinkCheckTest::SendPacket, this, endDevices.Get(0), true);
322
323 Simulator::Stop(Seconds(10)); // Allow for time to receive a downlink packet
326
328}
329
330/**
331 * @ingroup lorawan
332 *
333 * It verifies that the NetworkServer application responds to uplinks with the ADRACKReq bit set
334 */
336{
337 public:
338 AdrAckReqTest(); //!< Default constructor
339 ~AdrAckReqTest() override; //!< Destructor
340
341 private:
342 void DoRun() override;
343
344 /**
345 * Callback for packet reception by the end device MAC layer
346 *
347 * @param packet The received packet
348 */
349 void OnReception(Ptr<const Packet> packet);
350
351 bool m_adrAckReceived = false; //!< Set to true if a downlink packet is received by the end
352 //!< device after setting the uplink ADRACKReq bit
353};
354
356 : TestCase("Verify that the NetworkServer responds to uplinks with the ADRACKReq bit set")
357{
358}
359
363
364void
369
370void
372{
373 NS_LOG_DEBUG("AdrAckReqTest");
374 auto components = InitializeNetwork(1, 1);
375 auto ed = components.endDevices.Get(0);
376 auto netdev = DynamicCast<LoraNetDevice>(ed->GetDevice(0));
377 auto mac = DynamicCast<ClassAEndDeviceLorawanMac>(netdev->GetMac());
378 // Turn-off ADR downlinks from the server, ADRACKReq mechanism still works
379 mac->SetUplinkAdrBit(false);
381 mac->TraceConnectWithoutContext("ReceivedPacket", cb);
382 // Trigger ADRACKReq bit set
383 for (uint16_t fCnt = 0; fCnt <= EndDeviceLorawanMac::ADR_ACK_LIMIT; ++fCnt)
384 {
387 ed->GetDevice(0),
388 Create<Packet>(20),
389 Address(),
390 0);
392 }
393 NS_TEST_EXPECT_MSG_EQ(m_adrAckReceived, true, "No downlink received by the end device");
394}
395
396/**
397 * @ingroup lorawan
398 *
399 * The TestSuite class names the TestSuite, identifies what type of TestSuite, and enables the
400 * TestCases to be run. Typically, only the constructor for this class must be defined
401 */
403{
404 public:
405 NetworkServerTestSuite(); //!< Default constructor
406};
407
409 : TestSuite("network-server", Type::UNIT)
410{
411 // Activate only at need, as these can create problems among test suites when running ./test.py
412 // LogComponentEnable("NetworkServerTestSuite", LOG_LEVEL_DEBUG);
413 // LogComponentEnable("NetworkServer", LOG_LEVEL_ALL);
414 // LogComponentEnable("NetworkStatus", LOG_LEVEL_ALL);
415 // LogComponentEnable("NetworkScheduler", LOG_LEVEL_ALL);
416 // LogComponentEnable("NetworkController", LOG_LEVEL_ALL);
417 // LogComponentEnable("NetworkControllerComponent", LOG_LEVEL_ALL);
418 // LogComponentEnable("LoraNetDevice", LOG_LEVEL_ALL);
419 // LogComponentEnable("GatewayLorawanMac", LOG_LEVEL_ALL);
420 // LogComponentEnable("EndDeviceLorawanMac", LOG_LEVEL_ALL);
421 // LogComponentEnable("EndDeviceLoraPhy", LOG_LEVEL_ALL);
422 // LogComponentEnable("EndDeviceStatus", LOG_LEVEL_ALL);
423 // LogComponentEnableAll(LOG_PREFIX_FUNC);
424 // LogComponentEnableAll(LOG_PREFIX_NODE);
425 // LogComponentEnableAll(LOG_PREFIX_TIME);
426
431}
432
433// Do not forget to allocate an instance of this TestSuite
It verifies that the NetworkServer application responds to uplinks with the ADRACKReq bit set.
bool m_adrAckReceived
Set to true if a downlink packet is received by the end device after setting the uplink ADRACKReq bit...
void OnReception(Ptr< const Packet > packet)
Callback for packet reception by the end device MAC layer.
void DoRun() override
Implementation to actually run this TestCase.
AdrAckReqTest()
Default constructor.
~AdrAckReqTest() override
Destructor.
The TestSuite class names the TestSuite, identifies what type of TestSuite, and enables the TestCases...
NetworkServerTestSuite()
Default constructor.
a polymophic address class
Definition address.h:90
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)=0
keep track of a set of node pointers.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition node.cc:138
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:67
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:293
@ QUICK
Fast test.
Definition test.h:1054
TestCase(const TestCase &)=delete
Type
Type of test.
Definition test.h:1257
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:491
Simulation virtual time values and global simulation resolution.
Definition nstime.h:96
static constexpr uint16_t ADR_ACK_LIMIT
ADRACKCnt threshold for setting ADRACKReq.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:439
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition test.h:240
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
Time Minutes(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1357
static LorawanTestSuite lorawanTestSuite
NetworkComponents InitializeNetwork(int nDevices, int nGateways)
Definition utilities.cc:117
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:585
Stores the main elements of a simulated LoRaWAN network.
Definition utilities.h:29
Ptr< Node > nsNode
A pointer to the network server Node.
Definition utilities.h:33
Ptr< LoraChannel > channel
A pointer to the LoraChannel object.
Definition utilities.h:30
NodeContainer endDevices
Container of the end device nodes.
Definition utilities.h:31
NodeContainer gateways
Container of the gateway nodes.
Definition utilities.h:32