1 # Copyright 2017 gRPC authors. 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 require 'spec_helper' 15 16 describe 'Server Interceptors' do 17 let(:interceptor) { TestServerInterceptor.new } 18 let(:request) { EchoMsg.new } 19 let(:trailing_metadata) { {} } 20 let(:service) { EchoService.new(trailing_metadata) } 21 let(:interceptors) { [] } 22 23 before(:each) do 24 build_rpc_server(server_opts: { interceptors: interceptors }) 25 end 26 27 context 'when a server interceptor is added' do 28 let(:interceptors) { [interceptor] } 29 let(:client_metadata) { { client_md: 'test' } } 30 let(:client_call_opts) { { metadata: client_metadata, return_op: true } } 31 32 context 'with a request/response call' do 33 let(:trailing_metadata) { { server_om: 'from_request_response' } } 34 35 it 'should be called', server: true do 36 expect(interceptor).to receive(:request_response) 37 .once.and_call_original 38 39 run_services_on_server(@server, services: [service]) do 40 stub = build_insecure_stub(EchoStub) 41 expect(stub.an_rpc(request)).to be_a(EchoMsg) 42 end 43 end 44 45 it 'can modify trailing metadata', server: true do 46 expect(interceptor).to receive(:request_response) 47 .once.and_call_original 48 49 run_services_on_server(@server, services: [service]) do 50 stub = build_insecure_stub(EchoStub) 51 expect_any_instance_of(GRPC::ActiveCall).to( 52 receive(:request_response).with(request, metadata: client_metadata) 53 .once.and_call_original 54 ) 55 op = stub.an_rpc(request, client_call_opts) 56 msg = op.execute 57 expect(op.trailing_metadata).to eq( 58 'interc' => 'from_request_response', 59 'server_om' => 'from_request_response' 60 ) 61 expect(msg).to be_a(EchoMsg) 62 end 63 end 64 end 65 66 context 'with a client streaming call' do 67 let(:trailing_metadata) { { server_om: 'from_client_streamer' } } 68 let(:requests) { [EchoMsg.new, EchoMsg.new] } 69 70 it 'should be called', server: true do 71 expect(interceptor).to receive(:client_streamer) 72 .once.and_call_original 73 74 run_services_on_server(@server, services: [service]) do 75 stub = build_insecure_stub(EchoStub) 76 expect(stub.a_client_streaming_rpc(requests)).to be_a(EchoMsg) 77 end 78 end 79 80 it 'can modify trailing metadata', server: true do 81 expect(interceptor).to receive(:client_streamer) 82 .once.and_call_original 83 84 run_services_on_server(@server, services: [service]) do 85 stub = build_insecure_stub(EchoStub) 86 expect_any_instance_of(GRPC::ActiveCall).to( 87 receive(:client_streamer).with(requests) 88 .once.and_call_original 89 ) 90 op = stub.a_client_streaming_rpc(requests, client_call_opts) 91 msg = op.execute 92 expect(op.trailing_metadata).to eq( 93 'interc' => 'from_client_streamer', 94 'server_om' => 'from_client_streamer' 95 ) 96 expect(msg).to be_a(EchoMsg) 97 end 98 end 99 end 100 101 context 'with a server streaming call' do 102 let(:trailing_metadata) { { server_om: 'from_server_streamer' } } 103 let(:request) { EchoMsg.new } 104 105 it 'should be called', server: true do 106 expect(interceptor).to receive(:server_streamer) 107 .once.and_call_original 108 109 run_services_on_server(@server, services: [service]) do 110 stub = build_insecure_stub(EchoStub) 111 responses = stub.a_server_streaming_rpc(request) 112 responses.each do |r| 113 expect(r).to be_a(EchoMsg) 114 end 115 end 116 end 117 118 it 'can modify trailing metadata', server: true do 119 expect(interceptor).to receive(:server_streamer) 120 .once.and_call_original 121 122 run_services_on_server(@server, services: [service]) do 123 stub = build_insecure_stub(EchoStub) 124 expect_any_instance_of(GRPC::ActiveCall).to( 125 receive(:server_streamer).with(request) 126 .once.and_call_original 127 ) 128 op = stub.a_server_streaming_rpc(request, client_call_opts) 129 responses = op.execute 130 responses.each do |r| 131 expect(r).to be_a(EchoMsg) 132 end 133 expect(op.trailing_metadata).to eq( 134 'interc' => 'from_server_streamer', 135 'server_om' => 'from_server_streamer' 136 ) 137 end 138 end 139 end 140 141 context 'with a bidi call' do 142 let(:trailing_metadata) { { server_om: 'from_bidi_streamer' } } 143 let(:requests) { [EchoMsg.new, EchoMsg.new] } 144 145 it 'should be called', server: true do 146 expect(interceptor).to receive(:bidi_streamer) 147 .once.and_call_original 148 149 run_services_on_server(@server, services: [service]) do 150 stub = build_insecure_stub(EchoStub) 151 responses = stub.a_bidi_rpc(requests) 152 responses.each do |r| 153 expect(r).to be_a(EchoMsg) 154 end 155 end 156 end 157 158 it 'can modify trailing metadata', server: true do 159 expect(interceptor).to receive(:bidi_streamer) 160 .once.and_call_original 161 162 run_services_on_server(@server, services: [service]) do 163 stub = build_insecure_stub(EchoStub) 164 expect_any_instance_of(GRPC::ActiveCall).to( 165 receive(:bidi_streamer).with(requests) 166 .once.and_call_original 167 ) 168 op = stub.a_bidi_rpc(requests, client_call_opts) 169 responses = op.execute 170 responses.each do |r| 171 expect(r).to be_a(EchoMsg) 172 end 173 expect(op.trailing_metadata).to eq( 174 'interc' => 'from_bidi_streamer', 175 'server_om' => 'from_bidi_streamer' 176 ) 177 end 178 end 179 end 180 end 181 182 context 'when multiple interceptors are added' do 183 let(:interceptor2) { TestServerInterceptor.new } 184 let(:interceptor3) { TestServerInterceptor.new } 185 let(:interceptors) do 186 [ 187 interceptor, 188 interceptor2, 189 interceptor3 190 ] 191 end 192 193 it 'each should be called', server: true do 194 expect(interceptor).to receive(:request_response) 195 .once.and_call_original 196 expect(interceptor2).to receive(:request_response) 197 .once.and_call_original 198 expect(interceptor3).to receive(:request_response) 199 .once.and_call_original 200 201 run_services_on_server(@server, services: [service]) do 202 stub = build_insecure_stub(EchoStub) 203 expect(stub.an_rpc(request)).to be_a(EchoMsg) 204 end 205 end 206 end 207 208 context 'when an interceptor is not added' do 209 it 'should not be called', server: true do 210 expect(interceptor).to_not receive(:call) 211 212 run_services_on_server(@server, services: [service]) do 213 stub = build_insecure_stub(EchoStub) 214 expect(stub.an_rpc(request)).to be_a(EchoMsg) 215 end 216 end 217 end 218 end 219