def test_multiple_processes_different_binaries(self): # GIVEN self.given_ngrok_installed(self.pyngrok_config) self.assertEqual(len(process._current_processes.keys()), 0) installer.install_default_config(self.pyngrok_config.config_path, {"web_addr": "localhost:4040"}) ngrok_path2 = os.path.join(conf.BIN_DIR, "2", installer.get_ngrok_bin()) pyngrok_config2 = self.copy_with_updates(self.pyngrok_config, ngrok_path=ngrok_path2) self.given_ngrok_installed(pyngrok_config2) config_path2 = os.path.join(self.config_dir, "config2.yml") installer.install_default_config(config_path2, {"web_addr": "localhost:4041"}) pyngrok_config2 = self.copy_with_updates(self.pyngrok_config, config_path=config_path2, ngrok_path=ngrok_path2) # WHEN ngrok_process1 = process._start_process(self.pyngrok_config) ngrok_process2 = process._start_process(pyngrok_config2) # THEN self.assertEqual(len(process._current_processes.keys()), 2) self.assertIsNotNone(ngrok_process1) self.assertIsNone(ngrok_process1.proc.poll()) self.assertTrue(ngrok_process1._monitor_thread.is_alive()) self.assertTrue(urlparse(ngrok_process1.api_url).port, "4040") self.assertIsNotNone(ngrok_process2) self.assertIsNone(ngrok_process2.proc.poll()) self.assertTrue(ngrok_process2._monitor_thread.is_alive()) self.assertTrue(urlparse(ngrok_process2.api_url).port, "4041")
def test_start_process_port_in_use(self): # GIVEN self.given_ngrok_installed(self.pyngrok_config.ngrok_path) self.assertEqual(len(process._current_processes.keys()), 0) ngrok_process = process._start_process(self.pyngrok_config) port = urlparse(ngrok_process.api_url).port self.assertEqual(len(process._current_processes.keys()), 1) self.assertTrue(ngrok_process._monitor_thread.is_alive()) ngrok_path2 = os.path.join(conf.BIN_DIR, "2", installer.get_ngrok_bin()) self.given_ngrok_installed(ngrok_path2) config_path2 = os.path.join(self.config_dir, "config2.yml") installer.install_default_config(config_path2, {"web_addr": ngrok_process.api_url.lstrip("http://")}) pyngrok_config2 = PyngrokConfig(ngrok_path=ngrok_path2, config_path=config_path2) error = None retries = 0 while error is None and retries < 10: time.sleep(1) # WHEN with self.assertRaises(PyngrokNgrokError) as cm: process._start_process(pyngrok_config2) error = cm.exception.ngrok_error retries += 1 # THEN self.assertIsNotNone(error) if platform.system() == "Windows": self.assertIn("{}: bind: Only one usage of each socket address".format(port), cm.exception.ngrok_error) else: self.assertIn("{}: bind: address already in use".format(port), str(cm.exception.ngrok_error)) self.assertEqual(len(process._current_processes.keys()), 1)
import os from pyngrok.installer import get_ngrok_bin __author__ = "Alex Laird" __copyright__ = "Copyright 2021, Alex Laird" __version__ = "5.1.0" BIN_DIR = os.path.normpath( os.path.join(os.path.abspath(os.path.dirname(__file__)), "bin")) DEFAULT_NGROK_PATH = os.path.join(BIN_DIR, get_ngrok_bin()) DEFAULT_CONFIG_PATH = None DEFAULT_NGROK_CONFIG_PATH = os.path.join(os.path.expanduser("~"), ".ngrok2", "ngrok.yml") _default_pyngrok_config = None class PyngrokConfig: """ An object containing ``pyngrok``'s configuration for interacting with the ``ngrok`` binary. All values are optional when it is instantiated, and default values will be used for parameters not passed. Use :func:`~pyngrok.conf.get_default` and :func:`~pyngrok.conf.set_default` to interact with the default ``pyngrok_config``, or pass another instance of this object as the ``pyngrok_config`` keyword arg to most methods in the :mod:`~pyngrok.ngrok` module to override the default. .. code-block:: python from pyngrok import conf, ngrok