xref: /aosp_15_r20/external/grpc-grpc/src/ruby/end2end/end2end_common.rb (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker#!/usr/bin/env ruby
2*cc02d7e2SAndroid Build Coastguard Worker
3*cc02d7e2SAndroid Build Coastguard Worker# Copyright 2015 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker#
5*cc02d7e2SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker# You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker#
9*cc02d7e2SAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker#
11*cc02d7e2SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker# limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker
17*cc02d7e2SAndroid Build Coastguard Workerthis_dir = File.expand_path(File.dirname(__FILE__))
18*cc02d7e2SAndroid Build Coastguard Workerprotos_lib_dir = File.join(this_dir, 'lib')
19*cc02d7e2SAndroid Build Coastguard Workergrpc_lib_dir = File.join(File.dirname(this_dir), 'lib')
20*cc02d7e2SAndroid Build Coastguard Worker$LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
21*cc02d7e2SAndroid Build Coastguard Worker$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir)
22*cc02d7e2SAndroid Build Coastguard Worker$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
23*cc02d7e2SAndroid Build Coastguard Worker
24*cc02d7e2SAndroid Build Coastguard Workerrequire 'grpc'
25*cc02d7e2SAndroid Build Coastguard Workerrequire 'echo_services_pb'
26*cc02d7e2SAndroid Build Coastguard Workerrequire 'client_control_services_pb'
27*cc02d7e2SAndroid Build Coastguard Workerrequire 'socket'
28*cc02d7e2SAndroid Build Coastguard Workerrequire 'optparse'
29*cc02d7e2SAndroid Build Coastguard Workerrequire 'thread'
30*cc02d7e2SAndroid Build Coastguard Workerrequire 'timeout'
31*cc02d7e2SAndroid Build Coastguard Workerrequire 'English' # see https://github.com/bbatsov/rubocop/issues/1747
32*cc02d7e2SAndroid Build Coastguard Workerrequire_relative '../spec/support/helpers'
33*cc02d7e2SAndroid Build Coastguard Worker
34*cc02d7e2SAndroid Build Coastguard Workerinclude GRPC::Spec::Helpers
35*cc02d7e2SAndroid Build Coastguard Worker
36*cc02d7e2SAndroid Build Coastguard Worker# Useful to update a value within a do block
37*cc02d7e2SAndroid Build Coastguard Workerclass MutableValue
38*cc02d7e2SAndroid Build Coastguard Worker  attr_accessor :value
39*cc02d7e2SAndroid Build Coastguard Worker
40*cc02d7e2SAndroid Build Coastguard Worker  def initialize(value)
41*cc02d7e2SAndroid Build Coastguard Worker    @value = value
42*cc02d7e2SAndroid Build Coastguard Worker  end
43*cc02d7e2SAndroid Build Coastguard Workerend
44*cc02d7e2SAndroid Build Coastguard Worker
45*cc02d7e2SAndroid Build Coastguard Workerclass EchoServerImpl < Echo::EchoServer::Service
46*cc02d7e2SAndroid Build Coastguard Worker  def echo(echo_req, _)
47*cc02d7e2SAndroid Build Coastguard Worker    Echo::EchoReply.new(response: echo_req.request)
48*cc02d7e2SAndroid Build Coastguard Worker  end
49*cc02d7e2SAndroid Build Coastguard Workerend
50*cc02d7e2SAndroid Build Coastguard Worker
51*cc02d7e2SAndroid Build Coastguard Workerclass SecureEchoServerImpl < Echo::EchoServer::Service
52*cc02d7e2SAndroid Build Coastguard Worker  def echo(echo_req, call)
53*cc02d7e2SAndroid Build Coastguard Worker    unless call.metadata["authorization"] == 'test'
54*cc02d7e2SAndroid Build Coastguard Worker      fail "expected authorization header with value: test"
55*cc02d7e2SAndroid Build Coastguard Worker    end
56*cc02d7e2SAndroid Build Coastguard Worker    Echo::EchoReply.new(response: echo_req.request)
57*cc02d7e2SAndroid Build Coastguard Worker  end
58*cc02d7e2SAndroid Build Coastguard Workerend
59*cc02d7e2SAndroid Build Coastguard Worker
60*cc02d7e2SAndroid Build Coastguard Worker# ServerRunner starts an "echo server" that test clients can make calls to
61*cc02d7e2SAndroid Build Coastguard Workerclass ServerRunner
62*cc02d7e2SAndroid Build Coastguard Worker  attr_accessor :server_creds
63*cc02d7e2SAndroid Build Coastguard Worker
64*cc02d7e2SAndroid Build Coastguard Worker  def initialize(service_impl, rpc_server_args: {})
65*cc02d7e2SAndroid Build Coastguard Worker    @service_impl = service_impl
66*cc02d7e2SAndroid Build Coastguard Worker    @rpc_server_args = rpc_server_args
67*cc02d7e2SAndroid Build Coastguard Worker    @server_creds = :this_port_is_insecure
68*cc02d7e2SAndroid Build Coastguard Worker  end
69*cc02d7e2SAndroid Build Coastguard Worker
70*cc02d7e2SAndroid Build Coastguard Worker  def run
71*cc02d7e2SAndroid Build Coastguard Worker    @srv = new_rpc_server_for_testing(@rpc_server_args)
72*cc02d7e2SAndroid Build Coastguard Worker    port = @srv.add_http2_port('0.0.0.0:0', @server_creds)
73*cc02d7e2SAndroid Build Coastguard Worker    @srv.handle(@service_impl)
74*cc02d7e2SAndroid Build Coastguard Worker
75*cc02d7e2SAndroid Build Coastguard Worker    @thd = Thread.new do
76*cc02d7e2SAndroid Build Coastguard Worker      @srv.run
77*cc02d7e2SAndroid Build Coastguard Worker    end
78*cc02d7e2SAndroid Build Coastguard Worker    @srv.wait_till_running
79*cc02d7e2SAndroid Build Coastguard Worker    port
80*cc02d7e2SAndroid Build Coastguard Worker  end
81*cc02d7e2SAndroid Build Coastguard Worker
82*cc02d7e2SAndroid Build Coastguard Worker  def stop
83*cc02d7e2SAndroid Build Coastguard Worker    @srv.stop
84*cc02d7e2SAndroid Build Coastguard Worker    @thd.join
85*cc02d7e2SAndroid Build Coastguard Worker    fail 'server not stopped' unless @srv.stopped?
86*cc02d7e2SAndroid Build Coastguard Worker  end
87*cc02d7e2SAndroid Build Coastguard Workerend
88*cc02d7e2SAndroid Build Coastguard Worker
89*cc02d7e2SAndroid Build Coastguard Worker# ClientController is used to start a child process and communicate
90*cc02d7e2SAndroid Build Coastguard Worker# with it for test orchestration purposes via RPCs.
91*cc02d7e2SAndroid Build Coastguard Workerclass ClientController < ClientControl::ParentController::Service
92*cc02d7e2SAndroid Build Coastguard Worker  attr_reader :stub, :client_pid
93*cc02d7e2SAndroid Build Coastguard Worker
94*cc02d7e2SAndroid Build Coastguard Worker  def initialize(client_main, server_port)
95*cc02d7e2SAndroid Build Coastguard Worker    this_dir = File.expand_path(File.dirname(__FILE__))
96*cc02d7e2SAndroid Build Coastguard Worker    client_path = File.join(this_dir, client_main)
97*cc02d7e2SAndroid Build Coastguard Worker    @server = new_rpc_server_for_testing(poll_period: 3)
98*cc02d7e2SAndroid Build Coastguard Worker    port = @server.add_http2_port('localhost:0', :this_port_is_insecure)
99*cc02d7e2SAndroid Build Coastguard Worker    server_thread = Thread.new do
100*cc02d7e2SAndroid Build Coastguard Worker      @server.handle(self)
101*cc02d7e2SAndroid Build Coastguard Worker      @server.run
102*cc02d7e2SAndroid Build Coastguard Worker    end
103*cc02d7e2SAndroid Build Coastguard Worker    @server.wait_till_running
104*cc02d7e2SAndroid Build Coastguard Worker    @client_controller_port_mu = Mutex.new
105*cc02d7e2SAndroid Build Coastguard Worker    @client_controller_port_cv = ConditionVariable.new
106*cc02d7e2SAndroid Build Coastguard Worker    @client_controller_port = nil
107*cc02d7e2SAndroid Build Coastguard Worker    @client_pid = Process.spawn(RbConfig.ruby,
108*cc02d7e2SAndroid Build Coastguard Worker                                client_path,
109*cc02d7e2SAndroid Build Coastguard Worker                                "--parent_controller_port=#{port}",
110*cc02d7e2SAndroid Build Coastguard Worker                                "--server_port=#{server_port}")
111*cc02d7e2SAndroid Build Coastguard Worker    begin
112*cc02d7e2SAndroid Build Coastguard Worker      Timeout.timeout(60) do
113*cc02d7e2SAndroid Build Coastguard Worker        @client_controller_port_mu.synchronize do
114*cc02d7e2SAndroid Build Coastguard Worker          while @client_controller_port.nil?
115*cc02d7e2SAndroid Build Coastguard Worker            @client_controller_port_cv.wait(@client_controller_port_mu)
116*cc02d7e2SAndroid Build Coastguard Worker          end
117*cc02d7e2SAndroid Build Coastguard Worker        end
118*cc02d7e2SAndroid Build Coastguard Worker      end
119*cc02d7e2SAndroid Build Coastguard Worker    rescue => e
120*cc02d7e2SAndroid Build Coastguard Worker      fail "timeout waiting for child process to report port. error: #{e}"
121*cc02d7e2SAndroid Build Coastguard Worker    end
122*cc02d7e2SAndroid Build Coastguard Worker    @server.stop
123*cc02d7e2SAndroid Build Coastguard Worker    server_thread.join
124*cc02d7e2SAndroid Build Coastguard Worker    @stub = ClientControl::ClientController::Stub.new(
125*cc02d7e2SAndroid Build Coastguard Worker      "localhost:#{@client_controller_port}", :this_channel_is_insecure)
126*cc02d7e2SAndroid Build Coastguard Worker  end
127*cc02d7e2SAndroid Build Coastguard Worker
128*cc02d7e2SAndroid Build Coastguard Worker  def set_client_controller_port(req, _)
129*cc02d7e2SAndroid Build Coastguard Worker    @client_controller_port_mu.synchronize do
130*cc02d7e2SAndroid Build Coastguard Worker      unless @client_controller_port.nil?
131*cc02d7e2SAndroid Build Coastguard Worker        fail 'client controller port already set'
132*cc02d7e2SAndroid Build Coastguard Worker      end
133*cc02d7e2SAndroid Build Coastguard Worker      @client_controller_port = req.port
134*cc02d7e2SAndroid Build Coastguard Worker      @client_controller_port_cv.broadcast
135*cc02d7e2SAndroid Build Coastguard Worker    end
136*cc02d7e2SAndroid Build Coastguard Worker    ClientControl::Void.new
137*cc02d7e2SAndroid Build Coastguard Worker  end
138*cc02d7e2SAndroid Build Coastguard Workerend
139*cc02d7e2SAndroid Build Coastguard Worker
140*cc02d7e2SAndroid Build Coastguard Workerdef report_controller_port_to_parent(parent_controller_port, client_controller_port)
141*cc02d7e2SAndroid Build Coastguard Worker  unless parent_controller_port.to_i > 0
142*cc02d7e2SAndroid Build Coastguard Worker    fail "bad parent control port: |#{parent_controller_port}|"
143*cc02d7e2SAndroid Build Coastguard Worker  end
144*cc02d7e2SAndroid Build Coastguard Worker  stub = ClientControl::ParentController::Stub.new(
145*cc02d7e2SAndroid Build Coastguard Worker    "localhost:#{parent_controller_port.to_i}", :this_channel_is_insecure)
146*cc02d7e2SAndroid Build Coastguard Worker  m = ClientControl::Port.new
147*cc02d7e2SAndroid Build Coastguard Worker  m.port = client_controller_port.to_i
148*cc02d7e2SAndroid Build Coastguard Worker  stub.set_client_controller_port(m, deadline: Time.now + 10)
149*cc02d7e2SAndroid Build Coastguard Workerend
150*cc02d7e2SAndroid Build Coastguard Worker
151*cc02d7e2SAndroid Build Coastguard Workerdef with_logging(action)
152*cc02d7e2SAndroid Build Coastguard Worker  STDERR.puts "#{action}: begin (pid=#{Process.pid})"
153*cc02d7e2SAndroid Build Coastguard Worker  yield
154*cc02d7e2SAndroid Build Coastguard Worker  STDERR.puts "#{action}: done (pid=#{Process.pid})"
155*cc02d7e2SAndroid Build Coastguard Workerend
156