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 install_ngrok(pyngrok_config=None): """ Download, install, and initialize ``ngrok`` for the given config. If ``ngrok`` and its default config is already installed, calling this method will do nothing. :param pyngrok_config: A ``pyngrok`` configuration to use when interacting with the ``ngrok`` binary, overriding :func:`~pyngrok.conf.get_default()`. :type pyngrok_config: PyngrokConfig, optional """ if pyngrok_config is None: pyngrok_config = conf.get_default() if not os.path.exists(pyngrok_config.ngrok_path): installer.install_ngrok(pyngrok_config.ngrok_path) # If no config_path is set, ngrok will use its default path if pyngrok_config.config_path is not None: config_path = pyngrok_config.config_path else: config_path = conf.DEFAULT_NGROK_CONFIG_PATH # Install the config to the requested path if not os.path.exists(config_path): installer.install_default_config(config_path) # Install the default config, even if we don't need it this time, if it doesn't already exist if conf.DEFAULT_NGROK_CONFIG_PATH != config_path and \ not os.path.exists(conf.DEFAULT_NGROK_CONFIG_PATH): installer.install_default_config(conf.DEFAULT_NGROK_CONFIG_PATH)
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)
def test_multiple_processes_different_binaries(self): # GIVEN self.given_ngrok_installed(ngrok.DEFAULT_NGROK_PATH) self.assertEqual(len(process._current_processes.keys()), 0) installer.install_default_config(self.config_path, {"web_addr": "localhost:4040"}) ngrok_path2 = os.path.join(ngrok.BIN_DIR, "2", ngrok.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": "localhost:4041"}) # WHEN ngrok_process1 = process._start_process(ngrok.DEFAULT_NGROK_PATH, config_path=self.config_path) ngrok_process2 = process._start_process(ngrok_path2, config_path=config_path2) # THEN self.assertEqual(len(process._current_processes.keys()), 2) self.assertIsNotNone(ngrok_process1) self.assertIsNone(ngrok_process1.proc.poll()) self.assertTrue(urlparse(ngrok_process1.api_url).port, "4040") self.assertIsNotNone(ngrok_process2) self.assertIsNone(ngrok_process2.proc.poll()) self.assertTrue(urlparse(ngrok_process2.api_url).port, "4041")
def test_tunnel_definitions_pyngrok_default_with_overrides(self): if "NGROK_AUTHTOKEN" not in os.environ: self.skipTest("NGROK_AUTHTOKEN environment variable not set") # GIVEN config = { "tunnels": { "pyngrok-default": { "proto": "http", "addr": "8080", "subdomain": "pyngrok2" } } } config_path = os.path.join(self.config_dir, "config2.yml") installer.install_default_config(config_path, config) pyngrok_config = PyngrokConfig(config_path=config_path, auth_token=os.environ["NGROK_AUTHTOKEN"]) # WHEN ngrok_tunnel1 = ngrok.connect(pyngrok_config=pyngrok_config) ngrok_tunnel2 = ngrok.connect(5000, subdomain="pyngrok3", pyngrok_config=pyngrok_config) # THEN self.assertEqual(ngrok_tunnel1.name, "pyngrok-default (http)") self.assertEqual(ngrok_tunnel1.config["addr"], "http://localhost:{}".format(config["tunnels"]["pyngrok-default"]["addr"])) self.assertEqual(ngrok_tunnel1.proto, config["tunnels"]["pyngrok-default"]["proto"]) self.assertEqual(ngrok_tunnel1.public_url, "http://{}.ngrok.io".format(config["tunnels"]["pyngrok-default"]["subdomain"])) self.assertEqual(ngrok_tunnel2.name, "pyngrok-default (http)") self.assertEqual(ngrok_tunnel2.config["addr"], "http://localhost:5000") self.assertEqual(ngrok_tunnel2.proto, config["tunnels"]["pyngrok-default"]["proto"]) self.assertEqual(ngrok_tunnel2.public_url, "http://pyngrok3.ngrok.io")
def ensure_ngrok_installed(ngrok_path): """ Ensure ``ngrok`` is installed at the given path, downloading and installing the binary for the current system if not. :param ngrok_path: The path to the ``ngrok`` binary. :type ngrok_path: str """ if not os.path.exists(ngrok_path): install_ngrok(ngrok_path) if not os.path.exists(conf.DEFAULT_NGROK_CONFIG_PATH): install_default_config(conf.DEFAULT_NGROK_CONFIG_PATH)
def test_tunnel_definitions(self): if "NGROK_AUTHTOKEN" not in os.environ: self.skipTest("NGROK_AUTHTOKEN environment variable not set") subdomain = self.create_unique_subdomain() # GIVEN config = { "tunnels": { "http-tunnel": { "proto": "http", "addr": "8000", "subdomain": subdomain }, "tcp-tunnel": { "proto": "tcp", "addr": "22" } } } config_path = os.path.join(self.config_dir, "config2.yml") installer.install_default_config(config_path, config) pyngrok_config = self.copy_with_updates( self.pyngrok_config, config_path=config_path, auth_token=os.environ["NGROK_AUTHTOKEN"]) # WHEN http_tunnel = ngrok.connect(name="http-tunnel", pyngrok_config=pyngrok_config) ssh_tunnel = ngrok.connect(name="tcp-tunnel", pyngrok_config=pyngrok_config) # THEN self.assertEqual(http_tunnel.name, "http-tunnel (http)") self.assertEqual( http_tunnel.config["addr"], "http://localhost:{}".format( config["tunnels"]["http-tunnel"]["addr"])) self.assertEqual(http_tunnel.proto, config["tunnels"]["http-tunnel"]["proto"]) self.assertEqual( http_tunnel.public_url, "http://{}.ngrok.io".format( config["tunnels"]["http-tunnel"]["subdomain"])) self.assertEqual(ssh_tunnel.name, "tcp-tunnel") self.assertEqual( ssh_tunnel.config["addr"], "localhost:{}".format(config["tunnels"]["tcp-tunnel"]["addr"])) self.assertEqual(ssh_tunnel.proto, config["tunnels"]["tcp-tunnel"]["proto"]) self.assertTrue(ssh_tunnel.public_url.startswith("tcp://"))
def test_start_process_port_in_use(self): # GIVEN self.given_ngrok_installed(ngrok.DEFAULT_NGROK_PATH) self.assertEqual(len(process._current_processes.keys()), 0) ngrok_process = process._start_process(ngrok.DEFAULT_NGROK_PATH, config_path=self.config_path) port = urlparse(ngrok_process.api_url).port self.assertEqual(len(process._current_processes.keys()), 1) ngrok_path2 = os.path.join(ngrok.BIN_DIR, "2", ngrok.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://")}) # WHEN with self.assertRaises(PyngrokNgrokError) as cm: process._start_process(ngrok_path2, config_path=config_path2) # THEN self.assertIn("{}: bind: address already in use".format(port), str(cm.exception.ngrok_errors)) self.assertEqual(len(process._current_processes.keys()), 1)
def test_web_addr_false_not_allowed(self): # WHEN with self.assertRaises(PyngrokError): installer.install_default_config(self.pyngrok_config.config_path, {"web_addr": False})