1# Copyright 2019 The Matrix.org Foundation C.I.C. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14import sys 15from argparse import REMAINDER 16from contextlib import redirect_stderr 17from io import StringIO 18 19import pyperf 20 21from twisted.internet.defer import Deferred, ensureDeferred 22from twisted.logger import globalLogBeginner, textFileLogObserver 23from twisted.python.failure import Failure 24 25from synmark import make_reactor 26from synmark.suites import SUITES 27 28from tests.utils import setupdb 29 30 31def make_test(main): 32 """ 33 Take a benchmark function and wrap it in a reactor start and stop. 34 """ 35 36 def _main(loops): 37 38 reactor = make_reactor() 39 40 file_out = StringIO() 41 with redirect_stderr(file_out): 42 43 d = Deferred() 44 d.addCallback(lambda _: ensureDeferred(main(reactor, loops))) 45 46 def on_done(_): 47 if isinstance(_, Failure): 48 _.printTraceback() 49 print(file_out.getvalue()) 50 reactor.stop() 51 return _ 52 53 d.addBoth(on_done) 54 reactor.callWhenRunning(lambda: d.callback(True)) 55 reactor.run() 56 57 return d.result 58 59 return _main 60 61 62if __name__ == "__main__": 63 64 def add_cmdline_args(cmd, args): 65 if args.log: 66 cmd.extend(["--log"]) 67 cmd.extend(args.tests) 68 69 runner = pyperf.Runner( 70 processes=3, min_time=1.5, show_name=True, add_cmdline_args=add_cmdline_args 71 ) 72 runner.argparser.add_argument("--log", action="store_true") 73 runner.argparser.add_argument("tests", nargs=REMAINDER) 74 runner.parse_args() 75 76 orig_loops = runner.args.loops 77 runner.args.inherit_environ = ["SYNAPSE_POSTGRES"] 78 79 if runner.args.worker: 80 if runner.args.log: 81 globalLogBeginner.beginLoggingTo( 82 [textFileLogObserver(sys.__stdout__)], redirectStandardIO=False 83 ) 84 setupdb() 85 86 if runner.args.tests: 87 SUITES = list( 88 filter(lambda x: x[0].__name__.split(".")[-1] in runner.args.tests, SUITES) 89 ) 90 91 for suite, loops in SUITES: 92 if loops: 93 runner.args.loops = loops 94 else: 95 runner.args.loops = orig_loops 96 loops = "auto" 97 runner.bench_time_func( 98 suite.__name__ + "_" + str(loops), 99 make_test(suite.main), 100 ) 101