Пример #1
0
    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")
Пример #2
0
    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)
Пример #3
0
    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")
Пример #4
0
    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()
Пример #5
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)
Пример #6
0
    def test_retry_session_connection_failure(self, mock_proc_readline):
        # GIVEN
        log_line = "lvl=eror msg=\"failed to reconnect session\" err=EOF"
        mock_proc_readline.return_value.stdout.readline.side_effect = [log_line, log_line, log_line]
        pyngrok_config = self.copy_with_updates(self.pyngrok_config, reconnect_session_retries=2)
        self.given_ngrok_installed(pyngrok_config)

        # WHEN
        with self.assertRaises(PyngrokNgrokError) as cm:
            process._start_process(pyngrok_config)

        # THEN
        self.assertIsNotNone(cm)
        self.assertEqual(cm.exception.ngrok_logs[-1].msg, "failed to reconnect session")
        self.assertEqual(cm.exception.ngrok_error, "EOF")
        self.assertEqual(mock_proc_readline.call_count, 3)
        self.assertEqual(len(process._current_processes.keys()), 0)
Пример #7
0
    def test_start_new_session(self, mock_popen):
        # GIVEN
        self.given_ngrok_installed(self.pyngrok_config)

        # WHEN
        pyngrok_config = self.copy_with_updates(self.pyngrok_config, start_new_session=True)
        try:
            process._start_process(pyngrok_config=pyngrok_config)
        except TypeError:
            # Since we're mocking subprocess.Popen, this call will ultimately fail, but it gets far enough for us to
            # validate our assertion
            pass

        # THEN
        self.assertTrue(mock_popen.called)
        if os.name == "posix":
            self.assertIn("start_new_session", mock_popen.call_args[1])
        else:
            self.assertNotIn("start_new_session", mock_popen.call_args[1])
Пример #8
0
    def test_start_new_session(self, mock_popen):
        # GIVEN
        self.given_ngrok_installed(self.pyngrok_config.ngrok_path)

        # WHEN
        pyngrok_config = PyngrokConfig(
            config_path=conf.DEFAULT_NGROK_CONFIG_PATH, start_new_session=True)
        try:
            process._start_process(pyngrok_config=pyngrok_config)
        except TypeError:
            # Since we're mocking subprocess.Popen, this call will ultimately fail, but it gets far enough for us to
            # validate our assertion
            pass

        # THEN
        mock_popen.assert_called()
        if sys.version_info.major >= 3 and os.name == "posix":
            self.assertIn("start_new_session", mock_popen.call_args[1])
        else:
            self.assertNotIn("start_new_session", mock_popen.call_args[1])
Пример #9
0
    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")
        self.given_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)
Пример #10
0
    def test_process_logs(self):
        # GIVEN
        self.given_ngrok_installed(self.pyngrok_config)

        # WHEN
        ngrok_process = process._start_process(self.pyngrok_config)

        # THEN
        for log in ngrok_process.logs:
            self.assertIsNotNone(log.t)
            self.assertIsNotNone(log.lvl)
            self.assertIsNotNone(log.msg)
Пример #11
0
    def test_terminate_process(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.assertIsNone(ngrok_process1.proc.poll())

        # WHEN
        process._terminate_process(ngrok_process1.proc)
        time.sleep(1)

        # THEN
        self.assertIsNotNone(ngrok_process1.proc.poll())
Пример #12
0
    def test_terminate_process(self):
        # GIVEN
        self.given_ngrok_installed(self.pyngrok_config)
        ngrok_process = process._start_process(self.pyngrok_config)
        monitor_thread = ngrok_process._monitor_thread
        self.assertIsNone(ngrok_process.proc.poll())

        # WHEN
        process._terminate_process(ngrok_process.proc)
        time.sleep(1)

        # THEN
        self.assertIsNotNone(ngrok_process.proc.poll())
        self.assertFalse(monitor_thread.is_alive())
Пример #13
0
    def test_start_new_session(self):
        # GIVEN
        self.given_ngrok_installed(self.pyngrok_config.ngrok_path)

        # WHEN
        config = self.pyngrok_config
        config.start_new_session = True
        ngrok_process = process._start_process(self.pyngrok_config)

        # THEN
        for log in ngrok_process.logs:
            self.assertIsNotNone(log.t)
            self.assertIsNotNone(log.lvl)
            self.assertIsNotNone(log.msg)
Пример #14
0
    def test_process_external_kill(self):
        # GIVEN
        self.given_ngrok_installed(ngrok.DEFAULT_NGROK_PATH)
        ngrok_process = 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_process.proc.kill()
        ngrok_process.proc.wait()
        self.assertEqual(len(process._current_processes.keys()), 1)

        # Try to kill the process via pyngrok, no error, just update state
        process.kill_process(ngrok.DEFAULT_NGROK_PATH)
        self.assertEqual(len(process._current_processes.keys()), 0)
Пример #15
0
    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()
Пример #16
0
    def test_process_external_kill(self):
        # GIVEN
        self.given_ngrok_installed(self.pyngrok_config.ngrok_path)
        ngrok_process = process._start_process(self.pyngrok_config)
        monitor_thread = ngrok_process._monitor_thread
        self.assertEqual(len(process._current_processes.keys()), 1)
        self.assertTrue(ngrok_process._monitor_thread.is_alive())

        # WHEN
        # Kill the process by external means, pyngrok still thinks process is active
        ngrok_process.proc.kill()
        ngrok_process.proc.wait()
        self.assertEqual(len(process._current_processes.keys()), 1)
        time.sleep(1)
        self.assertFalse(monitor_thread.is_alive())

        # THEN
        # Try to kill the process via pyngrok, no error, just update state
        process.kill_process(conf.DEFAULT_NGROK_PATH)
        self.assertEqual(len(process._current_processes.keys()), 0)
        self.assertFalse(monitor_thread.is_alive())