blob: 4d563c7a4e3865e558213f52b074daf465d7825a [file] [log] [blame]
Alexander Afanasyeve6dc0ac2013-02-21 14:00:48 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2011,2012 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 */
20
21#include "ndnSIM-fib-entry.h"
22#include "ns3/core-module.h"
23#include "ns3/ndnSIM-module.h"
24#include "ns3/point-to-point-module.h"
25#include "ns3/node-list.h"
26
27#include <boost/lexical_cast.hpp>
28#include <boost/foreach.hpp>
29#include <boost/shared_ptr.hpp>
30#include <boost/make_shared.hpp>
31
32#include "ns3/ndn-fib-entry.h"
33
34NS_LOG_COMPONENT_DEFINE ("ndn.FibEntryTest");
35
36namespace ns3
37{
38
39class Client : public ndn::App
40{
41protected:
42 void
43 StartApplication ()
44 {
45 ndn::App::StartApplication ();
46
47 // add default route
Alexander Afanasyevcfdc14f2013-03-15 14:38:44 -070048 Ptr<ndn::fib::Entry> fibEntry = GetNode ()->GetObject<ndn::Fib> ()->Add (ndn::Name ("/"), m_face, 0);
Alexander Afanasyeve6dc0ac2013-02-21 14:00:48 -080049 fibEntry->UpdateStatus (m_face, ndn::fib::FaceMetric::NDN_FIB_GREEN);
50
51 Simulator::Schedule (Seconds (0.5), &Client::SendPacket, this, std::string("/1"), 1);
52 Simulator::Schedule (Seconds (4.0), &Client::SendPacket, this, std::string("/2"), 1);
53 }
54
55 void
56 StopApplication ()
57 {
58 ndn::App::StopApplication ();
59 }
60
61private:
62 void
63 SendPacket (const std::string &prefix, uint32_t nonce)
64 {
65 Ptr<Packet> pkt = Create<Packet> (0);
66 ndn::InterestHeader i;
Alexander Afanasyevcfdc14f2013-03-15 14:38:44 -070067 i.SetName (Create<ndn::Name> (prefix));
Alexander Afanasyeve6dc0ac2013-02-21 14:00:48 -080068 i.SetNonce (nonce);
69 i.SetInterestLifetime (Seconds (0.5));
70
71 pkt->AddHeader (i);
72 m_protocolHandler (pkt);
73 }
74};
75
76struct StatusRecorder
77{
78 StatusRecorder (Ptr<Node> node, Ptr<ndn::fib::Entry> fibEntry, Ptr<ndn::Face> face)
79 : m_node (node)
80 , m_fibEntry (fibEntry)
81 , m_face (face)
82 {
83 count = 0;
84 }
85
86 void
87 StatusChange (ndn::fib::FaceMetric::Status oldStatus, ndn::fib::FaceMetric::Status newStatus)
88 {
89 count ++;
90 // std::cout << Simulator::Now ().ToDouble (Time::S) << "s\tnode " << m_node->GetId () << " has changed fibEntry " << m_fibEntry->GetPrefix () << " face " << *m_face << " to " << newStatus << " from " << oldStatus << std::endl;
91 }
92
93 int count;
94
95private:
96 Ptr<Node> m_node;
97 Ptr<ndn::fib::Entry> m_fibEntry;
98 Ptr<ndn::Face> m_face;
99};
100
101void
102FibEntryTest::DoRun ()
103{
104 Ptr<Node> node = CreateObject<Node> ();
105 Ptr<Node> nodeSink = CreateObject<Node> ();
106 PointToPointHelper p2p;
107 p2p.Install (node, nodeSink);
108
109 ndn::StackHelper ndn;
110 ndn.SetForwardingStrategy ("ns3::ndn::fw::BestRoute");
111 ndn.Install (node);
112 ndn.Install (nodeSink);
113
114 ndn::StackHelper::AddRoute (node, "/", 0, 0);
115
116 Ptr<Client> app1 = CreateObject<Client> ();
117 node->AddApplication (app1);
118
119 ndn::AppHelper sinkHelper ("ns3::ndn::Producer");
120 sinkHelper.SetPrefix ("/");
121 sinkHelper.Install (nodeSink)
122 .Stop (Seconds (2.0));
123
124 std::list< boost::shared_ptr<StatusRecorder> > recorders;
125
126 for (NodeList::Iterator anode = NodeList::Begin ();
127 anode != NodeList::End ();
128 anode ++)
129 {
130 Ptr<ndn::Fib> fib = (*anode)->GetObject<ndn::Fib> ();
131
132 for (Ptr<ndn::fib::Entry> entry = fib->Begin ();
133 entry != fib->End ();
134 entry = fib->Next (entry))
135 {
136 BOOST_FOREACH (const ndn::fib::FaceMetric & faceMetric, entry->m_faces)
137 {
138 boost::shared_ptr<StatusRecorder> recorder = boost::make_shared<StatusRecorder> (*anode, entry, faceMetric.GetFace ());
139 recorders.push_back (recorder);
140
141 const_cast<ndn::fib::FaceMetric &> (faceMetric).GetStatusTrace ().ConnectWithoutContext (MakeCallback (&StatusRecorder::StatusChange, recorder.get ()));
142 }
143 }
144 }
145
146 Simulator::Stop (Seconds (10.0));
147 Simulator::Run ();
148 Simulator::Destroy ();
149
150 NS_TEST_ASSERT_MSG_EQ (recorders.size (), 1, "only one recorder should be: only one real FIB record should have existed");
151 NS_TEST_ASSERT_MSG_EQ (recorders.front ()->count, 2, "two events should have been reported");
152}
153
154}