StreamSocketClientTcpTest::testGetSocket()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
declare(strict_types=1);
3
4
/*
5
 * This file is part of the php-gelf package.
6
 *
7
 * (c) Benjamin Zikarsky <http://benjamin-zikarsky.de>
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
namespace Gelf\Test\Transport;
14
15
use Gelf\Transport\StreamSocketClient;
16
use LogicException;
17
use PHPUnit\Framework\TestCase;
18
use RuntimeException;
19
20
class StreamSocketClientTcpTest extends TestCase
21
{
22
    private StreamSocketClient $socketClient;
23
    private mixed $serverSocket;
24
25
    private string $host = "127.0.0.1";
26
    private int $port;
27
28
    public function setUp(): void
29
    {
30
        $host = $this->host;
31
        $this->serverSocket = stream_socket_server("tcp://$host:0");
32
33
        if (!$this->serverSocket) {
34
            throw new RuntimeException("Failed to create test-server-socket");
35
        }
36
37
        // get random port
38
        $socketName = stream_socket_get_name(
39
            $this->serverSocket,
40
            remote: false
41
        );
42
        [, $port] = explode(":", $socketName);
43
44
        $this->socketClient = new StreamSocketClient('tcp', $host, (int)$port);
45
        $this->port = (int)$port;
46
    }
47
48
    public function tearDown(): void
49
    {
50
        unset($this->socketClient);
51
        if ($this->serverSocket !== null) {
52
            fclose($this->serverSocket);
53
            $this->serverSocket = null;
54
        }
55
    }
56
57
    public function testGetSocket(): void
58
    {
59
        self::assertIsResource($this->socketClient->getSocket());
60
    }
61
62
    public function testWrite(): void
63
    {
64
        $testData = "Hello World!";
65
        $numBytes = $this->socketClient->write($testData);
66
67
        self::assertEquals(strlen($testData), $numBytes);
68
69
        // check that message is sent to server
70
        $connection = stream_socket_accept($this->serverSocket);
71
        $readData = fread($connection, $numBytes);
72
73
        self::assertEquals($testData, $readData);
74
    }
75
76
    public function testBadWrite(): void
77
    {
78
        self::expectException(RuntimeException::class);
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCase::expectException() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

78
        self::/** @scrutinizer ignore-call */ 
79
              expectException(RuntimeException::class);
Loading history...
79
80
        $this->socketClient->write("Hello ");
81
        fclose($this->serverSocket);
82
        $this->serverSocket = null;
83
        $this->socketClient->write("world!");
84
    }
85
86
    public function testMultiWrite(): void
87
    {
88
        // lower timeout for server-socket
89
        stream_set_timeout($this->serverSocket, 0, 100);
90
91
        // -- first write
92
93
        $testData = "First thing in the morning should be to check,";
94
95
        $numBytes = $this->socketClient->write($testData);
96
        self::assertEquals(strlen($testData), $numBytes);
97
98
        // open connection on server-socket
99
        $serverConnection = stream_socket_accept($this->serverSocket);
100
101
        $readData = fread($serverConnection, $numBytes);
102
        self::assertEquals($testData, $readData);
103
104
        // -- second write
105
106
        $testData = "if we can write multiple times on the same socket";
107
108
        $numBytes = $this->socketClient->write($testData);
109
        self::assertEquals(strlen($testData), $numBytes);
110
111
        $readData = fread($serverConnection, $numBytes);
112
        self::assertEquals($testData, $readData);
113
114
        fclose($serverConnection);
115
    }
116
117
    public function testRead(): void
118
    {
119
        $testData = "Hello Reader :)";
120
121
        $numBytes = $this->socketClient->write($testData);
122
        self::assertEquals(strlen($testData), $numBytes);
123
124
        // lower timeout for server-socket
125
        stream_set_timeout($this->serverSocket, 0, 100);
126
127
        $connection = stream_socket_accept($this->serverSocket);
128
129
        // return input as output
130
        stream_copy_to_stream($connection, $connection, strlen($testData));
131
132
        fclose($connection);
133
        $readData = $this->socketClient->read($numBytes);
134
135
        self::assertEquals($testData, $readData);
136
    }
