On Mon, Apr 20, 2009 at 11:56 AM, Luca Dionisi <[email protected]> wrote:
> I built a rudimentary test suite [1] for the exec_etp method of Etp class.
>
> When I run the test I obtain the attached output [2].
>
> Assume a simple network, composed by nodes belonging to the same gnode.
> Let theirs IP be 192.168.1.*
> Assume this topology
> 9 <---> 1 <---> 15 <---> 4
> RTT(9,1) = 55
> RTT(1,15) = 123
> RTT(15,4) = 100
>
> Suppose that node 15, which already knows a route towards 4, detects
> the link towards 1 and produces a ETP and sends it to 1.
> At this moment, the test suite examines the ETP processing done by
> node 1 and then by node 9.
>
> What appears from the output is that the resulting maproutes are wrong.
> Before doing some deeper debug, I would like to ask what are the
> expected results.
>
> 1)
> The portion R of the ETP forwarded through the chain of nodes, does
> not change. I could assume that it always represents the portion of
> map how it is seen by the first producer of the ETP. The receiver of
> the ETP may know who the first producer is, and how far it is from
> him, by reading the TPL.
> Is this right? Or should the portion R change?
>
> 2)
> The node 1 changed its maproute appropriately.
> It has updated it basing on R. The TPL part is void indeed.
>
> 3)
> The node 9 changed its maproute not appropriately.
> It has updated it basing on R + TPL. The Rems are summed in the wrong order.
>
>
> [1] attachment test_qspn.py
> [2] attachment output_test_qspn.txt
>
> --Luca Dionisi
>
Applying this [1] little patch I fixed the behavior for the previous
topology, where all nodes belong to the same gnode of level 1.
Now the attached [2] test suite, with new nodes from other gnodes,
produces attached log [3]
Note that when node 10.0.0.1 processes the ETP and forwards it, the
REM 178 (useless) is retained, while the REM 40 (its link with
192.168.1.9) is discarded.
I think that in the TPL the only rem set to None should be in the
first pair of the first block. And that the first pair of the other
blocks should contain the REM for the link towards the previous block.
Am I right?
[1] revert_sum_rem.patch
[2] attachment test_qspn.py
[3] attachment output_test_qspn.txt
--Luca
_____________________________________________________
I am (maproute.me)
[1, 1, 168, 192]
I know these routes (maproute.bestroutes_get)
Empty
I received from [15, 1, 168, 192] , which is my neighbour through ('eth0', 123)
, this ETP:
R =
L 3
Empty
L 2
Empty
L 1
Empty
L 0
dst = 4 , rem = 100
TPL =
Level 0
hop = 15 , rem = None
flag_of_interest = 1
processing...
Now, I know these routes (maproute.bestroutes_get):
Towards [4, 1, 168, 192] gateway [15L, 1L, 168L, 192L] rem value 223
Towards [15, 1, 168, 192] gateway [15L, 1L, 168L, 192L] rem value 123
and I will forward this ETP:
R =
L 3
Empty
L 2
Empty
L 1
Empty
L 0
dst = 4 , rem = 100
TPL =
Level 0
hop = 15 , rem = None
hop = 1 , rem = 123
flag_of_interest = 1
to all neighbours except: [15L, 1L, 168L, 192L]
_____________________________________________________
I am (maproute.me)
[9, 1, 168, 192]
I know these routes (maproute.bestroutes_get)
Empty
I received from [1, 1, 168, 192] , which is my neighbour through ('eth0', 55) ,
this ETP:
R =
L 3
Empty
L 2
Empty
L 1
Empty
L 0
dst = 4 , rem = 100
TPL =
Level 0
hop = 15 , rem = None
hop = 1 , rem = 123
flag_of_interest = 1
processing...
Now, I know these routes (maproute.bestroutes_get):
Towards [1, 1, 168, 192] gateway [1L, 1L, 168L, 192L] rem value 55
Towards [4, 1, 168, 192] gateway [1L, 1L, 168L, 192L] rem value 278
Towards [15, 1, 168, 192] gateway [1L, 1L, 168L, 192L] rem value 178
and I will forward this ETP:
R =
L 3
Empty
L 2
Empty
L 1
Empty
L 0
dst = 4 , rem = 100
TPL =
Level 0
hop = 15 , rem = None
hop = 1 , rem = 123
hop = 9 , rem = 55
flag_of_interest = 1
to all neighbours except: [1L, 1L, 168L, 192L]
_____________________________________________________
I am (maproute.me)
[1, 0, 0, 10]
I know these routes (maproute.bestroutes_get)
Empty
I received from [9, 1, 168, 192] , which is my neighbour through ('eth1', 40) ,
this ETP:
R =
L 3
Empty
L 2
Empty
L 1
Empty
L 0
dst = 4 , rem = 100
TPL =
Level 0
hop = 15 , rem = None
hop = 1 , rem = 123
hop = 9 , rem = 55
flag_of_interest = 1
processing...
Now, I know these routes (maproute.bestroutes_get):
Towards ['*', '*', '*', 192] gateway [9L, 1L, 168L, 192L] rem value 40
and I will forward this ETP:
R =
L 3
Empty
L 2
Empty
L 1
Empty
L 0
Empty
TPL =
Level 3
hop = 192 , rem = 178
Level 0
hop = 1 , rem = None
flag_of_interest = 1
to all neighbours except: [9L, 1L, 168L, 192L]
_____________________________________________________
I am (maproute.me)
[9, 1, 0, 10]
I know these routes (maproute.bestroutes_get)
Empty
I received from [1, 0, 0, 10] , which is my neighbour through ('eth1', 74) ,
this ETP:
R =
L 3
Empty
L 2
Empty
L 1
Empty
L 0
Empty
TPL =
Level 3
hop = 192 , rem = 178
Level 0
hop = 1 , rem = None
flag_of_interest = 1
processing...
Now, I know these routes (maproute.bestroutes_get):
Towards ['*', 0, 0, 10] gateway [1, 0, 0, 10L] rem value 252
Towards ['*', '*', '*', 192] gateway [1, 0, 0, 10L] rem value 74
and I will forward this ETP:
R =
L 3
Empty
L 2
Empty
L 1
Empty
L 0
Empty
TPL =
Level 3
hop = 192 , rem = 178
Level 1
hop = 0 , rem = None
Level 0
hop = 9 , rem = None
flag_of_interest = 1
to all neighbours except: [1, 0, 0, 10L]
Index: pyntk/ntk/core/qspn.py
===================================================================
--- pyntk/ntk/core/qspn.py (revision 1572)
+++ pyntk/ntk/core/qspn.py (working copy)
@@ -204,11 +204,13 @@
tprem=gwrem
TPL_is_interesting=0
for block in TPL:
- lvl=block[0]
- for dst, rem in block[1]:
- tprem+=rem # TODO: sometimes rem is an integer
+ lvl = block[0]
+ TP = block[1]
+ for i in xrange(len(TP)-1, -1, -1):
+ dst, rem = TP[i]
if self.maproute.route_change(lvl, dst, gw, tprem):
TPL_is_interesting+=1
+ tprem+=rem # TODO: sometimes rem is an integer
##
## Update the map from R
# -*- coding: iso-8859-1 -*-
##
# This file is part of Netsukuku
# (c) Copyright 2009 Luca Dionisi
#
# This source code is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation; either version 2 of the License,
# or (at your option) any later version.
#
# This source code is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# Please refer to the GNU Public License for more details.
#
# You should have received a copy of the GNU Public License along with
# this source code; if not, write to:
# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##
#
# Tests for ntk.core.qspn
#
import unittest
import sys
sys.path.append('..')
############## To avoid using tasklets in the test-suite
import functools
def fake_microfunc(is_micro=False, is_atomic=False):
def decorate(func):
@functools.wraps(func)
def launch(*data):
func(*data)
return launch
return decorate
import ntk.lib.micro
ntk.lib.micro.microfunc = fake_microfunc
##################
############# To avoid using sockets in the test-suite
class fake_TCPClient:
def __init__(self,
host='localhost',
port=269,
net=None,
me=None,
sockmodgen=None,
xtimemod=None):
pass
import ntk.lib.rpc
ntk.lib.rpc.TCPClient = fake_TCPClient
###########################
import ntk.core.radar as radar
import ntk.core.route as maproute
import ntk.core.qspn as qspn
import ntk.wrap.xtime as xtime
def print_etp_r(R):
for i in xrange(3, -1, -1):
print ' L', i
Li = R[i]
if len(Li) == 0:
print ' Empty'
for j in xrange(len(Li)):
tuplej = Li[j]
print ' dst =', tuplej[0], ', rem =', tuplej[1].value
def print_etp_tpl(TPL):
for i in xrange(len(TPL)):
block = TPL[i]
lvl = block[0]
TP = block[1]
print ' Level', lvl
for j in xrange(len(TP)):
pair = TP[j]
hop = pair[0]
rem = pair[1]
print ' hop =', hop, ', rem =', rem.value
def print_etp(etp):
print ' R ='
R = etp[0]
print_etp_r(R)
print ' TPL ='
TPL = etp[1]
print_etp_tpl(TPL)
print ' flag_of_interest =', etp[2]
class TestEtp(unittest.TestCase):
def setUp(self):
self.levels = 4
self.gsize = 256
def print_best_routes(self, LL):
if qspn.is_listlist_empty(LL):
print ' Empty'
else:
for i in xrange(4):
L = LL[i]
last_part = []
if i < 3 : last_part = self.maproute.me[i-3:]
for j in xrange(len(L)):
route = L[j]
route_id = route[0]
route_gw = route[1]
route_rem = route[2]
towards = []
towards += ['*']*(i)
towards.append(route_id)
towards += last_part[:]
gwnip = self.maproute.ip_to_nip(self.radar.neigh.id_to_ip(route_gw))
print ' Towards', towards, 'gateway', gwnip, 'rem value', route_rem.value
def fake_etp_forward(self, etp, exclude):
print 'Now, I know these routes (maproute.bestroutes_get):'
self.print_best_routes(self.maproute.bestroutes_get())
print 'and I will forward this ETP:'
print_etp(etp)
print 'to all neighbours except:',
for excluding in exclude:
print self.maproute.ip_to_nip(self.radar.neigh.id_to_ip(excluding)),
print
print
self.next_etp = etp
def fake_etp_exec(self, sender_nip, R, TPL, flag_of_interest):
print sender_nip, R, TPL, flag_of_interest
def introduce_yourself(self):
print
print '_____________________________________________________'
print 'I am (maproute.me)'
print ' ', self.maproute.me
print
print 'I know these routes (maproute.bestroutes_get)'
self.print_best_routes(self.maproute.bestroutes_get())
print
def process_etp(self):
print 'I received from', self.sender_nip, ', which is my neighbour through',
print self.radar.neigh.ip_to_neigh(self.maproute.nip_to_ip(self.sender_nip)).bestdev, ', this ETP:'
print_etp(self.next_etp)
print
print 'processing...'
print
self.etp.etp_exec(self.sender_nip, *self.next_etp)
def testEtpExec(self):
'''Test etp propagation'''
# I am 192.168.1.1 and have this neighbour 192.168.1.15
self.radar = radar.Radar(self, xtime) #passing self instead of bcastclient, to replace the remote calls to equivalent local methods
self.maproute = maproute.MapRoute(self.levels, self.gsize, [1, 1, 168, 192])
self.sender_nip = [15, 1, 168, 192]
ip_neigh = self.maproute.nip_to_ip(self.sender_nip)
self.radar.neigh.netid_table[ip_neigh] = -1
ip_table = {}
devs_neigh = [('eth0', 123)]
ip_table[ip_neigh] = radar.Neigh(bestdev=devs_neigh[0], devs=dict(devs_neigh))
self.radar.neigh.store(ip_table)
self.radar.neigh.ntk_client[ip_neigh] = self # instead of rpc.TCPClient(ip_to_str(key), xtimemod=self.xtime)
self.etp = qspn.Etp(self.radar, self.maproute)
self.etp.etp_forward = self.fake_etp_forward
#self.etp.etp_exec = self.fake_etp_exec
self.introduce_yourself()
# Preparing a first etp. It will "be sent" to me from my neighbour 192.168.1.15
L0 = [(4, maproute.Rtt(100))]
# This route towards host with ID 4 of level 0, that is 192.168.1.4, ...
R = [L0, [], [], []] # is the only known route for host 15.
flag_of_interest=1
TP = [[15, maproute.NullRem()]] # the etp is sent to me from 192.168.1.15
self.next_etp = (R, [[0, TP]], flag_of_interest)
self.process_etp()
# I am 192.168.1.9 and have this neighbour 192.168.1.1
self.radar = radar.Radar(self, xtime) #passing self instead of bcastclient, to replace the remote calls to equivalent local methods
self.maproute = maproute.MapRoute(self.levels, self.gsize, [9, 1, 168, 192])
self.sender_nip = [1, 1, 168, 192]
ip_neigh = self.maproute.nip_to_ip(self.sender_nip)
self.radar.neigh.netid_table[ip_neigh] = -1
ip_table = {}
devs_neigh = [('eth0', 55)]
ip_table[ip_neigh] = radar.Neigh(bestdev=devs_neigh[0], devs=dict(devs_neigh))
self.radar.neigh.store(ip_table)
self.radar.neigh.ntk_client[ip_neigh] = self # instead of rpc.TCPClient(ip_to_str(key), xtimemod=self.xtime)
self.etp = qspn.Etp(self.radar, self.maproute)
self.etp.etp_forward = self.fake_etp_forward
#self.etp.etp_exec = self.fake_etp_exec
self.introduce_yourself()
self.process_etp()
# I am 10.0.0.1 and have this neighbour 192.168.1.9
self.radar = radar.Radar(self, xtime) #passing self instead of bcastclient, to replace the remote calls to equivalent local methods
self.maproute = maproute.MapRoute(self.levels, self.gsize, [1, 0, 0, 10])
self.sender_nip = [9, 1, 168, 192]
ip_neigh = self.maproute.nip_to_ip(self.sender_nip)
self.radar.neigh.netid_table[ip_neigh] = -1
ip_table = {}
devs_neigh = [('eth1', 40)]
ip_table[ip_neigh] = radar.Neigh(bestdev=devs_neigh[0], devs=dict(devs_neigh))
self.radar.neigh.store(ip_table)
self.radar.neigh.ntk_client[ip_neigh] = self # instead of rpc.TCPClient(ip_to_str(key), xtimemod=self.xtime)
self.etp = qspn.Etp(self.radar, self.maproute)
self.etp.etp_forward = self.fake_etp_forward
#self.etp.etp_exec = self.fake_etp_exec
self.introduce_yourself()
self.process_etp()
# I am 10.0.1.9 and have this neighbour 10.0.0.1
self.radar = radar.Radar(self, xtime) #passing self instead of bcastclient, to replace the remote calls to equivalent local methods
self.maproute = maproute.MapRoute(self.levels, self.gsize, [9, 1, 0, 10])
self.sender_nip = [1, 0, 0, 10]
ip_neigh = self.maproute.nip_to_ip(self.sender_nip)
self.radar.neigh.netid_table[ip_neigh] = -1
ip_table = {}
devs_neigh = [('eth1', 74)]
ip_table[ip_neigh] = radar.Neigh(bestdev=devs_neigh[0], devs=dict(devs_neigh))
self.radar.neigh.store(ip_table)
self.radar.neigh.ntk_client[ip_neigh] = self # instead of rpc.TCPClient(ip_to_str(key), xtimemod=self.xtime)
self.etp = qspn.Etp(self.radar, self.maproute)
self.etp.etp_forward = self.fake_etp_forward
#self.etp.etp_exec = self.fake_etp_exec
self.introduce_yourself()
self.process_etp()
if __name__ == '__main__':
unittest.main()
_______________________________________________
Netsukuku mailing list
[email protected]
http://lists.dyne.org/mailman/listinfo/netsukuku