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 "utilities.h"
15
16// An essential include is test.h
17#include "ns3/application.h"
18#include "ns3/simulator.h"
19#include "ns3/test.h"
20
21// Include headers of classes to test
22#include "ns3/class-a-end-device-lorawan-mac.h"
23
24using namespace ns3;
25using namespace lorawan;
26
27NS_LOG_COMPONENT_DEFINE("NetworkServerTestSuite");
28
29/**
30 * @ingroup lorawan
31 *
32 * It verifies that the NetworkServer application can receive packets sent in uplink by devices
33 */
35{
36 public:
37 UplinkPacketTest(); //!< Default constructor
38 ~UplinkPacketTest() override; //!< Destructor
39
40 /**
41 * Callback for tracing ReceivedPacket.
42 *
43 * @param packet The packet received.
44 */
46
47 /**
48 * Send a packet from the input end device.
49 *
50 * @param endDevice A pointer to the end device Node.
51 */
52 void SendPacket(Ptr<Node> endDevice);
53
54 private:
55 void DoRun() override;
56
57 bool m_receivedPacket = false; //!< Set to true if a packet is received by the server
58};
59
60// Add some help text to this case to describe what it is intended to test
62 : TestCase("Verify that the NetworkServer application can receive"
63 " packets sent in the uplink by devices")
64{
65}
66
67// Reminder that the test case should clean up after itself
71
72void
74{
75 NS_LOG_DEBUG("Received a packet at the network server");
76 m_receivedPacket = true;
77}
78
79void
81{
82 endDevice->GetDevice(0)->Send(Create<Packet>(20), Address(), 0);
83}
84
85// This method is the pure virtual method from class TestCase that every
86// TestCase must implement
87void
89{
90 NS_LOG_DEBUG("UplinkPacketTest");
91
92 // Create a bunch of actual devices
93 NetworkComponents components = InitializeNetwork(1, 1);
94
95 Ptr<LoraChannel> channel = components.channel;
96 NodeContainer endDevices = components.endDevices;
97 NodeContainer gateways = components.gateways;
98 Ptr<Node> nsNode = components.nsNode;
99
100 // Connect the trace source for received packets
101 nsNode->GetApplication(0)->TraceConnectWithoutContext(
102 "ReceivedPacket",
104
105 // Send a packet
107
111
112 // Check that we received the packet
114}
115
116/**
117 * @ingroup lorawan
118 *
119 * It verifies that devices requesting an acknowledgment receive a reply from the network server
120 */
122{
123 public:
124 DownlinkPacketTest(); //!< Default constructor
125 ~DownlinkPacketTest() override; //!< Destructor
126
127 /**
128 * Record the exit status of a MAC layer packet retransmission process of an end device.
129 *
130 * This trace sink is only used here to determine whether an ack was received by the end device
131 * after sending a package requiring an acknowledgement.
132 *
133 * @param requiredTransmissions Number of transmissions attempted during the process.
134 * @param success Whether the retransmission procedure was successful.
135 * @param time Timestamp of the initial transmission attempt.
136 * @param packet The packet being retransmitted.
137 */
138 void ReceivedPacketAtEndDevice(uint8_t requiredTransmissions,
139 bool success,
140 Time time,
141 Ptr<Packet> packet);
142
143 /**
144 * Send a packet from the input end device.
145 *
146 * @param endDevice A pointer to the end device Node.
147 * @param requestAck Whether to require an acknowledgement from the server.
148 */
149 void SendPacket(Ptr<Node> endDevice, bool requestAck);
150
151 private:
152 void DoRun() override;
153
154 bool m_receivedPacketAtEd = false; //!< Set to true if a packet is received by the end device
155};
156
157// Add some help text to this case to describe what it is intended to test
159 : TestCase("Verify that devices requesting an acknowledgment receive"
160 " a reply from the network server.")
161{
162}
163
164// Reminder that the test case should clean up after itself
168
169void
171 bool success,
172 Time time,
173 Ptr<Packet> packet)
174{
175 NS_LOG_DEBUG("Received a packet at the end device");
176 m_receivedPacketAtEd = success;
177}
178
179void
180DownlinkPacketTest::SendPacket(Ptr<Node> endDevice, bool requestAck)
181{
182 if (requestAck)
183 {
185 DynamicCast<LoraNetDevice>(endDevice->GetDevice(0))->GetMac())
187 }
188 endDevice->GetDevice(0)->Send(Create<Packet>(20), Address(), 0);
189}
190
191// This method is the pure virtual method from class TestCase that every
192// TestCase must implement
193void
195{
196 NS_LOG_DEBUG("DownlinkPacketTest");
197
198 // Create a bunch of actual devices
199 NetworkComponents components = InitializeNetwork(1, 1);
200
201 Ptr<LoraChannel> channel = components.channel;
202 NodeContainer endDevices = components.endDevices;
203 NodeContainer gateways = components.gateways;
204 Ptr<Node> nsNode = components.nsNode;
205
206 // Connect the end device's trace source for received packets
208 DynamicCast<LoraNetDevice>(endDevices.Get(0)->GetDevice(0))->GetMac())
210 "RequiredTransmissions",
212
213 // Send a packet in uplink
214 Simulator::Schedule(Seconds(1), &DownlinkPacketTest::SendPacket, this, endDevices.Get(0), true);
215
216 Simulator::Stop(Seconds(10)); // Allow for time to receive a downlink packet
219
221}
222
223/**
224 * @ingroup lorawan
225 *
226 * It verifies that the NetworkServer application correctly responds to LinkCheck requests
227 */
229{
230 public:
231 LinkCheckTest(); //!< Default constructor
232 ~LinkCheckTest() override; //!< Destructor
233
234 /**
235 * Trace changes in the last known gateway count variable (updated on reception of
236 * LinkCheckAns MAC commands) of an end device.
237 *
238 * @param newValue The updated value.
239 * @param oldValue The previous value.
240 */
241 void LastKnownGatewayCount(uint8_t newValue, uint8_t oldValue);
242
243 /**
244 * Send a packet containing a LinkCheckReq MAC command from the input end device.
245 *
246 * @param endDevice A pointer to the end device Node.
247 * @param requestAck Whether to require an acknowledgement from the server.
248 */
249 void SendPacket(Ptr<Node> endDevice, bool requestAck);
250
251 private:
252 void DoRun() override;
253 bool m_receivedPacketAtEd = false; //!< Set to true if a packet containing a LinkCheckAns MAC
254 //!< command is received by the end device
256 0; //!< Stores the number of gateways that received the last packet carrying a
257 //!< LinkCheckReq MAC command
258};
259
260// Add some help text to this case to describe what it is intended to test
262 : TestCase("Verify that the NetworkServer application correctly responds to "
263 "LinkCheck requests")
264{
265}
266
267// Reminder that the test case should clean up after itself
271
272void
273LinkCheckTest::LastKnownGatewayCount(uint8_t newValue, uint8_t oldValue)
274{
275 NS_LOG_DEBUG("Updated gateway count");
277
279}
280
281void
282LinkCheckTest::SendPacket(Ptr<Node> endDevice, bool requestAck)
283{
285 DynamicCast<LoraNetDevice>(endDevice->GetDevice(0))->GetMac());
286
287 if (requestAck)
288 {
289 macLayer->SetMType(LorawanMacHeader::CONFIRMED_DATA_UP);
290 }
291
292 macLayer->AddMacCommand(Create<LinkCheckReq>());
293
294 endDevice->GetDevice(0)->Send(Create<Packet>(20), Address(), 0);
295}
296
297// This method is the pure virtual method from class TestCase that every
298// TestCase must implement
299void
301{
302 NS_LOG_DEBUG("LinkCheckTest");
303
304 // Create a bunch of actual devices
305 NetworkComponents components = InitializeNetwork(1, 1);
306
307 Ptr<LoraChannel> channel = components.channel;
308 NodeContainer endDevices = components.endDevices;
309 NodeContainer gateways = components.gateways;
310 Ptr<Node> nsNode = components.nsNode;
311
312 // Connect the end device's trace source for last known gateway count
314 DynamicCast<LoraNetDevice>(endDevices.Get(0)->GetDevice(0))->GetMac())
315 ->TraceConnectWithoutContext("LastKnownGatewayCount",
317
318 // Send a packet in uplink
319 Simulator::Schedule(Seconds(1), &LinkCheckTest::SendPacket, this, endDevices.Get(0), true);
320
321 Simulator::Stop(Seconds(10)); // Allow for time to receive a downlink packet
324
326}
327
328/**
329 * @ingroup lorawan
330 *
331 * It verifies that the NetworkServer application responds to uplinks with the ADRACKReq bit set
332 */
334{
335 public:
336 AdrAckReqTest(); //!< Default constructor
337 ~AdrAckReqTest() override; //!< Destructor
338
339 private:
340 void DoRun() override;
341
342 /**
343 * Callback for packet reception by the end device MAC layer
344 *
345 * @param packet The received packet
346 */
347 void OnReception(Ptr<const Packet> packet);
348
349 bool m_adrAckReceived = false; //!< Set to true if a downlink packet is received by the end
350 //!< device after setting the uplink ADRACKReq bit
351};
352
354 : TestCase("Verify that the NetworkServer responds to uplinks with the ADRACKReq bit set")
355{
356}
357
361
362void
367
368void
370{
371 NS_LOG_DEBUG("AdrAckReqTest");
372 auto components = InitializeNetwork(1, 1);
373 auto ed = components.endDevices.Get(0);
374 auto netdev = DynamicCast<LoraNetDevice>(ed->GetDevice(0));
375 auto mac = DynamicCast<ClassAEndDeviceLorawanMac>(netdev->GetMac());
376 // Turn-off ADR downlinks from the server, ADRACKReq mechanism still works
377 mac->SetUplinkAdrBit(false);
379 mac->TraceConnectWithoutContext("ReceivedPacket", cb);
380 // Trigger ADRACKReq bit set
381 for (uint16_t fCnt = 0; fCnt <= EndDeviceLorawanMac::ADR_ACK_LIMIT; ++fCnt)
382 {
385 ed->GetDevice(0),
386 Create<Packet>(20),
387 Address(),
388 0);
390 }
391 NS_TEST_EXPECT_MSG_EQ(m_adrAckReceived, true, "No downlink received by the end device");
392}
393
394/**
395 * @ingroup lorawan
396 *
397 * The TestSuite class names the TestSuite, identifies what type of TestSuite, and enables the
398 * TestCases to be run. Typically, only the constructor for this class must be defined
399 */
401{
402 public:
403 NetworkServerTestSuite(); //!< Default constructor
404};
405
407 : TestSuite("network-server", Type::UNIT)
408{
409 // Activate only at need, as these can create problems among test suites when running ./test.py
410 // LogComponentEnable("NetworkServerTestSuite", LOG_LEVEL_DEBUG);
411 // LogComponentEnable("NetworkServer", LOG_LEVEL_ALL);
412 // LogComponentEnable("NetworkStatus", LOG_LEVEL_ALL);
413 // LogComponentEnable("NetworkScheduler", LOG_LEVEL_ALL);
414 // LogComponentEnable("NetworkController", LOG_LEVEL_ALL);
415 // LogComponentEnable("NetworkControllerComponent", LOG_LEVEL_ALL);
416 // LogComponentEnable("LoraNetDevice", LOG_LEVEL_ALL);
417 // LogComponentEnable("GatewayLorawanMac", LOG_LEVEL_ALL);
418 // LogComponentEnable("EndDeviceLorawanMac", LOG_LEVEL_ALL);
419 // LogComponentEnable("EndDeviceLoraPhy", LOG_LEVEL_ALL);
420 // LogComponentEnable("EndDeviceStatus", LOG_LEVEL_ALL);
421 // LogComponentEnableAll(LOG_PREFIX_FUNC);
422 // LogComponentEnableAll(LOG_PREFIX_NODE);
423 // LogComponentEnableAll(LOG_PREFIX_TIME);
424
429}
430
431// 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:114
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:70
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:580
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:125
static void Run()
Run the simulation.
Definition simulator.cc:161
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:169
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:296
@ QUICK
Fast test.
Definition test.h:1057
TestCase(const TestCase &)=delete
Caller graph was not generated because of its size.
Type
Type of test.
Definition test.h:1271
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:494
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
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
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:690
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:260
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:454
#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:1273
Time Minutes(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1256
static LorawanTestSuite lorawanTestSuite
NetworkComponents InitializeNetwork(int nDevices, int nGateways)
Definition utilities.cc:124
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:605
Stores the main elements of a simulated LoRaWAN network.
Definition utilities.h:28
Ptr< Node > nsNode
A pointer to the network server Node.
Definition utilities.h:32
Ptr< LoraChannel > channel
A pointer to the LoraChannel object.
Definition utilities.h:29
NodeContainer endDevices
Container of the end device nodes.
Definition utilities.h:30
NodeContainer gateways
Container of the gateway nodes.
Definition utilities.h:31