137
138
    public function testReadContents(): void
139
    {
140
        $testData = str_repeat("0123456789", mt_rand(1, 10));
141
142
        $numBytes = $this->socketClient->write($testData);
143
        self::assertEquals(strlen($testData), $numBytes);
144
145
        // lower timeout for server-socket
146
        stream_set_timeout($this->serverSocket, 0, 100);
147
148
        $connection = stream_socket_accept($this->serverSocket);
149
150
        // return input as output
151
        stream_copy_to_stream($connection, $connection, strlen($testData));
152
153
        fclose($connection);
154
155
        $readData = $this->socketClient->read(1024);
156
157
        self::assertEquals($testData, $readData);
158
    }
159
160
    public function testCloseWithoutConnectionWrite(): void
161
    {
162
        // close unopened stream
163
        $this->socketClient->close();
164
        self::assertTrue($this->socketClient->isClosed());
165
166
        $this->socketClient->write("abcd");
167
        self::assertFalse($this->socketClient->isClosed());
168
        $client = stream_socket_accept($this->serverSocket);
169
        self::assertEquals("abcd", fread($client, 4));
170
    }
171
172
    public function testCloseWrite(): void
173
    {
174
        $this->socketClient->write("abcd");
175
        self::assertFalse($this->socketClient->isClosed());
176
        $client = stream_socket_accept($this->serverSocket);
177
        self::assertEquals("abcd", fread($client, 4));
178
179
        $this->socketClient->close();
180
        self::assertTrue($this->socketClient->isClosed());
181
182
        $this->socketClient->write("efgh");
183
        $client2 = stream_socket_accept($this->serverSocket);
184
        self::assertEquals("efgh", fread($client2, 4));
185
    }
186
187
    public function testStreamContext(): void
188
    {
189
        $testName = '127.0.0.1:12345';
190
        $context = [
191
            'socket' => [
192
                'bindto' => $testName
193
            ]
194
        ];
195
196
        $client = new StreamSocketClient("tcp", $this->host, $this->port, $context);
197
        self::assertEquals($context, $client->getContext());
198
199
        self::assertEquals($testName, stream_socket_get_name($client->getSocket(), false));
200
        self::assertNotEquals($testName, stream_socket_get_name($this->socketClient->getSocket(), false));
201
    }
202
203
    public function testUpdateStreamContext(): void
204
    {
205
        $testName = '127.0.0.1:12345';
206
        $context = array(
207
            'socket' => array(
208
                'bindto' => $testName
209
            )
210
        );
211
212
        self::assertEquals(array(), $this->socketClient->getContext());
213
        self::assertNotEquals($testName, stream_socket_get_name($this->socketClient->getSocket(), false));
214
        $this->socketClient->close();
215
216
        $this->socketClient->setContext($context);
217
        self::assertEquals($context, $this->socketClient->getContext());
218
219
        self::assertEquals($testName, stream_socket_get_name($this->socketClient->getSocket(), false));
220
    }
221
222
    public function testSetContextFailsAfterConnect(): void
223
    {
224
        self::expectException(LogicException::class);
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCase::expectException() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

224
        self::/** @scrutinizer ignore-call */ 
225
              expectException(LogicException::class);
Loading history...
225
        // enforce connect
226
        $this->socketClient->getSocket();
227
228
        $this->socketClient->setContext(array("foo" => "bar"));
229
    }
230
231
    public function testSetConnectTimeoutFailsAfterConnect(): void
232
    {
233
        self::expectException(LogicException::class);
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCase::expectException() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

233
        self::/** @scrutinizer ignore-call */ 
234
              expectException(LogicException::class);
Loading history...
234
        // enforce connect
235
        $this->socketClient->getSocket();
236
237
        $this->socketClient->setConnectTimeout(1);
238
    }
239
240
    public function testConnectTimeout()
241
    {
242
        $this->socketClient->setConnectTimeout(1);
243
        self::assertEquals(1, $this->socketClient->getConnectTimeout());
244
    }
245
}
246