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 20class CallCredentials2Test extends \PHPUnit\Framework\TestCase 21{ 22 private $server; 23 private $port; 24 private $host_override; 25 private $channel; 26 27 public function setUp(): void 28 { 29 $credentials = Grpc\ChannelCredentials::createSsl( 30 file_get_contents(dirname(__FILE__).'/../data/ca.pem')); 31 $server_credentials = Grpc\ServerCredentials::createSsl( 32 null, 33 file_get_contents(dirname(__FILE__).'/../data/server1.key'), 34 file_get_contents(dirname(__FILE__).'/../data/server1.pem')); 35 $this->server = new Grpc\Server(); 36 $this->port = $this->server->addSecureHttp2Port('0.0.0.0:0', 37 $server_credentials); 38 $this->server->start(); 39 $this->host_override = 'foo.test.google.fr'; 40 $this->channel = new Grpc\Channel( 41 'localhost:'.$this->port, 42 [ 43 'force_new' => true, 44 'grpc.ssl_target_name_override' => $this->host_override, 45 'grpc.default_authority' => $this->host_override, 46 'credentials' => $credentials, 47 ] 48 ); 49 } 50 51 public function tearDown(): void 52 { 53 unset($this->channel); 54 unset($this->server); 55 } 56 57 public function callbackFunc($context) 58 { 59 $this->assertTrue(is_string($context->service_url)); 60 $this->assertTrue(is_string($context->method_name)); 61 62 return ['k1' => ['v1'], 'k2' => ['v2']]; 63 } 64 65 public function testCreateFromPlugin() 66 { 67 $deadline = Grpc\Timeval::infFuture(); 68 $status_text = 'xyz'; 69 $call = new Grpc\Call($this->channel, 70 '/abc/phony_method', 71 $deadline, 72 $this->host_override); 73 74 $call_credentials = Grpc\CallCredentials::createFromPlugin( 75 array($this, 'callbackFunc')); 76 $call->setCredentials($call_credentials); 77 78 $event = $call->startBatch([ 79 Grpc\OP_SEND_INITIAL_METADATA => [], 80 Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, 81 ]); 82 83 $this->assertTrue($event->send_metadata); 84 $this->assertTrue($event->send_close); 85 86 $event = $this->server->requestCall(); 87 88 $this->assertTrue(is_array($event->metadata)); 89 $metadata = $event->metadata; 90 $this->assertTrue(array_key_exists('k1', $metadata)); 91 $this->assertTrue(array_key_exists('k2', $metadata)); 92 $this->assertSame($metadata['k1'], ['v1']); 93 $this->assertSame($metadata['k2'], ['v2']); 94 95 $this->assertSame('/abc/phony_method', $event->method); 96 $server_call = $event->call; 97 98 $event = $server_call->startBatch([ 99 Grpc\OP_SEND_INITIAL_METADATA => [], 100 Grpc\OP_SEND_STATUS_FROM_SERVER => [ 101 'metadata' => [], 102 'code' => Grpc\STATUS_OK, 103 'details' => $status_text, 104 ], 105 Grpc\OP_RECV_CLOSE_ON_SERVER => true, 106 ]); 107 108 $this->assertTrue($event->send_metadata); 109 $this->assertTrue($event->send_status); 110 $this->assertFalse($event->cancelled); 111 112 $event = $call->startBatch([ 113 Grpc\OP_RECV_INITIAL_METADATA => true, 114 Grpc\OP_RECV_STATUS_ON_CLIENT => true, 115 ]); 116 117 $this->assertSame([], $event->metadata); 118 $status = $event->status; 119 $this->assertSame([], $status->metadata); 120 $this->assertSame(Grpc\STATUS_OK, $status->code); 121 $this->assertSame($status_text, $status->details); 122 123 unset($call); 124 unset($server_call); 125 } 126 127 public function invalidKeyCallbackFunc($context) 128 { 129 $this->assertTrue(is_string($context->service_url)); 130 $this->assertTrue(is_string($context->method_name)); 131 132 return ['K1' => ['v1']]; 133 } 134 135 public function testCallbackWithInvalidKey() 136 { 137 $deadline = Grpc\Timeval::infFuture(); 138 $status_text = 'xyz'; 139 $call = new Grpc\Call($this->channel, 140 '/abc/phony_method', 141 $deadline, 142 $this->host_override); 143 144 $call_credentials = Grpc\CallCredentials::createFromPlugin( 145 array($this, 'invalidKeyCallbackFunc')); 146 $call->setCredentials($call_credentials); 147 148 $event = $call->startBatch([ 149 Grpc\OP_SEND_INITIAL_METADATA => [], 150 Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, 151 Grpc\OP_RECV_STATUS_ON_CLIENT => true, 152 ]); 153 154 $this->assertTrue($event->send_metadata); 155 $this->assertTrue($event->send_close); 156 $this->assertTrue($event->status->code == Grpc\STATUS_UNAVAILABLE); 157 } 158 159 public function invalidReturnCallbackFunc($context) 160 { 161 $this->assertTrue(is_string($context->service_url)); 162 $this->assertTrue(is_string($context->method_name)); 163 164 return 'a string'; 165 } 166 167 public function testCallbackWithInvalidReturnValue() 168 { 169 $deadline = Grpc\Timeval::infFuture(); 170 $status_text = 'xyz'; 171 $call = new Grpc\Call($this->channel, 172 '/abc/phony_method', 173 $deadline, 174 $this->host_override); 175 176 $call_credentials = Grpc\CallCredentials::createFromPlugin( 177 array($this, 'invalidReturnCallbackFunc')); 178 $call->setCredentials($call_credentials); 179 180 $event = $call->startBatch([ 181 Grpc\OP_SEND_INITIAL_METADATA => [], 182 Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, 183 Grpc\OP_RECV_STATUS_ON_CLIENT => true, 184 ]); 185 186 $this->assertTrue($event->send_metadata); 187 $this->assertTrue($event->send_close); 188 $this->assertTrue($event->status->code == Grpc\STATUS_UNAVAILABLE); 189 } 190} 191