11
11
import logging
12
12
13
13
14
+ class PtfAgent :
15
+ def __init__ (self , ptf_ip , ptf_ipv6 , ptf_nn_port , device_num , ptf_port_set ):
16
+ self .ptf_ip = ptf_ip
17
+ self .ptf_ipv6 = ptf_ipv6
18
+ self .ptf_nn_port = ptf_nn_port
19
+ self .device_num = device_num
20
+ self .ptf_port_set = ptf_port_set
21
+
22
+
14
23
class PtfAdapterNNConnectionError (Exception ):
15
24
16
25
def __init__ (self , remote_sock_addr ):
@@ -30,21 +39,17 @@ class PtfTestAdapter(BaseTest):
30
39
# the number of currently established connections
31
40
NN_STAT_CURRENT_CONNECTIONS = 201
32
41
33
- def __init__ (self , ptf_ip , ptf_ipv6 , ptf_nn_port , device_num , ptf_port_set , ptfhost ):
42
+ def __init__ (self , ptfagents , ptfhosts ):
34
43
""" initialize PtfTestAdapter
35
- :param ptf_ip: PTF host IP
36
- :param ptf_ipv6: PTF host IPv6 address
37
- :param ptf_nn_port: PTF nanomessage agent port
38
- :param device_num: device number
39
- :param ptf_port_set: PTF ports
40
- :return:
41
44
"""
42
45
self .runTest = lambda : None # set a no op runTest attribute to satisfy BaseTest interface
43
46
super (PtfTestAdapter , self ).__init__ ()
44
47
self .payload_pattern = ""
45
48
self .connected = False
46
- self .ptfhost = ptfhost
47
- self ._init_ptf_dataplane (ptf_ip , ptf_ipv6 , ptf_nn_port , device_num , ptf_port_set )
49
+ self .ptfhosts = ptfhosts
50
+ self .ptfagents = ptfagents
51
+ self .ptf_port_set = [k for a in ptfagents for k in a .ptf_port_set .keys ()]
52
+ self ._init_ptf_dataplane ()
48
53
49
54
def __enter__ (self ):
50
55
""" enter in 'with' block """
@@ -65,42 +70,33 @@ def _check_ptf_nn_agent_availability(self, socket_addr):
65
70
finally :
66
71
sock .close ()
67
72
68
- def _init_ptf_dataplane (self , ptf_ip , ptf_ipv6 , ptf_nn_port , device_num , ptf_port_set , ptf_config = None ):
73
+ def _init_ptf_dataplane (self , ptf_config = None ):
69
74
"""
70
75
initialize ptf framework and establish connection to ptf_nn_agent
71
76
running on PTF host
72
- :param ptf_ip: PTF host IP
73
- :param ptf_ipv6: PTF host IPv6 address
74
- :param ptf_nn_port: PTF nanomessage agent port
75
- :param device_num: device number
76
- :param ptf_port_set: PTF ports
77
77
:return:
78
78
"""
79
- self .ptf_ip = ptf_ip
80
- self .ptf_ipv6 = ptf_ipv6
81
- self .ptf_nn_port = ptf_nn_port
82
- self .device_num = device_num
83
- self .ptf_port_set = ptf_port_set
84
79
self .connected = False
85
80
86
81
ptfutils .default_timeout = self .DEFAULT_PTF_TIMEOUT
87
82
ptfutils .default_negative_timeout = self .DEFAULT_PTF_NEG_TIMEOUT
88
83
89
- ptf_nn_sock_addr = 'tcp://{}:{}' .format (ptf_ip , ptf_nn_port )
90
-
91
84
ptf .config .update ({
92
85
'platform' : 'nn' ,
93
- 'device_sockets' : [
94
- (device_num , ptf_port_set , ptf_nn_sock_addr )
95
- ],
86
+ 'device_sockets' : [],
96
87
'qlen' : self .DEFAULT_PTF_QUEUE_LEN ,
97
88
'relax' : True ,
98
89
})
90
+
99
91
if ptf_config is not None :
100
92
ptf .config .update (ptf_config )
101
93
102
- if not self ._check_ptf_nn_agent_availability (ptf_nn_sock_addr ):
103
- raise PtfAdapterNNConnectionError (ptf_nn_sock_addr )
94
+ for ptfagent in self .ptfagents :
95
+ ptf_nn_sock_addr = 'tcp://{}:{}' .format (ptfagent .ptf_ip , ptfagent .ptf_nn_port )
96
+ ptf .config ['device_sockets' ].append ((ptfagent .device_num , ptfagent .ptf_port_set , ptf_nn_sock_addr ))
97
+
98
+ if not self ._check_ptf_nn_agent_availability (ptf_nn_sock_addr ):
99
+ raise PtfAdapterNNConnectionError (ptf_nn_sock_addr )
104
100
105
101
# update ptf.config based on NN platform and create dataplane instance
106
102
nn .platform_config_update (ptf .config )
@@ -112,6 +108,26 @@ def _init_ptf_dataplane(self, ptf_ip, ptf_ipv6, ptf_nn_port, device_num, ptf_por
112
108
device_id , port_id = id
113
109
ptf .dataplane_instance .port_add (ifname , device_id , port_id )
114
110
self .connected = True
111
+ ptf .dataplane_instance .port_device_map = {p : d for d , p in ptf .dataplane_instance .ports .keys ()}
112
+ ptf .dataplane_instance .port_to_device = lambda port : ptf .dataplane_instance .port_device_map [port ]
113
+ ptf .dataplane_instance .port_to_tuple = lambda port : (ptf .dataplane_instance .port_device_map [port ], port )
114
+ ptf .dataplane_instance ._poll = ptf .dataplane_instance .poll
115
+ ptf .dataplane_instance .poll = lambda device_number , port_number = None , timeout = None , exp_pkt = None , filters = []: \
116
+ ptf .dataplane_instance ._poll (
117
+ ptf .dataplane_instance .port_to_device (port_number )
118
+ if port_number is not None else device_number if device_number is not None else None ,
119
+ port_number ,
120
+ timeout ,
121
+ exp_pkt ,
122
+ filters
123
+ )
124
+ ptf .dataplane_instance ._send = ptf .dataplane_instance .send
125
+ ptf .dataplane_instance .send = lambda device_number , port_number , packet : \
126
+ ptf .dataplane_instance ._send (
127
+ ptf .dataplane_instance .port_to_device (port_number ),
128
+ port_number ,
129
+ packet
130
+ )
115
131
self .dataplane = ptf .dataplane_instance
116
132
117
133
def kill (self ):
@@ -136,12 +152,12 @@ def reinit(self, ptf_config=None):
136
152
137
153
# Restart ptf_nn_agent to close any TCP connection from the server side
138
154
logging .info ("Restarting ptf_nn_agent" )
139
- self .ptfhost .command ('supervisorctl reread' )
140
- self .ptfhost .command ('supervisorctl update' )
141
- self .ptfhost .command ('supervisorctl restart ptf_nn_agent' )
155
+ for ptfhost in self .ptfhosts :
156
+ ptfhost .command ('supervisorctl reread' )
157
+ ptfhost .command ('supervisorctl update' )
158
+ ptfhost .command ('supervisorctl restart ptf_nn_agent' )
142
159
143
- self ._init_ptf_dataplane (self .ptf_ip , self .ptf_ipv6 , self .ptf_nn_port ,
144
- self .device_num , self .ptf_port_set , ptf_config )
160
+ self ._init_ptf_dataplane (ptf_config )
145
161
146
162
def update_payload (self , pkt ):
147
163
"""Update the payload of packet to the default pattern when certain conditions are met.
0 commit comments