Add basic benchmark
Benchmark shows performance penalty rootwrap introduces compared to one of plain sudo. To run benchmark, issue: tox -e benchmark Example output: Running 'ip a': method : min avg max dev ip a : 4.185ms 4.570ms 5.657ms 187.705us sudo ip a : 13.564ms 14.437ms 28.452ms 1.470ms sudo rootwrap conf ip a : 148.839ms 192.424ms 254.043ms 19.219ms Running 'ip netns exec bench_ns ip a': method : min avg max dev sudo ip netns exec bench_ns ip a : 109.772ms 151.627ms 209.943ms 22.991ms sudo rootwrap conf ip netns exec bench_ns ip a : 289.345ms 345.471ms 463.807ms 32.873ms Change-Id: Id8e41be6602fa8dcff48a8a4ba44d35dd3043731
This commit is contained in:
parent
e2e0c03f5a
commit
196bdc0fa2
101
benchmark/benchmark.py
Normal file
101
benchmark/benchmark.py
Normal file
@ -0,0 +1,101 @@
|
||||
# Copyright (c) 2014 Mirantis Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import atexit
|
||||
import math
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import timeit
|
||||
|
||||
config_path = "rootwrap.conf"
|
||||
num_iterations = 100
|
||||
|
||||
|
||||
def run_plain(cmd):
|
||||
obj = subprocess.Popen(cmd,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
out, err = obj.communicate()
|
||||
return obj.returncode, out, err
|
||||
|
||||
|
||||
def run_sudo(cmd):
|
||||
return run_plain(["sudo"] + cmd)
|
||||
|
||||
|
||||
def run_rootwrap(cmd):
|
||||
return run_plain([
|
||||
"sudo", sys.executable, "-c",
|
||||
"from oslo.rootwrap import cmd; cmd.main()", config_path] + cmd)
|
||||
|
||||
|
||||
def run_one(runner, cmd):
|
||||
def __inner():
|
||||
code, out, err = runner(cmd)
|
||||
assert err == "", "Stderr not empty:\n" + err
|
||||
assert code == 0, "Command failed"
|
||||
return __inner
|
||||
|
||||
runners = [
|
||||
("{0}", run_plain),
|
||||
("sudo {0}", run_sudo),
|
||||
("sudo rootwrap conf {0}", run_rootwrap),
|
||||
]
|
||||
|
||||
|
||||
def get_time_string(sec):
|
||||
if sec > 0.9:
|
||||
return "{0:7.3f}s ".format(sec)
|
||||
elif sec > 0.0009:
|
||||
return "{0:7.3f}ms".format(sec * 1000.0)
|
||||
else:
|
||||
return "{0:7.3f}us".format(sec * 1000000.0)
|
||||
|
||||
|
||||
def run_bench(cmd, runners):
|
||||
strcmd = ' '.join(cmd)
|
||||
max_name_len = max(len(name) for name, _ in runners) + len(strcmd) - 3
|
||||
print("Running '{0}':".format(strcmd))
|
||||
print("{0:^{1}} :".format("method", max_name_len),
|
||||
"".join(map("{0:^10}".format, ["min", "avg", "max", "dev"])))
|
||||
for name, runner in runners:
|
||||
results = timeit.repeat(run_one(runner, cmd), repeat=num_iterations,
|
||||
number=1)
|
||||
avg = sum(results) / num_iterations
|
||||
min_ = min(results)
|
||||
max_ = max(results)
|
||||
dev = math.sqrt(sum((r - avg) ** 2 for r in results) / num_iterations)
|
||||
print("{0:>{1}} :".format(name.format(strcmd), max_name_len),
|
||||
" ".join(map(get_time_string, [min_, avg, max_, dev])))
|
||||
|
||||
|
||||
def main():
|
||||
os.chdir(os.path.dirname(__file__))
|
||||
code, _, _ = run_sudo(["-vn"])
|
||||
if code:
|
||||
print("We need you to authorize with sudo to run this benchmark")
|
||||
run_sudo(["-v"])
|
||||
|
||||
run_bench(["ip", "a"], runners)
|
||||
run_sudo(["ip", "netns", "add", "bench_ns"])
|
||||
atexit.register(run_sudo, ["ip", "netns", "delete", "bench_ns"])
|
||||
run_bench('ip netns exec bench_ns ip a'.split(), runners[1:])
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
4
benchmark/filters.d/ip.filters
Normal file
4
benchmark/filters.d/ip.filters
Normal file
@ -0,0 +1,4 @@
|
||||
[Filters]
|
||||
|
||||
ip: IpFilter, ip, root
|
||||
ip_exec: IpNetnsExecFilter, ip, root
|
4
benchmark/rootwrap.conf
Normal file
4
benchmark/rootwrap.conf
Normal file
@ -0,0 +1,4 @@
|
||||
[DEFAULT]
|
||||
filters_path=filters.d
|
||||
exec_dirs=/sbin,/usr/sbin,/bin,/usr/bin
|
||||
use_syslog=False
|
Loading…
Reference in New Issue
Block a user