3 # NEPI, a framework to manage network experiments
4 # Copyright (C) 2013 INRIA
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License version 2 as
8 # published by the Free Software Foundation;
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
21 from nepi.execution.ec import ExperimentController
22 from nepi.execution.runner import ExperimentRunner
23 from nepi.util.netgraph import TopologyType
24 import nepi.data.processing.ccn.parser as ccn_parser
30 from scipy import stats
31 from matplotlib import pyplot
35 def avg_interest_rtt(ec, run):
38 # Parse downloaded CCND logs
41 interest_expiry_count,
42 interest_dupnonce_count,
44 content_count) = ccn_parser.process_content_history_logs(
45 logs_dir, ec.netgraph.topology)
48 rtts = [content_names[content_name]["rtt"] \
49 for content_name in content_names]
51 # sample mean and standard deviation
52 sample = numpy.array(rtts)
53 n, min_max, mean, var, skew, kurt = stats.describe(sample)
55 ci = stats.t.interval(0.95, n-1, loc = mean,
56 scale = std/math.sqrt(n))
59 metrics.append((mean, ci[0], ci[1]))
63 def normal_law(ec, run, sample):
64 x = numpy.array(sample)
67 se = std / math.sqrt(n)
71 return m * 0.05 >= se95
73 def post_process(ec, runs):
76 # plot convergence graph
77 y = numpy.array([float(m[0]) for m in metrics])
78 low = numpy.array([float(m[1]) for m in metrics])
79 high = numpy.array([float(m[2]) for m in metrics])
80 error = [y - low, high - y]
83 # plot average RTT and confidence interval for each iteration
84 pyplot.errorbar(x, y, yerr = error, fmt='o')
85 pyplot.plot(x, y, 'r-')
86 pyplot.xlim([0.5, runs + 0.5])
87 pyplot.xticks(numpy.arange(1, len(y)+1, 1))
88 pyplot.xlabel('Iteration')
89 pyplot.ylabel('Average RTT')
91 pyplot.savefig("plot.png")
94 content_name = "ccnx:/test/bunny.ts"
98 repofile = os.path.join(
99 os.path.dirname(os.path.realpath(__file__)),
102 def get_simulator(ec):
103 simulator = ec.filter_resources("linux::ns3::Simulation")
106 node = ec.register_resource("linux::Node")
107 ec.set(node, "hostname", "localhost")
109 simu = ec.register_resource("linux::ns3::Simulation")
110 ec.register_connection(simu, node)
115 def add_collector(ec, trace_name, subdir, newname = None):
116 collector = ec.register_resource("Collector")
117 ec.set(collector, "traceName", trace_name)
118 ec.set(collector, "subDir", subdir)
120 ec.set(collector, "rename", newname)
124 def add_dce_host(ec, nid):
125 simu = get_simulator(ec)
127 host = ec.register_resource("ns3::Node")
128 ec.set(host, "enableStack", True)
129 ec.register_connection(host, simu)
132 ec.netgraph.annotate_node(nid, "host", host)
134 def add_dce_ccnd(ec, nid):
135 # Retrieve annotation from netgraph
136 host = ec.netgraph.node_annotation(nid, "host")
138 # Add dce ccnd to the dce node
139 ccnd = ec.register_resource("linux::ns3::dce::CCND")
140 ec.set (ccnd, "stackSize", 1<<20)
141 ec.set (ccnd, "debug", 7)
142 ec.set (ccnd, "capacity", 50000)
143 ec.set (ccnd, "StartTime", "1s")
144 ec.set (ccnd, "StopTime", STOP_TIME)
145 ec.register_connection(ccnd, host)
147 # Collector to retrieve ccnd log
148 collector = add_collector(ec, "stderr", str(nid), "log")
149 ec.register_connection(collector, ccnd)
152 ec.netgraph.annotate_node(nid, "ccnd", ccnd)
154 def add_dce_ccnr(ec, nid):
155 # Retrieve annotation from netgraph
156 host = ec.netgraph.node_annotation(nid, "host")
158 # Add a CCN content repository to the dce node
159 ccnr = ec.register_resource("linux::ns3::dce::CCNR")
160 ec.set (ccnr, "repoFile1", repofile)
161 ec.set (ccnr, "stackSize", 1<<20)
162 ec.set (ccnr, "StartTime", "2s")
163 ec.set (ccnr, "StopTime", STOP_TIME)
164 ec.register_connection(ccnr, host)
166 def add_dce_ccncat(ec, nid):
167 # Retrieve annotation from netgraph
168 host = ec.netgraph.node_annotation(nid, "host")
170 # Add a ccncat application to the dce host
171 ccncat = ec.register_resource("linux::ns3::dce::CCNCat")
172 ec.set (ccncat, "contentName", content_name)
173 ec.set (ccncat, "stackSize", 1<<20)
174 ec.set (ccncat, "StartTime", "8s")
175 ec.set (ccncat, "StopTime", STOP_TIME)
176 ec.register_connection(ccncat, host)
178 def add_dce_fib_entry(ec, nid1, nid2):
179 # Retrieve annotations from netgraph
180 host1 = ec.netgraph.node_annotation(nid1, "host")
181 net = ec.netgraph.edge_net_annotation(nid1, nid2)
184 # Add FIB entry between peer hosts
185 ccndc = ec.register_resource("linux::ns3::dce::FIBEntry")
186 ec.set (ccndc, "protocol", "udp")
187 ec.set (ccndc, "uri", "ccnx:/")
188 ec.set (ccndc, "host", ip2)
189 ec.set (ccndc, "stackSize", 1<<20)
190 ec.set (ccndc, "StartTime", "2s")
191 ec.set (ccndc, "StopTime", STOP_TIME)
192 ec.register_connection(ccndc, host1)
194 def add_dce_net_iface(ec, nid1, nid2):
195 # Retrieve annotations from netgraph
196 host = ec.netgraph.node_annotation(nid1, "host")
197 net = ec.netgraph.edge_net_annotation(nid1, nid2)
199 prefix = net["prefix"]
201 dev = ec.register_resource("ns3::PointToPointNetDevice")
202 ec.set(dev,"DataRate", "5Mbps")
203 ec.set(dev, "ip", ip1)
204 ec.set(dev, "prefix", prefix)
205 ec.register_connection(host, dev)
207 queue = ec.register_resource("ns3::DropTailQueue")
208 ec.register_connection(dev, queue)
212 def add_edge(ec, nid1, nid2):
213 ### Add network interfaces to hosts
214 p2p1 = add_dce_net_iface(ec, nid1, nid2)
215 p2p2 = add_dce_net_iface(ec, nid2, nid1)
217 # Create point to point link between interfaces
218 chan = ec.register_resource("ns3::PointToPointChannel")
219 ec.set(chan, "Delay", "0ms")
221 ec.register_connection(chan, p2p1)
222 ec.register_connection(chan, p2p2)
224 #### Add routing between CCN nodes
225 add_dce_fib_entry(ec, nid1, nid2)
226 add_dce_fib_entry(ec, nid2, nid1)
228 def add_node(ec, nid):
229 ### Add CCN nodes (ec.netgraph holds the topology graph)
230 add_dce_host(ec, nid)
231 add_dce_ccnd(ec, nid)
233 if nid == ec.netgraph.targets()[0]:
234 add_dce_ccnr(ec, nid)
236 if nid == ec.netgraph.sources()[0]:
237 add_dce_ccncat(ec, nid)
240 return ec.filter_resources("linux::ns3::dce::CCNCat")
242 if __name__ == '__main__':
246 # topology translation to NEPI model
247 ec = ExperimentController("dce_4n_linear",
248 topo_type = TopologyType.LINEAR,
252 add_node_callback = add_node,
253 add_edge_callback = add_edge)
255 #### Run experiment until metric convergence
256 rnr = ExperimentRunner()
260 compute_metric_callback = avg_interest_rtt,
261 evaluate_convergence_callback = normal_law,
262 wait_guids = wait_guids(ec))
265 post_process(ec, runs)