xref: /aosp_15_r20/external/grpc-grpc/src/php/tests/unit_tests/ServerCallTest.php (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1<?php
2/*
3 *
4 * Copyright 2015 gRPC authors.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20require_once(dirname(__FILE__) . '/../../lib/Grpc/ServerCallReader.php');
21require_once(dirname(__FILE__) . '/../../lib/Grpc/ServerCallWriter.php');
22require_once(dirname(__FILE__) . '/../../lib/Grpc/Status.php');
23require_once(dirname(__FILE__) . '/../../lib/Grpc/ServerContext.php');
24
25class StartBatchEvent
26{
27    public function __construct(string $message)
28    {
29        $this->message = $message;
30    }
31    public $message;
32}
33
34class StringValue
35{
36    public function setValue(string $value)
37    {
38        $this->value = $value;
39    }
40
41    public function getValue(): string
42    {
43        return $this->value;
44    }
45
46    public function serializeToString(): string
47    {
48        return $this->value;
49    }
50
51    public function mergeFromString(string $value)
52    {
53        $this->value = $value;
54    }
55
56    private $value = '';
57}
58
59class ServerCallTest extends \PHPUnit\Framework\TestCase
60{
61    private $mockCall;
62    private $serverContext;
63
64    public function setUp(): void
65    {
66        $this->mockCall = $this->getMockBuilder(stdClass::class)
67            ->setMethods(['startBatch'])
68            ->getMock();
69        $this->serverContext = new \Grpc\ServerContext($this->mockCall);
70    }
71
72    public function newStringMessage(string $value = 'a string')
73    {
74        $message = new StringValue();
75        $message->setValue($value);
76        return $message;
77    }
78
79    public function testRead()
80    {
81        $message = $this->newStringMessage();
82
83        $this->mockCall->expects($this->once())
84            ->method('startBatch')
85            ->with($this->identicalTo([
86                \Grpc\OP_RECV_MESSAGE => true,
87            ]))->willReturn(new StartBatchEvent($message->serializeToString()));
88
89        $serverCallReader = new \Grpc\ServerCallReader(
90            $this->mockCall,
91            '\StringValue'
92        );
93        $return = $serverCallReader->read();
94        $this->assertEquals($message, $return);
95    }
96
97    public function testStartEmptyMetadata()
98    {
99        $this->mockCall->expects($this->once())
100            ->method('startBatch')
101            ->with($this->identicalTo([
102                \Grpc\OP_SEND_INITIAL_METADATA => [],
103            ]));
104
105        $serverCallWriter = new \Grpc\ServerCallWriter(
106            $this->mockCall,
107            $this->serverContext
108        );
109        $this->serverContext->setInitialMetadata([]);
110        $serverCallWriter->start();
111    }
112
113    public function testStartWithMetadata()
114    {
115        $metadata = ['a' => 1];
116
117        $this->mockCall->expects($this->once())
118            ->method('startBatch')
119            ->with($this->identicalTo([
120                \Grpc\OP_SEND_INITIAL_METADATA => $metadata,
121            ]));
122
123        $serverCallWriter = new \Grpc\ServerCallWriter(
124            $this->mockCall,
125            $this->serverContext
126        );
127        $this->serverContext->setInitialMetadata($metadata);
128        $serverCallWriter->start();
129        return $serverCallWriter;
130    }
131
132    public function testStartWithMessage()
133    {
134        $metadata = ['a' => 1];
135        $message = $this->newStringMessage();
136
137        $this->mockCall->expects($this->once())
138            ->method('startBatch')
139            ->with($this->identicalTo([
140                \Grpc\OP_SEND_INITIAL_METADATA => $metadata,
141                \Grpc\OP_SEND_MESSAGE => ['message' => $message->serializeToString()],
142            ]));
143
144        $serverCallWriter = new \Grpc\ServerCallWriter(
145            $this->mockCall,
146            $this->serverContext
147        );
148        $this->serverContext->setInitialMetadata($metadata);
149        $serverCallWriter->start($message);
150    }
151
152    public function testWriteStartWithMessageAndOptions()
153    {
154        $metadata = ['a' => 1];
155        $message = $this->newStringMessage();
156
157        $this->mockCall->expects($this->once())
158            ->method('startBatch')
159            ->with($this->identicalTo([
160                \Grpc\OP_SEND_INITIAL_METADATA => $metadata,
161                \Grpc\OP_SEND_MESSAGE => [
162                    'message' => $message->serializeToString(),
163                    'flags' => 0x02,
164                ],
165            ]));
166
167        $serverCallWriter = new \Grpc\ServerCallWriter(
168            $this->mockCall,
169            $this->serverContext
170        );
171        $this->serverContext->setInitialMetadata($metadata);
172        $serverCallWriter->start($message, ['flags' => 0x02]);
173    }
174
175    public function testWriteDataOnly()
176    {
177        $message = $this->newStringMessage();
178
179        $this->mockCall->expects($this->once())
180            ->method('startBatch')
181            ->with($this->identicalTo([
182                \Grpc\OP_SEND_INITIAL_METADATA => [],
183                \Grpc\OP_SEND_MESSAGE => ['message' => $message->serializeToString()],
184            ]));
185
186        $serverCallWriter = new \Grpc\ServerCallWriter(
187            $this->mockCall,
188            $this->serverContext
189        );
190        $serverCallWriter->write($message);
191    }
192
193    public function testWriteDataWithOptions()
194    {
195        $message = $this->newStringMessage();
196
197        $this->mockCall->expects($this->once())
198            ->method('startBatch')
199            ->with($this->identicalTo([
200                \Grpc\OP_SEND_INITIAL_METADATA => [],
201                \Grpc\OP_SEND_MESSAGE => [
202                    'message' => $message->serializeToString(),
203                    'flags' => 0x02
204                ],
205            ]));
206
207        $serverCallWriter = new \Grpc\ServerCallWriter(
208            $this->mockCall,
209            $this->serverContext
210        );
211        $serverCallWriter->write($message, ['flags' => 0x02]);
212    }
213
214    public function testWriteDataWithMetadata()
215    {
216        $metadata = ['a' => 1];
217        $message = $this->newStringMessage();
218
219        $this->mockCall->expects($this->once())
220            ->method('startBatch')
221            ->with($this->identicalTo([
222                \Grpc\OP_SEND_INITIAL_METADATA => $metadata,
223                \Grpc\OP_SEND_MESSAGE => ['message' => $message->serializeToString()],
224            ]));
225
226        $serverCallWriter = new \Grpc\ServerCallWriter(
227            $this->mockCall,
228            $this->serverContext
229        );
230        $this->serverContext->setInitialMetadata($metadata);
231        $serverCallWriter->write($message, []);
232    }
233
234    public function testFinish()
235    {
236        $status = \Grpc\Status::status(
237            \Grpc\STATUS_INVALID_ARGUMENT,
238            "invalid argument",
239            ['trailiingMeta' => 100]
240        );
241
242        $this->mockCall->expects($this->once())
243            ->method('startBatch')
244            ->with($this->identicalTo([
245                \Grpc\OP_SEND_STATUS_FROM_SERVER => $status,
246                \Grpc\OP_RECV_CLOSE_ON_SERVER => true,
247                \Grpc\OP_SEND_INITIAL_METADATA => [],
248            ]));
249
250        $serverCallWriter = new \Grpc\ServerCallWriter(
251            $this->mockCall,
252            $this->serverContext
253        );
254        $this->serverContext->setStatus($status);
255        $serverCallWriter->finish();
256    }
257
258    public function testFinishWithMetadataAndMessage()
259    {
260        $metadata = ['a' => 1];
261        $message = $this->newStringMessage();
262        $status = \Grpc\Status::ok(['trailiingMeta' => 100]);
263
264        $this->mockCall->expects($this->once())
265            ->method('startBatch')
266            ->with($this->identicalTo([
267                \Grpc\OP_SEND_STATUS_FROM_SERVER => $status,
268                \Grpc\OP_RECV_CLOSE_ON_SERVER => true,
269                \Grpc\OP_SEND_INITIAL_METADATA => $metadata,
270                \Grpc\OP_SEND_MESSAGE => [
271                    'message' => $message->serializeToString(),
272                    'flags' => 0x02,
273                ],
274            ]));
275
276        $serverCallWriter = new \Grpc\ServerCallWriter(
277            $this->mockCall,
278            $this->serverContext
279        );
280        $this->serverContext->setInitialMetadata($metadata);
281        $this->serverContext->setStatus($status);
282        $serverCallWriter->finish($message, ['flags' => 0x02]);
283    }
284
285    /**
286     * @todo `at` is deprecated and will be removed in phpunit 10
287     */
288    public function testStartWriteFinish()
289    {
290        $metadata = ['a' => 1];
291        $metadata2 = ['a' => 2];
292        $message1 = $this->newStringMessage();
293        $message2 = $this->newStringMessage('another string');
294
295        $this->mockCall->expects($this->exactly(4))
296            ->method('startBatch')
297            ->withConsecutive(
298                [$this->identicalTo([
299                    \Grpc\OP_SEND_INITIAL_METADATA => $metadata,
300                ])],
301                [$this->identicalTo([
302                    \Grpc\OP_SEND_MESSAGE => ['message' => $message1->serializeToString()],
303                ])],
304                [$this->identicalTo([
305                    \Grpc\OP_SEND_MESSAGE => [
306                        'message' => $message2->serializeToString(),
307                        'flags' => 0x02,
308                    ]
309                ])],
310                [$this->identicalTo([
311                    \Grpc\OP_SEND_STATUS_FROM_SERVER => \Grpc\Status::ok(),
312                    \Grpc\OP_RECV_CLOSE_ON_SERVER => true,
313                ])]
314            );
315
316        $serverCallWriter = new \Grpc\ServerCallWriter(
317            $this->mockCall,
318            $this->serverContext
319        );
320        $this->serverContext->setInitialMetadata($metadata);
321        $serverCallWriter->start();
322        $serverCallWriter->write($message1, [], $metadata2 /* should not send */);
323        $serverCallWriter->write($message2, ['flags' => 0x02]);
324        $serverCallWriter->finish();
325    }
326}
327