A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
three-gpp-http-client-server-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 Magister Solutions
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Budiarto Herman <budiarto.herman@magister.fi>
18 *
19 */
20
21#include <ns3/basic-data-calculators.h>
22#include <ns3/config.h>
23#include <ns3/error-model.h>
24#include <ns3/integer.h>
25#include <ns3/internet-stack-helper.h>
26#include <ns3/ipv4-address-helper.h>
27#include <ns3/ipv6-address-helper.h>
28#include <ns3/log.h>
29#include <ns3/mac48-address.h>
30#include <ns3/node.h>
31#include <ns3/nstime.h>
32#include <ns3/packet.h>
33#include <ns3/ptr.h>
34#include <ns3/simple-channel.h>
35#include <ns3/simple-net-device.h>
36#include <ns3/tcp-congestion-ops.h>
37#include <ns3/tcp-l4-protocol.h>
38#include <ns3/test.h>
39#include <ns3/three-gpp-http-client.h>
40#include <ns3/three-gpp-http-header.h>
41#include <ns3/three-gpp-http-helper.h>
42#include <ns3/three-gpp-http-server.h>
43
44#include <list>
45#include <sstream>
46
47NS_LOG_COMPONENT_DEFINE("ThreeGppHttpClientServerTest");
48
49using namespace ns3;
50
51// HTTP OBJECT TEST CASE //////////////////////////////////////////////////////
52
53/**
54 * \ingroup http
55 * \ingroup applications-test
56 * \ingroup tests
57 * A test class which verifies that each HTTP object sent is also received the
58 * same size.
59 *
60 * The test uses a minimalist scenario of one HTTP server and one HTTP client,
61 * connected through a SimpleChannel. The simulation runs until 3 web pages
62 * have been successfully downloaded by the client.
63 *
64 * The test also collects some statistical information from the simulation for
65 * informational or debugging purpose. This can be seen by enabling LOG_INFO.
66 */
68{
69 public:
70 /**
71 * \param name A textual label to briefly describe the test.
72 * \param rngRun Run index to be used, intended to affect the values produced
73 * by random number generators throughout the test.
74 * \param tcpType Type of TCP algorithm to be used by the connection between
75 * the client and the server. Must be a child type of
76 * ns3::TcpSocketFactory.
77 * \param channelDelay Transmission delay between the client and the server
78 * (and vice versa) which is due to the channel.
79 * \param bitErrorRate The probability of transmission error between the
80 * client and the server (and vice versa) in the unit of
81 * bits.
82 * \param mtuSize Maximum transmission unit (in bytes) to be used by the
83 * server model.
84 * \param useIpv6 If true, IPv6 will be used to address both client and
85 * server. Otherwise, IPv4 will be used.
86 */
87 ThreeGppHttpObjectTestCase(const std::string& name,
88 uint32_t rngRun,
89 const TypeId& tcpType,
90 const Time& channelDelay,
91 double bitErrorRate,
92 uint32_t mtuSize,
93 bool useIpv6);
94
95 private:
96 /**
97 * Creates a Node, complete with a TCP/IP stack and address assignment.
98 * #m_tcpType determines the TCP algorithm installed at the TCP stack.
99 * #m_useIpv6 determines whether to use IPv4 addressing or IPv6 addressing.
100 *
101 * \param[in] channel Pointer to a channel which the node's device will be
102 * attached to.
103 * \param[out] assignedAddress The resulting address of the node.
104 * \return Pointer to the newly created node.
105 */
107
108 // Inherited from TestCase base class.
109 void DoRun() override;
110 void DoTeardown() override;
111
112 /**
113 * \internal
114 * Internal class used by ThreeGppHttpObjectTestCase. Keep track of the number
115 * of object and bytes that have been sent and received in the simulation by
116 * listening to the relevant trace sources.
117 */
119 {
120 public:
121 /// Creates a new instance with all counters begin at zero.
123 /**
124 * Shall be invoked when a whole object has been transmitted.
125 * \param size Size of the whole object (in bytes).
126 */
127 void ObjectSent(uint32_t size);
128 /**
129 * Shall be invoked when an object part has been received.
130 * \param size Size of the object part (in bytes). This amount will be
131 * accumulated until ObjectReceived() is invoked.
132 */
133 void PartReceived(uint32_t size);
134 /**
135 * Shall be invoked after all parts of a complete object have been
136 * received.
137 * \param[out] txSize Size of the whole object (in bytes) when it was
138 * transmitted.
139 * \param[out] rxSize Size of the whole object (in bytes) received.
140 * \return True if this receive operation has a matching transmission
141 * operation (ObjectSent()), otherwise false. Both arguments are
142 * guaranteed to be replaced with initialized values if the return
143 * value is true.
144 */
145 bool ObjectReceived(uint32_t& txSize, uint32_t& rxSize);
146 /// \return True if zero object is currently tracked.
147 bool IsEmpty() const;
148 /// \return Number of whole objects that have been received so far.
149 uint16_t GetNumOfObjectsReceived() const;
150
151 private:
152 /**
153 * Each entry is the size (in bytes) of object transmitted. A new entry is
154 * pushed to the back when a new object is transmitted. The frontmost entry
155 * is then removed when a whole object is received, i.e., it's logically a
156 * first-in-first-out queue data structure.
157 */
158 std::list<uint32_t> m_objectsSize;
159 /// The accumulated size (in bytes) of parts of a whole object.
161 /// Number of whole objects that have been received so far.
163 };
164
165 // The following defines one tracker for each HTTP object type.
166 ThreeGppHttpObjectTracker m_requestObjectTracker; ///< Tracker of request objects.
167 ThreeGppHttpObjectTracker m_mainObjectTracker; ///< Tracker of main objects.
168 ThreeGppHttpObjectTracker m_embeddedObjectTracker; ///< Tracker of embedded objects.
169
170 // CALLBACK TO TRACE SOURCES.
171
172 /**
173 * Connected with `TxMainObjectRequest` trace source of the client.
174 * Updates #m_requestObjectTracker.
175 * \param packet The packet of main object sent.
176 */
178 /**
179 * Connected with `TxEmbeddedObjectRequest` trace source of the client.
180 * Updates #m_requestObjectTracker.
181 * \param packet The packet of embedded object sent.
182 */
184 /**
185 * Connected with `Rx` trace source of the server.
186 * Updates #m_requestObjectTracker and perform some tests on the packet and
187 * the size of the object.
188 * \param packet The packet received.
189 * \param from The address where the packet originates from.
190 */
191 void ServerRxCallback(Ptr<const Packet> packet, const Address& from);
192 /**
193 * Connected with `MainObject` trace source of the server.
194 * Updates #m_mainObjectTracker.
195 * \param size Size of the generated main object (in bytes).
196 */
198 /**
199 * Connected with `RxMainObjectPacket` trace source of the client.
200 * Updates #m_mainObjectTracker and perform some tests on the packet.
201 * \param packet The packet received.
202 */
204 /**
205 * Connected with `RxMainObject` trace source of the client. Updates
206 * #m_mainObjectTracker and perform some tests on the size of the object.
207 * \param httpClient Pointer to the application.
208 * \param packet Full packet received by application.
209 */
211 Ptr<const Packet> packet);
212 /**
213 * Connected with `EmbeddedObject` trace source of the server.
214 * Updates #m_embeddedObjectTracker.
215 * \param size Size of the generated embedded object (in bytes).
216 */
218 /**
219 * Connected with `RxEmbeddedObjectPacket` trace source of the client.
220 * Updates #m_embeddedObjectTracker and perform some tests on the packet.
221 * \param packet The packet received.
222 */
224 /**
225 * Connected with `RxEmbeddedObject` trace source of the client. Updates
226 * #m_embeddedObjectTracker and perform some tests on the size of the object.
227 * \param httpClient Pointer to the application.
228 * \param packet Full packet received by application.
229 */
231 Ptr<const Packet> packet);
232 /**
233 * Connected with `StateTransition` trace source of the client.
234 * Increments #m_numOfPagesReceived when the client enters READING state.
235 * \param oldState The name of the previous state.
236 * \param newState The name of the current state.
237 */
238 void ClientStateTransitionCallback(const std::string& oldState, const std::string& newState);
239 /**
240 * Connected with `RxDelay` trace source of the client.
241 * Updates the statistics in #m_delayCalculator.
242 * \param delay The packet one-trip delay time.
243 * \param from The address of the device where the packet originates from.
244 */
245 void ClientRxDelayCallback(const Time& delay, const Address& from);
246 /**
247 * Connected with `RxRtt` trace source of the client.
248 * Updates the statistics in #m_rttCalculator.
249 * \param rtt The packet round trip delay time.
250 * \param from The address of the device where the packet originates from.
251 */
252 void ClientRxRttCallback(const Time& rtt, const Address& from);
253 /**
254 * Connected with `PhyRxDrop` trace source of both the client's and server's
255 * devices. Increments #m_numOfPacketDrops.
256 * \param packet Pointer to the packet being dropped.
257 */
259 /**
260 * Dummy event
261 */
262 void ProgressCallback();
263
264 // THE PARAMETERS OF THE TEST CASE.
265
266 uint32_t m_rngRun; ///< Determines the set of random values generated.
267 TypeId m_tcpType; ///< TCP algorithm used.
268 Time m_channelDelay; ///< %Time needed by a packet to propagate.
269 uint32_t m_mtuSize; ///< Maximum transmission unit (in bytes).
270 bool m_useIpv6; ///< Whether to use IPv6 or IPv4.
271
272 // OTHER MEMBER VARIABLES.
273
274 /// Receive error model to be attached to the devices of both directions.
276 /// Begins with 0. Simulation stops if this reaches 3.
278 /// Number of packets dropped because of #m_errorModel.
280 /// Installs TCP/IP stack on the nodes.
282 /// Assigns IPv4 addresses to the nodes.
284 /// Assigns IPv6 addresses to the nodes.
286 /// Keeps statistical information of one-trip delays (in seconds).
288 /// Keeps statistical information of round-trip delays (in seconds).
290
291}; // end of `class HttpClientServerTestCase`
292
294 uint32_t rngRun,
295 const TypeId& tcpType,
296 const Time& channelDelay,
297 double bitErrorRate,
298 uint32_t mtuSize,
299 bool useIpv6)
300 : TestCase(name),
301 m_rngRun(rngRun),
302 m_tcpType(tcpType),
303 m_channelDelay(channelDelay),
304 m_mtuSize(mtuSize),
305 m_useIpv6(useIpv6),
306 m_numOfPagesReceived(0),
307 m_numOfPacketDrops(0)
308{
309 NS_LOG_FUNCTION(this << GetName());
310
311 // NS_ASSERT (tcpType.IsChildOf (TypeId::LookupByName ("ns3::TcpSocketBase")));
312 NS_ASSERT(channelDelay.IsPositive());
313
314 m_errorModel = CreateObject<RateErrorModel>();
315 m_errorModel->SetRate(bitErrorRate);
317
319 Ipv4Mask("255.0.0.0"),
320 Ipv4Address("0.0.0.1"));
322
323 m_delayCalculator = CreateObject<MinMaxAvgTotalCalculator<double>>();
324 m_rttCalculator = CreateObject<MinMaxAvgTotalCalculator<double>>();
325}
326
329 Address& assignedAddress)
330{
331 NS_LOG_FUNCTION(this << channel);
332
333 Ptr<SimpleNetDevice> dev = CreateObject<SimpleNetDevice>();
334 dev->SetAddress(Mac48Address::Allocate());
335 dev->SetChannel(channel);
336 dev->SetReceiveErrorModel(m_errorModel);
337
338 Ptr<Node> node = CreateObject<Node>();
339 node->AddDevice(dev);
341
342 // Assign IP address according to the selected Ip version.
343 if (m_useIpv6)
344 {
346 NS_ASSERT(ipv6Ifs.GetN() == 1);
347 assignedAddress = ipv6Ifs.GetAddress(0, 0);
348 }
349 else
350 {
352 NS_ASSERT(ipv4Ifs.GetN() == 1);
353 assignedAddress = ipv4Ifs.GetAddress(0, 0);
354 }
355
356 NS_LOG_DEBUG(this << " node is assigned to " << assignedAddress << ".");
357
358 // Set the TCP algorithm.
359 Ptr<TcpL4Protocol> tcp = node->GetObject<TcpL4Protocol>();
360 tcp->SetAttribute("SocketType", TypeIdValue(m_tcpType));
361
362 // Connect with the trace source that informs about packet drop due to error.
363 dev->TraceConnectWithoutContext(
364 "PhyRxDrop",
366
367 return node;
368}
369
370void
372{
373 NS_LOG_FUNCTION(this << GetName());
375 NS_LOG_INFO(this << " Running test case " << GetName());
376
377 /*
378 * Create topology:
379 *
380 * Server Node Client Node
381 * +-----------------+ +-----------------+
382 * | HTTP Server | | HTTP Client |
383 * | Application | | Application |
384 * +-----------------+ +-----------------+
385 * | TCP | | TCP |
386 * +-----------------+ +-----------------+
387 * | IPv4/v6 | | IPv4/v6 |
388 * +-----------------+ +-----------------+
389 * | Simple NetDev | | Simple NetDev |
390 * +-----------------+ +-----------------+
391 * | |
392 * | |
393 * +----------------------------+
394 * Simple Channel
395 */
396
397 // Channel.
398 Ptr<SimpleChannel> channel = CreateObject<SimpleChannel>();
399 channel->SetAttribute("Delay", TimeValue(m_channelDelay));
400
401 // Server node.
402 Address serverAddress;
403 Ptr<Node> serverNode = CreateSimpleInternetNode(channel, serverAddress);
404 ThreeGppHttpServerHelper serverHelper(serverAddress);
405 ApplicationContainer serverApplications = serverHelper.Install(serverNode);
406 NS_TEST_ASSERT_MSG_EQ(serverApplications.GetN(),
407 1,
408 "Invalid number of HTTP servers has been installed");
409 Ptr<ThreeGppHttpServer> httpServer = serverApplications.Get(0)->GetObject<ThreeGppHttpServer>();
410 NS_TEST_ASSERT_MSG_NE(httpServer,
411 nullptr,
412 "HTTP server installation fails to produce a proper type");
413 httpServer->SetMtuSize(m_mtuSize);
414
415 // Client node.
416 Address clientAddress;
417 Ptr<Node> clientNode = CreateSimpleInternetNode(channel, clientAddress);
418 ThreeGppHttpClientHelper clientHelper(serverAddress);
419 ApplicationContainer clientApplications = clientHelper.Install(clientNode);
420 NS_TEST_ASSERT_MSG_EQ(clientApplications.GetN(),
421 1,
422 "Invalid number of HTTP clients has been installed");
423 Ptr<ThreeGppHttpClient> httpClient = clientApplications.Get(0)->GetObject<ThreeGppHttpClient>();
424 NS_TEST_ASSERT_MSG_NE(httpClient,
425 nullptr,
426 "HTTP client installation fails to produce a proper type");
427
428 // Uplink (requests) trace sources.
429 bool traceSourceConnected = httpClient->TraceConnectWithoutContext(
430 "TxMainObjectRequest",
432 NS_ASSERT(traceSourceConnected);
433 traceSourceConnected = httpClient->TraceConnectWithoutContext(
434 "TxEmbeddedObjectRequest",
436 NS_ASSERT(traceSourceConnected);
437 traceSourceConnected = httpServer->TraceConnectWithoutContext(
438 "Rx",
440 NS_ASSERT(traceSourceConnected);
441
442 // Downlink (main objects) trace sources.
443 traceSourceConnected = httpServer->TraceConnectWithoutContext(
444 "MainObject",
446 NS_ASSERT(traceSourceConnected);
447 traceSourceConnected = httpClient->TraceConnectWithoutContext(
448 "RxMainObjectPacket",
450 NS_ASSERT(traceSourceConnected);
451 traceSourceConnected = httpClient->TraceConnectWithoutContext(
452 "RxMainObject",
454 NS_ASSERT(traceSourceConnected);
455
456 // Downlink (embedded objects) trace sources.
457 traceSourceConnected = httpServer->TraceConnectWithoutContext(
458 "EmbeddedObject",
460 NS_ASSERT(traceSourceConnected);
461
462 traceSourceConnected = httpClient->TraceConnectWithoutContext(
463 "RxEmbeddedObjectPacket",
465 NS_ASSERT(traceSourceConnected);
466
467 traceSourceConnected = httpClient->TraceConnectWithoutContext(
468 "RxEmbeddedObject",
470 NS_ASSERT(traceSourceConnected);
471
472 // Other trace sources.
473 traceSourceConnected = httpClient->TraceConnectWithoutContext(
474 "StateTransition",
476 NS_ASSERT(traceSourceConnected);
477 traceSourceConnected = httpClient->TraceConnectWithoutContext(
478 "RxDelay",
480 NS_ASSERT(traceSourceConnected);
481 traceSourceConnected = httpClient->TraceConnectWithoutContext(
482 "RxRtt",
484 NS_ASSERT(traceSourceConnected);
485
487
488 /*
489 * Here we don't set the simulation stop time. During the run, the simulation
490 * will stop immediately after the client has completely received the third
491 * web page.
492 */
494
495 // Dump some statistical information about the simulation.
496 NS_LOG_INFO(this << " Total request objects received: "
497 << m_requestObjectTracker.GetNumOfObjectsReceived() << " object(s).");
498 NS_LOG_INFO(this << " Total main objects received: "
499 << m_mainObjectTracker.GetNumOfObjectsReceived() << " object(s).");
500 NS_LOG_INFO(this << " Total embedded objects received: "
502 NS_LOG_INFO(this << " One-trip delays:"
503 << " average=" << m_delayCalculator->getMean() << " min="
504 << m_delayCalculator->getMin() << " max=" << m_delayCalculator->getMax());
505 NS_LOG_INFO(this << " Round-trip delays:"
506 << " average=" << m_rttCalculator->getMean() << " min="
507 << m_rttCalculator->getMin() << " max=" << m_rttCalculator->getMax());
508 NS_LOG_INFO(this << " Number of packets dropped by the devices: " << m_numOfPacketDrops
509 << " packet(s).");
510
511 // Some post-simulation tests.
512 NS_TEST_EXPECT_MSG_EQ(m_numOfPagesReceived, 3, "Unexpected number of web pages processed.");
514 true,
515 "Tracker of request objects detected irrelevant packet(s).");
517 true,
518 "Tracker of main objects detected irrelevant packet(s).");
520 true,
521 "Tracker of embedded objects detected irrelevant packet(s).");
522
524
525} // end of `void HttpClientServerTestCase::DoRun ()`
526
527void
529{
530 NS_LOG_FUNCTION(this << GetName());
531}
532
534 : m_rxBuffer(0),
535 m_numOfObjectsReceived(0)
536{
537 NS_LOG_FUNCTION(this);
538}
539
540void
542{
543 NS_LOG_FUNCTION(this << size);
544 m_objectsSize.push_back(size);
545}
546
547void
549{
550 NS_LOG_FUNCTION(this << size);
551 m_rxBuffer += size;
552}
553
554bool
556 uint32_t& rxSize)
557{
558 NS_LOG_FUNCTION(this);
559
560 if (m_objectsSize.empty())
561 {
562 return false;
563 }
564
565 // Set output values.
566 txSize = m_objectsSize.front();
567 rxSize = m_rxBuffer;
568
569 // Reset counters.
570 m_objectsSize.pop_front();
571 m_rxBuffer = 0;
572 m_numOfObjectsReceived++;
573
574 return true;
575}
576
577bool
579{
580 return (m_objectsSize.empty() && (m_rxBuffer == 0));
581}
582
583uint16_t
585{
586 return m_numOfObjectsReceived;
587}
588
589void
591{
592 NS_LOG_FUNCTION(this << packet << packet->GetSize());
593 m_requestObjectTracker.ObjectSent(packet->GetSize());
594}
595
596void
598{
599 NS_LOG_FUNCTION(this << packet << packet->GetSize());
600 m_requestObjectTracker.ObjectSent(packet->GetSize());
601}
602
603void
605{
606 NS_LOG_FUNCTION(this << packet << packet->GetSize() << from);
607
608 // Check the header in packet
609 Ptr<Packet> copy = packet->Copy();
610 ThreeGppHttpHeader httpHeader;
611 NS_TEST_ASSERT_MSG_EQ(copy->RemoveHeader(httpHeader),
612 22,
613 "Error finding ThreeGppHttpHeader in a packet received by the server");
615 Seconds(0.0),
616 "Request object's client TS is unexpectedly non-positive");
617
618 m_requestObjectTracker.PartReceived(packet->GetSize());
619
620 /*
621 * Request objects are assumed to be small and to not typically split. So we
622 * immediately follow by concluding the receive of a whole request object.
623 */
624 uint32_t txSize = 0;
625 uint32_t rxSize = 0;
626 bool isSent = m_requestObjectTracker.ObjectReceived(txSize, rxSize);
627 NS_TEST_ASSERT_MSG_EQ(isSent, true, "Server receives one too many request object");
629 rxSize,
630 "Transmitted size and received size of request object differ");
631}
632
633void
635{
636 NS_LOG_FUNCTION(this << size);
638}
639
640void
642{
643 NS_LOG_FUNCTION(this << packet << packet->GetSize());
644 m_mainObjectTracker.PartReceived(packet->GetSize());
645}
646
647void
649 Ptr<const Packet> packet)
650{
651 NS_LOG_FUNCTION(this << httpClient << httpClient->GetNode()->GetId());
652
653 // Verify the header in the packet.
654 Ptr<Packet> copy = packet->Copy();
655 ThreeGppHttpHeader httpHeader;
656 NS_TEST_ASSERT_MSG_EQ(copy->RemoveHeader(httpHeader),
657 22,
658 "Error finding ThreeGppHttpHeader in a packet received by the server");
661 "Invalid content type in the received packet");
663 Seconds(0.0),
664 "Main object's client TS is unexpectedly non-positive");
666 Seconds(0.0),
667 "Main object's server TS is unexpectedly non-positive");
668
669 uint32_t txSize = 0;
670 uint32_t rxSize = 0;
671 bool isSent = m_mainObjectTracker.ObjectReceived(txSize, rxSize);
672 NS_TEST_ASSERT_MSG_EQ(isSent, true, "Client receives one too many main object");
674 rxSize,
675 "Transmitted size and received size of main object differ");
677 rxSize,
678 "Actual main object packet size and received size of main object differ");
679}
680
681void
683{
684 NS_LOG_FUNCTION(this << size);
686}
687
688void
690{
691 NS_LOG_FUNCTION(this << packet << packet->GetSize());
692 m_embeddedObjectTracker.PartReceived(packet->GetSize());
693}
694
695void
697 Ptr<const Packet> packet)
698{
699 NS_LOG_FUNCTION(this << httpClient << httpClient->GetNode()->GetId());
700
701 // Verify the header in the packet.
702 Ptr<Packet> copy = packet->Copy();
703 ThreeGppHttpHeader httpHeader;
704 NS_TEST_ASSERT_MSG_EQ(copy->RemoveHeader(httpHeader),
705 22,
706 "Error finding ThreeGppHttpHeader in a packet received by the server");
709 "Invalid content type in the received packet");
711 Seconds(0.0),
712 "Embedded object's client TS is unexpectedly non-positive");
714 Seconds(0.0),
715 "Embedded object's server TS is unexpectedly non-positive");
716
717 uint32_t txSize = 0;
718 uint32_t rxSize = 0;
719 bool isSent = m_embeddedObjectTracker.ObjectReceived(txSize, rxSize);
720 NS_TEST_ASSERT_MSG_EQ(isSent, true, "Client receives one too many embedded object");
722 rxSize,
723 "Transmitted size and received size of embedded object differ");
725 httpHeader.GetContentLength(),
726 rxSize,
727 "Actual embedded object packet size and received size of embedded object differ");
728}
729
730void
732 const std::string& newState)
733{
734 NS_LOG_FUNCTION(this << oldState << newState);
735
736 if (newState == "READING")
737 {
739
740 if (m_numOfPagesReceived >= 3)
741 {
742 // We have processed 3 web pages and that should be enough for this test.
743 NS_LOG_LOGIC(this << " Test is stopping now.");
745 }
746 }
747}
748
749void
751{
752 NS_LOG_INFO("Simulator time now: " << Simulator::Now().As(Time::S) << ".");
754}
755
756void
758{
759 NS_LOG_FUNCTION(this << delay.As(Time::S) << from);
761}
762
763void
765{
766 NS_LOG_FUNCTION(this << rtt.As(Time::S) << from);
768}
769
770void
772{
773 NS_LOG_FUNCTION(this << packet << packet->GetSize());
775}
776
777// TEST SUITE /////////////////////////////////////////////////////////////////
778
779/**
780 * \ingroup http
781 * \ingroup applications-test
782 * \ingroup tests
783 * A test class for running several system tests which validate the web
784 * browsing traffic model.
785 *
786 * The tests cover the combinations of the following parameters:
787 * - the use of NewReno (ns-3's default)
788 * - various lengths of channel delay: 3 ms, 30 ms, and 300 ms;
789 * - the existence of transmission error;
790 * - different MTU (maximum transmission unit) sizes;
791 * - IPv4 and IPv6; and
792 * - the use of different set of random numbers.
793 *
794 * The _fullness_ parameter specified when running the test framework will
795 * determine the number of test cases created by this test suite.
796 */
798{
799 public:
800 /// Instantiate the test suite.
802 : TestSuite("applications-three-gpp-http-client-server", Type::SYSTEM)
803 {
804 // LogComponentEnable ("ThreeGppHttpClientServerTest", LOG_INFO);
805 // LogComponentEnable ("ThreeGppHttpClient", LOG_INFO);
806 // LogComponentEnable ("ThreeGppHttpServer", LOG_INFO);
807 // LogComponentEnableAll (LOG_PREFIX_ALL);
808
809 Time channelDelay[] = {MilliSeconds(3), MilliSeconds(30), MilliSeconds(300)};
810 double bitErrorRate[] = {0.0, 5.0e-6};
811 uint32_t mtuSize[] = {536, 1460};
812
813 uint32_t run = 1;
814 while (run <= 100)
815 {
816 for (uint32_t i1 = 0; i1 < 3; i1++)
817 {
818 for (uint32_t i2 = 0; i2 < 2; i2++)
819 {
820 for (uint32_t i3 = 0; i3 < 2; i3++)
821 {
822 AddHttpObjectTestCase(run++,
823 channelDelay[i1],
824 bitErrorRate[i2],
825 mtuSize[i3],
826 false);
827 AddHttpObjectTestCase(run++,
828 channelDelay[i1],
829 bitErrorRate[i2],
830 mtuSize[i3],
831 true);
832 }
833 }
834 }
835 }
836 }
837
838 private:
839 /**
840 * Creates a test case with the given parameters.
841 *
842 * \param rngRun Run index to be used, intended to affect the values produced
843 * by random number generators throughout the test.
844 * \param channelDelay Transmission delay between the client and the server
845 * (and vice versa) which is due to the channel.
846 * \param bitErrorRate The probability of transmission error between the
847 * client and the server (and vice versa) in the unit of
848 * bits.
849 * \param mtuSize Maximum transmission unit (in bytes) to be used by the
850 * server model.
851 * \param useIpv6 If true, IPv6 will be used to address both client and
852 * server. Otherwise, IPv4 will be used.
853 */
855 const Time& channelDelay,
856 double bitErrorRate,
857 uint32_t mtuSize,
858 bool useIpv6)
859 {
860 std::ostringstream name;
861 name << "Run #" << rngRun;
862 name << " delay=" << channelDelay.As(Time::MS);
863 name << " ber=" << bitErrorRate;
864 name << " mtu=" << mtuSize;
865
866 if (useIpv6)
867 {
868 name << " IPv6";
869 }
870 else
871 {
872 name << " IPv4";
873 }
874
875 // Assign higher fullness for tests with higher RngRun.
876 TestCase::Duration testDuration = TestCase::Duration::QUICK;
877 if (rngRun > 20)
878 {
879 testDuration = TestCase::Duration::EXTENSIVE;
880 }
881 if (rngRun > 50)
882 {
883 testDuration = TestCase::Duration::TAKES_FOREVER;
884 }
885
886 AddTestCase(new ThreeGppHttpObjectTestCase(name.str(),
887 rngRun,
889 channelDelay,
890 bitErrorRate,
891 mtuSize,
892 useIpv6),
893 testDuration);
894 }
895
896}; // end of class `ThreeGppHttpClientServerTestSuite`
897
898/// The global instance of the `three-gpp-http-client-server` system test.
A test class for running several system tests which validate the web browsing traffic model.
void AddHttpObjectTestCase(uint32_t rngRun, const Time &channelDelay, double bitErrorRate, uint32_t mtuSize, bool useIpv6)
Creates a test case with the given parameters.
ThreeGppHttpClientServerTestSuite()
Instantiate the test suite.
ThreeGppHttpObjectTracker()
Creates a new instance with all counters begin at zero.
void PartReceived(uint32_t size)
Shall be invoked when an object part has been received.
void ObjectSent(uint32_t size)
Shall be invoked when a whole object has been transmitted.
bool ObjectReceived(uint32_t &txSize, uint32_t &rxSize)
Shall be invoked after all parts of a complete object have been received.
uint32_t m_rxBuffer
The accumulated size (in bytes) of parts of a whole object.
uint16_t m_numOfObjectsReceived
Number of whole objects that have been received so far.
std::list< uint32_t > m_objectsSize
Each entry is the size (in bytes) of object transmitted.
A test class which verifies that each HTTP object sent is also received the same size.
ThreeGppHttpObjectTracker m_embeddedObjectTracker
Tracker of embedded objects.
void DeviceDropCallback(Ptr< const Packet > packet)
Connected with PhyRxDrop trace source of both the client's and server's devices.
InternetStackHelper m_internetStackHelper
Installs TCP/IP stack on the nodes.
void ClientRxDelayCallback(const Time &delay, const Address &from)
Connected with RxDelay trace source of the client.
ThreeGppHttpObjectTestCase(const std::string &name, uint32_t rngRun, const TypeId &tcpType, const Time &channelDelay, double bitErrorRate, uint32_t mtuSize, bool useIpv6)
void ClientTxEmbeddedObjectRequestCallback(Ptr< const Packet > packet)
Connected with TxEmbeddedObjectRequest trace source of the client.
void ClientTxMainObjectRequestCallback(Ptr< const Packet > packet)
Connected with TxMainObjectRequest trace source of the client.
void ClientRxEmbeddedObjectCallback(Ptr< const ThreeGppHttpClient > httpClient, Ptr< const Packet > packet)
Connected with RxEmbeddedObject trace source of the client.
uint16_t m_numOfPagesReceived
Begins with 0. Simulation stops if this reaches 3.
void DoRun() override
Implementation to actually run this TestCase.
Ipv4AddressHelper m_ipv4AddressHelper
Assigns IPv4 addresses to the nodes.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
uint32_t m_mtuSize
Maximum transmission unit (in bytes).
void ServerRxCallback(Ptr< const Packet > packet, const Address &from)
Connected with Rx trace source of the server.
void ClientRxMainObjectPacketCallback(Ptr< const Packet > packet)
Connected with RxMainObjectPacket trace source of the client.
void ClientRxMainObjectCallback(Ptr< const ThreeGppHttpClient > httpClient, Ptr< const Packet > packet)
Connected with RxMainObject trace source of the client.
void ClientRxEmbeddedObjectPacketCallback(Ptr< const Packet > packet)
Connected with RxEmbeddedObjectPacket trace source of the client.
Ptr< Node > CreateSimpleInternetNode(Ptr< SimpleChannel > channel, Address &assignedAddress)
Creates a Node, complete with a TCP/IP stack and address assignment.
Ptr< MinMaxAvgTotalCalculator< double > > m_rttCalculator
Keeps statistical information of round-trip delays (in seconds).
void ClientStateTransitionCallback(const std::string &oldState, const std::string &newState)
Connected with StateTransition trace source of the client.
ThreeGppHttpObjectTracker m_requestObjectTracker
Tracker of request objects.
Time m_channelDelay
Time needed by a packet to propagate.
uint32_t m_rngRun
Determines the set of random values generated.
void ServerEmbeddedObjectCallback(uint32_t size)
Connected with EmbeddedObject trace source of the server.
uint16_t m_numOfPacketDrops
Number of packets dropped because of m_errorModel.
Ipv6AddressHelper m_ipv6AddressHelper
Assigns IPv6 addresses to the nodes.
Ptr< MinMaxAvgTotalCalculator< double > > m_delayCalculator
Keeps statistical information of one-trip delays (in seconds).
void ClientRxRttCallback(const Time &rtt, const Address &from)
Connected with RxRtt trace source of the client.
bool m_useIpv6
Whether to use IPv6 or IPv4.
Ptr< RateErrorModel > m_errorModel
Receive error model to be attached to the devices of both directions.
void ServerMainObjectCallback(uint32_t size)
Connected with MainObject trace source of the server.
ThreeGppHttpObjectTracker m_mainObjectTracker
Tracker of main objects.
a polymophic address class
Definition: address.h:101
holds a vector of ns3::Application pointers.
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
uint32_t GetN() const
Get the number of Ptr<Application> stored in this container.
ApplicationContainer Install(NodeContainer c)
Install an application on each node of the input container configured with all the attributes set wit...
aggregate IP/TCP/UDP functionality to existing Nodes.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
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...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
Helper class to auto-assign global IPv6 unicast addresses.
void SetBase(Ipv6Address network, Ipv6Prefix prefix, Ipv6Address base=Ipv6Address("::1"))
Set the base network number, network prefix, and base interface ID.
Ipv6InterfaceContainer Assign(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses.
Describes an IPv6 address.
Definition: ipv6-address.h:49
Keep track of a set of IPv6 interfaces.
Ipv6Address GetAddress(uint32_t i, uint32_t j) const
Get the address for the specified index.
Describes an IPv6 prefix.
Definition: ipv6-address.h:455
static Mac48Address Allocate()
Allocate a new Mac48Address.
double getMax() const override
Returns the maximum value.
double getMean() const override
Returns the mean value.
double getMin() const override
Returns the minimum value.
void Update(const T i)
Updates all variables of MinMaxAvgTotalCalculator.
holds a vector of ns3::NetDevice pointers
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:522
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
void SetRate(double rate)
Definition: error-model.cc:215
void SetUnit(ErrorUnit error_unit)
Definition: error-model.cc:201
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
TCP socket creation and multiplexing/demultiplexing.
static TypeId GetTypeId()
Get the type ID.
encapsulates test code
Definition: test.h:1061
Duration
How long the test takes to execute.
Definition: test.h:1065
std::string GetName() const
Definition: test.cc:373
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
Helper to make it easier to instantiate an ThreeGppHttpClient on a set of nodes.
Model application which simulates the traffic of a web browser.
Header used by web browsing applications to transmit information about content type,...
@ EMBEDDED_OBJECT
Integer equivalent = 2.
@ MAIN_OBJECT
Integer equivalent = 1.
ContentType_t GetContentType() const
Helper to make it easier to instantiate an ThreeGppHttpServer on a set of nodes.
Model application which simulates the traffic of a web server.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
bool IsPositive() const
Exactly equivalent to t >= 0.
Definition: nstime.h:333
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
@ MS
millisecond
Definition: nstime.h:117
@ S
second
Definition: nstime.h:116
AttributeValue implementation for Time.
Definition: nstime.h:1406
a unique identifier for an interface.
Definition: type-id.h:59
AttributeValue implementation for TypeId.
Definition: type-id.h:598
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
void SetGlobal(std::string name, const AttributeValue &value)
Definition: config.cc:940
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#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:145
#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:252
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition: test.h:565
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report and abort if not.
Definition: test.h:875
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1331
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:706
static ThreeGppHttpClientServerTestSuite g_httpClientServerTestSuiteInstance
The global instance of the three-gpp-http-client-server system test.