1 // 2 // 3 // Copyright 2017 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // 17 // 18 19 #if defined(GRPC_PORT_ISOLATED_RUNTIME) 20 21 // When individual tests run in an isolated runtime environment (e.g. each test 22 // runs in a separate container) the framework takes a round-robin pick of a 23 // port within certain range. There is no need to recycle ports. 24 // 25 #include <grpc/support/atm.h> 26 #include <grpc/support/time.h> 27 #include <stdlib.h> 28 29 #include "absl/log/check.h" 30 #include "src/core/lib/iomgr/port.h" 31 #include "src/core/util/crash.h" 32 #include "test/core/test_util/port.h" 33 #include "test/core/test_util/test_config.h" 34 35 #define MIN_PORT 1025 36 #define MAX_PORT 32766 37 get_random_port_offset()38static int get_random_port_offset() { 39 srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec); 40 double rnd = static_cast<double>(rand()) / 41 (static_cast<double>(RAND_MAX) + 1.0); // values from [0,1) 42 return static_cast<int>(rnd * (MAX_PORT - MIN_PORT + 1)); 43 } 44 45 static int s_initial_offset = get_random_port_offset(); 46 static gpr_atm s_pick_counter = 0; 47 grpc_pick_unused_port_or_die_impl(void)48static int grpc_pick_unused_port_or_die_impl(void) { 49 int orig_counter_val = 50 static_cast<int>(gpr_atm_full_fetch_add(&s_pick_counter, 1)); 51 CHECK(orig_counter_val < (MAX_PORT - MIN_PORT + 1)); 52 return MIN_PORT + 53 (s_initial_offset + orig_counter_val) % (MAX_PORT - MIN_PORT + 1); 54 } 55 isolated_pick_unused_port_or_die(void)56static int isolated_pick_unused_port_or_die(void) { 57 while (true) { 58 int port = grpc_pick_unused_port_or_die_impl(); 59 // 5985 cannot be bound on Windows RBE and results in 60 // WSA_ERROR 10013: "An attempt was made to access a socket in a way 61 // forbidden by its access permissions." 62 if (port == 5985) { 63 continue; 64 } 65 return port; 66 } 67 } 68 isolated_recycle_unused_port(int port)69static void isolated_recycle_unused_port(int port) { (void)port; } 70 71 // We don't actually use prev_fns for anything, but need to save it in order to 72 // be able to call grpc_set_pick_port_functions() to override defaults for this 73 // environment. 74 static const auto prev_fns = 75 grpc_set_pick_port_functions(grpc_pick_port_functions{ 76 isolated_pick_unused_port_or_die, isolated_recycle_unused_port}); 77 78 #endif // GRPC_PORT_ISOLATED_RUNTIME 79