blob: 329244b913d1478a7fa44a49dd5a90786a195628 [file] [log] [blame]
Junxiao Shi80ee7cb2014-12-14 10:53:05 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Hila Ben Abraham39a79be2016-03-30 22:00:55 -07003 * Copyright (c) 2014-2016, Regents of the University of California,
Junxiao Shi80ee7cb2014-12-14 10:53:05 -07004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26/** \file
27 * \brief allows testing forwarding in a network topology
28 */
29
30#ifndef NFD_TESTS_NFD_FW_TOPOLOGY_TESTER_HPP
31#define NFD_TESTS_NFD_FW_TOPOLOGY_TESTER_HPP
32
Junxiao Shi5e5e4452015-09-24 16:56:52 -070033#include <ndn-cxx/face.hpp>
Junxiao Shi6535f1e2015-10-08 13:02:18 -070034#include "face/internal-transport.hpp"
Junxiao Shicde37ad2015-12-24 01:02:05 -070035#include "face/face.hpp"
Junxiao Shi80ee7cb2014-12-14 10:53:05 -070036#include "fw/strategy.hpp"
Junxiao Shia49a1ab2016-07-15 18:24:36 +000037#include "install-strategy.hpp"
Junxiao Shi80ee7cb2014-12-14 10:53:05 -070038#include "tests/test-common.hpp"
Junxiao Shi80ee7cb2014-12-14 10:53:05 -070039
40namespace nfd {
Spyridon Mastorakisd0381c02015-02-19 10:29:41 -080041namespace fw {
Junxiao Shi80ee7cb2014-12-14 10:53:05 -070042namespace tests {
43
Spyridon Mastorakisd0381c02015-02-19 10:29:41 -080044using namespace nfd::tests;
Junxiao Shi80ee7cb2014-12-14 10:53:05 -070045
46/** \brief identifies a node (forwarder) in the topology
47 */
48typedef size_t TopologyNode;
49
Junxiao Shi6535f1e2015-10-08 13:02:18 -070050/** \brief represents a network link in the topology which connects two or more nodes
Junxiao Shi80ee7cb2014-12-14 10:53:05 -070051 */
Junxiao Shi6535f1e2015-10-08 13:02:18 -070052class TopologyLink : noncopyable
Junxiao Shi80ee7cb2014-12-14 10:53:05 -070053{
54public:
Junxiao Shi6535f1e2015-10-08 13:02:18 -070055 explicit
56 TopologyLink(const time::nanoseconds& delay);
Junxiao Shi80ee7cb2014-12-14 10:53:05 -070057
58 /** \brief fail the link, cause packets to be dropped silently
59 */
60 void
61 fail()
62 {
63 m_isUp = false;
64 }
65
66 /** \brief recover the link from a failure
67 */
68 void
69 recover()
70 {
71 m_isUp = true;
72 }
73
Hila Ben Abraham39a79be2016-03-30 22:00:55 -070074 /** \brief change the link delay
75 * \param delay link delay, must be positive
76 */
77 void
78 setDelay(const time::nanoseconds& delay);
79
Junxiao Shicde37ad2015-12-24 01:02:05 -070080 /** \brief attach a face to the link
81 * \param i forwarder index
82 * \param face a Face with InternalForwarderTransport
83 */
Junxiao Shi5e5e4452015-09-24 16:56:52 -070084 void
Junxiao Shicde37ad2015-12-24 01:02:05 -070085 addFace(TopologyNode i, shared_ptr<Face> face);
Junxiao Shi5e5e4452015-09-24 16:56:52 -070086
Junxiao Shi80ee7cb2014-12-14 10:53:05 -070087 /** \return a face of forwarder \p i which is attached to this link
88 */
Junxiao Shi5e5e4452015-09-24 16:56:52 -070089 Face&
Junxiao Shi80ee7cb2014-12-14 10:53:05 -070090 getFace(TopologyNode i)
91 {
Junxiao Shi5e5e4452015-09-24 16:56:52 -070092 return *m_faces.at(i);
Junxiao Shi80ee7cb2014-12-14 10:53:05 -070093 }
94
Junxiao Shi6535f1e2015-10-08 13:02:18 -070095protected:
96 /** \brief attach a Transport onto this link
97 */
98 void
99 attachTransport(TopologyNode i, face::InternalTransportBase* transport);
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700100
101private:
Junxiao Shi6535f1e2015-10-08 13:02:18 -0700102 void
103 transmit(TopologyNode i, const Block& packet);
104
105 void
106 scheduleReceive(face::InternalTransportBase* recipient, const Block& packet);
107
108private:
109 bool m_isUp;
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700110 time::nanoseconds m_delay;
Junxiao Shi6535f1e2015-10-08 13:02:18 -0700111 std::unordered_map<TopologyNode, face::InternalTransportBase*> m_transports;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700112 std::unordered_map<TopologyNode, shared_ptr<Face>> m_faces;
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700113};
114
115/** \brief represents a link to a local application
116 */
Junxiao Shi6535f1e2015-10-08 13:02:18 -0700117class TopologyAppLink : noncopyable
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700118{
119public:
Junxiao Shicde37ad2015-12-24 01:02:05 -0700120 /** \brief constructor
121 * \param forwarderFace a Face with InternalForwarderTransport
122 */
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700123 explicit
Junxiao Shicde37ad2015-12-24 01:02:05 -0700124 TopologyAppLink(shared_ptr<Face> forwarderFace);
Junxiao Shi6535f1e2015-10-08 13:02:18 -0700125
126 /** \brief fail the link, cause packets to be dropped silently
127 */
128 void
129 fail();
130
131 /** \brief recover the link from a failure
132 */
133 void
134 recover();
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700135
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700136 /** \return face on forwarder side
137 */
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700138 Face&
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700139 getForwarderFace()
140 {
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700141 return *m_face;
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700142 }
143
144 /** \return face on application side
145 */
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700146 ndn::Face&
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700147 getClientFace()
148 {
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700149 return *m_client;
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700150 }
151
152private:
Junxiao Shi6535f1e2015-10-08 13:02:18 -0700153 shared_ptr<Face> m_face;
154 face::InternalForwarderTransport* m_forwarderTransport;
155 shared_ptr<face::InternalClientTransport> m_clientTransport;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700156 shared_ptr<ndn::Face> m_client;
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700157};
158
159/** \brief builds a topology for forwarding tests
160 */
161class TopologyTester : noncopyable
162{
163public:
164 /** \brief creates a forwarder
165 * \return index of new forwarder
166 */
167 TopologyNode
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700168 addForwarder(const std::string& label);
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700169
170 /** \return forwarder instance \p i
171 */
172 Forwarder&
173 getForwarder(TopologyNode i)
174 {
175 return *m_forwarders.at(i);
176 }
177
178 /** \brief sets strategy on forwarder \p i
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000179 * \tparam S the strategy type
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700180 * \note Test scenario can also access StrategyChoice table directly.
181 */
182 template<typename S>
183 void
184 setStrategy(TopologyNode i, Name prefix = Name("ndn:/"))
185 {
186 Forwarder& forwarder = this->getForwarder(i);
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000187 choose<S>(forwarder, prefix);
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700188 }
189
190 /** \brief makes a link that interconnects two or more forwarders
191 *
192 * A face is created on each of \p forwarders .
193 * When a packet is sent onto one of the faces on this link,
194 * this packet will be received by all other faces on this link after \p delay .
195 */
196 shared_ptr<TopologyLink>
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700197 addLink(const std::string& label, const time::nanoseconds& delay,
198 std::initializer_list<TopologyNode> forwarders,
199 bool forceMultiAccessFace = false);
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700200
201 /** \brief makes a link to local application
202 */
203 shared_ptr<TopologyAppLink>
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700204 addAppFace(const std::string& label, TopologyNode i);
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700205
206 /** \brief makes a link to local application, and register a prefix
207 */
208 shared_ptr<TopologyAppLink>
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700209 addAppFace(const std::string& label, TopologyNode i, const Name& prefix, uint64_t cost = 0);
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700210
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700211 /** \brief registers a prefix on a forwarder face
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700212 */
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700213 void
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700214 registerPrefix(TopologyNode i, const Face& face, const Name& prefix, uint64_t cost = 0);
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700215
216 /** \brief creates a producer application that answers every Interest with Data of same Name
217 */
218 void
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700219 addEchoProducer(ndn::Face& face, const Name& prefix = "/");
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700220
221 /** \brief creates a consumer application that sends \p n Interests under \p prefix
222 * at \p interval fixed rate.
223 */
224 void
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700225 addIntervalConsumer(ndn::Face& face, const Name& prefix,
226 const time::nanoseconds& interval, size_t n);
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700227
228private:
229 std::vector<unique_ptr<Forwarder>> m_forwarders;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700230 std::vector<std::string> m_forwarderLabels;
231 std::vector<shared_ptr<TopologyLink>> m_links;
232 std::vector<shared_ptr<TopologyAppLink>> m_appLinks;
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700233};
234
235} // namespace tests
Spyridon Mastorakisd0381c02015-02-19 10:29:41 -0800236} // namespace fw
Junxiao Shi80ee7cb2014-12-14 10:53:05 -0700237} // namespace nfd
238
239#endif // NFD_TESTS_NFD_FW_TOPOLOGY_TESTER_HPP