Passed
Push — master ( 41d019...4608a5 )
by Eugene
05:43
created

TestCase::getTarantoolVersion()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 5
rs 10
c 2
b 0
f 1
1
<?php
2
3
/**
4
 * This file is part of the Tarantool Client package.
5
 *
6
 * (c) Eugene Leonovich <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Tarantool\Client\Tests\Integration;
15
16
use PHPUnit\Framework\TestCase as BaseTestCase;
17
use PHPUnit\Util\Test;
18
use Tarantool\Client\Client;
19
use Tarantool\Client\Connection\Connection;
20
use Tarantool\Client\Connection\StreamConnection;
21
use Tarantool\Client\Exception\CommunicationFailed;
22
use Tarantool\Client\Handler\Handler;
23
use Tarantool\Client\Request\Request;
24
25
abstract class TestCase extends BaseTestCase
26
{
27
    protected const STAT_REQUEST_SELECT = 'SELECT';
28
    protected const STAT_REQUEST_AUTH = 'AUTH';
29
30
    /**
31
     * @var Client
32
     */
33
    protected $client;
34
35
    private const REGEX_REQURES_TARANTOOL_VERSION = '/tarantool\s+?(?<version>.+?)$/i';
36
37
    public static function setUpBeforeClass() : void
38
    {
39
        $annotations = Test::parseTestMethodAnnotations(static::class);
40
41
        self::handleCustomAnnotations($annotations['class']);
42
    }
43
44
    protected function setUp() : void
45
    {
46
        $this->client = ClientBuilder::createFromEnv()->build();
47
48
        $annotations = $this->getAnnotations();
49
50
        self::handleCustomAnnotations($annotations['method']);
51
    }
52
53
    private static function handleCustomAnnotations(array $annotations) : void
54
    {
55
        if (isset($annotations['requires'])) {
56
            foreach ($annotations['requires'] as $requirement) {
57
                if (!preg_match(self::REGEX_REQURES_TARANTOOL_VERSION, $requirement, $matches)) {
58
                    continue;
59
                }
60
61
                if (version_compare(self::getTarantoolVersion(), $matches['version'], '<')) {
62
                    self::markTestSkipped(sprintf('Tarantool >= %s is required.', $matches['version']));
63
                }
64
65
                break;
66
            }
67
        }
68
69
        if (isset($annotations['eval'])) {
70
            $client = ClientBuilder::createFromEnv()->build();
71
            foreach ($annotations['eval'] as $expr) {
72
                $client->evaluate($expr);
73
            }
74
        }
75
    }
76
77
    final protected static function getTotalCalls(string $requestName) : int
78
    {
79
        $client = ClientBuilder::createFromEnv()->build();
80
81
        return $client->evaluate("return box.stat().$requestName.total")[0];
82
    }
83
84
    final protected static function getTarantoolVersion() : string
85
    {
86
        $connection = ClientBuilder::createFromEnv()->createConnection();
87
88
        return $connection->open()->getServerVersion();
89
    }
90
91
    final protected static function triggerUnexpectedResponse(Handler $handler, Request $initialRequest, int $sync = 0) : Connection
92
    {
93
        $connection = $handler->getConnection();
94
        $packer = $handler->getPacker();
95
        $rawRequest = $packer->pack($initialRequest, $sync);
96
97
        // write a request without reading a response
98
        $connection->open();
99
        if (!\fwrite(self::getRawStream($connection), $rawRequest)) {
100
            throw new CommunicationFailed('Unable to write request.');
101
        }
102
103
        return $connection;
104
    }
105
106
    final public static function getRawStream(StreamConnection $connection)
107
    {
108
        $prop = (new \ReflectionObject($connection))->getProperty('stream');
109
        $prop->setAccessible(true);
110
111
        return $prop->getValue($connection);
112
    }
113
}
114