<commit_before><?php

namespace Swoole;

//关闭错误输出
//error_reporting(0);

class CoBenchMarkTest
{
    protected $nConcurrency = 100;
    protected $nRequest = 10000; // total
    protected $nShow;

    protected $scheme;
    protected $host;
    protected $port = 9501;

    protected $nRecvBytes = 0;
    protected $nSendBytes = 0;

    protected $requestCount = 0; // success
    protected $connectCount = 0;

    protected $connectTime = 0;

    protected $startTime;
    protected $beginSendTime;
    protected $testMethod;

    protected $sentData;
    protected $sentLen = 1024;

    public function __construct($opt)
    {
        $this->parseOpts();
        $this->setSentData(str_repeat('A', $this->sentLen));
        if (!isset($this->scheme) or !method_exists($this, $this->scheme)) {
            throw new \RuntimeException("Not support pressure measurement objects [{$this->scheme}].");
        }
        $this->testMethod = $this->scheme;
    }

    protected function parseOpts()
    {
        $shortOpts = "c:n:l:s:h";
        $opts = getopt($shortOpts);

        if (isset($opts['h'])) {
            $this->showHelp();
        }

        if (isset($opts['c']) and intval($opts['c']) > 0) {
            $this->nConcurrency = intval($opts['c']);
        }
        if (isset($opts['n']) and intval($opts['n']) > 0) {
            $this->nRequest = intval($opts['n']);
        }
        $this->nShow = $this->nRequest / 10;
        
        if (isset($opts['l']) and intval($opts['l']) > 0) {
            $this->sentLen = intval($opts['l']);
        }

        if (!isset($opts['s'])) {
            exit("Require -s [server_url]. E.g: -s tcp://127.0.0.1:9501" . PHP_EOL);
        }

        $serv = parse_url($opts['s']);
        $this->scheme = $serv['scheme'];
        if (filter_var($serv['host'], FILTER_VALIDATE_IP) === false) {
            exit("Invalid ip address" . PHP_EOL);
        }
        $this->host = $serv['host'];
        if (isset($serv['port']) and intval($serv['port']) > 0) {
            $this->port = $serv['port'];
        }
    }

    public function showHelp()
    {
        exit(<<<HELP
Usage: php co_run.php [OPTIONS]

A bench script

Options:
  -c      Number of coroutines      E.g: -c 100
  -n      Number of requests        E.g: -n 10000
  -l      The length of the data sent per request       E.g: -l 1024
  -s      URL       E.g: -s tcp://127.0.0.1:9501
\n
HELP
        );
    }

    public function setSentData($data)
    {
        $this->sentData = $data;
        $this->sentLen = strlen($data);
    }

    protected function finish()
    {
        $costTime = $this->format(microtime(true) - $this->startTime);
        $nRequest = number_format($this->nRequest);
        $requestErrorCount = number_format($this->nRequest - $this->requestCount);
        $connectErrorCount = number_format($this->nConcurrency - $this->connectCount);
        $nSendBytes = number_format($this->nSendBytes);
        $nRecvBytes = number_format($this->nRecvBytes);
        $requestPerSec = $this->requestCount / $costTime;
        $connectTime = $this->format($this->connectTime);

        echo <<<EOF
Concurrency Level:      {$this->nConcurrency}
Time taken for tests:   {$costTime} seconds
Complete requests:      {$nRequest}
Failed requests:        {$requestErrorCount}
Connect failed:         {$connectErrorCount}
Total send:             {$nSendBytes} bytes
Total reveive:          {$nRecvBytes} bytes
Requests per second:    {$requestPerSec}
Connection time:        {$connectTime} seconds
\n
EOF;
    }

    public function format($time)
    {
        return round($time, 4);
    }

    protected function websocket()
    {
        $cli = new Coroutine\http\client($this->host, $this->port);
        $cli->set(array('websocket_mask' => true));
        $cli->upgrade('/');
        $data = $this->sentData;
        $sendLen = strlen($data);
        $n = $this->nRequest / $this->nConcurrency;
        while ($n--) {
            //requset
            $cli->push($data);
            $this->nSendBytes += $sendLen;
            $this->requestCount++;
            //response
            $frame = $cli->recv();
            $this->nRecvBytes += strlen($frame->data);
        }
        $cli->close();
    }

