def close(self): """Shut down the socket connection, client and controller""" self._sock = None self._controller = None if hasattr(self, "_port") and self._port: portpicker.return_port(self._port) self._port = None
def return_ports(ports): """Returns previously reserved ports so that may be reused.""" for port in ports: if port in _contiguous_ports: _contiguous_ports.discard(port) else: portpicker.return_port(port)
def testDoesntReuseRandomPorts(self): ports = set() for _ in range(10): port = portpicker.pick_unused_port() ports.add(port) portpicker.return_port(port) self.assertGreater(len(ports), 5) # Allow some random reuse.
def _clean(self): logger.info("Cleaning up...") if self._process is not None: if self._process.poll() is None: for _ in range(3): self._process.terminate() time.sleep(0.5) if not self._process or self._process.poll() is not None: break else: self._process.kill() self._process.wait() logger.error("KILLED") # Try to kill wineserver on linux if platform.system() == "Linux": try: p = subprocess.Popen(["wineserver", "-k"]) p.wait() # Command wineserver not detected except FileNotFoundError: pass if os.path.exists(self._tmp_dir): shutil.rmtree(self._tmp_dir) self._process = None self._ws = None if self._used_portpicker and self._port is not None: portpicker.return_port(self._port) self._port = None logger.info("Cleanup complete")
def __del__(self): """Stop server and free up the port if was reserved through portpicker.""" if hasattr(self, '_server'): self.stop() if hasattr(self, '_port'): portpicker.return_port(self._port)
def releasePort(port): """Release a used port after a webserver goes down.""" if _GetSharedTestConfig().min_port < 0: portpicker.return_port(port) global _ports if port in _ports: _ports.remove(port)
def _clean(self, verbose=True): if verbose: logger.info("Cleaning up...") if self._process is not None: if paths.PF in {"WSL1", "WSL2"}: if wsl.kill(self._process): logger.error("KILLED") elif self._process.poll() is None: for _ in range(3): self._process.terminate() time.sleep(0.5) if not self._process or self._process.poll() is not None: break else: self._process.kill() self._process.wait() logger.error("KILLED") # Try to kill wineserver on linux if paths.PF in {"Linux", "WineLinux"}: # Command wineserver not detected with suppress(FileNotFoundError): with subprocess.Popen(["wineserver", "-k"]) as p: p.wait() if os.path.exists(self._tmp_dir): shutil.rmtree(self._tmp_dir) self._process = None self._ws = None if self._used_portpicker and self._port is not None: portpicker.return_port(self._port) self._port = None if verbose: logger.info("Cleanup complete")
def testReusesPortServerPorts(self): server = mock.Mock() server.recv.side_effect = [b'12345\n', b'23456\n', b'34567\n'] with mock.patch.object(socket, 'socket', return_value=server): self.assertEqual(portpicker.pick_unused_port(), 12345) self.assertEqual(portpicker.pick_unused_port(), 23456) portpicker.return_port(12345) self.assertEqual(portpicker.pick_unused_port(), 12345)
def close(self): """Shut down the game and clean up.""" self._shutdown() self._proc = None self._sock = None self._controller = None if hasattr(self, "_port") and self._port: portpicker.return_port(self._port) self._port = None if os.path.exists(self._tmp_dir): shutil.rmtree(self._tmp_dir)
def test_server_info_timeout(self): try: # Setup a client that doesn't actually connect to anything. dummy_port = portpicker.pick_unused_port() dummy_client = client.Client(f'localhost:{dummy_port}') with self.assertRaises( errors.DeadlineExceededError, msg='ServerInfo call did not complete within provided timeout of 1s'): dummy_client.server_info(timeout=1) finally: portpicker.return_port(dummy_port)
def testDoesntReuseRandomPorts(self): ports = set() for _ in range(10): try: port = portpicker.pick_unused_port() except portpicker.NoFreePortFoundError: # This sometimes happens when not using portserver. Just # skip to the next attempt. continue ports.add(port) portpicker.return_port(port) self.assertGreater(len(ports), 5) # Allow some random reuse.
def close(self): """Shut down the game and clean up.""" if hasattr(self, "_controller") and self._controller: self._controller.quit() self._controller.close() self._controller = None self._shutdown() if hasattr(self, "_port") and self._port: if not FLAGS.sc2_port: portpicker.return_port(self._port) self._port = None if hasattr(self, "_tmp_dir") and os.path.exists(self._tmp_dir): shutil.rmtree(self._tmp_dir)
def connect(self, url=c.LOCALHOST, port=None, timeout=c.INITIAL_TIMEOUT, debug=False): """socket connect to an already running starcraft2 process""" if port != None: # force a selection to a new port if self._port != None: # if previously allocated port, return it portpicker.return_port(self._port) self._port = port elif self._port == None: # no connection exists self._port = portpicker.pick_unused_port() self._url = url if ":" in url and not url.startswith("["): # Support ipv6 addresses. url = "[%s]" % url for i in range(timeout): startTime = time.time() if debug: print("attempt #%d to websocket connect to %s:%s" % (i, url, port)) try: finalUrl = "ws://%s:%s/sc2api" % (url, self._port) ws = websocket.create_connection(finalUrl, timeout=timeout) #print("ws:", ws) self._client = protocol.StarcraftProtocol(ws) #super(ClientController, self).__init__(client) # ensure RemoteController initializtion is performed #if self.ping(): print("init ping()") # ensure the latest state is synced # ping returns: # game_version: "4.1.2.60604" # data_version: "33D9FE28909573253B7FC352CE7AEA40" # data_build: 60604 # base_build: 60321 return self except socket.error: pass # SC2 hasn't started listening yet. except websocket.WebSocketException as err: print(err, type(err)) if "Handshake Status 404" in str(err): pass # SC2 is listening, but hasn't set up the /sc2api endpoint yet. else: raise except Exception as e: print(type(e), e) sleepTime = max( 0, 1 - (time.time() - startTime)) # try to wait for up to 1 second total if sleepTime: time.sleep(sleepTime) raise websocket.WebSocketException( "Could not connect to game at %s on port %s" % (url, port))
def testReturnsReservedPorts(self): with mock.patch.object(portpicker, '_pick_unused_port_without_server'): portpicker._pick_unused_port_without_server.side_effect = ( Exception('eek!')) # Arbitrary port. In practice you should get this from somewhere # that assigns ports. reserved_port = 28465 portpicker.add_reserved_port(reserved_port) ports = set() for _ in range(10): port = portpicker.pick_unused_port() ports.add(port) portpicker.return_port(port) self.assertEqual(len(ports), 1) self.assertEqual(ports.pop(), reserved_port)
def _pick_unused_ports(num_ports, retry_interval_secs=3, retry_attempts=5): """Returns a list of `num_ports` unused ports.""" ports = set() for _ in range(retry_attempts): ports.update( portpicker.pick_unused_port() for _ in range(num_ports - len(ports))) ports.discard(None) # portpicker returns None on error. if len(ports) == num_ports: return list(ports) # Duplicate ports can be returned, especially when insufficient ports are # free. Wait for more ports to be freed and retry. time.sleep(retry_interval_secs) # Could not obtain enough ports. Release what we do have. for port in ports: portpicker.return_port(port) raise RuntimeError("Unable to obtain %d unused ports." % num_ports)
def run_games_multiple( self, games: List[GameConfig], instances: int = int(cpu_count() / 2) ) -> List[Result]: ports = [portpicker.pick_unused_port() for _ in range(len(games))] results = [] while len(games) > 0: used_ports = ports[:instances] new_games = [ self._run_game(game, port) for game, port in zip(games[:instances], used_ports) ] del games[:instances] del ports[:instances] results += get_event_loop().run_until_complete(gather(*new_games)) for port in used_ports: portpicker.return_port(port) return results
def pick_contiguous_unused_ports(num_ports, retry_interval_secs=1, retry_attempts=5): """Reserves and returns a list of `num_ports` contiguous unused ports.""" if num_ports <= 0: raise ValueError("Number of ports, must be >= 1, got: %s" % num_ports) for _ in range(retry_attempts): start_port = portpicker.pick_unused_port() if start_port is not None: ports = [start_port + p for p in range(num_ports)] if all(portpicker.is_port_free(p) for p in ports): _contiguous_ports.update(ports[1:]) return ports else: portpicker.return_port(start_port) time.sleep(retry_interval_secs) raise RuntimeError("Unable to obtain %d contiguous unused ports." % num_ports)
def close(self): logging.info("Environment Close") if hasattr(self, "_renderer_human") and self._renderer_human: self._renderer_human.close() self._renderer_human = None # Don't use parallel since it might be broken by an exception. if hasattr(self, "_controllers") and self._controllers: for c in self._controllers: c.quit() self._controllers = None if hasattr(self, "_sc2_procs") and self._sc2_procs: for p in self._sc2_procs: p.close() self._sc2_procs = None if hasattr(self, "_ports") and self._ports: for port in self._ports: portpicker.return_port(port) self._ports = None logging.info("%s", sw)
def tearDown(self): super().tearDown() if self._synthesis_server: self._synthesis_server.kill() self._synthesis_server.wait() portpicker.return_port(self._port)
def tearDown(self): super().tearDown() portpicker.return_port(self.port)
def clean(self): while self._picked_ports: portpicker.return_port(self._picked_ports.pop())
def return_ports(ports): """Returns previously reserved ports so that may be reused.""" for port in ports: portpicker.return_port(port)
def _return_ports(self): for port in self._ports: portpicker.return_port(port)