Skip to content

Commit

Permalink
Eliminate support for cgroups-based throttling and rely on dev tools …
Browse files Browse the repository at this point in the history
…for 100% of throttling for mobile emulation.
  • Loading branch information
Patrick Meenan committed Jul 22, 2020
1 parent 97803c6 commit f7fe0d6
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 93 deletions.
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,6 @@ run the agent in a docker container.
* netem,\<interface\> - Use NetEm for bridging rndis traffic (specify outbound interface). i.e. --shaper netem,eth0
* remote,\<server\>,\<down pipe\>,\<up pipe\> - Connect to the remote server over ssh and use pre-configured dummynet pipes (ssh keys for root user should be pre-authorized).

### CPU Throttling
* **--throttle**: Enable cgroup-based CPU throttling for mobile emulation (Linux only).

### Android testing options
* **--android** : Run tests on an attached android device.
* **--device** : Device ID (only needed if more than one android device attached).
Expand Down
70 changes: 0 additions & 70 deletions internal/desktop_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,6 @@ def find_default_interface(self):

def launch_browser(self, command_line):
"""Launch the browser and keep track of the process"""
if not self.job['lighthouse_config'] or not self.task['running_lighthouse']:
# Only enable CPU throttling for Lighthouse runs if a custom config was not provided
command_line = self.enable_cpu_throttling(command_line)
logging.debug(command_line)
if platform.system() == 'Windows':
self.proc = subprocess.Popen(command_line, shell=True)
Expand Down Expand Up @@ -315,7 +312,6 @@ def stop(self, job, task):
self.recording = False
logging.debug("Stopping browser")
self.close_browser(job, task)
self.disable_cpu_throttling()
self.restore_hosts()
# Clean up the downloads folder in case anything was downloaded
if platform.system() == 'Linux':
Expand Down Expand Up @@ -504,7 +500,6 @@ def on_start_recording(self, task):
self.thread = threading.Thread(target=self.background_thread)
self.thread.daemon = True
self.thread.start()
self.start_cpu_throttling()

def on_stop_capture(self, task):
"""Do any quick work to stop things that are capturing data"""
Expand Down Expand Up @@ -533,7 +528,6 @@ def on_stop_capture(self, task):

def on_stop_recording(self, task):
"""Notification that we are done with recording"""
self.stop_cpu_throttling()
import psutil
if self.cpu_start is not None:
cpu_end = psutil.cpu_times()
Expand Down Expand Up @@ -749,67 +743,3 @@ def background_thread(self):
else:
self.ffmpeg.terminate()
self.usage_queue.put(None)

def enable_cpu_throttling(self, command_line):
"""Prepare the CPU throttling if necessary"""
if self.options.throttle and 'throttle_cpu' in self.job:
logging.debug('Preparing cgroups CPU Throttle (not enabled yet) target: %0.3fx', self.job['throttle_cpu'])
if self.options.throttle and 'throttle_cpu' in self.job and \
self.job['throttle_cpu'] > 1:
try:
import getpass
uid = '{0}:{0}'.format(getpass.getuser())
cmd = ['sudo', 'cgcreate', '-a', uid, '-t', uid, '-g', 'cpu,cpuset:wptagent']
logging.debug(' '.join(cmd))
subprocess.check_call(cmd)
cmd = ['sudo', 'cgset', '-r', 'cpuset.cpus="0"', 'wptagent']
logging.debug(' '.join(cmd))
subprocess.check_call(cmd)
cmd = ['sudo', 'cgset', '-r', 'cpu.cfs_period_us=1000', 'wptagent']
logging.debug(' '.join(cmd))
subprocess.check_call(cmd)
cmd = ['sudo', 'cgset', '-r', 'cpu.cfs_quota_us=1000', 'wptagent']
logging.debug(' '.join(cmd))
subprocess.check_call(cmd)
command_line = 'cgexec -g cpu:wptagent ' + command_line
except Exception as err:
logging.exception("Exception enabling throttling: %s", err.__str__())
self.throttling_cpu = True
return command_line

def disable_cpu_throttling(self):
"""Remove the CPU throttling if necessary"""
if self.throttling_cpu:
logging.debug("Disabling cgroup CPU throttling")
try:
cmd = ['sudo', 'cgdelete', '-r', 'cpu,cpuset:wptagent']
logging.debug(' '.join(cmd))
subprocess.check_call(cmd)
except Exception:
logging.exception('Error disabling throttling')

