diff --git a/.gitignore b/.gitignore index 906e368..474e9eb 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ vendor/ core core.* composer.phar +perf.data +processed-perf.data diff --git a/README.md b/README.md index 65f4048..fbc5097 100644 --- a/README.md +++ b/README.md @@ -26,12 +26,16 @@ As a regular user: composer.phar install # see https://getcomposer.org/download/ hhvm perf.php --wordpress --php5=/path/to/bin/php-cgi # also works with php7 + hhvm perf.php --wordpress --php=/path/to/bin/php-fpm # also works with php7 hhvm perf.php --wordpress --hhvm=/path/to/hhvm Running with --hhvm gives some additional server-side statistics. It is usual for HHVM to report more requests than siege - some frameworks do call-back requests to the current webserver. +:heavy_exclamation_mark: If you run with a debug build you may hit timeouts and +other issues. + Batch Usage =========== @@ -45,9 +49,14 @@ See batch-run.json.example to get an idea of how to create batch-run.json. Requirements ============ +On Ubuntu you can run scripts/setup.sh. This should provision your machine with +everything you need to begin running the benchmarks. + +This installs: + - composer - nginx -- siege 2.x +- siege (versions 2.x, or 3.1.x or 4.0.3) - unzip - A mysql server on 127.0.0.1:3306 - hhvm @@ -55,8 +64,9 @@ Requirements I've been using the current versions available from yum on Centos 6.3. HHVM is required as this is written in Hack. -Siege 3.x is not supported; as of writing, all 3.x releases have bugs that make -it unable to correctly make the benchmark requests. +Siege 3.0.x is not supported; as of writing, all 3.0.x releases have bugs that make +it unable to correctly make the benchmark requests. 4.0.0, 4.0.1, 4.0.2 all +automatically request resources on pages, and should not be used for benchmarking. The Targets =========== @@ -188,6 +198,8 @@ loaded to provide a slightly more rounded workload. Profiling ========= +Perf +---- perf.php can keep the suite running indefinitely: hhvm perf.php --i-am-not-benchmarking --no-time-limit --wordpress --hhvm=$HHVM_BIN @@ -195,7 +207,40 @@ perf.php can keep the suite running indefinitely: You can then attach 'perf' or another profiler to the running HHVM or php-cgi process, once the 'benchmarking' phase has started. -Direct support (especially for XHProf) is planned, but not yet implemented. +There is also a script to run perf for you at the apropriate moment: + + hhvm perf.php --i-am-not-benchmarking --wordpress --hhvm=$HHVM_BIN --exec-after-warmup="./scripts/perf.sh -e cycles" + +This will record 25 seconds of samples. To see where most time is spent you can +dive into the data using perf, or use the perf rollup script as follows: + + sudo perf script -F comm,ip,sym | hhvm -vEval.EnableHipHopSyntax=true /hphp/tools/perf-rollup.php + +In order to have all the symbols from the the translation cache you +may need to change the owner of /tmp/hhvm-.map to root. + + +TC-print +-------- +TC-print will use data from perf to determine the hotest functions and +translations. Run the benchmark as follows: + + hhvm perf.php --i-am-not-benchmarking --wordpress --hhvm=$HHVM_BIN --exec-after-warmup="./scripts/perf.sh -e cycles" --tcprint + +In order to have all the symbols from the the translation cache you +may need to change the owner of /tmp/hhvm-.map to root. + +We process the perf data before passing it along to tc-print + sudo perf script -f -F hw:comm,event,ip,sym | /hphp/tools/perf-script-raw.py > processed-perf.data + +tc-print is only built if the appropriate disassembly tools are available. On +x86 this is LibXed. Consider building hhvm using: + + cmake . -DLibXed_INCLUDE_DIR= -DLibXed_LIBRARY= + +Use tc-print with the generated perf.data: + hphp/tools/tc-print/tc-print -c /tmp//conf.hdf -p processed-perf.data + Contributing ============ diff --git a/base/BuildChecker.php b/base/BuildChecker.php index b0bd239..31103b9 100644 --- a/base/BuildChecker.php +++ b/base/BuildChecker.php @@ -39,7 +39,7 @@ public static function Check( if ($skipKeys->contains($k)) { continue; } - invariant(is_array($v), $k.' is not an array'); + invariant(is_array($v), '%s is not an array', $k); $v = self::MakeCheckedValue($v); if ($v['OK']) { continue; diff --git a/base/DatabaseInstaller.php b/base/DatabaseInstaller.php index 10b6c4d..72deacc 100644 --- a/base/DatabaseInstaller.php +++ b/base/DatabaseInstaller.php @@ -15,7 +15,9 @@ final class DatabaseInstaller { private ?string $username; private ?string $password = null; - public function __construct(private PerfOptions $options): void {} + public function __construct(private PerfOptions $options): void { + $this->configureMysqlAffinity(); + } public function getUsername(): ?string { return $this->username ? $this->username : $this->databaseName; @@ -35,9 +37,19 @@ public function setDumpFile(string $dump_file): this { return $this; } + public function configureMysqlAffinity(): void { + if ($this->options->cpuBind) { + exec("sudo taskset -acp ".$this->options->helperProcessors." `pgrep mysqld`"); + print "You need to restart mysql after the benchmarks to remove the "; + print "processor affinity.\n"; + } + } + public function installDatabase(): bool { $db = $this->databaseName; $dump = $this->dumpFile; + $dbHost = $this->options->dbHost; + invariant( $db !== null && $dump !== null, 'database and dump must be specified', @@ -47,7 +59,7 @@ public function installDatabase(): bool { return false; } - $conn = mysql_connect('127.0.0.1', $db, $db); + $conn = mysql_connect($dbHost, $db, $db); $db_selected = mysql_select_db($db, $conn); if ($conn === false || $db_selected === false) { $this->createMySQLDatabase(); @@ -76,7 +88,7 @@ public function installDatabase(): bool { '|'. $sed. Utils::EscapeCommand( - Vector {'mysql', '-h', '127.0.0.1', $db, '-u', $db, '-p'.$db}, + Vector {'mysql', '-h', $dbHost.'', $db, '-u', $db, '-p'.$db}, ), $output, $ret, @@ -92,11 +104,17 @@ public function installDatabase(): bool { } private function getRootConnection(): resource { - print "MySQL admin user (default is 'root'): "; - $this->username = trim(fgets(STDIN)) ?: 'root'; - fprintf(STDERR, '%s', 'MySQL admin password: '); - $this->password = trim(fgets(STDIN)); - $conn = mysql_connect('127.0.0.1', $this->username, $this->password); + if ($this->options->dbUsername !== null + && $this->options->dbPassword !== null) { + $this->username = $this->options->dbUsername; + $this->password = $this->options->dbPassword; + } else { + print "MySQL admin user (default is 'root'): "; + $this->username = trim(fgets(STDIN)) ?: 'root'; + fprintf(STDERR, '%s', 'MySQL admin password: '); + $this->password = trim(fgets(STDIN)); + } + $conn = mysql_connect($this->options->dbHost, $this->username, $this->password); if ($conn === false) { throw new Exception('Failed to connect: '.mysql_error()); } @@ -105,7 +123,7 @@ private function getRootConnection(): resource { private function checkMySQLConnectionLimit(): void { $conn = - mysql_connect('127.0.0.1', $this->getUsername(), $this->getPassword()); + mysql_connect($this->options->dbHost, $this->getUsername(), $this->getPassword()); if ($conn === false) { throw new Exception('Failed to connect: '.mysql_error()); } @@ -135,7 +153,7 @@ private function createMySQLDatabase(): void { STDERR, '%s', "Can't connect to database ". - "(mysql -h 127.0.0.1 -p$db -u $db $db). This can be ". + "(mysql -h $this->options->dbHost -p$db -u $db $db). This can be ". "fixed for you.\n", ); $conn = $this->getRootConnection(); @@ -162,7 +180,7 @@ private function createMySQLDatabase(): void { $conn, ); mysql_query( - "GRANT ALL PRIVILEGES ON $edb.* TO '$edb'@127.0.0.1 ". + "GRANT ALL PRIVILEGES ON $edb.* TO '$edb'@'$this->options->dbHost' ". "IDENTIFIED BY '$edb'", $conn, ); diff --git a/base/HHVMDaemon.php b/base/HHVMDaemon.php index 06c325e..3a354d6 100644 --- a/base/HHVMDaemon.php +++ b/base/HHVMDaemon.php @@ -64,6 +64,9 @@ protected function getTarget(): PerfTarget { <<__Override>> protected function getArguments(): Vector { + if ($this->options->cpuBind) { + $this->cpuRange = $this->options->daemonProcessors; + } $args = Vector { '-m', 'server', @@ -79,13 +82,21 @@ protected function getArguments(): Vector { 'Server.ErrorDocument404=index.php', '-v', 'Server.SourceRoot='.$this->target->getSourceRoot(), - '-v', - 'Eval.Jit=1', + '-d', + 'hhvm.log.file='.$this->options->tempDir.'/hhvm_error.log', '-d', 'pid='.escapeshellarg($this->getPidFilePath()), '-c', OSS_PERFORMANCE_ROOT.'/conf/php.ini', }; + if ($this->options->jit) { + $args->addAll(Vector {'-v', 'Eval.Jit=1'}); + } else { + $args->addAll(Vector {'-v', 'Eval.Jit=0'}); + } + if ($this->options->statCache) { + $args->addAll(Vector {'-v', 'Server.StatCache=1'}); + } if ($this->options->pcreCache) { $args->addAll( Vector {'-v', 'Eval.PCRECacheType='.$this->options->pcreCache}, @@ -107,6 +118,7 @@ protected function getArguments(): Vector { if (count($this->options->hhvmExtraArguments) > 0) { $args->addAll($this->options->hhvmExtraArguments); } + $args->add('-dhhvm.server.thread_count='.$this->options->serverThreads); if ($this->options->precompile) { $bcRepo = $this->options->tempDir.'/hhvm.hhbc'; $args->add('-v'); @@ -123,8 +135,6 @@ protected function getArguments(): Vector { $args->add('Server.SourceRoot='.$sourceRoot); } if ($this->options->tcprint !== null) { - $args->add('-v'); - $args->add('Eval.JitTransCounters=true'); $args->add('-v'); $args->add('Eval.DumpTC=true'); } @@ -273,46 +283,23 @@ public function stop(): void { public function writeStats(): void { $tcprint = $this->options->tcprint; - if ($tcprint) { - $conf = $this->options->tempDir.'/conf.hdf'; - $args = Vector {}; - $hdf = false; - foreach ($this->getArguments() as $arg) { - if ($hdf) - $args->add($arg); - $hdf = $arg === '-v'; - } - $confData = implode("\n", $args); - - file_put_contents($conf, $confData); - $args = Vector {$tcprint, '-c', $conf}; + $conf = $this->options->tempDir.'/conf.hdf'; + $args = Vector {}; + $hdf = false; + foreach ($this->getArguments() as $arg) { + if ($hdf) + $args->add($arg); + $hdf = $arg === '-v'; + } + $confData = implode("\n", $args); + file_put_contents($conf, $confData); + if ($tcprint) { $result = $this->adminRequest('/vm-dump-tc'); invariant( $result === 'Done' && file_exists('/tmp/tc_dump_a'), 'Failed to dump TC', ); - - if ($this->options->tcAlltrans) { - $alltrans = Utils::RunCommand($args); - file_put_contents('tc-all', $alltrans); - } - - if ($this->options->tcToptrans) { - $new_args = new Vector($args); - $new_args->add('-t'); - $new_args->add('100'); - $toptrans = Utils::RunCommand($new_args); - file_put_contents('tc-top-trans', $toptrans); - } - - if ($this->options->tcTopfuncs) { - $new_args = new Vector($args); - $new_args->add('-T'); - $new_args->add('100'); - $topfuncs = Utils::RunCommand($new_args); - file_put_contents('tc-top-funcs', $topfuncs); - } } if ($this->options->pcredump) { diff --git a/base/NginxDaemon.php b/base/NginxDaemon.php index 5b0ee87..5980276 100644 --- a/base/NginxDaemon.php +++ b/base/NginxDaemon.php @@ -110,6 +110,9 @@ protected function getPidFilePath(): string { <<__Override>> protected function getArguments(): Vector { + if ($this->options->cpuBind) { + $this->cpuRange = $this->options->helperProcessors; + } return Vector { '-c', $this->getGeneratedConfigFile(), diff --git a/base/PHP5Daemon.php b/base/PHP5Daemon.php index f6a0ed1..faa73ca 100644 --- a/base/PHP5Daemon.php +++ b/base/PHP5Daemon.php @@ -16,30 +16,51 @@ public function __construct(private PerfOptions $options) { $this->target = $options->getTarget(); parent::__construct((string) $options->php5); - $output = []; - $check_command = implode( - ' ', - (Vector { - $options->php5, - '-q', - '-c', - OSS_PERFORMANCE_ROOT.'/conf', - __DIR__.'/php-src_config_check.php', - })->map($x ==> escapeshellarg($x)), - ); + if ($options->fpm) { + $output = []; + $check_command = implode( + ' ', + (Vector { + $options->php5, + '-i', + '-c', + OSS_PERFORMANCE_ROOT.'/conf', + })->map($x ==> escapeshellarg($x)), + ); + + // Basic check for opcode caching. + if ($options->traceSubProcess) { + fprintf(STDERR, "%s\n", $check_command); + } + exec($check_command, $output); + $check = array_search('Opcode Caching => Up and Running', $output, true); + invariant($check, 'Got invalid output from php-fpm -i'); + } else { + $output = []; + $check_command = implode( + ' ', + (Vector { + $options->php5, + '-q', + '-c', + OSS_PERFORMANCE_ROOT.'/conf', + __dir__.'/php-src_config_check.php', + })->map($x ==> escapeshellarg($x)), + ); - if ($options->traceSubProcess) { - fprintf(STDERR, "%s\n", $check_command); + if ($options->traceSubProcess) { + fprintf(STDERR, "%s\n", $check_command); + } + exec($check_command, $output); + $checks = json_decode(implode("\n", $output), /* as array = */ true); + invariant($checks, 'Got invalid output from php-src_config_check.php'); + BuildChecker::Check( + $options, + (string) $options->php5, + $checks, + Set {'PHP_VERSION', 'PHP_VERSION_ID'}, + ); } - exec($check_command, $output); - $checks = json_decode(implode("\n", $output), /* as array = */ true); - invariant($checks, 'Got invalid output from php-src_config_check.php'); - BuildChecker::Check( - $options, - (string) $options->php5, - $checks, - Set {'PHP_VERSION', 'PHP_VERSION_ID'}, - ); } public function start(): void { @@ -51,12 +72,45 @@ public function start(): void { } protected function getArguments(): Vector { - $args = Vector { - '-b', - '127.0.0.1:'.PerfSettings::BackendPort(), - '-c', - OSS_PERFORMANCE_ROOT.'/conf/', - }; + if ($this->options->cpuBind) { + $this->cpuRange = $this->options->daemonProcessors; + } + if ($this->options->fpm) { + echo 'Creating PHP FPM config'; + $path = $this->options->tempDir.'/php-fpm.conf'; + $config = file_get_contents(OSS_PERFORMANCE_ROOT.'/conf/php-fpm.conf.in'); + $config = str_replace( + "__FASTCGI_PORT__", + PerfSettings::BackendPort(), + $config + ); + $config = str_replace( + "__CHILDREN__", + $this->options->serverThreads, + $config + ); + $config = str_replace( + "__TMP_DIR__", + $this->options->tempDir, + $config + ); + file_put_contents($path, $config); + + $args = Vector { + '-F', + '--fpm-config', + $path, + '-c', + OSS_PERFORMANCE_ROOT.'/conf/', + }; + } else { + $args = Vector { + '-b', + '127.0.0.1:'.PerfSettings::BackendPort(), + '-c', + OSS_PERFORMANCE_ROOT.'/conf/', + }; + } if (count($this->options->phpExtraArguments) > 0) { $args->addAll($this->options->phpExtraArguments); @@ -102,7 +156,8 @@ private function isPHPCGIProcess(int $pid): bool { if (!file_exists($exe)) { return false; } - return (bool) preg_match('/php.*-cgi/', readlink($exe)); + return (bool) preg_match('/php.*-cgi/', readlink($exe)) || + (bool) preg_match('/php.*-fpm/', readlink($exe)); } protected function getEnvironmentVariables(): Map { diff --git a/base/PerfOptions.php b/base/PerfOptions.php index bf22796..1c4ad20 100644 --- a/base/PerfOptions.php +++ b/base/PerfOptions.php @@ -21,6 +21,9 @@ final class PerfOptions { public ?string $php5; public ?string $hhvm; + // When running with php, this enables fpm cgi. + public bool $fpm = false; + // // setUpTest and tearDownTest are called before and after each // individual invocation of the $php5 or $hhvm @@ -36,6 +39,14 @@ final class PerfOptions { public string $siege; public string $nginx; + public ?string $dbUsername; + public ?string $dbPassword; + + public bool $cpuBind = false; + public ?string $daemonProcessors; + public ?string $helperProcessors; + + public bool $fetchResources = false; public bool $forceInnodb = false; public bool $skipSanityCheck = false; public bool $skipWarmUp = false; @@ -63,15 +74,14 @@ final class PerfOptions { public bool $allVolatile = false; public bool $interpPseudomains = false; public bool $proxygen = false; + public bool $jit = false; + public bool $statCache = false; // // HHVM specific options for generating performance data and profiling // information. // - public ?string $tcprint = null; - public bool $tcAlltrans = false; - public bool $tcToptrans = false; - public bool $tcTopfuncs = false; + public bool $tcprint = false; public bool $pcredump = false; public bool $profBC = false; @@ -107,9 +117,12 @@ final class PerfOptions { public ?string $scriptBeforeWarmup; public ?string $scriptAfterWarmup; public ?string $scriptAfterBenchmark; + public string $serverThreads = '100'; + public string $clientThreads = '200'; public bool $notBenchmarking = false; + public string $dbHost = '127.0.0.1'; //The hostname/IP of server which hosts the database. private array $args; private Vector $notBenchmarkingArgs = Vector {}; @@ -117,15 +130,19 @@ public function __construct(Vector $argv) { $def = Vector { 'help', 'verbose', - 'php5:', + 'php:', // Uses FPM by default (see no-fpm). + 'php5:', // Uses CGI. Legacy option. 'hhvm:', + 'no-fpm', 'siege:', 'nginx:', 'wait-at-end', 'wait-after-warmup', 'no-proxygen', 'no-repo-auth', + 'no-jit', 'no-file-cache', + 'stat-cache', 'pcre-cache:', 'pcre-cache-expire:', 'pcre-cache-size:', @@ -134,19 +151,20 @@ public function __construct(Vector $argv) { 'apply-patches', 'force-innodb', 'fbcode::', - 'tcprint::', - 'dump-top-trans', - 'dump-top-funcs', - 'dump-all-trans', + 'tcprint', 'dump-pcre-cache', 'profBC', 'setUpTest:', + 'db-username:', + 'db-password:', + 'cpu-fraction:', 'tearDownTest:', 'i-am-not-benchmarking', 'hhvm-extra-arguments:', 'php-extra-arguments:', 'php-fcgi-children:', 'no-time-limit', + 'fetch-resources', 'skip-sanity-check', 'skip-warmup', 'skip-version-checks', @@ -166,6 +184,9 @@ public function __construct(Vector $argv) { 'daemon-files', // daemon output goes to files in the temp directory 'temp-dir:', // temp directory to use; if absent one in /tmp is made 'src-dir:', // location for source to copy into tmp dir instead of ZIP + 'db-host:', //The IP Address or Hostname of the remote Database + 'server-threads:', + 'client-threads:', }; $targets = $this->getTargetDefinitions()->keys(); $def->addAll($targets); @@ -180,7 +201,8 @@ public function __construct(Vector $argv) { fprintf( STDERR, "Usage: %s \\\n". - " --\\\n". + " --\\\n". " --<". implode('|', $targets). ">\n". @@ -191,15 +213,24 @@ public function __construct(Vector $argv) { ); exit(1); } - ; + $this->verbose = array_key_exists('verbose', $o); - $this->php5 = hphp_array_idx($o, 'php5', null); + $php5 = hphp_array_idx($o, 'php5', null); // Will only use cgi. + $php = hphp_array_idx($o, 'php', null); // Will use fpm by default. + if ($php5 !== null) { + $this->php5 = $php5; + } else { + $this->php5 = $php; + } $this->hhvm = hphp_array_idx($o, 'hhvm', null); $this->setUpTest = hphp_array_idx($o, 'setUpTest', null); $this->tearDownTest = hphp_array_idx($o, 'tearDownTest', null); + $this->dbUsername = hphp_array_idx($o, 'db-username', null); + $this->dbPassword = hphp_array_idx($o, 'db-password', null); + $this->siege = hphp_array_idx($o, 'siege', 'siege'); $this->nginx = hphp_array_idx($o, 'nginx', 'nginx'); @@ -224,6 +255,11 @@ public function __construct(Vector $argv) { // argument too. $this->args = $o; + if ($php5 === null) { + $this->fpm = !$this->getBool('no-fpm'); + } + + $this->fetchResources = $this->getBool('fetch-resources'); $this->skipSanityCheck = $this->getBool('skip-sanity-check'); $this->skipWarmUp = $this->getBool('skip-warmup'); $this->waitAfterWarmup = $this->getBool('wait-after-warmup'); @@ -232,8 +268,21 @@ public function __construct(Vector $argv) { $this->noTimeLimit = $this->getBool('no-time-limit'); $this->waitAtEnd = $this->getBool('wait-at-end'); $this->proxygen = !$this->getBool('no-proxygen'); + $this->statCache = $this->getBool('stat-cache'); + $this->jit = !$this->getBool('no-jit'); $this->applyPatches = $this->getBool('apply-patches'); + $fraction = $this->getFloat('cpu-fraction', 1.0); + if ($fraction !== 1.0) { + $this->cpuBind = true; + $output = []; + exec('nproc', $output); + $numProcessors = (int)($output[0]); + $numDaemonProcessors = (int)($numProcessors * $fraction); + $this->helperProcessors = "$numDaemonProcessors-$numProcessors"; + $this->daemonProcessors = "0-$numDaemonProcessors"; + } + $this->precompile = !$this->getBool('no-repo-auth'); $this->filecache = $this->precompile && !$this->getBool('no-file-cache'); $this->pcreCache = $this->getNullableString('pcre-cache'); @@ -246,28 +295,14 @@ public function __construct(Vector $argv) { $this->scriptAfterWarmup = $this->getNullableString('exec-after-warmup'); $this->scriptAfterBenchmark = $this->getNullableString('exec-after-benchmark'); - if ($this->getBool('tcprint')) { - $tcprint = hphp_array_idx($o, 'tcprint', null); - if (is_string($tcprint) && $tcprint !== '') { - $this->tcprint = $tcprint; - } else if ($isFacebook) { - $this->tcprint = - $fbcode.'/_bin/hphp/facebook/tools/tc-print/tc-print'; - } - } - $this->tcAlltrans = $this->getBool('dump-all-trans'); - $this->tcToptrans = $this->getBool('dump-top-trans'); - $this->tcTopfuncs = $this->getBool('dump-top-funcs'); + $this->tcprint = $this->getBool('tcprint'); + $this->pcredump = $this->getBool('dump-pcre-cache'); $this->profBC = $this->getBool('profBC'); $this->forceInnodb = $isFacebook || $this->getBool('force-innodb'); - if ($this->tcprint !== null && !$this->tcTopfuncs && !$this->tcToptrans) { - $this->tcAlltrans = true; - } - if ($isFacebook && $this->php5 === null && $this->hhvm === null) { - $this->hhvm = $fbcode.'/_bin/hphp/hhvm/hhvm'; + $this->hhvm = $fbcode.'/buck-out/gen/hphp/hhvm/hhvm/hhvm'; } $this->traceSubProcess = $this->getBool('trace'); @@ -291,7 +326,20 @@ public function __construct(Vector $argv) { $this->daemonOutputToFile = $this->getBool('daemon-files'); $argTempDir = $this->getNullableString('temp-dir'); + + if(array_key_exists('server-threads', $o)){ + $this->serverThreads = $this->args['server-threads']; + } + $host = $this->getNullableString('db-host'); + if($host){ + $this->dbHost = $host; + } + + if(array_key_exists('client-threads', $o)){ + $this->clientThreads = $this->args['client-threads']; + } + if ($argTempDir === null) { $this->tempDir = tempnam('/tmp', 'hhvm-nginx'); // Currently a file - change to a dir @@ -302,15 +350,18 @@ public function __construct(Vector $argv) { } $this->srcDir = $this->getNullableString('src-dir'); - } public function validate() { if ($this->php5) { $this->precompile = false; $this->proxygen = false; + $this->jit = false; $this->filecache = false; } + if ($this->hhvm) { + $this->fpm = false; + } if ($this->notBenchmarkingArgs && !$this->notBenchmarking) { $message = sprintf( "These arguments are invalid without --i-am-not-benchmarking: %s", @@ -326,8 +377,8 @@ public function validate() { } if ($this->php5 === null && $this->hhvm === null) { invariant_violation( - 'Either --php5=/path/to/php-cgi or --hhvm=/path/to/hhvm '. - "must be specified", + 'Either --php5=/path/to/php-cgi or --php=/path/to/php-fpm or '. + '--hhvm=/path/to/hhvm must be specified', ); } $engine = $this->php5 !== null ? $this->php5 : $this->hhvm; @@ -344,21 +395,10 @@ public function validate() { ); $tcprint = $this->tcprint; - if ($tcprint !== null) { - invariant( - $tcprint !== '' && - (shell_exec('which '.escapeshellarg($tcprint)) !== null || - is_executable($tcprint)), - 'Invalid tcprint: %s', - $tcprint, - ); - } - - if ($this->tcAlltrans || $this->tcToptrans || $this->tcTopfuncs) { + if ($tcprint) { invariant( - $tcprint !== null, - '--tcprint=/path/to/tc-print must be specified if --tc-all-trans, '. - '--tc-top-trans, or --tc-top-funcs are specified', + $this->hhvm !== null, + 'tcprint is only valid for hhvm', ); } diff --git a/base/PerfRunner.php b/base/PerfRunner.php index 8b36580..1aed7ba 100644 --- a/base/PerfRunner.php +++ b/base/PerfRunner.php @@ -84,7 +84,8 @@ private static function RunWithOptionsAndEngine( Process::sleepSeconds($options->delayPhpStartup); invariant( $php_engine->isRunning(), - 'Failed to start '.get_class($php_engine), + 'Failed to start %s', + get_class($php_engine), ); if ($target->needsUnfreeze()) { @@ -114,7 +115,8 @@ private static function RunWithOptionsAndEngine( invariant(!$siege->isRunning(), 'Siege is still running :/'); invariant( $php_engine->isRunning(), - get_class($php_engine).' crashed', + '%s crashed', + get_class($php_engine), ); } else { self::PrintProgress('Skipping single request warmup'); @@ -130,7 +132,8 @@ private static function RunWithOptionsAndEngine( invariant(!$siege->isRunning(), 'Siege is still running :/'); invariant( $php_engine->isRunning(), - get_class($php_engine).' crashed', + '%s crashed', + get_class($php_engine), ); } else { self::PrintProgress('Skipping multi request warmup'); diff --git a/base/PerfSettings.php b/base/PerfSettings.php index 0452eea..b222c36 100644 --- a/base/PerfSettings.php +++ b/base/PerfSettings.php @@ -28,10 +28,6 @@ public static function BenchmarkTime(): string { return '1M'; // 1 minute } - public static function BenchmarkConcurrency(): int { - return 200; - } - ///// Server Settings ///// public static function HttpPort(): int { diff --git a/base/PerfTarget.php b/base/PerfTarget.php index 1ce9b2d..982a080 100644 --- a/base/PerfTarget.php +++ b/base/PerfTarget.php @@ -30,7 +30,9 @@ final public function sanityCheck(): void { $content = file_get_contents($url, /* include path = */ false, $ctx); invariant( strstr($content, $this->getSanityCheckString()) !== false, - 'Failed to find string "'.$this->getSanityCheckString().'" in '.$url, + 'Failed to find string "%s" in %s', + $this->getSanityCheckString(), + $url, ); } diff --git a/base/Process.php b/base/Process.php index 755a853..24eed2d 100644 --- a/base/Process.php +++ b/base/Process.php @@ -14,6 +14,7 @@ abstract class Process { protected ?resource $stdin; protected ?resource $stdout; protected ?string $command; + protected ?string $cpuRange = null; protected bool $suppress_stdout = false; private static Vector $processes = Vector {}; @@ -54,6 +55,11 @@ public function startWorker( if ($this->suppress_stdout) { $this->command .= ' >/dev/null'; } + + if ($this->cpuRange !== null) { + $this->command = 'taskset -c '.$this->cpuRange.' '.$this->command; + } + $use_pipe = ($outputFileName === null); $spec = [ diff --git a/base/Siege.php b/base/Siege.php index 0cc1922..d8ae674 100644 --- a/base/Siege.php +++ b/base/Siege.php @@ -28,19 +28,27 @@ public function __construct( escapeshellarg($options->siege).' --version 2>&1 | head -n 1', ), ); - $bad_prefix = 'SIEGE 3'; - if (substr($version_line, 0, strlen($bad_prefix)) === $bad_prefix) { - fprintf( - STDERR, - "WARNING: Siege 3.0.0-3.0.7 sends an incorrect HOST header to ports ". - "other than :80 and :443. Siege 3.0.8 and 3.0.9 sometimes sends full ". - "URLs as paths. You are using '%s'.\n\n". - "You can specify a path to siege 2.7x with the ". - "--siege=/path/to/siege option. If you have patched siege to fix ". - "these issues, pass --skip-version-checks.\n", - $version_line, - ); - exit(1); + $bad_prefixes = Vector { + 'SIEGE 3.0', + 'SIEGE 4.0.0', + 'SIEGE 4.0.1', + 'SIEGE 4.0.2', + }; + foreach ($bad_prefixes as $bad_prefix) { + if (substr($version_line, 0, strlen($bad_prefix)) === $bad_prefix) { + fprintf( + STDERR, + "WARNING: Siege 3.0.0-3.0.7 sends an incorrect HOST header to ". + "ports other than :80 and :443. Siege 3.0.8 and 3.0.9 sometimes ". + "sends full URLs as paths. Siege 4.0.0 - 4.0.2 automatically ". + "requests page resources. You are using '%s'.\n\n". + "You can specify a path to a proper siege version with the ". + "--siege=/path/to/siege option. If you have patched siege to fix ". + "these issues, pass --skip-version-checks.\n", + $version_line, + ); + exit(1); + } } } @@ -76,6 +84,9 @@ public function getExecutablePath(): string { <<__Override>> protected function getArguments(): Vector { + if ($this->options->cpuBind) { + $this->cpuRange = $this->options->helperProcessors; + } $urls_file = tempnam($this->options->tempDir, 'urls'); $urls = file_get_contents($this->target->getURLsFile()); $urls = @@ -98,6 +109,10 @@ protected function getArguments(): Vector { $arguments->addAll(Vector {'-R', $siege_rc}); } + if (!$this->options->fetchResources) { + $arguments->add('--no-parser'); + } + switch ($this->mode) { case RequestModes::WARMUP: $arguments->addAll( @@ -117,7 +132,7 @@ protected function getArguments(): Vector { $arguments->addAll( Vector { '-c', - (string) PerfSettings::BenchmarkConcurrency(), + $this->options->clientThreads, '-t', '1M', '-f', @@ -131,7 +146,7 @@ protected function getArguments(): Vector { $arguments->addAll( Vector { '-c', - (string) PerfSettings::BenchmarkConcurrency(), + $this->options->clientThreads, '-f', $urls_file, '--benchmark', @@ -146,7 +161,7 @@ protected function getArguments(): Vector { return $arguments; default: invariant_violation( - 'Unexpected request mode: '.(string) $this->mode, + 'Unexpected request mode: %s', (string) $this->mode, ); } } diff --git a/batch-run.json.example b/batch-run.json.example index a6fd604..b39aac3 100644 --- a/batch-run.json.example +++ b/batch-run.json.example @@ -1,51 +1,53 @@ { "runtimes": { - "HHVM 3.1 (2014-05-27)": { + "HHVM 3.18": { "type": "hhvm", - "bin": "hhvm-3.1.0" + "bin": "hhvm" }, - "HHVM 3.4 (2014-11-14)": { + "HHVM 3.18 (norepo auth)": { "type": "hhvm", - "bin": "hhvm-3.4.0" + "bin": "hhvm", + "args": [ + "--no-repo-auth", + "--i-am-not-benchmarking" + ] }, - "HHVM 3.5 (2015-01-16)": { - "type": "hhvm", - "bin": "hhvm-3.5.0" - }, - "PHP7 (*)": { - "type": "php-src", - "bin": "php7-cgi-2015-01-14" + "PHP7 FPM": { + "type": "php-fpm", + "bin": "php-fpm7.0" }, - "PHP 5.6.5 (2015-01-22)": { + "PHP7 CGI": { "type": "php-src", - "bin": "php-cgi-5.6.5" + "bin": "php-cgi7.0" } }, "targets": [ "wordpress", "drupal7", + "drupal8-no-cache", "mediawiki", - "magento1", - "sugarcrm-login-page", - "sugarcrm-home-page" + "magento1" ], "runtime-overrides": { - "sugarcrm-home-page": { - "__comment": [ - "Recent versions of PHP7 segfault in clean_non_persistent_constants()" - ], - "PHP7 (*)": { - "bin": "php7-cgi-2014-08-15" - } - }, "magento1": { "__comment": [ "Recent versions of PHP7 can not run Magento1 because of", "https://wiki.php.net/rfc/uniform_variable_syntax" ], - "PHP7 (*)": { - "bin": "php7-cgi-2014-08-15" + "PHP7 FPM": { + "skip": true + }, + "PHP7 CGI": { + "skip": true } } + }, + "settings": { + "username": "root", + "password": "root", + "options": [ + "cpu-fraction=0.5", + "i-am-not-benchmarking" + ] } } diff --git a/batch-run.php b/batch-run.php index 2df7cce..c8990a1 100644 --- a/batch-run.php +++ b/batch-run.php @@ -12,6 +12,7 @@ enum BatchRuntimeType : string { HHVM = 'hhvm'; PHP_SRC = 'php-src'; + PHP_FPM = 'php-fpm'; } ; @@ -27,6 +28,7 @@ enum BatchRuntimeType : string { type BatchTarget = shape( 'name' => string, 'runtimes' => Vector, + 'settings' => Map, ); function batch_get_runtime(string $name, array $data): BatchRuntime { @@ -51,6 +53,7 @@ function batch_get_target( string $name, Map $runtimes, Map> $overrides, + Map $settings, ): BatchTarget { $target_overrides = Map {}; if ($overrides->containsKey($name)) { @@ -67,7 +70,11 @@ function batch_get_target( $target_runtimes[] = $runtime; } } - return shape('name' => $name, 'runtimes' => $target_runtimes); + return shape( + 'name' => $name, + 'runtimes' => $target_runtimes, + 'settings' => $settings, + ); } function batch_get_targets(string $json_data): Vector { @@ -114,9 +121,14 @@ function batch_get_targets(string $json_data): Vector { } } + $settings = Map {}; + foreach ($data['settings'] as $name => $value) { + $settings[$name] = $value; + } + $targets = Vector {}; foreach ($data['targets'] as $target) { - $targets[] = batch_get_target($target, $runtimes, $overrides); + $targets[] = batch_get_target($target, $runtimes, $overrides, $settings); } return $targets; @@ -131,6 +143,13 @@ function batch_get_single_run( $argv->addAll($runtime['args']); $argv[] = '--'.$target['name']; + foreach ($target['settings'] as $name => $value) { + if ($name === 'options') { + foreach ((array)$value as $v) { + $argv[] = '--'.$v; + } + } + } $options = new PerfOptions($argv); switch ($runtime['type']) { case BatchRuntimeType::HHVM: @@ -138,9 +157,25 @@ function batch_get_single_run( break; case BatchRuntimeType::PHP_SRC: $options->php5 = $runtime['bin']; + $options->fpm = false; + break; + case BatchRuntimeType::PHP_FPM: + $options->php5 = $runtime['bin']; + $options->fpm = true; break; } + foreach ($target['settings'] as $name => $value) { + switch ($name) { + case 'username': + $options->dbUsername = $value; + break; + case 'password': + $options->dbPassword = $value; + break; + } + } + $options->setUpTest = $runtime['setUpTest']; $options->tearDownTest = $runtime['tearDownTest']; @@ -190,7 +225,9 @@ function batch_main(Vector $argv): void { sleep(5); } } - print (json_encode($results, JSON_PRETTY_PRINT)."\n"); + $json = json_encode($results, JSON_PRETTY_PRINT)."\n"; + print ($json); + file_put_contents('results'.uniqid().'.json', $json); } require_once ('base/cli-init.php'); diff --git a/conf/php-fpm.conf.in b/conf/php-fpm.conf.in new file mode 100644 index 0000000..5f8132f --- /dev/null +++ b/conf/php-fpm.conf.in @@ -0,0 +1,27 @@ +;;;;;;;;;;;;;;;;;;;;; +; FPM Configuration ; +;;;;;;;;;;;;;;;;;;;;; + +[global] +; Pid file +pid = /__TMP_DIR__/php7.0-fpm.pid + +; Error log file +error_log = /__TMP_DIR__/php7.0-fpm.log + +;;;;;;;;;;;;;;;;;;;; +; Pool Definitions ; +;;;;;;;;;;;;;;;;;;;; + +[www] +; The address on which to accept FastCGI requests. +listen = 127.0.0.1:__FASTCGI_PORT__ + +; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect. +listen.allowed_clients = 127.0.0.1 + +; static - a fixed number (pm.max_children) of child processes; +pm = static + +; The number of child processes to be created when pm is set to 'static' +pm.max_children = __CHILDREN__ diff --git a/conf/php.ini b/conf/php.ini index 56d3c7a..a4dc59e 100644 --- a/conf/php.ini +++ b/conf/php.ini @@ -15,9 +15,6 @@ assert.active=false ;;;;;;;;;;;;; ; HHVM Only ; ;;;;;;;;;;;;; -; HHVM's default is 2*CPU cores; this works reasonably well if you're using -; HHVM's async features, however it's way too low for most other loads. -hhvm.server.thread_count=100 ; This is a no-op on production builds, but makes it possible to get meaningful ; profiles from debug builds hhvm.hhir_generate_asserts=0 diff --git a/scripts/perf.sh b/scripts/perf.sh new file mode 100755 index 0000000..c3ee231 --- /dev/null +++ b/scripts/perf.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +set -xe + +# Switch to scripts dir. +cd "$(dirname "$0")" +ARGS="$@" + +echo "Running as $(whoami)" + +HHVM_PID="$(pgrep -xn 'hhvm')" +OSS_DIR=$(pwd) + +echo "The first arg is the output directory." +echo "The remaining args are passed along to perf record." +echo "Running perf on HHVM pid: $HHVM_PID" + + +# Go to repo root. +cd "$OSS_DIR/.." +sudo nohup sh -xec "timeout --signal INT 30s \ + perf record -a -g -D 5000 $ARGS -p $HHVM_PID" >nohup.out & diff --git a/scripts/setup.sh b/scripts/setup.sh new file mode 100755 index 0000000..02e328d --- /dev/null +++ b/scripts/setup.sh @@ -0,0 +1,40 @@ +#!/bin/sh +sudo apt-get -y install nginx unzip mysql-server util-linux coreutils +sudo apt-get -y install autotools-dev +sudo apt-get -y install autoconf +sudo apt-get -y install software-properties-common build-essential +sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0x5a16e7281be7a449 +sudo add-apt-repository "deb http://dl.hhvm.com/ubuntu xenial main" +sudo apt-get update +sudo apt-get -y install hhvm +sudo apt-get -y install php7.0 php7.0-cgi php7.0-fpm +sudo apt-get -y install php7.0-mysql php7.0-curl php7.0-gd php7.0-intl php-pear php-imagick php7.0-imap php7.0-mcrypt php-memcache php7.0-pspell php7.0-recode php7.0-sqlite3 php7.0-tidy php7.0-xmlrpc php7.0-xsl php7.0-mbstring php-gettext + +git clone https://github.com/JoeDog/siege.git +cd siege +git checkout tags/v4.0.3rc3 +./utils/bootstrap +automake --add-missing +./configure +make +sudo make uninstall +sudo make install +cd .. +rm -rf siege + +cd "$(dirname "$0")" +cd .. +php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" +php -r "if (hash_file('SHA384', 'composer-setup.php') === '55d6ead61b29c7bdee5cccfb50076874187bd9f21f65d8991d46ec5cc90518f447387fb9f76ebae1fbbacf329e583e30') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" +php composer-setup.php +php -r "unlink('composer-setup.php');" + +php composer.phar install + +for file in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do + sudo -- sh -c "echo performance > $file" +done + +echo 1 | sudo tee /proc/sys/net/ipv4/tcp_tw_reuse + +echo 1 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo || true diff --git a/targets/drupal7/Drupal7Target.php b/targets/drupal7/Drupal7Target.php index eb2ccba..4ac29ec 100644 --- a/targets/drupal7/Drupal7Target.php +++ b/targets/drupal7/Drupal7Target.php @@ -35,6 +35,11 @@ public function install(): void { 'compress.zlib://'.__DIR__.'/settings.php.gz', $this->getSourceRoot().'/sites/default/settings.php', ); + + $file = $this->getSourceRoot().'/sites/default/settings.php'; + $file_contents = file_get_contents($file); + $file_contents = str_replace('__DB_HOST__', $this->options->dbHost, $file_contents ); + file_put_contents($file, $file_contents); (new DatabaseInstaller($this->options)) ->setDatabaseName('drupal_bench') diff --git a/targets/drupal7/settings.php.gz b/targets/drupal7/settings.php.gz index 575f1a9..1bf7750 100644 Binary files a/targets/drupal7/settings.php.gz and b/targets/drupal7/settings.php.gz differ diff --git a/targets/drupal8/Drupal8Target.php b/targets/drupal8/Drupal8Target.php index 8f45940..32e76d1 100644 --- a/targets/drupal8/Drupal8Target.php +++ b/targets/drupal8/Drupal8Target.php @@ -46,6 +46,10 @@ public function install(): void { __DIR__.'/settings/settings.php', $this->getSourceRoot().'/sites/default/settings.php', ); + $file = $this->getSourceRoot().'/sites/default/settings.php'; + $file_contents = file_get_contents($file); + $file_contents = str_replace('__DB_HOST__', $this->options->dbHost, $file_contents ); + file_put_contents($file, $file_contents); copy( __DIR__.'/settings/setup.php', $this->getSourceRoot().'/sites/default/setup.php', diff --git a/targets/drupal8/settings/settings.php b/targets/drupal8/settings/settings.php index 6dd31a2..c76c3c9 100644 --- a/targets/drupal8/settings/settings.php +++ b/targets/drupal8/settings/settings.php @@ -678,7 +678,7 @@ 'username' => 'drupal_bench', 'password' => 'drupal_bench', 'prefix' => '', - 'host' => '127.0.0.1', + 'host' => '__DB_HOST__', 'port' => '3306', 'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql', 'driver' => 'mysql', diff --git a/targets/magento1/Magento1Target.php b/targets/magento1/Magento1Target.php index 1d21bea..aba4b3e 100644 --- a/targets/magento1/Magento1Target.php +++ b/targets/magento1/Magento1Target.php @@ -98,6 +98,10 @@ public function install(): void { __DIR__.'/local.xml', $this->getSourceRoot().'/app/etc/local.xml', ); + $file = $this->getSourceRoot().'/app/etc/local.xml'; + $file_contents = file_get_contents($file); + $file_contents = str_replace('__DB_HOST__', $this->options->dbHost, $file_contents ); + file_put_contents($file, $file_contents); return; } @@ -127,7 +131,7 @@ public function install(): void { private function getInstallerArgs(): array { $url = 'http://'.gethostname().':'.PerfSettings::HttpPort().'/'; return array( - 'db_host' => '127.0.0.1', + 'db_host' => $this->options->dbHost, 'db_name' => $this->getDatabaseName(), 'db_user' => $this->installer->getUsername(), 'db_pass' => $this->installer->getPassword(), diff --git a/targets/magento1/local.xml b/targets/magento1/local.xml index 4da021e..0e15102 100755 --- a/targets/magento1/local.xml +++ b/targets/magento1/local.xml @@ -40,7 +40,7 @@ - + diff --git a/targets/mediawiki/LocalSettings.php b/targets/mediawiki/LocalSettings.php index ac4e815..f2a57ef 100644 --- a/targets/mediawiki/LocalSettings.php +++ b/targets/mediawiki/LocalSettings.php @@ -55,7 +55,7 @@ ## Database settings $wgDBtype = "mysql"; -#$wgDBserver = "localhost"; +$wgDBserver = "__DB_HOST__"; $wgDBname = "mw_bench"; $wgDBuser = "mw_bench"; $wgDBpassword = "mw_bench"; diff --git a/targets/mediawiki/MediaWikiTarget.php b/targets/mediawiki/MediaWikiTarget.php index 07b8f27..183a8de 100644 --- a/targets/mediawiki/MediaWikiTarget.php +++ b/targets/mediawiki/MediaWikiTarget.php @@ -11,7 +11,7 @@ final class MediaWikiTarget extends PerfTarget { - const MEDIAWIKI_VERSION = 'mediawiki-1.26.2'; + const MEDIAWIKI_VERSION = 'mediawiki-1.28.0'; public function __construct(private PerfOptions $options) {} @@ -39,8 +39,13 @@ public function install(): void { // we're in repo-auth mode, the generated files end up in the repo $cache_dir = $this->getSourceRoot().'/mw-cache'; mkdir($cache_dir); - copy(__DIR__.'/LocalSettings.php', $this->getSourceRoot().'/LocalSettings.php'); + + $file = $this->getSourceRoot().'/LocalSettings.php'; + $file_contents = file_get_contents($file); + $file_contents = str_replace('__DB_HOST__', $this->options->dbHost, $file_contents ); + file_put_contents($file, $file_contents); + file_put_contents( $this->getSourceRoot().'/LocalSettings.php', '$wgCacheDirectory="'.$cache_dir.'";', diff --git a/targets/mediawiki/mediawiki-1.26.2.tar.gz b/targets/mediawiki/mediawiki-1.28.0.tar.gz similarity index 62% rename from targets/mediawiki/mediawiki-1.26.2.tar.gz rename to targets/mediawiki/mediawiki-1.28.0.tar.gz index 4674df6..f8391e1 100644 Binary files a/targets/mediawiki/mediawiki-1.26.2.tar.gz and b/targets/mediawiki/mediawiki-1.28.0.tar.gz differ diff --git a/targets/sugarcrm/SugarCRMTarget.php b/targets/sugarcrm/SugarCRMTarget.php index 4cf1959..6818631 100644 --- a/targets/sugarcrm/SugarCRMTarget.php +++ b/targets/sugarcrm/SugarCRMTarget.php @@ -22,6 +22,10 @@ public function install(): void { } copy(__DIR__.'/config.php', $this->getSourceRoot().'/config.php'); + $file = $this->getSourceRoot().'/config.php'; + $file_contents = file_get_contents($file); + $file_contents = str_replace('__DB_HOST__', $this->options->dbHost, $file_contents ); + file_put_contents($file, $file_contents); if ($this->options->skipDatabaseInstall) { return; diff --git a/targets/sugarcrm/config.php b/targets/sugarcrm/config.php index 3408dcf..969a8a3 100644 --- a/targets/sugarcrm/config.php +++ b/targets/sugarcrm/config.php @@ -52,7 +52,7 @@ 'datef' => 'm/d/Y', 'dbconfig' => array ( - 'db_host_name' => '127.0.0.1', + 'db_host_name' => '__DB_HOST__', 'db_host_instance' => 'SQLEXPRESS', 'db_user_name' => 'sugarcrm', 'db_password' => 'sugarcrm', diff --git a/targets/wordpress/WordpressTarget.php b/targets/wordpress/WordpressTarget.php index 20df7ae..e944933 100644 --- a/targets/wordpress/WordpressTarget.php +++ b/targets/wordpress/WordpressTarget.php @@ -27,8 +27,13 @@ public function install(): void { $this->options->tempDir, ); } - + copy(__DIR__.'/wp-config.php', $this->getSourceRoot().'/wp-config.php'); + + $file = $this->getSourceRoot().'/wp-config.php'; + $file_contents = file_get_contents($file); + $file_contents = str_replace('__DB_HOST__', $this->options->dbHost, $file_contents ); + file_put_contents($file, $file_contents); $created_database = (new DatabaseInstaller($this->options)) @@ -45,7 +50,7 @@ public function install(): void { : PerfSettings::HttpPort(); $root = 'http://'.gethostname().':'.$visible_port; - $conn = mysql_connect('127.0.0.1', 'wp_bench', 'wp_bench'); + $conn = mysql_connect($this->options->dbHost, 'wp_bench', 'wp_bench'); $db_selected = mysql_select_db('wp_bench', $conn); $result = mysql_query( 'UPDATE wp_options '. @@ -100,11 +105,9 @@ private function unfreezeRequest(PerfOptions $options): void { $data = file_get_contents($url, /* include path = */ false, $ctx); invariant( $data !== false, - 'Failed to unfreeze '. - $url. - ' after '. - $options->maxdelayUnfreeze. - ' secs', + 'Failed to unfreeze %s after %f secs', + $url, + $options->maxdelayUnfreeze, ); } } diff --git a/targets/wordpress/wp-config.php b/targets/wordpress/wp-config.php index bd89a31..b36c90f 100644 --- a/targets/wordpress/wp-config.php +++ b/targets/wordpress/wp-config.php @@ -42,7 +42,7 @@ define('DB_PASSWORD', 'wp_bench'); /** MySQL hostname */ -define('DB_HOST', '127.0.0.1'); +define('DB_HOST', '__DB_HOST__'); ////////////////////////////////////////////// ///// END CHANGES TO DEFAULT CONFIG FILE /////