|  | @@ -0,0 +1,218 @@
 | 
	
		
			
				|  |  | +# Copyright 2017 gRPC authors.
 | 
	
		
			
				|  |  | +#
 | 
	
		
			
				|  |  | +# Licensed under the Apache License, Version 2.0 (the "License");
 | 
	
		
			
				|  |  | +# you may not use this file except in compliance with the License.
 | 
	
		
			
				|  |  | +# You may obtain a copy of the License at
 | 
	
		
			
				|  |  | +#
 | 
	
		
			
				|  |  | +#     http://www.apache.org/licenses/LICENSE-2.0
 | 
	
		
			
				|  |  | +#
 | 
	
		
			
				|  |  | +# Unless required by applicable law or agreed to in writing, software
 | 
	
		
			
				|  |  | +# distributed under the License is distributed on an "AS IS" BASIS,
 | 
	
		
			
				|  |  | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
	
		
			
				|  |  | +# See the License for the specific language governing permissions and
 | 
	
		
			
				|  |  | +# limitations under the License.
 | 
	
		
			
				|  |  | +require 'spec_helper'
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +describe 'Server Interceptors' do
 | 
	
		
			
				|  |  | +  let(:interceptor) { TestServerInterceptor.new }
 | 
	
		
			
				|  |  | +  let(:request) { EchoMsg.new }
 | 
	
		
			
				|  |  | +  let(:trailing_metadata) { {} }
 | 
	
		
			
				|  |  | +  let(:service) { EchoService.new(trailing_metadata) }
 | 
	
		
			
				|  |  | +  let(:interceptors) { [] }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  before(:each) do
 | 
	
		
			
				|  |  | +    build_rpc_server(server_opts: { interceptors: interceptors })
 | 
	
		
			
				|  |  | +  end
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  context 'when a server interceptor is added' do
 | 
	
		
			
				|  |  | +    let(:interceptors) { [interceptor] }
 | 
	
		
			
				|  |  | +    let(:client_metadata) { { client_md: 'test' } }
 | 
	
		
			
				|  |  | +    let(:client_call_opts) { { metadata: client_metadata, return_op: true } }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    context 'with a request/response call' do
 | 
	
		
			
				|  |  | +      let(:trailing_metadata) { { server_om: 'from_request_response' } }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      it 'should be called', server: true do
 | 
	
		
			
				|  |  | +        expect(interceptor).to receive(:request_response)
 | 
	
		
			
				|  |  | +          .once.and_call_original
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        run_services_on_server(@server, services: [service]) do
 | 
	
		
			
				|  |  | +          stub = build_insecure_stub(EchoStub)
 | 
	
		
			
				|  |  | +          expect(stub.an_rpc(request)).to be_a(EchoMsg)
 | 
	
		
			
				|  |  | +        end
 | 
	
		
			
				|  |  | +      end
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      it 'can modify trailing metadata', server: true do
 | 
	
		
			
				|  |  | +        expect(interceptor).to receive(:request_response)
 | 
	
		
			
				|  |  | +          .once.and_call_original
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        run_services_on_server(@server, services: [service]) do
 | 
	
		
			
				|  |  | +          stub = build_insecure_stub(EchoStub)
 | 
	
		
			
				|  |  | +          expect_any_instance_of(GRPC::ActiveCall).to(
 | 
	
		
			
				|  |  | +            receive(:request_response).with(request, metadata: client_metadata)
 | 
	
		
			
				|  |  | +              .once.and_call_original
 | 
	
		
			
				|  |  | +          )
 | 
	
		
			
				|  |  | +          op = stub.an_rpc(request, client_call_opts)
 | 
	
		
			
				|  |  | +          msg = op.execute
 | 
	
		
			
				|  |  | +          expect(op.trailing_metadata).to eq(
 | 
	
		
			
				|  |  | +            'interc' => 'from_request_response',
 | 
	
		
			
				|  |  | +            'server_om' => 'from_request_response'
 | 
	
		
			
				|  |  | +          )
 | 
	
		
			
				|  |  | +          expect(msg).to be_a(EchoMsg)
 | 
	
		
			
				|  |  | +        end
 | 
	
		
			
				|  |  | +      end
 | 
	
		
			
				|  |  | +    end
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    context 'with a client streaming call' do
 | 
	
		
			
				|  |  | +      let(:trailing_metadata) { { server_om: 'from_client_streamer' } }
 | 
	
		
			
				|  |  | +      let(:requests) { [EchoMsg.new, EchoMsg.new] }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      it 'should be called', server: true do
 | 
	
		
			
				|  |  | +        expect(interceptor).to receive(:client_streamer)
 | 
	
		
			
				|  |  | +          .once.and_call_original
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        run_services_on_server(@server, services: [service]) do
 | 
	
		
			
				|  |  | +          stub = build_insecure_stub(EchoStub)
 | 
	
		
			
				|  |  | +          expect(stub.a_client_streaming_rpc(requests)).to be_a(EchoMsg)
 | 
	
		
			
				|  |  | +        end
 | 
	
		
			
				|  |  | +      end
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      it 'can modify trailing metadata', server: true do
 | 
	
		
			
				|  |  | +        expect(interceptor).to receive(:client_streamer)
 | 
	
		
			
				|  |  | +          .once.and_call_original
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        run_services_on_server(@server, services: [service]) do
 | 
	
		
			
				|  |  | +          stub = build_insecure_stub(EchoStub)
 | 
	
		
			
				|  |  | +          expect_any_instance_of(GRPC::ActiveCall).to(
 | 
	
		
			
				|  |  | +            receive(:client_streamer).with(requests)
 | 
	
		
			
				|  |  | +              .once.and_call_original
 | 
	
		
			
				|  |  | +          )
 | 
	
		
			
				|  |  | +          op = stub.a_client_streaming_rpc(requests, client_call_opts)
 | 
	
		
			
				|  |  | +          msg = op.execute
 | 
	
		
			
				|  |  | +          expect(op.trailing_metadata).to eq(
 | 
	
		
			
				|  |  | +            'interc' => 'from_client_streamer',
 | 
	
		
			
				|  |  | +            'server_om' => 'from_client_streamer'
 | 
	
		
			
				|  |  | +          )
 | 
	
		
			
				|  |  | +          expect(msg).to be_a(EchoMsg)
 | 
	
		
			
				|  |  | +        end
 | 
	
		
			
				|  |  | +      end
 | 
	
		
			
				|  |  | +    end
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    context 'with a server streaming call' do
 | 
	
		
			
				|  |  | +      let(:trailing_metadata) { { server_om: 'from_server_streamer' } }
 | 
	
		
			
				|  |  | +      let(:request) { EchoMsg.new }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      it 'should be called', server: true do
 | 
	
		
			
				|  |  | +        expect(interceptor).to receive(:server_streamer)
 | 
	
		
			
				|  |  | +          .once.and_call_original
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        run_services_on_server(@server, services: [service]) do
 | 
	
		
			
				|  |  | +          stub = build_insecure_stub(EchoStub)
 | 
	
		
			
				|  |  | +          responses = stub.a_server_streaming_rpc(request)
 | 
	
		
			
				|  |  | +          responses.each do |r|
 | 
	
		
			
				|  |  | +            expect(r).to be_a(EchoMsg)
 | 
	
		
			
				|  |  | +          end
 | 
	
		
			
				|  |  | +        end
 | 
	
		
			
				|  |  | +      end
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      it 'can modify trailing metadata', server: true do
 | 
	
		
			
				|  |  | +        expect(interceptor).to receive(:server_streamer)
 | 
	
		
			
				|  |  | +          .once.and_call_original
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        run_services_on_server(@server, services: [service]) do
 | 
	
		
			
				|  |  | +          stub = build_insecure_stub(EchoStub)
 | 
	
		
			
				|  |  | +          expect_any_instance_of(GRPC::ActiveCall).to(
 | 
	
		
			
				|  |  | +            receive(:server_streamer).with(request)
 | 
	
		
			
				|  |  | +              .once.and_call_original
 | 
	
		
			
				|  |  | +          )
 | 
	
		
			
				|  |  | +          op = stub.a_server_streaming_rpc(request, client_call_opts)
 | 
	
		
			
				|  |  | +          responses = op.execute
 | 
	
		
			
				|  |  | +          responses.each do |r|
 | 
	
		
			
				|  |  | +            expect(r).to be_a(EchoMsg)
 | 
	
		
			
				|  |  | +          end
 | 
	
		
			
				|  |  | +          expect(op.trailing_metadata).to eq(
 | 
	
		
			
				|  |  | +            'interc' => 'from_server_streamer',
 | 
	
		
			
				|  |  | +            'server_om' => 'from_server_streamer'
 | 
	
		
			
				|  |  | +          )
 | 
	
		
			
				|  |  | +        end
 | 
	
		
			
				|  |  | +      end
 | 
	
		
			
				|  |  | +    end
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    context 'with a bidi call' do
 | 
	
		
			
				|  |  | +      let(:trailing_metadata) { { server_om: 'from_bidi_streamer' } }
 | 
	
		
			
				|  |  | +      let(:requests) { [EchoMsg.new, EchoMsg.new] }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      it 'should be called', server: true do
 | 
	
		
			
				|  |  | +        expect(interceptor).to receive(:bidi_streamer)
 | 
	
		
			
				|  |  | +          .once.and_call_original
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        run_services_on_server(@server, services: [service]) do
 | 
	
		
			
				|  |  | +          stub = build_insecure_stub(EchoStub)
 | 
	
		
			
				|  |  | +          responses = stub.a_bidi_rpc(requests)
 | 
	
		
			
				|  |  | +          responses.each do |r|
 | 
	
		
			
				|  |  | +            expect(r).to be_a(EchoMsg)
 | 
	
		
			
				|  |  | +          end
 | 
	
		
			
				|  |  | +        end
 | 
	
		
			
				|  |  | +      end
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      it 'can modify trailing metadata', server: true do
 | 
	
		
			
				|  |  | +        expect(interceptor).to receive(:bidi_streamer)
 | 
	
		
			
				|  |  | +          .once.and_call_original
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        run_services_on_server(@server, services: [service]) do
 | 
	
		
			
				|  |  | +          stub = build_insecure_stub(EchoStub)
 | 
	
		
			
				|  |  | +          expect_any_instance_of(GRPC::ActiveCall).to(
 | 
	
		
			
				|  |  | +            receive(:bidi_streamer).with(requests)
 | 
	
		
			
				|  |  | +              .once.and_call_original
 | 
	
		
			
				|  |  | +          )
 | 
	
		
			
				|  |  | +          op = stub.a_bidi_rpc(requests, client_call_opts)
 | 
	
		
			
				|  |  | +          responses = op.execute
 | 
	
		
			
				|  |  | +          responses.each do |r|
 | 
	
		
			
				|  |  | +            expect(r).to be_a(EchoMsg)
 | 
	
		
			
				|  |  | +          end
 | 
	
		
			
				|  |  | +          expect(op.trailing_metadata).to eq(
 | 
	
		
			
				|  |  | +            'interc' => 'from_bidi_streamer',
 | 
	
		
			
				|  |  | +            'server_om' => 'from_bidi_streamer'
 | 
	
		
			
				|  |  | +          )
 | 
	
		
			
				|  |  | +        end
 | 
	
		
			
				|  |  | +      end
 | 
	
		
			
				|  |  | +    end
 | 
	
		
			
				|  |  | +  end
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  context 'when multiple interceptors are added' do
 | 
	
		
			
				|  |  | +    let(:interceptor2) { TestServerInterceptor.new }
 | 
	
		
			
				|  |  | +    let(:interceptor3) { TestServerInterceptor.new }
 | 
	
		
			
				|  |  | +    let(:interceptors) do
 | 
	
		
			
				|  |  | +      [
 | 
	
		
			
				|  |  | +        interceptor,
 | 
	
		
			
				|  |  | +        interceptor2,
 | 
	
		
			
				|  |  | +        interceptor3
 | 
	
		
			
				|  |  | +      ]
 | 
	
		
			
				|  |  | +    end
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    it 'each should be called', server: true do
 | 
	
		
			
				|  |  | +      expect(interceptor).to receive(:request_response)
 | 
	
		
			
				|  |  | +        .once.and_call_original
 | 
	
		
			
				|  |  | +      expect(interceptor2).to receive(:request_response)
 | 
	
		
			
				|  |  | +        .once.and_call_original
 | 
	
		
			
				|  |  | +      expect(interceptor3).to receive(:request_response)
 | 
	
		
			
				|  |  | +        .once.and_call_original
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      run_services_on_server(@server, services: [service]) do
 | 
	
		
			
				|  |  | +        stub = build_insecure_stub(EchoStub)
 | 
	
		
			
				|  |  | +        expect(stub.an_rpc(request)).to be_a(EchoMsg)
 | 
	
		
			
				|  |  | +      end
 | 
	
		
			
				|  |  | +    end
 | 
	
		
			
				|  |  | +  end
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  context 'when an interceptor is not added' do
 | 
	
		
			
				|  |  | +    it 'should not be called', server: true do
 | 
	
		
			
				|  |  | +      expect(interceptor).to_not receive(:call)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      run_services_on_server(@server, services: [service]) do
 | 
	
		
			
				|  |  | +        stub = build_insecure_stub(EchoStub)
 | 
	
		
			
				|  |  | +        expect(stub.an_rpc(request)).to be_a(EchoMsg)
 | 
	
		
			
				|  |  | +      end
 | 
	
		
			
				|  |  | +    end
 | 
	
		
			
				|  |  | +  end
 | 
	
		
			
				|  |  | +end
 |