51 public: |
55 public: |
52 Ns3TcpLossTestCase1 (); |
56 Ns3TcpLossTestCase1 (); |
53 virtual ~Ns3TcpLossTestCase1 () {} |
57 virtual ~Ns3TcpLossTestCase1 () {} |
54 |
58 |
55 private: |
59 private: |
|
60 virtual void DoSetup (void); |
56 virtual bool DoRun (void); |
61 virtual bool DoRun (void); |
|
62 virtual void DoTeardown (void); |
|
63 |
|
64 std::string m_pcapFilename; |
|
65 PcapFile m_pcapFile; |
|
66 bool m_writeVectors; |
57 bool m_writeResults; |
67 bool m_writeResults; |
58 |
68 |
59 void SinkRx (std::string path, Ptr<const Packet> p, const Address &address); |
69 void Ipv4L3Tx (std::string context, Ptr<const Packet> packet, Ptr<Ipv4> ipv4, uint32_t interface); |
60 |
70 |
61 TestVectors<uint32_t> m_inputs; |
|
62 TestVectors<uint32_t> m_responses; |
|
63 }; |
71 }; |
64 |
72 |
65 Ns3TcpLossTestCase1::Ns3TcpLossTestCase1 () |
73 Ns3TcpLossTestCase1::Ns3TcpLossTestCase1 () |
66 : TestCase ("Check that ns-3 TCP survives loss of first two SYNs"), |
74 : TestCase ("Check that ns-3 TCP survives loss of first two SYNs"), |
|
75 m_writeVectors (WRITE_VECTORS), |
67 m_writeResults (false) |
76 m_writeResults (false) |
68 { |
77 { |
69 } |
78 } |
70 |
79 |
71 void |
80 void |
72 Ns3TcpLossTestCase1::SinkRx (std::string path, Ptr<const Packet> p, const Address &address) |
81 Ns3TcpLossTestCase1::DoSetup (void) |
73 { |
82 { |
74 m_responses.Add (p->GetSize ()); |
83 // |
|
84 // We expect there to be a file called ns3tcp-loss1-response-vectors.pcap" in |
|
85 // the source directory of this file. |
|
86 // |
|
87 m_pcapFilename = NS_TEST_SOURCEDIR + "ns3tcp-loss1-response-vectors.pcap"; |
|
88 |
|
89 if (m_writeVectors) |
|
90 { |
|
91 m_pcapFile.Open (m_pcapFilename, std::ios::out|std::ios::binary); |
|
92 m_pcapFile.Init(PCAP_LINK_TYPE, PCAP_SNAPLEN); |
|
93 } |
|
94 else |
|
95 { |
|
96 m_pcapFile.Open (m_pcapFilename, std::ios::in|std::ios::binary); |
|
97 NS_ABORT_MSG_UNLESS (m_pcapFile.GetDataLinkType () == PCAP_LINK_TYPE, "Wrong response vectors in directory"); |
|
98 } |
|
99 } |
|
100 |
|
101 void |
|
102 Ns3TcpLossTestCase1::DoTeardown (void) |
|
103 { |
|
104 m_pcapFile.Close (); |
|
105 } |
|
106 |
|
107 void |
|
108 Ns3TcpLossTestCase1::Ipv4L3Tx (std::string context, Ptr<const Packet> packet, Ptr<Ipv4> ipv4, uint32_t interface) |
|
109 { |
|
110 // |
|
111 // We're not testing IP so remove and toss the header. In order to do this, |
|
112 // though, we need to copy the packet since we have a const version. |
|
113 // |
|
114 Ptr<Packet> p = packet->Copy (); |
|
115 Ipv4Header ipHeader; |
|
116 p->RemoveHeader (ipHeader); |
|
117 |
|
118 // |
|
119 // What is left is the TCP header and any data that may be sent. We aren't |
|
120 // sending any TCP data, so we expect what remains is only TCP header, which |
|
121 // is a small thing to save. |
|
122 // |
|
123 if (m_writeVectors) |
|
124 { |
|
125 // |
|
126 // Save the TCP under test response for later testing. |
|
127 // |
|
128 Time tNow = Simulator::Now (); |
|
129 int64_t tMicroSeconds = tNow.GetMicroSeconds (); |
|
130 m_pcapFile.Write (uint32_t (tMicroSeconds / 1000000), |
|
131 uint32_t (tMicroSeconds % 1000000), |
|
132 p->PeekData(), |
|
133 p->GetSize ()); |
|
134 } |
|
135 else |
|
136 { |
|
137 // |
|
138 // Read the TCP under test expected response from the expected vector |
|
139 // file and see if it still does the right thing. |
|
140 // |
|
141 uint8_t expected[PCAP_SNAPLEN]; |
|
142 uint32_t tsSec, tsUsec, inclLen, origLen, readLen; |
|
143 m_pcapFile.Read (expected, sizeof(expected), tsSec, tsUsec, inclLen, origLen, readLen); |
|
144 |
|
145 uint8_t const *actual = p->PeekData(); |
|
146 |
|
147 uint32_t result = memcmp(actual, expected, readLen); |
|
148 |
|
149 // |
|
150 // Avoid streams of errors -- only report the first. |
|
151 // |
|
152 if (GetErrorStatus () == false) |
|
153 { |
|
154 NS_TEST_EXPECT_MSG_EQ (result, 0, "Expected data comparison error"); |
|
155 } |
|
156 } |
75 } |
157 } |
76 |
158 |
77 bool |
159 bool |
78 Ns3TcpLossTestCase1::DoRun (void) |
160 Ns3TcpLossTestCase1::DoRun (void) |
79 { |
161 { |
114 ApplicationContainer apps = sink.Install (n1); |
196 ApplicationContainer apps = sink.Install (n1); |
115 // Start the sink application at time zero, and stop it at sinkStopTime |
197 // Start the sink application at time zero, and stop it at sinkStopTime |
116 apps.Start (Seconds (0.0)); |
198 apps.Start (Seconds (0.0)); |
117 apps.Stop (sinkStopTimeObj); |
199 apps.Stop (sinkStopTimeObj); |
118 |
200 |
119 Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx", |
201 Config::Connect ("/NodeList/0/$ns3::Ipv4L3Protocol/Tx", |
120 MakeCallback (&Ns3TcpLossTestCase1::SinkRx, this)); |
202 MakeCallback (&Ns3TcpLossTestCase1::Ipv4L3Tx, this)); |
121 |
203 |
122 Simulator::Schedule(Seconds (2), &SocketWriter::Connect, socketWriter); |
204 Simulator::Schedule(Seconds (2), &SocketWriter::Connect, socketWriter); |
123 Simulator::Schedule(Seconds (10), &SocketWriter::Write, socketWriter, 500); |
205 Simulator::Schedule(Seconds (10), &SocketWriter::Write, socketWriter, 500); |
124 m_inputs.Add (500); |
|
125 Simulator::Schedule(writerStopTimeObj, &SocketWriter::Close, socketWriter); |
206 Simulator::Schedule(writerStopTimeObj, &SocketWriter::Close, socketWriter); |
126 |
207 |
127 std::list<uint32_t> sampleList; |
208 std::list<uint32_t> sampleList; |
128 // Lose first two SYNs |
209 // Lose first two SYNs |
129 sampleList.push_back (0); |
210 sampleList.push_back (0); |
141 |
222 |
142 Simulator::Stop (simStopTimeObj); |
223 Simulator::Stop (simStopTimeObj); |
143 Simulator::Run (); |
224 Simulator::Run (); |
144 Simulator::Destroy (); |
225 Simulator::Destroy (); |
145 |
226 |
146 // Compare inputs and outputs |
|
147 NS_TEST_ASSERT_MSG_EQ (m_inputs.GetN (), m_responses.GetN (), "Incorrect number of expected receive events"); |
|
148 for (uint32_t i = 0; i < m_responses.GetN (); i++) |
|
149 { |
|
150 uint32_t in = m_inputs.Get (i); |
|
151 uint32_t out = m_responses.Get (i); |
|
152 NS_TEST_ASSERT_MSG_EQ (in, out, "Mismatch: expected " << in << " bytes, got " << out << " bytes"); |
|
153 } |
|
154 |
|
155 return GetErrorStatus (); |
227 return GetErrorStatus (); |
156 } |
228 } |
157 |
229 |
158 class Ns3TcpLossTestCase2 : public TestCase |
230 class Ns3TcpLossTestCase2 : public TestCase |
159 { |
231 { |
160 public: |
232 public: |
161 Ns3TcpLossTestCase2 (); |
233 Ns3TcpLossTestCase2 (); |
162 virtual ~Ns3TcpLossTestCase2 () {} |
234 virtual ~Ns3TcpLossTestCase2 () {} |
163 |
235 |
164 private: |
236 private: |
|
237 virtual void DoSetup (void); |
165 virtual bool DoRun (void); |
238 virtual bool DoRun (void); |
|
239 virtual void DoTeardown (void); |
|
240 |
|
241 std::string m_pcapFilename; |
|
242 PcapFile m_pcapFile; |
|
243 bool m_writeVectors; |
166 bool m_writeResults; |
244 bool m_writeResults; |
167 |
245 |
168 void SinkRx (std::string path, Ptr<const Packet> p, const Address &address); |
246 void Ipv4L3Tx (std::string context, Ptr<const Packet> packet, Ptr<Ipv4> ipv4, uint32_t interface); |
169 |
|
170 TestVectors<uint32_t> m_inputs; |
|
171 TestVectors<uint32_t> m_responses; |
|
172 }; |
247 }; |
173 |
248 |
174 Ns3TcpLossTestCase2::Ns3TcpLossTestCase2 () |
249 Ns3TcpLossTestCase2::Ns3TcpLossTestCase2 () |
175 : TestCase ("Check that ns-3 TCP survives loss of first data packet"), |
250 : TestCase ("Check that ns-3 TCP survives loss of first data packet"), |
|
251 m_writeVectors (WRITE_VECTORS), |
176 m_writeResults (false) |
252 m_writeResults (false) |
177 { |
253 { |
178 } |
254 } |
179 |
255 |
180 void |
256 void |
181 Ns3TcpLossTestCase2::SinkRx (std::string path, Ptr<const Packet> p, const Address &address) |
257 Ns3TcpLossTestCase2::DoSetup (void) |
182 { |
258 { |
183 m_responses.Add (p->GetSize ()); |
259 // |
|
260 // We expect there to be a file called ns3tcp-loss1-response-vectors.pcap" in |
|
261 // the source directory of this file. |
|
262 // |
|
263 m_pcapFilename = NS_TEST_SOURCEDIR + "ns3tcp-loss2-response-vectors.pcap"; |
|
264 |
|
265 if (m_writeVectors) |
|
266 { |
|
267 m_pcapFile.Open (m_pcapFilename, std::ios::out|std::ios::binary); |
|
268 m_pcapFile.Init(PCAP_LINK_TYPE, PCAP_SNAPLEN); |
|
269 } |
|
270 else |
|
271 { |
|
272 m_pcapFile.Open (m_pcapFilename, std::ios::in|std::ios::binary); |
|
273 NS_ABORT_MSG_UNLESS (m_pcapFile.GetDataLinkType () == PCAP_LINK_TYPE, "Wrong response vectors in directory"); |
|
274 } |
|
275 } |
|
276 |
|
277 void |
|
278 Ns3TcpLossTestCase2::DoTeardown (void) |
|
279 { |
|
280 m_pcapFile.Close (); |
|
281 } |
|
282 |
|
283 void |
|
284 Ns3TcpLossTestCase2::Ipv4L3Tx (std::string context, Ptr<const Packet> packet, Ptr<Ipv4> ipv4, uint32_t interface) |
|
285 { |
|
286 // |
|
287 // We're not testing IP so remove and toss the header. In order to do this, |
|
288 // though, we need to copy the packet since we have a const version. |
|
289 // |
|
290 Ptr<Packet> p = packet->Copy (); |
|
291 Ipv4Header ipHeader; |
|
292 p->RemoveHeader (ipHeader); |
|
293 |
|
294 // |
|
295 // What is left is the TCP header and any data that may be sent. We aren't |
|
296 // sending any TCP data, so we expect what remains is only TCP header, which |
|
297 // is a small thing to save. |
|
298 // |
|
299 if (m_writeVectors) |
|
300 { |
|
301 // |
|
302 // Save the TCP under test response for later testing. |
|
303 // |
|
304 Time tNow = Simulator::Now (); |
|
305 int64_t tMicroSeconds = tNow.GetMicroSeconds (); |
|
306 m_pcapFile.Write (uint32_t (tMicroSeconds / 1000000), |
|
307 uint32_t (tMicroSeconds % 1000000), |
|
308 p->PeekData(), |
|
309 p->GetSize ()); |
|
310 } |
|
311 else |
|
312 { |
|
313 // |
|
314 // Read the TCP under test expected response from the expected vector |
|
315 // file and see if it still does the right thing. |
|
316 // |
|
317 uint8_t expected[PCAP_SNAPLEN]; |
|
318 uint32_t tsSec, tsUsec, inclLen, origLen, readLen; |
|
319 m_pcapFile.Read (expected, sizeof(expected), tsSec, tsUsec, inclLen, origLen, readLen); |
|
320 |
|
321 uint8_t const *actual = p->PeekData(); |
|
322 |
|
323 uint32_t result = memcmp(actual, expected, readLen); |
|
324 |
|
325 // |
|
326 // Avoid streams of errors -- only report the first. |
|
327 // |
|
328 if (GetErrorStatus () == false) |
|
329 { |
|
330 NS_TEST_EXPECT_MSG_EQ (result, 0, "Expected data comparison error"); |
|
331 } |
|
332 } |
184 } |
333 } |
185 |
334 |
186 bool |
335 bool |
187 Ns3TcpLossTestCase2::DoRun (void) |
336 Ns3TcpLossTestCase2::DoRun (void) |
188 { |
337 { |
223 ApplicationContainer apps = sink.Install (n1); |
372 ApplicationContainer apps = sink.Install (n1); |
224 // Start the sink application at time zero, and stop it at sinkStopTime |
373 // Start the sink application at time zero, and stop it at sinkStopTime |
225 apps.Start (Seconds (0.0)); |
374 apps.Start (Seconds (0.0)); |
226 apps.Stop (sinkStopTimeObj); |
375 apps.Stop (sinkStopTimeObj); |
227 |
376 |
228 Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx", |
377 Config::Connect ("/NodeList/0/$ns3::Ipv4L3Protocol/Tx", |
229 MakeCallback (&Ns3TcpLossTestCase2::SinkRx, this)); |
378 MakeCallback (&Ns3TcpLossTestCase2::Ipv4L3Tx, this)); |
230 |
379 |
231 Simulator::Schedule(Seconds (2), &SocketWriter::Connect, socketWriter); |
380 Simulator::Schedule(Seconds (2), &SocketWriter::Connect, socketWriter); |
232 Simulator::Schedule(Seconds (10), &SocketWriter::Write, socketWriter, 500); |
381 Simulator::Schedule(Seconds (10), &SocketWriter::Write, socketWriter, 500); |
233 m_inputs.Add (500); |
|
234 Simulator::Schedule(writerStopTimeObj, &SocketWriter::Close, socketWriter); |
382 Simulator::Schedule(writerStopTimeObj, &SocketWriter::Close, socketWriter); |
235 |
383 |
236 std::list<uint32_t> sampleList; |
384 std::list<uint32_t> sampleList; |
237 // Lose first data segment |
385 // Lose first data segment |
238 sampleList.push_back (2); |
386 sampleList.push_back (2); |