Debug event processing

This commit is contained in:
Loic Guegan 2022-06-29 11:19:36 +02:00
parent be6d819080
commit 1bef51d878
18 changed files with 292 additions and 101 deletions

View file

@ -4,7 +4,7 @@ class Node:
available_node_id=0 available_node_id=0
def __init__(self,src,interfaces): def __init__(self,src,interfaces):
""" """
self.chest: contains mutex protected data
""" """
self.node_id=Node.available_node_id self.node_id=Node.available_node_id
Node.available_node_id+=1 # Refresh node id Node.available_node_id+=1 # Refresh node id
@ -71,12 +71,16 @@ class Node:
def wait(self,duration): def wait(self,duration):
if type(duration) != int and type(duration) != float: if type(duration) != int and type(duration) != float:
self.abort("wait() called with a non-number duration") self.abort("wait() called with a non-number duration")
elif duration < 0:
self.abort("wait() called with a negative duration (duration="+str(duration)+")")
elif duration == 0:
return
self.rargs=duration self.rargs=duration
self["request"]="timeout_add" self["request"]="notify_add"
self["state"]="call_non_blocking" self["state"]="call_non_blocking"
self.wait_ack(["timeout_add"]) self.wait_ack(["notify_add"])
self["state"]="pending" self["state"]="pending"
self.wait_ack(["timeout"]) self.wait_ack(["notify"])
def wait_end(self): def wait_end(self):
self["request"]="wait_end" self["request"]="wait_end"
@ -103,6 +107,8 @@ class Node:
self.abort("send() called with a non-number datasize") self.abort("send() called with a non-number datasize")
elif type(dst) != int and type(dst) != float and dst != None: elif type(dst) != int and type(dst) != float and dst != None:
self.abort("send() called with a non-number dst (wired interfaces) or dst is not None (wireless interfaces)") self.abort("send() called with a non-number dst (wired interfaces) or dst is not None (wireless interfaces)")
elif not self["turned_on"]:
self.abort("send() called while node is turned off")
self.plugin_notify("send_call",(interface,data,datasize,dst)) self.plugin_notify("send_call",(interface,data,datasize,dst))
self.rargs=(interface, data, datasize, dst) self.rargs=(interface, data, datasize, dst)
self["request"]="send" self["request"]="send"
@ -118,8 +124,12 @@ class Node:
self.abort("sendt() called with a non-number datasize") self.abort("sendt() called with a non-number datasize")
elif type(timeout) != int and type(timeout) != float: elif type(timeout) != int and type(timeout) != float:
self.abort("sendt() called with a non-number timeout") self.abort("sendt() called with a non-number timeout")
elif timeout < 0:
self.abort("sendt() called with a negative timeout (timeout="+str(timeout)+")")
elif type(dst) != int and type(dst) != float and dst != None: elif type(dst) != int and type(dst) != float and dst != None:
self.abort("send() called with a non-number dst (wired interfaces) or dst is not None (wireless interfaces)") self.abort("send() called with a non-number dst (wired interfaces) or dst is not None (wireless interfaces)")
elif not self["turned_on"]:
self.abort("sendt() called while node is turned off")
self.rargs=timeout self.rargs=timeout
self["request"]="timeout_add" self["request"]="timeout_add"
self["state"]="call_non_blocking" self["state"]="call_non_blocking"
@ -141,6 +151,8 @@ class Node:
def receive(self,interface): def receive(self,interface):
if interface not in self["interfaces"]: if interface not in self["interfaces"]:
self.abort("receive() called with an unknown interface \""+interface+"\"") self.abort("receive() called with an unknown interface \""+interface+"\"")
elif not self["turned_on"]:
self.abort("receive() called while node is turned off")
self["request"]="receive" self["request"]="receive"
self.rargs=interface self.rargs=interface
self["state"]="call_blocking" self["state"]="call_blocking"
@ -154,6 +166,10 @@ class Node:
self.abort("receivet() called with an unknown interface \""+interface+"\"") self.abort("receivet() called with an unknown interface \""+interface+"\"")
elif type(timeout) != int and type(timeout) != float: elif type(timeout) != int and type(timeout) != float:
self.abort("receivet() called with a non-number timeout") self.abort("receivet() called with a non-number timeout")
elif timeout < 0:
self.abort("receivet() called with a negative timeout (timeout="+str(timeout)+")")
elif not self["turned_on"]:
self.abort("receivet() called while node is turned off")
self.rargs=timeout self.rargs=timeout
self["request"]="timeout_add" self["request"]="timeout_add"
self["state"]="call_non_blocking" self["state"]="call_non_blocking"