def start_cpu_throttling(self):
"""Start the CPU throttling if necessary"""
if self.options.throttle and 'throttle_cpu' in self.job:
self.task['page_data']['throttle_cpu_requested'] = self.job['throttle_cpu_requested']
if self.throttling_cpu:
logging.debug("Starting cgroup CPU throttling target: %0.3fx", self.job['throttle_cpu'])
self.task['page_data']['throttle_cpu'] = self.job['throttle_cpu']
try:
# Leave the quota at 1000 and vary the period to get to the correct multiplier
period = int(round(1000.0 * self.job['throttle_cpu']))
cmd = ['sudo', 'cgset', '-r', 'cpu.cfs_period_us={0:d}'.format(period), 'wptagent']
logging.debug(' '.join(cmd))
subprocess.check_call(cmd)
except Exception:
logging.exception('Error starting throttling')

def stop_cpu_throttling(self):
"""Start the CPU throttling if necessary"""
if self.throttling_cpu:
try:
cmd = ['sudo', 'cgset', '-r', 'cpu.cfs_period_us=1000', 'wptagent']
logging.debug(' '.join(cmd))
subprocess.check_call(cmd)
except Exception:
logging.exception('Error stopping throttling')
13 changes: 5 additions & 8 deletions internal/devtools_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,10 @@ def prepare_browser(self, task):
wait=True)

# DevTools-based CPU throttling for desktop and emulated mobile tests
# This throttling should only be applied for:
# 1. Normal test runs where cgroups throttling (--throttle) is disabled
# 2. Lighthouse test runs where a custom config path is not specified
if not self.options.android and \
(task['running_lighthouse'] or not self.options.throttle) and \
(not task['running_lighthouse'] or not self.job['lighthouse_config']) and \
'throttle_cpu' in self.job:
# This throttling should only be applied for lighthouse test runs where
# a custom config path is not specified
if not self.options.android and 'throttle_cpu' in self.job and\
(not task['running_lighthouse'] or not self.job['lighthouse_config']):
logging.debug('DevTools CPU Throttle target: %0.3fx', self.job['throttle_cpu'])
if self.job['throttle_cpu'] > 1:
self.devtools.send_command("Emulation.setCPUThrottlingRate",
Expand Down Expand Up @@ -179,7 +176,7 @@ def on_start_recording(self, task):
if self.browser_version is not None and 'browserVersion' not in task['page_data']:
task['page_data']['browserVersion'] = self.browser_version
task['page_data']['browser_version'] = self.browser_version
if not self.options.throttle and 'throttle_cpu' in self.job:
if 'throttle_cpu' in self.job:
task['page_data']['throttle_cpu_requested'] = self.job['throttle_cpu_requested']
if self.job['throttle_cpu'] > 1:
task['page_data']['throttle_cpu'] = self.job['throttle_cpu']
Expand Down
12 changes: 0 additions & 12 deletions wptagent.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,13 +395,6 @@ def startup(self, detected_browsers):
elif platform.system() == "Windows":
self.capture_display = 'desktop'

if self.options.throttle:
try:
subprocess.check_output('sudo cgset -h', shell=True)
except Exception:
print("Missing cgroups, make sure cgroup-tools is installed.")
ret = False

# Fix Lighthouse install permissions
if platform.system() != "Windows" and sys.version_info < (3, 0):
from internal.os_util import run_elevated
Expand Down Expand Up @@ -884,11 +877,6 @@ def main():
'should be pre-authorized).')
parser.add_argument('--tcpdump', help='Specify an interface to use for tcpdump.')

# CPU Throttling
parser.add_argument('--throttle', action='store_true', default=False,
help='Enable cgroup-based CPU throttling for mobile emulation '
'(Linux only).')

# Android options
parser.add_argument('--android', action='store_true', default=False,
help="Run tests on an attached android device.")
Expand Down

3 comments on commit f7fe0d6

@wildlyinaccurate
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this remove CPU throttling support for Firefox?

@pmeenan
Copy link
Contributor

@pmeenan pmeenan commented on f7fe0d6 Jul 23, 2020 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Mutebifred
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am very happy. Thank you.

Please sign in to comment.