def test_get_process_no_binary(self): # GIVEN self.given_ngrok_not_installed(conf.DEFAULT_NGROK_PATH) self.assertEqual(len(process._current_processes.keys()), 0) # WHEN with self.assertRaises(PyngrokNgrokError) as cm: process.get_process(self.pyngrok_config) # THEN self.assertIn("ngrok binary was not found", str(cm.exception)) self.assertEqual(len(process._current_processes.keys()), 0)
def get_ngrok_process(ngrok_path=None, config_path=None, auth_token=None, region=None): """ Retrieve the current `ngrok` process for the given path. If `ngrok` is not installed at the given path, calling this method will first download and install `ngrok`. If `ngrok` is not running, calling this method will start a process for the given path. :param ngrok_path: A `ngrok` binary override (instead of using `pyngrok`'s). :type ngrok_path: string, optional :param config_path: A config path override. Ignored if `ngrok` is already running. :type config_path: string, optional :param auth_token: An authtoken override. Ignored if `ngrok` is already running. :type auth_token: string, optional :param region: A region override. Ignored if `ngrok` is already running. :type region: string, optional :return: The `ngrok` process. :rtype: NgrokProcess """ ngrok_path = ngrok_path if ngrok_path else DEFAULT_NGROK_PATH config_path = config_path if config_path else DEFAULT_CONFIG_PATH ensure_ngrok_installed(ngrok_path) return process.get_process(ngrok_path, config_path, auth_token, region)
def test_connect_fileserver(self): if "NGROK_AUTHTOKEN" not in os.environ: self.skipTest("NGROK_AUTHTOKEN environment variable not set") # GIVEN self.assertEqual(len(process._current_processes.keys()), 0) pyngrok_config = PyngrokConfig(config_path=conf.DEFAULT_NGROK_CONFIG_PATH, auth_token=os.environ["NGROK_AUTHTOKEN"]) # WHEN ngrok_tunnel = ngrok.connect("file:///", pyngrok_config=pyngrok_config) current_process = ngrok.get_ngrok_process() time.sleep(1) tunnels = ngrok.get_tunnels() # THEN self.assertEqual(len(tunnels), 2) self.assertIsNotNone(current_process) self.assertIsNone(current_process.proc.poll()) self.assertTrue(current_process._monitor_thread.is_alive()) self.assertTrue(ngrok_tunnel.name.startswith("http-file-")) self.assertEqual("file:///", ngrok_tunnel.config["addr"]) self.assertIsNotNone(ngrok_tunnel.public_url) self.assertIsNotNone(process.get_process(self.pyngrok_config)) self.assertIn('http://', ngrok_tunnel.public_url) self.assertEqual(len(process._current_processes.keys()), 1)
def test_process_external_kill_get_process_restart(self): # GIVEN self.given_ngrok_installed(self.pyngrok_config) ngrok_process1 = process._start_process(self.pyngrok_config) monitor_thread1 = ngrok_process1._monitor_thread self.assertEqual(len(process._current_processes.keys()), 1) self.assertTrue(ngrok_process1._monitor_thread.is_alive()) # WHEN # Kill the process by external means, pyngrok still thinks process is active ngrok_process1.proc.kill() ngrok_process1.proc.wait() time.sleep(1) self.assertEqual(len(process._current_processes.keys()), 1) self.assertFalse(monitor_thread1.is_alive()) # THEN # Try to get process via pyngrok, it has been killed, restart and correct state with mock.patch("atexit.register") as mock_atexit: ngrok_process2 = process.get_process(self.pyngrok_config) self.assertNotEqual(ngrok_process1.proc.pid, ngrok_process2.proc.pid) self.assertEqual(len(process._current_processes.keys()), 1) self.assertFalse(monitor_thread1.is_alive()) self.assertTrue(ngrok_process2._monitor_thread.is_alive()) self.assertTrue(mock_atexit.called) self.assertNoZombies()
def test_regional_subdomain(self): if "NGROK_AUTHTOKEN" not in os.environ: self.skipTest("NGROK_AUTHTOKEN environment variable not set") # GIVEN self.assertEqual(len(process._current_processes.keys()), 0) subdomain = self.create_unique_subdomain() pyngrok_config = self.copy_with_updates( self.pyngrok_config, auth_token=os.environ["NGROK_AUTHTOKEN"], region="au") # WHEN url = ngrok.connect(5000, subdomain=subdomain, pyngrok_config=pyngrok_config).public_url current_process = ngrok.get_ngrok_process() # THEN self.assertIsNotNone(current_process) self.assertIsNone(current_process.proc.poll()) self.assertIsNotNone(url) self.assertIsNotNone(process.get_process(pyngrok_config)) self.assertIn("http://", url) self.assertIn(".au.", url) self.assertIn(subdomain, url) self.assertEqual(len(process._current_processes.keys()), 1)
def get_ngrok_process(pyngrok_config=None): """ Get the current ``ngrok`` process for the given config's ``ngrok_path``. If ``ngrok`` is not installed at :class:`~pyngrok.conf.PyngrokConfig`'s ``ngrok_path``, calling this method will first download and install ``ngrok``. If ``ngrok`` is not running, calling this method will first start a process with :class:`~pyngrok.conf.PyngrokConfig`. Use :func:`~pyngrok.process.is_process_running` to check if a process is running without also implicitly installing and starting it. :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 :return: The ``ngrok`` process. :rtype: NgrokProcess """ if pyngrok_config is None: pyngrok_config = conf.get_default() install_ngrok(pyngrok_config) return process.get_process(pyngrok_config)
def test_regional_tcp(self): if "NGROK_AUTHTOKEN" not in os.environ: self.skipTest("NGROK_AUTHTOKEN environment variable not set") # GIVEN self.assertEqual(len(process._current_processes.keys()), 0) subdomain = "pyngrok-{}-{}-{}{}-tcp".format( platform.system(), platform.python_implementation(), sys.version_info[0], sys.version_info[1]).lower() pyngrok_config = PyngrokConfig( config_path=conf.DEFAULT_NGROK_CONFIG_PATH, auth_token=os.environ["NGROK_AUTHTOKEN"], region="au") # WHEN ngrok_tunnel = ngrok.connect(5000, "tcp", subdomain=subdomain, pyngrok_config=pyngrok_config) current_process = ngrok.get_ngrok_process() # THEN self.assertIsNotNone(current_process) self.assertIsNone(current_process.proc.poll()) self.assertIsNotNone(ngrok_tunnel.public_url) self.assertIsNotNone(process.get_process(pyngrok_config)) self.assertEqual("localhost:5000", ngrok_tunnel.config["addr"]) self.assertIn("tcp://", ngrok_tunnel.public_url) self.assertIn(".au.", ngrok_tunnel.public_url) self.assertEqual(len(process._current_processes.keys()), 1)
def test_connect_fileserver(self): if "NGROK_AUTHTOKEN" not in os.environ: self.skipTest("NGROK_AUTHTOKEN environment variable not set") # GIVEN self.assertEqual(len(process._current_processes.keys()), 0) pyngrok_config = PyngrokConfig( config_path=conf.DEFAULT_NGROK_CONFIG_PATH, auth_token=os.environ["NGROK_AUTHTOKEN"]) # WHEN url = ngrok.connect("file:///", pyngrok_config=pyngrok_config) current_process = ngrok.get_ngrok_process() time.sleep(1) tunnels = ngrok.get_tunnels() # THEN self.assertEqual(len(tunnels), 2) self.assertIsNotNone(current_process) self.assertIsNone(current_process.proc.poll()) self.assertTrue(current_process._monitor_thread.is_alive()) self.assertIsNotNone(url) self.assertIsNotNone(process.get_process(self.pyngrok_config)) self.assertIn('http://', url) self.assertEqual(len(process._current_processes.keys()), 1) # WHEN ngrok.disconnect(url) time.sleep(1) tunnels = ngrok.get_tunnels() # THEN # There is still one tunnel left, as we only disconnected the http tunnel self.assertEqual(len(tunnels), 1)
def test_regional_subdomain(self): if "NGROK_AUTHTOKEN" not in os.environ: self.skipTest("NGROK_AUTHTOKEN environment variable not set") # GIVEN self.assertEqual(len(process._current_processes.keys()), 0) subdomain = "pyngrok-{}-{}-{}{}-http".format( platform.system(), platform.python_implementation(), sys.version_info[0], sys.version_info[1]).lower() pyngrok_config = PyngrokConfig( config_path=conf.DEFAULT_NGROK_CONFIG_PATH, auth_token=os.environ["NGROK_AUTHTOKEN"], region="au") # WHEN url = ngrok.connect(5000, options={"subdomain": subdomain}, pyngrok_config=pyngrok_config) current_process = ngrok.get_ngrok_process() # THEN self.assertIsNotNone(current_process) self.assertIsNone(current_process.proc.poll()) self.assertIsNotNone(url) self.assertIsNotNone(process.get_process(pyngrok_config)) self.assertIn("http://", url) self.assertIn(".au.", url) self.assertIn(subdomain, url) self.assertEqual(len(process._current_processes.keys()), 1)
def test_kill(self): # GIVEN ngrok.connect(5000, config_path=self.config_path) time.sleep(1) ngrok_process = process.get_process(ngrok.DEFAULT_NGROK_PATH) # WHEN ngrok.kill() time.sleep(1) # THEN self.assertIsNotNone(ngrok_process.proc.poll()) self.assertEqual(len(process._current_processes.keys()), 0)
def test_connect(self): # GIVEN self.assertEqual(len(process._current_processes.keys()), 0) # WHEN url = ngrok.connect(5000, config_path=self.config_path) current_process = ngrok.get_ngrok_process() # THEN self.assertIsNotNone(current_process) self.assertIsNone(current_process.process.poll()) self.assertIsNotNone(url) self.assertIsNotNone(process.get_process(ngrok.DEFAULT_NGROK_PATH)) self.assertEqual(len(process._current_processes.keys()), 1)
def test_kill(self): # GIVEN ngrok.connect(5000, pyngrok_config=self.pyngrok_config) time.sleep(1) ngrok_process = process.get_process(self.pyngrok_config) monitor_thread = ngrok_process._monitor_thread # WHEN ngrok.kill() time.sleep(1) # THEN self.assertIsNotNone(ngrok_process.proc.poll()) self.assertFalse(monitor_thread.is_alive()) self.assertEqual(len(process._current_processes.keys()), 0)
def test_multiple_processes_same_binary_fails(self): # GIVEN self.given_ngrok_installed(self.pyngrok_config) self.assertEqual(len(process._current_processes.keys()), 0) # WHEN ngrok_process1 = process._start_process(self.pyngrok_config) with self.assertRaises(PyngrokNgrokError) as cm: process._start_process(self.pyngrok_config) # THEN self.assertIn("ngrok is already running", str(cm.exception)) self.assertIsNotNone(ngrok_process1) self.assertIsNone(ngrok_process1.proc.poll()) self.assertEqual(ngrok_process1, process.get_process(self.pyngrok_config)) self.assertEqual(len(process._current_processes.keys()), 1)
def test_connect(self): # GIVEN self.assertEqual(len(process._current_processes.keys()), 0) # WHEN url = ngrok.connect(5000, pyngrok_config=self.pyngrok_config) current_process = ngrok.get_ngrok_process() # THEN self.assertIsNotNone(current_process) self.assertIsNone(current_process.proc.poll()) self.assertTrue(current_process._monitor_thread.is_alive()) self.assertIsNotNone(url) self.assertIsNotNone(process.get_process(self.pyngrok_config)) self.assertIn('http://', url) self.assertEqual(len(process._current_processes.keys()), 1)
def test_process_external_kill_get_process_restart(self): # GIVEN self.given_ngrok_installed(ngrok.DEFAULT_NGROK_PATH) ngrok_process1 = process._start_process(ngrok.DEFAULT_NGROK_PATH, config_path=self.config_path) self.assertEqual(len(process._current_processes.keys()), 1) # WHEN # Kill the process by external means, pyngrok still thinks process is active ngrok_process1.proc.kill() ngrok_process1.proc.wait() self.assertEqual(len(process._current_processes.keys()), 1) # THEN # Try to get process via pyngrok, it has been killed, restart and correct state with mock.patch("atexit.register") as mock_atexit: ngrok_process2 = process.get_process(ngrok.DEFAULT_NGROK_PATH, config_path=self.config_path) self.assertNotEqual(ngrok_process1.proc.pid, ngrok_process2.proc.pid) self.assertEqual(len(process._current_processes.keys()), 1) mock_atexit.assert_called_once()
def test_connect(self): # GIVEN self.assertEqual(len(process._current_processes.keys()), 0) self.assertEqual(len(ngrok._current_tunnels.keys()), 0) # WHEN ngrok_tunnel = ngrok.connect(5000, pyngrok_config=self.pyngrok_config) current_process = ngrok.get_ngrok_process() # THEN self.assertEqual(len(ngrok._current_tunnels.keys()), 1) self.assertIsNotNone(current_process) self.assertIsNone(current_process.proc.poll()) self.assertTrue(current_process._monitor_thread.is_alive()) self.assertTrue(ngrok_tunnel.name.startswith("http-5000-")) self.assertEqual("http", ngrok_tunnel.proto) self.assertEqual("http://localhost:5000", ngrok_tunnel.config["addr"]) self.assertIsNotNone(ngrok_tunnel.public_url) self.assertIsNotNone(process.get_process(self.pyngrok_config)) self.assertIn('http://', ngrok_tunnel.public_url) self.assertEqual(len(process._current_processes.keys()), 1)
def get_ngrok_process(pyngrok_config=None): """ Retrieve the current :code:`ngrok` process for the given config's :code:`ngrok_path`. If :code:`ngrok` is not installed at :class:`~pyngrok.conf.PyngrokConfig`'s :code:`ngrok_path`, calling this method will first download and install :code:`ngrok`. If :code:`ngrok` is not running, calling this method will first start a process with :class:`~pyngrok.conf.PyngrokConfig`. :param pyngrok_config: The :code:`pyngrok` configuration to use when interacting with the :code:`ngrok` binary. :type pyngrok_config: PyngrokConfig, optional :return: The :code:`ngrok` process. :rtype: NgrokProcess """ if pyngrok_config is None: pyngrok_config = PyngrokConfig() ensure_ngrok_installed(pyngrok_config.ngrok_path) return process.get_process(pyngrok_config)
def get_ngrok_process(pyngrok_config=None): """ Retrieve the current ``ngrok`` process for the given config's ``ngrok_path``. If ``ngrok`` is not installed at :class:`~pyngrok.conf.PyngrokConfig`'s ``ngrok_path``, calling this method will first download and install ``ngrok``. If ``ngrok`` is not running, calling this method will first start a process with :class:`~pyngrok.conf.PyngrokConfig`. :param pyngrok_config: The ``pyngrok`` configuration to use when interacting with the ``ngrok`` binary, defaults to ``conf.DEFAULT_PYNGROK_CONFIG``. :type pyngrok_config: PyngrokConfig, optional :return: The ``ngrok`` process. :rtype: NgrokProcess """ if pyngrok_config is None: pyngrok_config = conf.DEFAULT_PYNGROK_CONFIG ensure_ngrok_installed(pyngrok_config.ngrok_path) return process.get_process(pyngrok_config)