View file

@ -7,10 +7,12 @@ class Simulator:
Flow-Level Discrete Event Simulator for Cyber-Physical Systems Flow-Level Discrete Event Simulator for Cyber-Physical Systems
The general format for an event is (type,timestamp,event,priority) The general format for an event is (type,timestamp,event,priority)
Event types: Event types:
- 0 send (0,timestamp,(src,dst,interface,data,datasize,duration,datasize_remaining), 1) - 0 send (0,timestamp,(src,dst,interface,data,datasize,duration,datasize_remaining), 2)
- 1 timeout (1,timestamp,node_id,4) - 1 timeout (1,timestamp,node_id,3)
- 2 breakpoint_manual (3,timestamp,0,0) - 2 breakpoint_manual (3,timestamp,0,1)
- 3 breakpoint_auto (4,timestamp,0,0) - 3 breakpoint_auto (4,timestamp,0,1)
- 4 notify (0,timestamp,node_id,0)
Very important notes: Very important notes:
- When the simulator wakes up a node (changing is state to running) data that should be received by that node - When the simulator wakes up a node (changing is state to running) data that should be received by that node
@ -18,6 +20,8 @@ class Simulator:
Otherwise plugings such as the power states one may not gives accurate results because of missing entries in the nodes received queues. Otherwise plugings such as the power states one may not gives accurate results because of missing entries in the nodes received queues.
- The state of a node should always be updated (e.g node["state"]="running") BEFORE updating its - The state of a node should always be updated (e.g node["state"]="running") BEFORE updating its
queue (e.g node.rqueue.put(("timeout_remove",0)) queue (e.g node.rqueue.put(("timeout_remove",0))
- Notify as the same behavior as timeout. Except it has the highest priority among all the events! This is particularly usefull for wait events which SHOULD
be handle before any other one. That way after a wait, nodes a ready perform receivet() with timeout=0.
""" """
def __init__(self,netmat): def __init__(self,netmat):
@ -123,21 +127,13 @@ class Simulator:
sorted_indexes=np.lexsort((self.events[:,3],self.events[:,1])) sorted_indexes=np.lexsort((self.events[:,3],self.events[:,1]))
self.events=self.events[sorted_indexes] self.events=self.events[sorted_indexes]
def sync_node_non_blocking(self,node): def sync_node_non_blocking(self,node, timeout_remove_only=False):
""" """
Process all call request and wait for Node.sync() to return Process all call request and wait for Node.sync() to return
""" """
node.sync() node.sync()
while node["state"] == "call_non_blocking": while node["state"] == "call_non_blocking":
if node["request"] == "log": if node["request"] == "timeout_remove":
self.log(node.rargs,node=node.node_id)
node["state"]="running"
node.rqueue.put(("log",0))
elif node["request"] == "timeout_add":
self.add_event(1,self.time+node.rargs,node.node_id,priority=3)
node["state"]="running"
node.rqueue.put(("timeout_add",0))
elif node["request"] == "timeout_remove":
selector=list() selector=list()
for event in self.events: for event in self.events:
if event[0] == 1 and event[2]==node.node_id: if event[0] == 1 and event[2]==node.node_id:
@ -147,69 +143,94 @@ class Simulator:
self.events=self.events[~np.array(selector)] self.events=self.events[~np.array(selector)]
node["state"]="running" node["state"]="running"
node.rqueue.put(("timeout_remove",0)) node.rqueue.put(("timeout_remove",0))
elif node["request"] == "abort": elif timeout_remove_only:
self.log("Simulation aborted: "+node.rargs,node=node.node_id) break
exit(1) elif not timeout_remove_only:
elif node["request"] == "read": if node["request"] == "log":
node["state"]="running" self.log(node.rargs,node=node.node_id)
if node.rargs == "clock": node["state"]="running"
node.rqueue.put(("read",float(self.time))) node.rqueue.put(("log",0))
elif node.rargs[0:5] == "ncom_": # ncom_<interface> register elif node["request"] == "timeout_add":
interface=node.rargs[5:] self.add_event(1,self.time+node.rargs,node.node_id,priority=3)
count=0 node["state"]="running"
# Count number of communication on interface node.rqueue.put(("timeout_add",0))
elif node["request"] == "notify_add":
self.add_event(4,self.time+node.rargs,node.node_id,priority=0)
node["state"]="running"
node.rqueue.put(("notify_add",0))
elif node["request"] == "notify_remove":
selector=list()
for event in self.events: for event in self.events:
if event[0] == 0 and event[2][1] == node.node_id and event[2][2] == interface: if event[0] == 4 and event[2]==node.node_id:
count+=1 selector.append(True)
node.rqueue.put(("read",count))
else:
node.rqueue.put(("read",0)) # Always return 0 if register is unknown
elif node["request"] == "turn_on":
node["state"]="running"
node.rqueue.put(("turn_on",0))
self.log("Turned on",node=node.node_id)
elif node["request"] == "turn_off":
# Create communications selectors (True/False arrays)
selector_wireless=list() # Select all wireless events where node is involved
selector_wired=list() # Select all wired events where node is involved
for event in self.events:
if event[0]==0 and int(event[2][1])==node.node_id:
if self.netmat[event[2][2]]["is_wired"]:
selector_wireless.append(False)
selector_wired.append(True)
else: else:
selector_wireless.append(True) selector.append(False)
self.events=self.events[~np.array(selector)]
node["state"]="running"
node.rqueue.put(("notify_remove",0))
elif node["request"] == "abort":
self.log("Simulation aborted: "+node.rargs,node=node.node_id)
exit(1)
elif node["request"] == "read":
node["state"]="running"
if node.rargs == "clock":
node.rqueue.put(("read",float(self.time)))
elif node.rargs[0:5] == "ncom_": # ncom_<interface> register
interface=node.rargs[5:]
count=0
# Count number of communication on interface
for event in self.events:
if event[0] == 0 and event[2][1] == node.node_id and event[2][2] == interface:
count+=1
node.rqueue.put(("read",count))
else:
node.rqueue.put(("read",0)) # Always return 0 if register is unknown
elif node["request"] == "turn_on":
node["state"]="running"
node.rqueue.put(("turn_on",0))
self.log("Turned on",node=node.node_id)
elif node["request"] == "turn_off":
# Create communications selectors (True/False arrays)
selector_wireless=list() # Select all wireless events where node is involved
selector_wired=list() # Select all wired events where node is involved
for event in self.events:
if event[0]==0 and int(event[2][1])==node.node_id:
if self.netmat[event[2][2]]["is_wired"]:
selector_wireless.append(False)
selector_wired.append(True)
else:
selector_wireless.append(True)
selector_wired.append(False)
else:
selector_wireless.append(False)
selector_wired.append(False) selector_wired.append(False)
else: # Informed senders of wired events to cancel send
selector_wireless.append(False) for event in self.events[selector_wired]:
selector_wired.append(False) sender=self.nodes[int(event[2][0])]
# Informed senders of wired events to cancel send sender["state"]="running"
for event in self.events[selector_wired]: sender.rqueue.put(("send_cancel",2))
sender=self.nodes[int(event[2][0])] # Remove communications from the event list
sender["state"]="running" if(len(self.events) != 0):
sender.rqueue.put(("send_cancel",2)) self.events=self.events[~(np.array(selector_wireless)|np.array(selector_wired))]
# Remove communications from the event list # Refresh wired sharing
if(len(self.events) != 0): for interface in self.sharing.keys():
self.events=self.events[~(np.array(selector_wireless)|np.array(selector_wired))] self.sharing[interface][node.node_id]=0 # Sharing goes back to zero
# Refresh wired sharing # Update node state after turning off
for interface in self.sharing.keys(): node["state"]="running"
self.sharing[interface][node.node_id]=0 # Sharing goes back to zero node.rqueue.put(("turn_off",0))
# Update node state after turning off self.log("Turned off",node=node.node_id)
node["state"]="running" elif node["request"] == "send_cancel":
node.rqueue.put(("turn_off",0)) selector=list()
self.log("Turned off",node=node.node_id) for event in self.events:
elif node["request"] == "send_cancel": if event[0]==0 and int(event[2][0]) == node.node_id:
selector=list() selector.append(True)
for event in self.events: if self.netmat[event[2][2]]["is_wired"]:
if event[0]==0 and int(event[2][0]) == node.node_id: self.update_sharing(int(event[2][1]),-1,event[2][2])
selector.append(True) else:
if self.netmat[event[2][2]]["is_wired"]: selector.append(False)
self.update_sharing(int(event[2][1]),-1,event[2][2]) self.events=self.events[~np.array(selector)]
else: node["state"]="running"
selector.append(False) node.rqueue.put(("send_cancel",0))
self.events=self.events[~np.array(selector)]
node["state"]="running"
node.rqueue.put(("send_cancel",0))
node.sync() node.sync()
def update_sharing(self, dst, amount,interface): def update_sharing(self, dst, amount,interface):
@ -326,7 +347,7 @@ class Simulator:
return np.arange(0,selector.shape[0])[selector] return np.arange(0,selector.shape[0])[selector]
def add_event(self,event_type,event_ts,event,priority=1): def add_event(self,event_type,event_ts,event,priority=2):
""" """
Call this function with sort=True the least amount of time possible Call this function with sort=True the least amount of time possible
""" """
@ -341,9 +362,9 @@ class Simulator:
self.startat=time.time() self.startat=time.time()
self.interferences=interferences self.interferences=interferences
for bp in breakpoints: for bp in breakpoints:
self.add_event(2,bp,0,0) self.add_event(2,bp,0,1)
if breakpoints_every != None: if breakpoints_every != None:
self.add_event(3,breakpoints_every,0,0) self.add_event(3,breakpoints_every,0,1)
if debug: if debug:
with open(self.debug_file_path, "w") as f: with open(self.debug_file_path, "w") as f:
f.write("Python version {}\n".format(sys.version)) f.write("Python version {}\n".format(sys.version))
@ -396,9 +417,10 @@ class Simulator:
dst["interfaces_queue_size"][interface]-=1 dst["interfaces_queue_size"][interface]-=1
dst["state"]="running" dst["state"]="running"
dst.rqueue.put(("receive",0)) dst.rqueue.put(("receive",0))
self.sync_node_non_blocking(dst) self.sync_node_non_blocking(dst,timeout_remove_only=True)
src["state"]="running" src["state"]="running"
src.rqueue.put(("send",0)) src.rqueue.put(("send",0))
self.sync_node_non_blocking(src,timeout_remove_only=True)
else: else:
if src.node_id != dst.node_id: if src.node_id != dst.node_id:
dst["interfaces"][interface].put((data,start_at,self.time)) dst["interfaces"][interface].put((data,start_at,self.time))
@ -409,19 +431,25 @@ class Simulator:
dst["interfaces_queue_size"][interface]-=1 dst["interfaces_queue_size"][interface]-=1
dst["state"]="running" dst["state"]="running"
dst.rqueue.put(("receive",0)) dst.rqueue.put(("receive",0))
self.sync_node_non_blocking(dst) self.sync_node_non_blocking(dst,timeout_remove_only=True)
else: else:
src["state"]="running" src["state"]="running"
src.rqueue.put(("send",0)) src.rqueue.put(("send",0))
self.sync_node_non_blocking(src,timeout_remove_only=True)
elif event_type == 1: elif event_type == 1:
node=self.nodes[int(event)] node=self.nodes[int(event)]
node["state"]="running" node["state"]="running"
node.rqueue.put(("timeout",0)) node.rqueue.put(("timeout",0))
self.sync_node_non_blocking(node) self.sync_node_non_blocking(node,timeout_remove_only=True)
elif event_type == 4:
node=self.nodes[int(event)]
node["state"]="running"
node.rqueue.put(("notify",0))
self.sync_node_non_blocking(node,timeout_remove_only=True)
elif event_type == 2 or event_type == 3: elif event_type == 2 or event_type == 3:
breakpoint_callback(self) breakpoint_callback(self)
if event_type == 3: if event_type == 3:
self.add_event(3,self.time+breakpoints_every,0,0) self.add_event(3,self.time+breakpoints_every,0,1)
##### Simulation ends ##### Simulation ends
self.log("Simulation ends") self.log("Simulation ends")

View file

@ -10,6 +10,7 @@ wai=$(dirname $(readlink -f "$0")) # Current script directory
tests=$(find ${wai}/ -maxdepth 1 -mindepth 1 -type d) # Find tests tests=$(find ${wai}/ -maxdepth 1 -mindepth 1 -type d) # Find tests
out=$(mktemp) out=$(mktemp)
test_timeout=20 test_timeout=20
abort=1
for test in ${tests} for test in ${tests}
do do
@ -38,7 +39,7 @@ do
echo "------------- Got -------------" echo "------------- Got -------------"
cat "$out"; cat "$out";
rm "$out" rm "$out"
exit 1 [ $abort -eq 1 ] && exit 1
fi fi
# Prepare for next test # Prepare for next test

View file

@ -0,0 +1,5 @@
[t=0.000,src=n0] Send 1 bytes to n1 on eth0
[t=0.000,src=n1] Receive failed code=-1
[t=1.000,src=n1] Receive 1 bytes on eth0
[t=1.000,src=n1] Received: Hello World!
[t=1.000,src=esds] Simulation ends

View file

@ -0,0 +1,14 @@
#!/usr/bin/env python
def receivet(node,timeout):
##### Simple receive
code, data=node.receivet("eth0",timeout)
msg="Received: "+data if code == 0 else "Receive failed code="+str(code)
node.log(msg)
def execute(api):
# Should not works
receivet(api,0)
api.wait(1)
# Should works
receivet(api,0)

View file

@ -0,0 +1,5 @@
#!/usr/bin/env python
def execute(api):
api.send("eth0","Hello World!",1,1)

View file

@ -0,0 +1,14 @@
#!/usr/bin/env python
# Load ESDS
import esds
import numpy as np
B=np.full((2,2),8)
L=np.full((2,2),0)
s=esds.Simulator({"wlan0":{"bandwidth":B, "latency":L, "is_wired":False}, "eth0":{"bandwidth":B, "latency":L, "is_wired":True}})
s.create_node("sender")
s.create_node("receiver")
s.run(debug=True)

View file

@ -0,0 +1,43 @@
Python version 3.10.5 (main, Jun 6 2022, 18:49:26) [GCC 12.1.0]
Simulation started at 1654802960.7880125
Number of nodes is 2
Manual breakpoints list: []
Breakpoints every Nones
-----------------------------------------------
Started since 0.02s
Simulated time 0.000s (or more precisely 0s)
Node number per state: pending=1 request=1
Node sharing: n1=1
Ids of node in timeout mode:
Sorted events list:
[[0 1.0 array([0, 1, 'eth0', 'Hello World!', 1, 1.0, 1, 0], dtype=object)
1]
[1 2 array(1, dtype=object) 3]]
-----------------------------------------------
Started since 0.04s
Simulated time 1.000s (or more precisely 1.0s)
Node number per state: pending=1 request=1
Node sharing: n1=1
Ids of node in timeout mode:
Sorted events list:
[[1 1.5 array(1, dtype=object) 3]
[0 2.0
array([0, 1, 'eth0', 'Hello World!', 1, 1.0, 1, 1.0], dtype=object) 1]]
-----------------------------------------------
Started since 0.06s
Simulated time 1.500s (or more precisely 1.5s)
Node number per state: pending=1 request=1
Node sharing: n1=1
Ids of node in timeout mode:
Sorted events list:
[[0 2.0
array([0, 1, 'eth0', 'Hello World!', 1, 1.0, 1, 1.0], dtype=object) 1]
[1 2.0 array(1, dtype=object) 3]]
-----------------------------------------------
Started since 0.08s
Simulated time 2.000s (or more precisely 2.0s)
Node number per state: terminated=2
Node sharing:
Ids of node in timeout mode:
Sorted events list:
[]

View file

@ -0,0 +1,16 @@
[t=0.000,src=n0] Send 0 bytes to n1 on eth0
[t=0.000,src=n1] Receive 0 bytes on eth0
[t=0.000,src=n1] Received: Hello World!
[t=0.000,src=n0] Send 0 bytes to n1 on eth0
[t=0.000,src=n1] Receive 0 bytes on eth0
[t=0.000,src=n1] Received: Hello World!
[t=1.000,src=n0] Send 0 bytes to n1 on eth0
[t=1.000,src=n1] Receive 0 bytes on eth0
[t=1.000,src=n1] Received: Hello World!
[t=3.000,src=n0] Send 0 bytes to n1 on eth0
[t=3.000,src=n1] Receive 0 bytes on eth0
[t=3.000,src=n1] Received: Hello World!
[t=3.000,src=n0] Send 0 bytes to n1 on eth0
[t=3.000,src=n1] Receive 0 bytes on eth0
[t=3.000,src=n1] Received: Hello World!
[t=3.000,src=esds] Simulation ends

View file

@ -0,0 +1,23 @@
#!/usr/bin/env python
def receive(api):
##### Simple receive
code, data=api.receive("eth0")
msg="Received: "+data if code == 0 else "Receive failed code="+str(code)
api.log(msg)
def execute(api):
receive(api)
# Simulated time t=0s here
receive(api)
# Simulated time t=0s here
receive(api)
# Simulated time t=1s here
receive(api)
# Simulated time t=3s here
code, data=api.receivet("eth0",0)
msg="Received: "+data if code == 0 else "Receive failed code="+str(code)
api.log(msg)
# Simulated time t=3s here

View file

@ -0,0 +1,12 @@
#!/usr/bin/env python
def execute(api):
api.send("eth0","Hello World!",0,1)
api.wait(0)
api.send("eth0","Hello World!",0,1)
api.wait(1)
api.send("eth0","Hello World!",0,1)
api.wait(1)
api.wait(1)
api.send("eth0","Hello World!",0,1)
api.send("eth0","Hello World!",0,1)

View file

@ -0,0 +1,14 @@
#!/usr/bin/env python
# Load ESDS
import esds
import numpy as np
B=np.full((2,2),8)
L=np.full((2,2),0)
s=esds.Simulator({"wlan0":{"bandwidth":B, "latency":L, "is_wired":False}, "eth0":{"bandwidth":B, "latency":L, "is_wired":True}})
s.create_node("sender")
s.create_node("receiver")
s.run(debug=True)

View file

@ -1,7 +1,7 @@
[t=0.000,src=n0] Send 1 bytes to n2 on eth0 [t=0.000,src=n0] Send 1 bytes to n2 on eth0
[t=0.000,src=n1] Send 1 bytes to n2 on eth0 [t=0.000,src=n1] Send 1 bytes to n2 on eth0
[t=2.000,src=n2] Receive 1 bytes on eth0 [t=2.000,src=n2] Receive 1 bytes on eth0
[t=2.000,src=n2] Received: Hello World from 0!
[t=2.000,src=n2] Receive 1 bytes on eth0 [t=2.000,src=n2] Receive 1 bytes on eth0
[t=2.000,src=n2] Received: Hello World from 0!
[t=2.000,src=n2] Received: Hello World from 1! [t=2.000,src=n2] Received: Hello World from 1!
[t=2.000,src=esds] Simulation ends [t=2.000,src=esds] Simulation ends

View file

@ -2,32 +2,32 @@
[t=0.000,src=n1] Send 1 bytes to n3 on eth0 [t=0.000,src=n1] Send 1 bytes to n3 on eth0
[t=0.000,src=n2] Send 1 bytes to n3 on eth0 [t=0.000,src=n2] Send 1 bytes to n3 on eth0
[t=3.000,src=n3] Receive 1 bytes on eth0 [t=3.000,src=n3] Receive 1 bytes on eth0
[t=3.000,src=n3] Receive 1 bytes on eth0
[t=3.000,src=n3] Receive 1 bytes on eth0
[t=3.000,src=n3] Received: Hello World from 0! [t=3.000,src=n3] Received: Hello World from 0!
[t=3.000,src=n3] Receive 1 bytes on eth0
[t=3.000,src=n3] Received: Hello World from 1!
[t=3.000,src=n3] Receive 1 bytes on eth0
[t=3.000,src=n3] Received: Hello World from 2!
[t=3.000,src=n0] Send 2 bytes to n3 on eth0 [t=3.000,src=n0] Send 2 bytes to n3 on eth0
[t=3.000,src=n1] Send 1 bytes to n3 on eth0 [t=3.000,src=n1] Send 1 bytes to n3 on eth0
[t=3.000,src=n2] Send 1 bytes to n3 on eth0 [t=3.000,src=n2] Send 1 bytes to n3 on eth0
[t=3.000,src=n3] Received: Hello World from 1!
[t=3.000,src=n3] Received: Hello World from 2!
[t=6.000,src=n3] Receive 1 bytes on eth0
[t=6.000,src=n3] Receive 1 bytes on eth0 [t=6.000,src=n3] Receive 1 bytes on eth0
[t=6.000,src=n3] Received: Hello World from 1! [t=6.000,src=n3] Received: Hello World from 1!
[t=6.000,src=n3] Receive 1 bytes on eth0
[t=6.000,src=n3] Received: Hello World from 2! [t=6.000,src=n3] Received: Hello World from 2!
[t=7.000,src=n3] Receive 2 bytes on eth0 [t=7.000,src=n3] Receive 2 bytes on eth0
[t=7.000,src=n3] Received: Hello World from 0! [t=7.000,src=n3] Received: Hello World (2bytes) from 0!
[t=7.000,src=n0] Send 2 bytes to n3 on eth0 [t=7.000,src=n0] Send 2 bytes to n3 on eth0
[t=7.000,src=n1] Send 2 bytes to n3 on eth0 [t=7.000,src=n1] Send 2 bytes to n3 on eth0
[t=7.000,src=n2] Send 1 bytes to n3 on eth0 [t=7.000,src=n2] Send 1 bytes to n3 on eth0
[t=10.000,src=n3] Receive 1 bytes on eth0 [t=10.000,src=n3] Receive 1 bytes on eth0
[t=10.000,src=n3] Received: Hello World from 2! [t=10.000,src=n3] Received: Hello World from 2!
[t=12.000,src=n3] Receive 2 bytes on eth0 [t=12.000,src=n3] Receive 2 bytes on eth0
[t=12.000,src=n3] Received: Hello World from 0!
[t=12.000,src=n3] Receive 2 bytes on eth0 [t=12.000,src=n3] Receive 2 bytes on eth0
[t=12.000,src=n3] Received: Hello World from 1! [t=12.000,src=n3] Received: Hello World (2bytes) from 0!
[t=12.000,src=n0] Send 1 bytes to n3 on eth0 [t=12.000,src=n0] Send 1 bytes to n3 on eth0
[t=12.000,src=n1] Send 2 bytes to n3 on eth0 [t=12.000,src=n1] Send 2 bytes to n3 on eth0
[t=12.000,src=n2] Send 3 bytes to n3 on eth0 [t=12.000,src=n2] Send 3 bytes to n3 on eth0
[t=12.000,src=n3] Received: Hello World (2bytes) from 1!
[t=15.000,src=n3] Receive 1 bytes on eth0 [t=15.000,src=n3] Receive 1 bytes on eth0
[t=15.000,src=n3] Received: Hello World from 0! [t=15.000,src=n3] Received: Hello World from 0!
[t=17.000,src=n3] Receive 2 bytes on eth0 [t=17.000,src=n3] Receive 2 bytes on eth0

View file

@ -8,14 +8,14 @@ def execute(api):
# These send should start at 3s and be completed at 7s # These send should start at 3s and be completed at 7s
if api.node_id==0: if api.node_id==0:
api.send("eth0","Hello World from {}!".format(api.node_id),2,3) # Should lasts 3s + 1s = 4s api.send("eth0","Hello World (2bytes) from {}!".format(api.node_id),2,3) # Should lasts 3s + 1s = 4s
else: else:
api.send("eth0","Hello World from {}!".format(api.node_id),1,3) # Should lasts 3s api.send("eth0","Hello World from {}!".format(api.node_id),1,3) # Should lasts 3s
api.wait(1) # Sync with node 0 at 7s api.wait(1) # Sync with node 0 at 7s
# Those sends should start at 7s and be completed at 12s # Those sends should start at 7s and be completed at 12s
if api.node_id<=1: if api.node_id<=1:
api.send("eth0","Hello World from {}!".format(api.node_id),2,3) # Should last 3s + 2s = 5s api.send("eth0","Hello World (2bytes) from {}!".format(api.node_id),2,3) # Should last 3s + 2s = 5s
# Completed at 12s since 3 nodes are sharing the bandwidth up to 10s # Completed at 12s since 3 nodes are sharing the bandwidth up to 10s
# then the 2 two remaining node send their last byte up to 12s # then the 2 two remaining node send their last byte up to 12s
else: else:

View file

@ -1,7 +1,7 @@
[t=0.000,src=n0] Send 1 bytes on wlan0 [t=0.000,src=n0] Send 1 bytes on wlan0
[t=1.000,src=n1] Receive 1 bytes on wlan0 [t=1.000,src=n1] Receive 1 bytes on wlan0
[t=1.000,src=n1] Received: Hello World!
[t=1.000,src=n2] Receive 1 bytes on wlan0 [t=1.000,src=n2] Receive 1 bytes on wlan0
[t=1.000,src=n1] Received: Hello World!
[t=1.000,src=n2] Received: Hello World! [t=1.000,src=n2] Received: Hello World!
[t=1.000,src=n2] Turned off [t=1.000,src=n2] Turned off
[t=1.000,src=n0] Send 1 bytes on wlan0 [t=1.000,src=n0] Send 1 bytes on wlan0

View file

@ -1,11 +1,11 @@
[t=0.000,src=n0] Send 1 bytes to n1 on eth0 [t=0.000,src=n0] Send 1 bytes to n1 on eth0
[t=1.000,src=n1] Receive 1 bytes on eth0 [t=1.000,src=n1] Receive 1 bytes on eth0
[t=1.000,src=n1] Received: Hello World!
[t=1.000,src=n0] Send worked! [t=1.000,src=n0] Send worked!
[t=1.000,src=n1] Received: Hello World!
[t=1.000,src=n0] Send 1 bytes to n1 on eth0 [t=1.000,src=n0] Send 1 bytes to n1 on eth0
[t=1.500,src=n0] Send failed [t=1.500,src=n0] Send failed
[t=1.500,src=n0] Send 1 bytes to n1 on eth0 [t=1.500,src=n0] Send 1 bytes to n1 on eth0
[t=2.500,src=n1] Receive 1 bytes on eth0 [t=2.500,src=n1] Receive 1 bytes on eth0
[t=2.500,src=n1] Received: Hello World!
[t=2.500,src=n0] Send worked! [t=2.500,src=n0] Send worked!
[t=2.500,src=n1] Received: Hello World!
[t=2.500,src=esds] Simulation ends [t=2.500,src=esds] Simulation ends

View file

@ -1,7 +1,7 @@
[t=0.000,src=n0] Send 1 bytes on wlan0 [t=0.000,src=n0] Send 1 bytes on wlan0
[t=1.000,src=n1] Receive 1 bytes on wlan0 [t=1.000,src=n1] Receive 1 bytes on wlan0
[t=1.000,src=n1] Received: Hello World!
[t=1.000,src=n2] Receive 1 bytes on wlan0 [t=1.000,src=n2] Receive 1 bytes on wlan0
[t=1.000,src=n1] Received: Hello World!
[t=1.000,src=n2] Received: Hello World! [t=1.000,src=n2] Received: Hello World!
[t=1.000,src=n0] Send 1 bytes on wlan0 [t=1.000,src=n0] Send 1 bytes on wlan0
[t=1.500,src=esds] Simulation ends [t=1.500,src=esds] Simulation ends