7e37435ba5d50590708ca01decc878c3e008aedf
[nepi.git] / examples / omf / testing / nepi_omf5_plexus_ccncat_linear.py
1 #!/usr/bin/env python
2 #
3 #    NEPI, a framework to manage network experiments
4 #    Copyright (C) 2013 INRIA
5 #
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;
9 #
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.
14 #
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/>.
17 #
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
19 #         Julien Tribino <julien.tribino@inria.fr>
20
21 """
22
23     Example :
24       - Testbed : Nitos
25       - Explanation :
26
27       CCN topology:
28     
29                  
30                    
31      content                ccncat        ccncat
32      h1      h2      h3      h4            h5
33      0 ----- 0 ----- 0 ------ 0 ------------0
34                
35
36       - Experiment:
37         * t0 : h4 retrieves the content and we measure the time
38         * t1 : h5 retrieve the content and should go faster than h4
39
40 """
41
42 from nepi.execution.resource import ResourceFactory, ResourceAction, ResourceState
43 from nepi.execution.ec import ExperimentController
44
45 from optparse import OptionParser, SUPPRESS_HELP
46
47 ###  Define OMF Method to simplify definition of resources ###
48 def add_node(ec, hostname, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"):
49     node = ec.register_resource("omf::Node")
50     ec.set(node, 'hostname', hostname)
51     ec.set(node, 'xmppServer', xmppServer)
52     ec.set(node, 'xmppUser', xmppUser)
53     ec.set(node, 'xmppPort', xmppPort)
54     ec.set(node, 'xmppPassword', xmppPassword)
55     ec.set(node, 'version', "5")
56     return node
57
58 def add_interface(ec, ip, xmppServer, xmppUser, essid = "ccn", name = "wlan0", mode = "adhoc",
59                  typ = "g", xmppPort = "5222", xmppPassword = "1234"):
60     iface = ec.register_resource("omf::WifiInterface")
61     ec.set(iface, 'name', name)
62     ec.set(iface, 'mode', mode)
63     ec.set(iface, 'hw_mode', typ)
64     ec.set(iface, 'essid', essid)
65     ec.set(iface, 'ip', ip)
66     ec.set(iface, 'version', "5")
67     return iface
68
69 def add_channel(ec, channel, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"):
70     chan = ec.register_resource("omf::Channel")
71     ec.set(chan, 'channel', channel)
72     ec.set(chan, 'xmppServer', xmppServer)
73     ec.set(chan, 'xmppUser', xmppUser)
74     ec.set(chan, 'xmppPort', xmppPort)
75     ec.set(chan, 'xmppPassword', xmppPassword)
76     ec.set(chan, 'version', "5")
77     return chan
78
79 def add_app(ec, host,  appid, command, env, xmppServer, xmppUser, 
80                 xmppPort = "5222", xmppPassword = "1234"):
81     app = ec.register_resource("omf::Application")
82     ec.set(app, 'appid', appid)
83     ec.set(app, 'command', command)
84     ec.set(app, 'env', env)
85     ec.set(app, 'version', "5")
86     ec.register_connection(app, host)
87     return app
88
89
90 ###  Define a CCND application  ###
91 def add_ccnd(ec, host, peers, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"):
92     env = 'PATH=$PATH:/root/ccnx-0.7.2/bin HOME=/root \
93 CCNR_DIRECTORY="/root" CCNR_STATUS_PORT="8080"'
94
95     # BASH command -> ' ccndstart ; ccndc add ccnx:/ udp host ; ccnr '
96     command = "ccndc add ccnx:/ udp " + peers
97     app = add_app(ec, host, "#ccnd", command, env, xmppServer, xmppUser,
98                     xmppPort = xmppPort, xmppPassword = xmppPassword)
99     return app
100
101 ###  Define a CCN SeqWriter application ###
102 def add_publish(ec, host,  movie, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"):
103     env = 'PATH=$PATH:/root/ccnx-0.7.2/bin HOME=/root CCNR_DIRECTORY="/root" CCNR_STATUS_PORT="8080"'
104
105     # BASH command -> 'ccnseqwriter -r ccnx:/VIDEO < movie'
106     command = "ccnseqwriter -r ccnx:/VIDEO"
107     command += " < " + movie
108
109     app = add_app(ec, host, "#ccn_write", command, env, xmppServer, xmppUser,
110                   xmppPort = xmppPort, xmppPassword = xmppPassword)
111     return app
112
113 ###  Define a streaming application ###
114 def add_stream(ec, host, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"):
115     env = 'PATH=$PATH:/root/ccnx-0.7.2/bin HOME=/root CCNR_DIRECTORY="/root" CCNR_STATUS_PORT="8080"'
116     command = " ddbus-uuidgen --ensure ; ( /root/ccnx-0.7.2/bin/ccncat ccnx:/VIDEO | /root/vlc-1.1.13/cvlc - )  "
117     app = add_app(ec, host, "#ccn_stream", command, env, xmppServer, xmppUser,
118                   xmppPort = xmppPort, xmppPassword = xmppPassword)
119     return app
120
121 ###  Many options to easily addapt the script ####
122 def get_options():
123     usage = "usage: %prog -c <channel> -s <xmpp_slice> -x <xmpp_host> -m <movie>"
124
125     parser = OptionParser(usage=usage)
126     parser.add_option("-c", "--channel", dest="channel", 
127             help="Channel of the communication", type="str")
128     parser.add_option("-s", "--xmpp-slice", dest="xmpp_slice", 
129             help="Name of the slice XMPP", type="str")
130     parser.add_option("-x", "--xmpp-host", dest="xmpp_host",
131             help="Name of the host XMPP", type="str")
132     #parser.add_option("-e", "--exp-id", dest="exp_id", 
133     #        help="Label to identify experiment", type="str")
134
135     (options, args) = parser.parse_args()
136
137     return (options.channel, options.xmpp_slice, 
138             options.xmpp_host)
139
140 ### Script itself ###
141 if __name__ == '__main__':
142     (channel, xmpp_slice, xmpp_host) = get_options()
143
144     env = 'PATH=$PATH:/root/ccnx-0.7.2/bin HOME=/root CCNR_DIRECTORY="/root" CCNR_STATUS_PORT="8080"'
145
146 # Create the EC
147     ec = ExperimentController()
148
149 # Create the topology
150     host1 = "omf.plexus.wlab5"
151     host2 = "omf.plexus.wlab9"
152     host3 = "omf.plexus.wlab10"
153     host4 = "omf.plexus.wlab24"
154     host5 = "omf.plexus.wlab29"  # b1
155
156     ip1 = "10.0.0.5/24"
157     ip2 = "10.0.0.9/24"
158     ip3 = "10.0.0.10/24"
159     ip4 = "10.0.0.24/24"
160     ip5 = "10.0.0.29/24"
161
162     all_hosts = [host1, host2, host3, host4, host5]
163     all_ip = [ip1, ip2, ip3, ip4, ip5]
164
165     ring_hosts = [host1, host2, host3, host4]
166     nodes = dict()
167
168     chann = add_channel(ec, channel, xmpp_slice, xmpp_host)
169     for i in xrange(len(all_hosts)):
170         node = add_node(ec,all_hosts[i], xmpp_slice, xmpp_host)
171         iface = add_interface(ec, all_ip[i], xmpp_slice, xmpp_host)
172         ec.register_connection(node, iface)
173         ec.register_connection(iface, chann)
174         nodes[all_hosts[i]] = node
175
176 #### CCN setup for the node
177 ###    ccnds = dict()
178 ###    ccnrs = dict()
179 ###    for i in xrange(len(all_hosts)):
180 ###        ccndstart = add_app(ec, nodes[all_hosts[i]],  "#ccndstart", "ccndstart &", 
181 ###                              env, xmpp_slice, xmpp_host)
182 ###        ccnr = add_app(ec, nodes[all_hosts[i]],  "#ccnr", "ccnr &", 
183 ###                            env, xmpp_slice, xmpp_host)
184 ###        ccnds[all_hosts[i]] = ccndstart
185 ###        ccnrs[all_hosts[i]] = ccnr
186 ###        ec.register_condition(ccnr, ResourceAction.START, ccndstart, ResourceState.STARTED, "1s")
187
188 #### CCNDC setup 
189 ###    # l1 : h1 - h2 , h2 - h1
190 ###    l1u = add_ccnd(ec, nodes[host1], ip2, xmpp_slice, xmpp_host)
191 ###    l1d = add_ccnd(ec, nodes[host2], ip1, xmpp_slice, xmpp_host)
192
193 ###    # l2 : h2 - h3 , h3 - h2
194 ###    l2u = add_ccnd(ec, nodes[host2], ip3, xmpp_slice, xmpp_host)
195 ###    l2d = add_ccnd(ec, nodes[host3], ip2, xmpp_slice, xmpp_host)
196
197 ###    # l3 : h3 - h4 , h4 - h3
198 ###    l3u = add_ccnd(ec, nodes[host3], ip4, xmpp_slice, xmpp_host)
199 ###    l3d = add_ccnd(ec, nodes[host4], ip3, xmpp_slice, xmpp_host)
200
201 ###    # l4 : h4 - h5 , h5 - h4
202 ###    l4u = add_ccnd(ec, nodes[host4], ip5, xmpp_slice, xmpp_host)
203 ###    l4d = add_ccnd(ec, nodes[host5], ip4, xmpp_slice, xmpp_host)
204
205 ###    link = [l1u, l1d, l2u, l2d, l3u, l3d, l4u, l4d]
206
207 #### List of condition
208 ###    for i in xrange(len(all_hosts)):
209 ###         ec.register_condition(ccnrs[all_hosts[i]], ResourceAction.START, ccnds[all_hosts[i]], ResourceState.STARTED, "1s")
210 ###         ec.register_condition(link, ResourceAction.START, ccnrs[all_hosts[i]], ResourceState.STARTED, "1s")
211
212
213 # Do the iperf
214     iperfserv = dict()
215     iperfclient = dict()
216     for i in xrange(len(all_hosts)):
217         perfserv = add_app(ec, nodes[all_hosts[i]],  "#perfserv", "iperf -s > /opt/iperfserv.txt", 
218                               env, xmpp_slice, xmpp_host)
219         iperfclient[all_hosts[i]] = []
220         if i > 0:
221             cmd = "iperf -c " + all_ip[i-1] + " > /opt/iperclient1.txt"
222             perfclient1 = add_app(ec, nodes[all_hosts[i]],  "#perfclient1", cmd, 
223                             env, xmpp_slice, xmpp_host)
224             iperfclient[all_hosts[i]].append(perfclient1)
225
226         if i < (len(all_hosts)-1):
227             cmd = "iperf -c " + all_ip[i+1] + " > /opt/iperclient2.txt"
228             perfclient2 = add_app(ec, nodes[all_hosts[i]],  "#perfclient2", cmd, 
229                             env, xmpp_slice, xmpp_host)
230             iperfclient[all_hosts[i]].append(perfclient2)
231
232         iperfserv[all_hosts[i]] = perfserv
233
234     for i in xrange(len(all_hosts)):
235          #ec.register_condition(iperfserv[all_hosts[i]], ResourceAction.START, link, ResourceState.STARTED, "2s")
236          for elt in iperfclient[all_hosts[i]]:
237              ec.register_condition(elt, ResourceAction.START, iperfserv[all_hosts[i]], ResourceState.STARTED, "3s")
238
239
240 ## Streaming Server
241 #    pub = add_publish(ec, nodes[host5], movie, xmpp_slice, xmpp_host)
242
243 ## Streaming client
244 #    stream = add_stream(ec, nodes[host6], xmpp_slice, xmpp_host)
245
246 ## Streaming conditions
247 #    ec.register_condition(pub, ResourceAction.START, link, ResourceState.STARTED, "2s")
248 #    ec.register_condition(stream, ResourceAction.START, link, ResourceState.STARTED, "2s")
249 #    ec.register_condition(stream, ResourceAction.START, pub, ResourceState.STARTED, "2s")
250
251
252
253 ### Cleanning ###
254 # Cleaning when the experiment stop
255 ##    ccndstops = []
256 ##    for i in xrange(len(all_hosts)):
257 ##        ccndstop = add_app(ec, nodes[all_hosts[i]], "#ccndstop", "ccndstop", env, xmpp_slice, xmpp_host)
258 ##        ccndstops.append(ccndstop)
259     perfkill = dict()
260     for i in xrange(len(all_hosts)):
261         kill = add_app(ec, nodes[all_hosts[i]], "#kill", "killall iperf", "", xmpp_slice, xmpp_host)
262         perfkill[all_hosts[i]] = kill
263
264
265 # Condition to stop and clean the experiment
266     apps = []
267     for i in xrange(len(all_hosts)):
268 #        apps.append(ccnds[all_hosts[i]])
269 #        apps.append(ccnrs[all_hosts[i]])
270         apps.append(iperfserv[all_hosts[i]])
271         for elt in iperfclient[all_hosts[i]]:
272             apps.append(elt)
273 #    apps += link
274     #apps.append(pub)
275     #apps.append(stream)
276
277     ec.register_condition(apps, ResourceAction.STOP, apps, ResourceState.STARTED, "20s")
278
279 #    ec.register_condition(ccndstops + [killall], ResourceAction.START, apps, ResourceState.STOPPED, "1s")
280 #    ec.register_condition(ccndstops + [killall], ResourceAction.STOP, ccndstops, ResourceState.STARTED, "1s")
281
282     killall = []
283     for i in xrange(len(all_hosts)):
284         killall.append(perfkill[all_hosts[i]])
285
286     ec.register_condition(killall, ResourceAction.START, apps, ResourceState.STOPPED, "1s")
287     ec.register_condition(killall, ResourceAction.STOP, killall, ResourceState.STARTED, "1s")
288
289 ### Deploy and Wait ###
290 # Deploy all ResourceManagers
291     ec.deploy()
292
293 # Wait until the applications are finished
294     ec.wait_finished(killall)
295
296 # Shutdown the experiment controller
297     ec.shutdown()
298
299