A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tgax-virtual-desktop-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 DERONNE SOFTWARE ENGINEERING
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
7 */
8
9#include "ns3/application-container.h"
10#include "ns3/application-helper.h"
11#include "ns3/config.h"
12#include "ns3/double.h"
13#include "ns3/internet-stack-helper.h"
14#include "ns3/ipv4-address-helper.h"
15#include "ns3/ipv4-address.h"
16#include "ns3/ipv4-interface-container.h"
17#include "ns3/ipv4-l3-protocol.h"
18#include "ns3/ipv4-list-routing-helper.h"
19#include "ns3/node-container.h"
20#include "ns3/node.h"
21#include "ns3/nstime.h"
22#include "ns3/packet-sink-helper.h"
23#include "ns3/packet-sink.h"
24#include "ns3/pointer.h"
25#include "ns3/rng-seed-manager.h"
26#include "ns3/simple-net-device-helper.h"
27#include "ns3/string.h"
28#include "ns3/test.h"
29#include "ns3/tgax-virtual-desktop.h"
30#include "ns3/traced-callback.h"
31
32#include <string>
33#include <vector>
34
35using namespace ns3;
36
37NS_LOG_COMPONENT_DEFINE("TgaxVirtualDesktopTest");
38
39/**
40 * @ingroup applications-test
41 * @ingroup tests
42 *
43 * TGax VDI traffic test.
44 *
45 * The test consider traffic values for the model presented in IEEE 802.11-14/0571r12 - 11ax
46 * Evaluation Methodology (Appendix 2 – Traffic model descriptions: Virtual Desktop Infrastructure
47 * Traffic Model) for both downlink and uplink.
48 *
49 * The test generates traffic between two nodes and keeps track of generated TX packets (size,
50 * and timestamp). The test verifies average sizes and inter arrivals of generated packets.
51 */
53{
54 public:
55 /// Information about VDI parameters
56 struct VdiParams
57 {
59 NanoSeconds(60226900)}; //!< mean of the distribution used to generate packet arrival
61 "41.0 3.2;1478.3 11.6"}; //!< parameters of the distribution used to generate the packet
62 //!< sizes
63 };
64
65 /**
66 * Constructor
67 * @param name the name of the test to run
68 * @param params the VDI parameters to use for the test
69 */
70 TgaxVirtualDesktopTestCase(const std::string& name, const VdiParams& params);
71
72 private:
73 void DoSetup() override;
74 void DoRun() override;
75
76 /**
77 * Record a transmitted VDI packet
78 * @param packet the transmitted packet
79 */
80 void PacketSent(Ptr<const Packet> packet);
81
82 /**
83 * Record a VDI packet successfully received
84 * @param context the context
85 * @param p the packet
86 * @param addr the sender's address
87 */
88 void ReceiveRx(std::string context, Ptr<const Packet> p, const Address& addr);
89
90 /// Information about a transmitted VDI packet
91 struct TxInfo
92 {
93 uint32_t size{}; //!< size of the packet in bytes
94 Time tstamp{}; //!< timestamp at which the packet is transmitted
95 };
96
97 std::vector<TxInfo> m_sent; //!< transmitted VDI packets
98 uint64_t m_received{0}; //!< number of bytes received
99
100 VdiParams m_params; //!< VDI parameters
101 Time m_startAppTime; //!< Time at which the application is started
102};
103
105 const VdiParams& params)
106 : TestCase{name},
107 m_params{params},
109{
110}
111
112void
114{
115 NS_LOG_FUNCTION(this << packet << packet->GetSize());
116 m_sent.push_back({packet->GetSize(), Simulator::Now()});
117}
118
119void
121{
122 NS_LOG_FUNCTION(this << p << addr << p->GetSize());
123 m_received += p->GetSize();
124}
125
126void
128{
129 NS_LOG_FUNCTION(this);
130
133
134 const auto simulationTime = Seconds(600);
135 uint16_t port = 90;
136
137 auto sender = CreateObject<Node>();
138 auto receiver = CreateObject<Node>();
139
141 nodes.Add(sender);
142 nodes.Add(receiver);
143
144 SimpleNetDeviceHelper simpleHelper;
145 auto devices = simpleHelper.Install(nodes);
146
147 InternetStackHelper internet;
148 internet.Install(nodes);
149
150 Ipv4AddressHelper ipv4Helper;
151 ipv4Helper.SetBase("10.11.12.0", "255.255.255.0");
152 auto interfaces = ipv4Helper.Assign(devices);
153
155 auto remoteAddress = InetSocketAddress(interfaces.GetAddress(1), port);
156 sourceHelper.SetAttribute("Remote", AddressValue(remoteAddress));
157 const auto protocol = "ns3::TcpSocketFactory";
158 sourceHelper.SetAttribute("Protocol", StringValue(protocol));
159
161 "Mean",
162 DoubleValue(m_params.meanPacketArrivalTime.GetNanoSeconds()));
163 sourceHelper.SetAttribute("CustomInterPacketArrivals", PointerValue(ipa));
164
165 sourceHelper.SetAttribute("CustomParametersPacketSize",
166 StringValue(m_params.parametersPacketSize));
167 auto sourceApp = sourceHelper.Install(sender);
168 sourceApp.Start(m_startAppTime);
169 sourceApp.Stop(m_startAppTime + simulationTime);
170
172 auto sinkApp = sinkHelper.Install(receiver);
173 sinkApp.Start(Seconds(0.0));
174 sinkApp.Stop(Seconds(2.0) + simulationTime);
175
176 int64_t streamNumber = 100;
177 sourceHelper.AssignStreams(nodes, streamNumber);
178
180 "/NodeList/*/$ns3::Node/ApplicationList/*/$ns3::TgaxVirtualDesktop/Tx",
182
183 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx",
185}
186
187void
189{
192
193 const auto totalTx =
194 std::accumulate(m_sent.cbegin(), m_sent.cend(), 0ULL, [](auto sum, const auto& tx) {
195 return sum + tx.size;
196 });
197 NS_TEST_ASSERT_MSG_EQ(totalTx, m_received, "Did not receive all transmitted VDI packets");
198
199 const auto delayConnectionEstablished = MilliSeconds(18);
201 delayConnectionEstablished,
202 MilliSeconds(20),
203 "Initial packet arrival larger than upper bound");
204
205 std::vector<Time> packetArrivals;
206 std::transform(m_sent.cbegin(),
207 m_sent.cend() - 1,
208 m_sent.cbegin() + 1,
209 std::back_inserter(packetArrivals),
210 [](const auto& lhs, const auto& rhs) { return (rhs.tstamp - lhs.tstamp); });
211 const auto totalPacketArrivals =
212 std::accumulate(packetArrivals.cbegin(),
213 packetArrivals.cend(),
214 Time(),
215 [](auto sum, const auto t) { return sum + t; });
216 const auto averagePacketArrivalNs =
217 static_cast<double>(totalPacketArrivals.GetNanoSeconds()) / packetArrivals.size();
218 const auto expectedAveragePacketArrivalNs = m_params.meanPacketArrivalTime.GetNanoSeconds();
219 NS_TEST_EXPECT_MSG_EQ_TOL(averagePacketArrivalNs,
220 expectedAveragePacketArrivalNs,
221 0.01 * expectedAveragePacketArrivalNs,
222 "Unexpected average packet arrival");
223
224 const auto averagePacketSize = static_cast<double>(totalTx) / m_sent.size();
225 const auto modalPos = m_params.parametersPacketSize.find(';');
226 double expectedAveragePacketSize{};
227 auto pos = m_params.parametersPacketSize.find(' ');
228 const auto mu1 = m_params.parametersPacketSize.substr(0, pos);
229 const auto mean1 = std::stod(mu1);
230 if (modalPos == std::string::npos)
231 {
232 // single mode
233 expectedAveragePacketSize = mean1;
234 }
235 else
236 {
237 // bimodal
238 auto mode2 = m_params.parametersPacketSize.substr(modalPos + 1,
239 m_params.parametersPacketSize.size() - 1);
240 pos = mode2.find(' ');
241 const auto mu2 = mode2.substr(0, pos);
242 const auto mean2 = std::stod(mu2);
243 const auto bernoulliProb = 22.4 / 76.1;
244 expectedAveragePacketSize = (mean1 * (1 - bernoulliProb)) + (mean2 * bernoulliProb);
245 }
246
247 NS_TEST_EXPECT_MSG_EQ_TOL(averagePacketSize,
248 expectedAveragePacketSize,
249 0.015 * expectedAveragePacketSize,
250 "Unexpected average packet size");
251}
252
253/**
254 * @ingroup applications-test
255 * @ingroup tests
256 *
257 * @brief TgaxVirtualDesktop TestSuite
258 */
260{
261 public:
263};
264
266 : TestSuite("applications-tgax-virtual-desktop", Type::UNIT)
267{
268 AddTestCase(new TgaxVirtualDesktopTestCase("DL VDI traffic (default)", {}),
271 new TgaxVirtualDesktopTestCase("UL VDI traffic", {MicroSeconds(48287), "50.598 5.0753"}),
273}
274
276 g_TgaxVirtualDesktopTestSuite; //!< Static variable for test initialization
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void PacketSent(Ptr< const Packet > packet)
Record a transmitted VDI packet.
uint64_t m_received
number of bytes received
Time m_startAppTime
Time at which the application is started.
std::vector< TxInfo > m_sent
transmitted VDI packets
void ReceiveRx(std::string context, Ptr< const Packet > p, const Address &addr)
Record a VDI packet successfully received.
TgaxVirtualDesktopTestCase(const std::string &name, const VdiParams &params)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
a polymophic address class
Definition address.h:114
AttributeValue implementation for Address.
Definition address.h:329
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
A helper to make it easier to instantiate an application on a set of nodes.
ApplicationContainer Install(NodeContainer c)
Install an application on each node of the input container configured with all the attributes set wit...
int64_t AssignStreams(NodeContainer c, int64_t stream)
Assigns a unique (monotonically increasing) stream number to all applications that match the configur...
void SetAttribute(const std::string &name, const AttributeValue &value)
Helper function used to set the underlying application attributes.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
static Ipv4Address GetAny()
keep track of a set of node pointers.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
AttributeValue implementation for Pointer.
Definition pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
build a set of SimpleNetDevice objects
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::SimpleChannel with the attributes configured by SimpleNetDeviceHelper::Se...
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:125
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:191
static void Run()
Run the simulation.
Definition simulator.cc:161
Hold variables of type string.
Definition string.h:45
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
static TypeId GetTypeId()
Get the type ID.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
uint16_t port
Definition dsdv-manet.cc:33
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
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:970
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition config.cc:946
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:627
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:133
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Definition test.h:499
#define NS_TEST_ASSERT_MSG_LT_OR_EQ(actual, limit, msg)
Test that an actual value is less than or equal to a limit and report and abort if not.
Definition test.h:739
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1307
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1324
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1273
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1290
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Information about a transmitted VDI packet.
Time tstamp
timestamp at which the packet is transmitted
Time meanPacketArrivalTime
mean of the distribution used to generate packet arrival
std::string parametersPacketSize
parameters of the distribution used to generate the packet sizes
static TgaxVirtualDesktopTestSuite g_TgaxVirtualDesktopTestSuite
Static variable for test initialization.