1*cc02d7e2SAndroid Build Coastguard Worker#!/usr/bin/env python 2*cc02d7e2SAndroid Build Coastguard Worker# Copyright 2021 gRPC authors. 3*cc02d7e2SAndroid Build Coastguard Worker# 4*cc02d7e2SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*cc02d7e2SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*cc02d7e2SAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*cc02d7e2SAndroid Build Coastguard Worker# 8*cc02d7e2SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*cc02d7e2SAndroid Build Coastguard Worker# 10*cc02d7e2SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*cc02d7e2SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 12*cc02d7e2SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*cc02d7e2SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*cc02d7e2SAndroid Build Coastguard Worker# limitations under the License. 15*cc02d7e2SAndroid Build Coastguard Worker"""Manage PHP child processes for the main PHP xDS Interop client""" 16*cc02d7e2SAndroid Build Coastguard Worker 17*cc02d7e2SAndroid Build Coastguard Workerimport argparse 18*cc02d7e2SAndroid Build Coastguard Workerimport fcntl 19*cc02d7e2SAndroid Build Coastguard Workerimport os 20*cc02d7e2SAndroid Build Coastguard Workerimport subprocess 21*cc02d7e2SAndroid Build Coastguard Worker 22*cc02d7e2SAndroid Build Coastguard Worker# This script is being launched from src/php/bin/run_xds_client.sh 23*cc02d7e2SAndroid Build Coastguard Worker# to manage PHP child processes which will send 1 RPC each 24*cc02d7e2SAndroid Build Coastguard Worker# asynchronously. This script keeps track of all those open 25*cc02d7e2SAndroid Build Coastguard Worker# processes and reports back to the main PHP interop client each 26*cc02d7e2SAndroid Build Coastguard Worker# of the child RPCs' status code. 27*cc02d7e2SAndroid Build Coastguard Worker 28*cc02d7e2SAndroid Build Coastguard Workerif __name__ == "__main__": 29*cc02d7e2SAndroid Build Coastguard Worker parser = argparse.ArgumentParser() 30*cc02d7e2SAndroid Build Coastguard Worker parser.add_argument("--tmp_file1", nargs="?", default="") 31*cc02d7e2SAndroid Build Coastguard Worker parser.add_argument("--tmp_file2", nargs="?", default="") 32*cc02d7e2SAndroid Build Coastguard Worker parser.add_argument("--bootstrap_path", nargs="?", default="") 33*cc02d7e2SAndroid Build Coastguard Worker args = parser.parse_args() 34*cc02d7e2SAndroid Build Coastguard Worker server_address = "" 35*cc02d7e2SAndroid Build Coastguard Worker rpcs_started = [] 36*cc02d7e2SAndroid Build Coastguard Worker open_processes = {} 37*cc02d7e2SAndroid Build Coastguard Worker client_env = dict(os.environ) 38*cc02d7e2SAndroid Build Coastguard Worker client_env["GRPC_XDS_BOOTSTRAP"] = args.bootstrap_path 39*cc02d7e2SAndroid Build Coastguard Worker while True: 40*cc02d7e2SAndroid Build Coastguard Worker # tmp_file1 contains a list of RPCs (and their spec) the parent process 41*cc02d7e2SAndroid Build Coastguard Worker # wants executed 42*cc02d7e2SAndroid Build Coastguard Worker f1 = open(args.tmp_file1, "r+") 43*cc02d7e2SAndroid Build Coastguard Worker fcntl.flock(f1, fcntl.LOCK_EX) 44*cc02d7e2SAndroid Build Coastguard Worker while True: 45*cc02d7e2SAndroid Build Coastguard Worker key = f1.readline() 46*cc02d7e2SAndroid Build Coastguard Worker if not key: 47*cc02d7e2SAndroid Build Coastguard Worker break 48*cc02d7e2SAndroid Build Coastguard Worker key = key.strip() 49*cc02d7e2SAndroid Build Coastguard Worker if key.startswith("server_address"): 50*cc02d7e2SAndroid Build Coastguard Worker if not server_address: 51*cc02d7e2SAndroid Build Coastguard Worker server_address = key[15:] 52*cc02d7e2SAndroid Build Coastguard Worker elif not key in rpcs_started: 53*cc02d7e2SAndroid Build Coastguard Worker # format here needs to be in sync with 54*cc02d7e2SAndroid Build Coastguard Worker # src/php/tests/interop/xds_client.php 55*cc02d7e2SAndroid Build Coastguard Worker items = key.split("|") 56*cc02d7e2SAndroid Build Coastguard Worker num = items[0] 57*cc02d7e2SAndroid Build Coastguard Worker metadata = items[2] 58*cc02d7e2SAndroid Build Coastguard Worker timeout_sec = items[3] 59*cc02d7e2SAndroid Build Coastguard Worker if items[1] == "UnaryCall": 60*cc02d7e2SAndroid Build Coastguard Worker p = subprocess.Popen( 61*cc02d7e2SAndroid Build Coastguard Worker [ 62*cc02d7e2SAndroid Build Coastguard Worker "php", 63*cc02d7e2SAndroid Build Coastguard Worker "-d", 64*cc02d7e2SAndroid Build Coastguard Worker "extension=grpc.so", 65*cc02d7e2SAndroid Build Coastguard Worker "-d", 66*cc02d7e2SAndroid Build Coastguard Worker "extension=pthreads.so", 67*cc02d7e2SAndroid Build Coastguard Worker "src/php/tests/interop/xds_unary_call.php", 68*cc02d7e2SAndroid Build Coastguard Worker "--server=" + server_address, 69*cc02d7e2SAndroid Build Coastguard Worker "--num=" + str(num), 70*cc02d7e2SAndroid Build Coastguard Worker "--metadata=" + metadata, 71*cc02d7e2SAndroid Build Coastguard Worker "--timeout_sec=" + timeout_sec, 72*cc02d7e2SAndroid Build Coastguard Worker ], 73*cc02d7e2SAndroid Build Coastguard Worker env=client_env, 74*cc02d7e2SAndroid Build Coastguard Worker ) 75*cc02d7e2SAndroid Build Coastguard Worker elif items[1] == "EmptyCall": 76*cc02d7e2SAndroid Build Coastguard Worker p = subprocess.Popen( 77*cc02d7e2SAndroid Build Coastguard Worker [ 78*cc02d7e2SAndroid Build Coastguard Worker "php", 79*cc02d7e2SAndroid Build Coastguard Worker "-d", 80*cc02d7e2SAndroid Build Coastguard Worker "extension=grpc.so", 81*cc02d7e2SAndroid Build Coastguard Worker "-d", 82*cc02d7e2SAndroid Build Coastguard Worker "extension=pthreads.so", 83*cc02d7e2SAndroid Build Coastguard Worker "src/php/tests/interop/xds_empty_call.php", 84*cc02d7e2SAndroid Build Coastguard Worker "--server=" + server_address, 85*cc02d7e2SAndroid Build Coastguard Worker "--num=" + str(num), 86*cc02d7e2SAndroid Build Coastguard Worker "--metadata=" + metadata, 87*cc02d7e2SAndroid Build Coastguard Worker "--timeout_sec=" + timeout_sec, 88*cc02d7e2SAndroid Build Coastguard Worker ], 89*cc02d7e2SAndroid Build Coastguard Worker env=client_env, 90*cc02d7e2SAndroid Build Coastguard Worker ) 91*cc02d7e2SAndroid Build Coastguard Worker else: 92*cc02d7e2SAndroid Build Coastguard Worker continue 93*cc02d7e2SAndroid Build Coastguard Worker rpcs_started.append(key) 94*cc02d7e2SAndroid Build Coastguard Worker open_processes[key] = p 95*cc02d7e2SAndroid Build Coastguard Worker f1.truncate(0) 96*cc02d7e2SAndroid Build Coastguard Worker fcntl.flock(f1, fcntl.LOCK_UN) 97*cc02d7e2SAndroid Build Coastguard Worker f1.close() 98*cc02d7e2SAndroid Build Coastguard Worker # tmp_file2 contains the RPC result of each key received from tmp_file1 99*cc02d7e2SAndroid Build Coastguard Worker f2 = open(args.tmp_file2, "a") 100*cc02d7e2SAndroid Build Coastguard Worker fcntl.flock(f2, fcntl.LOCK_EX) 101*cc02d7e2SAndroid Build Coastguard Worker keys_to_delete = [] 102*cc02d7e2SAndroid Build Coastguard Worker for key, process in open_processes.items(): 103*cc02d7e2SAndroid Build Coastguard Worker result = process.poll() 104*cc02d7e2SAndroid Build Coastguard Worker if result is not None: 105*cc02d7e2SAndroid Build Coastguard Worker # format here needs to be in sync with 106*cc02d7e2SAndroid Build Coastguard Worker # src/php/tests/interop/xds_client.php 107*cc02d7e2SAndroid Build Coastguard Worker f2.write(key + "," + str(process.returncode) + "\n") 108*cc02d7e2SAndroid Build Coastguard Worker keys_to_delete.append(key) 109*cc02d7e2SAndroid Build Coastguard Worker for key in keys_to_delete: 110*cc02d7e2SAndroid Build Coastguard Worker del open_processes[key] 111*cc02d7e2SAndroid Build Coastguard Worker fcntl.flock(f2, fcntl.LOCK_UN) 112*cc02d7e2SAndroid Build Coastguard Worker f2.close() 113