@@ -24,6 +24,8 @@ def __init__(self, options, root_path):
24
24
if shaper_name is not None :
25
25
if shaper_name == 'none' :
26
26
self .shaper = NoShaper ()
27
+ elif shaper_name == 'chrome' :
28
+ self .shaper = ChromeShaper ()
27
29
elif shaper_name [:5 ] == 'netem' :
28
30
parts = shaper_name .split (',' )
29
31
if_out = parts [1 ].strip () if len (parts ) > 1 else None
@@ -111,6 +113,20 @@ def configure(self, job, task):
111
113
job ['interface' ] = self .shaper .interface
112
114
return ret
113
115
116
+ def set_devtools (self , devtools ):
117
+ """Configure the devtools interface for the shaper (Chrome-only)"""
118
+ try :
119
+ self .shaper .set_devtools (devtools )
120
+ except Exception :
121
+ logging .exception ('Error setting shaper devtools interface' )
122
+ return
123
+
124
+ def apply (self , target_id = None ):
125
+ """Apply the traffic-shaping for Chrome"""
126
+ try :
127
+ self .shaper .apply (target_id )
128
+ except Exception :
129
+ logging .exception ('Error applying traffic shaping' )
114
130
115
131
#
116
132
# NoShaper
@@ -137,6 +153,64 @@ def configure(self, in_bps, out_bps, rtt, plr, shaperLimit):
137
153
if in_bps > 0 or out_bps > 0 or rtt > 0 or plr > 0 or shaperLimit > 0 :
138
154
return False
139
155
return True
156
+
157
+ def set_devtools (self , devtools ):
158
+ """Stub for configuring the devtools interface"""
159
+ return
160
+
161
+ def apply (self , target_id ):
162
+ """Stub for applying Chrome traffic-shaping"""
163
+ return
164
+ #
165
+ # ChromeShaper
166
+ #
167
+ class ChromeShaper (object ):
168
+ """Allow resets but fail any explicit shaping"""
169
+ def __init__ (self ):
170
+ self .interface = None
171
+ self .devtools = None
172
+ self .rtt = 0
173
+ self .in_Bps = - 1
174
+ self .out_Bps = - 1
175
+
176
+ def install (self ):
177
+ """Install and configure the traffic-shaper"""
178
+ return True
179
+
180
+ def remove (self ):
181
+ """Uninstall traffic-shaping"""
182
+ return True
183
+
184
+ def reset (self ):
185
+ """Disable traffic-shaping"""
186
+ self .rtt = 0
187
+ self .in_Bps = - 1
188
+ self .out_Bps = - 1
189
+ self .apply ()
190
+ return True
191
+
192
+ def configure (self , in_bps , out_bps , rtt , plr , shaperLimit ):
193
+ """Enable traffic-shaping"""
194
+ self .rtt = rtt
195
+ self .in_Bps = in_bps / 8
196
+ self .out_Bps = out_bps / 8
197
+ self .apply ()
198
+ return True
199
+
200
+ def set_devtools (self , devtools ):
201
+ """Stub for configuring the devtools interface"""
202
+ self .devtools = devtools
203
+
204
+ def apply (self , target_id = None ):
205
+ """Stub for applying Chrome traffic-shaping"""
206
+ if self .devtools is not None :
207
+ self .devtools .send_command ('Network.emulateNetworkConditions' , {
208
+ 'offline' : False ,
209
+ 'latency' : self .rtt ,
210
+ 'downloadThroughput' : self .in_Bps ,
211
+ 'uploadThroughput' : self .out_Bps
212
+ }, wait = True , target_id = target_id )
213
+ return
140
214
141
215
#
142
216
# winshaper
@@ -180,6 +254,14 @@ def configure(self, in_bps, out_bps, rtt, plr, shaperLimit):
180
254
'inbuff={0:d}' .format (int (self .in_buff )),
181
255
'outbuff={0:d}' .format (int (self .out_buff ))])
182
256
257
+ def set_devtools (self , devtools ):
258
+ """Stub for configuring the devtools interface"""
259
+ return
260
+
261
+ def apply (self , target_id ):
262
+ """Stub for applying Chrome traffic-shaping"""
263
+ return
264
+
183
265
#
184
266
# Dummynet
185
267
#
@@ -273,6 +355,14 @@ def configure(self, in_bps, out_bps, rtt, plr, shaperLimit):
273
355
self .ipfw (in_queue_command ) and \
274
356
self .ipfw (out_queue_command )
275
357
358
+ def set_devtools (self , devtools ):
359
+ """Stub for configuring the devtools interface"""
360
+ return
361
+
362
+ def apply (self , target_id ):
363
+ """Stub for applying Chrome traffic-shaping"""
364
+ return
365
+
276
366
#
277
367
# MacDummynet - Dummynet through pfctl
278
368
#
@@ -375,6 +465,14 @@ def configure(self, in_bps, out_bps, rtt, plr, shaperLimit):
375
465
return self .dnctl (in_command ) and \
376
466
self .dnctl (out_command )
377
467
468
+ def set_devtools (self , devtools ):
469
+ """Stub for configuring the devtools interface"""
470
+ return
471
+
472
+ def apply (self , target_id ):
473
+ """Stub for applying Chrome traffic-shaping"""
474
+ return
475
+
378
476
#
379
477
# RemoteDummynet - Remote PC running dummynet with pre-configured pipes
380
478
#
@@ -411,6 +509,14 @@ def remove(self):
411
509
"""Uninstall traffic-shaping"""
412
510
return True
413
511
512
+ def set_devtools (self , devtools ):
513
+ """Stub for configuring the devtools interface"""
514
+ return
515
+
516
+ def apply (self , target_id ):
517
+ """Stub for applying Chrome traffic-shaping"""
518
+ return
519
+
414
520
#
415
521
# netem
416
522
#
@@ -515,3 +621,11 @@ def configure_interface(self, interface, bps, latency, plr, shaperLimit):
515
621
args = self .build_command_args (interface , bps , latency , plr , shaperLimit )
516
622
logging .debug (' ' .join (args ))
517
623
return subprocess .call (args ) == 0
624
+
625
+ def set_devtools (self , devtools ):
626
+ """Stub for configuring the devtools interface"""
627
+ return
628
+
629
+ def apply (self , target_id ):
630
+ """Stub for applying Chrome traffic-shaping"""
631
+ return
0 commit comments