1# Copyright 2015 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 15require 'spec_helper' 16require 'English' 17 18def load_test_certs 19 test_root = File.join(File.dirname(__FILE__), 'testdata') 20 files = ['ca.pem', 'server1.key', 'server1.pem'] 21 files.map { |f| File.open(File.join(test_root, f)).read } 22end 23 24describe GRPC::Core::Channel do 25 let(:fake_host) { 'localhost:0' } 26 27 def create_test_cert 28 GRPC::Core::ChannelCredentials.new(load_test_certs[0]) 29 end 30 31 shared_examples '#new' do 32 it 'take a host name without channel args' do 33 blk = proc do 34 GRPC::Core::Channel.new('phony_host', nil, :this_channel_is_insecure) 35 end 36 expect(&blk).not_to raise_error 37 end 38 39 it 'does not take a hash with bad keys as channel args' do 40 blk = construct_with_args(Object.new => 1) 41 expect(&blk).to raise_error TypeError 42 blk = construct_with_args(1 => 1) 43 expect(&blk).to raise_error TypeError 44 end 45 46 it 'does not take a hash with bad values as channel args' do 47 blk = construct_with_args(symbol: Object.new) 48 expect(&blk).to raise_error TypeError 49 blk = construct_with_args('1' => {}) 50 expect(&blk).to raise_error TypeError 51 end 52 53 it 'can take a hash with a symbol key as channel args' do 54 blk = construct_with_args(a_symbol: 1) 55 expect(&blk).to_not raise_error 56 end 57 58 it 'can take a hash with a string key as channel args' do 59 blk = construct_with_args('a_symbol' => 1) 60 expect(&blk).to_not raise_error 61 end 62 63 it 'can take a hash with a string value as channel args' do 64 blk = construct_with_args(a_symbol: '1') 65 expect(&blk).to_not raise_error 66 end 67 68 it 'can take a hash with a symbol value as channel args' do 69 blk = construct_with_args(a_symbol: :another_symbol) 70 expect(&blk).to_not raise_error 71 end 72 73 it 'can take a hash with a numeric value as channel args' do 74 blk = construct_with_args(a_symbol: 1) 75 expect(&blk).to_not raise_error 76 end 77 78 it 'can take a hash with many args as channel args' do 79 args = Hash[127.times.collect { |x| [x.to_s, x] }] 80 blk = construct_with_args(args) 81 expect(&blk).to_not raise_error 82 end 83 end 84 85 describe '#new for secure channels' do 86 def construct_with_args(a) 87 proc { GRPC::Core::Channel.new('phony_host', a, create_test_cert) } 88 end 89 90 it_behaves_like '#new' 91 end 92 93 describe '#new for insecure channels' do 94 it_behaves_like '#new' 95 96 def construct_with_args(a) 97 proc do 98 GRPC::Core::Channel.new('phony_host', a, :this_channel_is_insecure) 99 end 100 end 101 end 102 103 describe '#new for XDS channels' do 104 it_behaves_like '#new' 105 106 def construct_with_args(a) 107 proc do 108 xds_creds = GRPC::Core::XdsChannelCredentials.new(create_test_cert) 109 GRPC::Core::Channel.new('dummy_host', a, xds_creds) 110 end 111 end 112 end 113 114 describe '#create_call' do 115 it 'creates a call OK' do 116 ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure) 117 118 deadline = Time.now + 5 119 120 blk = proc do 121 ch.create_call(nil, nil, 'phony_method', nil, deadline) 122 end 123 expect(&blk).to_not raise_error 124 end 125 126 it 'raises an error if called on a closed channel' do 127 STDERR.puts "#{Time.now}: begin: raises an error if called on a closed channel" 128 ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure) 129 STDERR.puts "#{Time.now}: created channel" 130 ch.close 131 STDERR.puts "#{Time.now}: closed channel" 132 133 deadline = Time.now + 5 134 blk = proc do 135 ch.create_call(nil, nil, 'phony_method', nil, deadline) 136 STDERR.puts "#{Time.now}: created call" 137 end 138 expect(&blk).to raise_error(RuntimeError) 139 STDERR.puts "#{Time.now}: finished: raises an error if called on a closed channel" 140 end 141 end 142 143 describe '#destroy' do 144 it 'destroys a channel ok' do 145 ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure) 146 blk = proc { ch.destroy } 147 expect(&blk).to_not raise_error 148 end 149 150 it 'can be called more than once without error' do 151 ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure) 152 blk = proc { ch.destroy } 153 blk.call 154 expect(&blk).to_not raise_error 155 end 156 end 157 158 describe '#connectivity_state' do 159 it 'returns an enum' do 160 ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure) 161 valid_states = [ 162 GRPC::Core::ConnectivityStates::IDLE, 163 GRPC::Core::ConnectivityStates::CONNECTING, 164 GRPC::Core::ConnectivityStates::READY, 165 GRPC::Core::ConnectivityStates::TRANSIENT_FAILURE, 166 GRPC::Core::ConnectivityStates::FATAL_FAILURE 167 ] 168 169 expect(valid_states).to include(ch.connectivity_state) 170 end 171 172 it 'returns an enum when trying to connect' do 173 ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure) 174 ch.connectivity_state(true) 175 valid_states = [ 176 GRPC::Core::ConnectivityStates::IDLE, 177 GRPC::Core::ConnectivityStates::CONNECTING, 178 GRPC::Core::ConnectivityStates::READY, 179 GRPC::Core::ConnectivityStates::TRANSIENT_FAILURE, 180 GRPC::Core::ConnectivityStates::FATAL_FAILURE 181 ] 182 183 expect(valid_states).to include(ch.connectivity_state) 184 end 185 end 186 187 describe '::SSL_TARGET' do 188 it 'is a symbol' do 189 expect(GRPC::Core::Channel::SSL_TARGET).to be_a(Symbol) 190 end 191 end 192 193 describe '#close' do 194 it 'closes a channel ok' do 195 ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure) 196 blk = proc { ch.close } 197 expect(&blk).to_not raise_error 198 end 199 200 it 'can be called more than once without error' do 201 ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure) 202 blk = proc { ch.close } 203 blk.call 204 expect(&blk).to_not raise_error 205 end 206 end 207end 208