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