    protected function tcp()
    {
        $cli = new Coroutine\Client(SWOOLE_TCP);
        $n = $this->nRequest / $this->nConcurrency;
        Coroutine::defer(function () use ($cli) {
            $cli->close();
        });

        if ($cli->connect($this->host, $this->port) === false) {
            echo swoole_strerror($cli->errCode) . PHP_EOL;
            return;
        }
        $this->connectCount++;

        while ($n--) {
            //requset
            if ($cli->send($this->sentData) === false) {
                echo swoole_strerror($cli->errCode) . PHP_EOL;
                continue;
            }
            $this->nSendBytes += $this->sentLen;
            $this->requestCount++;
            if ($this->requestCount % $this->nShow === 0) {
                echo "Completed {$this->requestCount} requests" . PHP_EOL;
            }
            //response
            $recvData = $cli->recv();
            if ($recvData === false) {
                echo swoole_strerror($cli->errCode) . PHP_EOL;
            } else {
                $this->nRecvBytes += strlen($recvData);
            }
        }
    }

    protected function eof()
    {
        $eof = "\r\n\r\n";
        $cli = new Coroutine\Client(SWOOLE_TCP);
        $cli->set(array('open_eof_check' => true, "package_eof" => $eof));
        $cli->connect($this->host, $this->port);
        $n = $this->nRequest / $this->nConcurrency;
        while ($n--) {
            //requset
            $data = $this->sentData . $eof;
            $cli->send($data);
            $this->nSendBytes += strlen($data);
            $this->requestCount++;
            //response
            $rdata = $cli->recv();
            $this->nRecvBytes += strlen($rdata);
        }<commit_msg>add the pressure test of http<commit_after><?php

namespace Swoole;

//关闭错误输出
//error_reporting(0);

class CoBenchMarkTest
{
    const TCP_SENT_LEN = 1024;

    protected $nConcurrency = 100;
    protected $nRequest = 10000; // total
    protected $nShow;

    protected $scheme;
    protected $host;
    protected $port = 9501;

    protected $nRecvBytes = 0;
    protected $nSendBytes = 0;

    protected $requestCount = 0; // success
    // protected $connectCount = 0;
    protected $connectErrorCount = 0;

    protected $connectTime = 0;

    protected $startTime;
    protected $beginSendTime;
    protected $testMethod;

    protected $sentData;
    protected $sentLen = 0;

    protected $verbose = false; // debug info

    public function __construct($opt)
    {
        $this->parseOpts();
        if (!isset($this->scheme) or !method_exists($this, $this->scheme)) {
            exit("Not support pressure measurement objects [{$this->scheme}]." . PHP_EOL);
        }
        $this->testMethod = $this->scheme;
    }

    protected function parseOpts()
    {
        $shortOpts = "c:n:l:s:hv";
        $opts = getopt($shortOpts);

        if (isset($opts['h'])) {
            $this->showHelp();
        }

        if (isset($opts['c']) and intval($opts['c']) > 0) {
            $this->nConcurrency = intval($opts['c']);
        }
        if (isset($opts['n']) and intval($opts['n']) > 0) {
            $this->nRequest = intval($opts['n']);
        }
        $this->nShow = $this->nRequest / 10;

        if (isset($opts['l']) and intval($opts['l']) > 0) {
            $this->sentLen = intval($opts['l']);
        }

        if (!isset($opts['s'])) {
            exit("Require -s [server_url]. E.g: -s tcp://127.0.0.1:9501" . PHP_EOL);
        }
        $serv = parse_url($opts['s']);
        if (!$serv) {
            exit("Invalid URL" . PHP_EOL);
        }
        $this->scheme = $serv['scheme'];
        if (!filter_var($serv['host'], FILTER_VALIDATE_IP)) {
            exit("Invalid ip address" . PHP_EOL);
        }
        $this->host = $serv['host'];
        if (isset($serv['port']) and intval($serv['port']) > 0) {
            $this->port = $serv['port'];
        }

        if (isset($opts['v'])) {
            $this->verbose = true;
        }
    }

    public function showHelp()
    {
        exit(<<<HELP
Usage: php co_run.php [OPTIONS]

A bench script

Options:
  -c      Number of coroutines      E.g: -c 100
  -n      Number of requests        E.g: -n 10000
  -l      The length of the data sent per request       E.g: -l 1024
  -s      URL       E.g: -s tcp://127.0.0.1:9501
                    Support: tcp、longHttp
  -h      Help list
  -v      Flag enables verbose progress and debug output
\n
HELP
        );
    }

    public function setSentData($data)
    {
        $this->sentData = $data;
        $this->sentLen = strlen($data);
    }

    protected function finish()
    {
        $costTime = $this->format(microtime(true) - $this->startTime);
        $nRequest = number_format($this->nRequest);
        $requestErrorCount = number_format($this->nRequest - $this->requestCount);
        $connectErrorCount = number_format($this->connectErrorCount);
        $nSendBytes = number_format($this->nSendBytes);
        $nRecvBytes = number_format($this->nRecvBytes);
        $requestPerSec = $this->requestCount / $costTime;
        $connectTime = $this->format($this->connectTime);

        echo <<<EOF
Concurrency Level:      {$this->nConcurrency}
Time taken for tests:   {$costTime} seconds
Complete requests:      {$nRequest}
Failed requests:        {$requestErrorCount}
Connect failed:         {$connectErrorCount}
Total send:             {$nSendBytes} bytes
Total reveive:          {$nRecvBytes} bytes
Requests per second:    {$requestPerSec}
Connection time:        {$connectTime} seconds
\n
EOF;
    }

    public function format($time)
    {
        return round($time, 4);
    }

    protected function websocket()
    {
        $cli = new Coroutine\http\client($this->host, $this->port);
        $cli->set(array('websocket_mask' => true));
        $cli->upgrade('/');
        $data = $this->sentData;
        $sendLen = strlen($data);
        $n = $this->nRequest / $this->nConcurrency;
        while ($n--) {
            //requset
            $cli->push($data);
            $this->nSendBytes += $sendLen;
            $this->requestCount++;
            //response
            $frame = $cli->recv();
            $this->nRecvBytes += strlen($frame->data);
        }
        $cli->close();
    }

    protected function tcp()
    {
        $cli = new Coroutine\Client(SWOOLE_TCP);
        $n = $this->nRequest / $this->nConcurrency;
        Coroutine::defer(function () use ($cli) {
            $cli->close();
        });

        if ($this->sentLen === 0) {
            $this->sentLen = SELF::TCP_SENT_LEN;
        }
        $this->setSentData(str_repeat('A', $this->sentLen));

        if (!$cli->connect($this->host, $this->port)) {
            if ($this->verbose) {
                echo swoole_strerror($cli->errCode) . PHP_EOL;
            }
            $this->connectErrorCount++;
            return;
        }

        while ($n--) {
            //requset
            if (!$cli->send($this->sentData)) {
                if ($this->verbose) {
                    echo swoole_strerror($cli->errCode) . PHP_EOL;
                }
                continue;
            }
            $this->nSendBytes += $this->sentLen;
            $this->requestCount++;
            if (($this->requestCount % $this->nShow === 0) and $this->verbose) {
                echo "Completed {$this->requestCount} requests" . PHP_EOL;
            }
            //response
            $recvData = $cli->recv();
            if ($recvData === false and $this->verbose) {
                echo swoole_strerror($cli->errCode) . PHP_EOL;
            } else {
                $this->nRecvBytes += strlen($recvData);
            }
        }
    }

    protected function longHttp()
    {
        $httpCli = new Coroutine\Http\Client($this->host, $this->port);
        $n = $this->nRequest / $this->nConcurrency;
        $httpCli->setHeaders([
            'Host' => "{$this->host}:{$this->port}",
            'Accept' => 'text/html,application/xhtml+xml,application/xml',
        ]);
        Coroutine::defer(function () use ($httpCli) {
            $httpCli->close();
        });

        while ($n--) {
            if ($httpCli->get('/') === false) {
                if (!$httpCli->connected) {
                    $this->connectErrorCount++;
                }
                if ($this->verbose) {
                    echo swoole_strerror($httpCli->errCode) . PHP_EOL;
                }
                continue;
            }
            $this->requestCount++;
            if ($this->requestCount % $this->nShow === 0 and $this->verbose) {
                echo "Completed {$this->requestCount} requests" . PHP_EOL;
            }
            $recvData = $httpCli->body;
            $this->nRecvBytes += strlen($recvData);
        }
    }

    protected function eof()
    {
        $eof = "\r\n\r\n";
        $cli = new Coroutine\Client(SWOOLE_TCP);
        $cli->set(array('open_eof_check' => true, "package_eof" => $eof));
        $cli->connect($this->host, $this->port);
        $n = $this->nRequest / $this->nConcurrency;
        while ($n--) {
            //requset
            $data = $this->sentData . $eof;
            $cli->send($data);
            $this->nSendBytes += strlen($data);
            $this->requestCount++;
            //response
            $rdata = $cli->recv();
            $this->nRecvBytes += strlen($rdata);
        }
{'fraction_non_alphanumeric': 0.16274121358867122, 'fraction_numerical': 0.009391738205297527, 'mean_word_length': 1.8634453781512605, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 201, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7016833', 'n_tokens_mistral': 4290, 'n_tokens_neox': 4141, 'n_words': 839}