Exemplo n.º 1
0
    def stop(self, mode=None):
        """Terminate the process."""
        if mode is None:
            mode = fixture_interface.TeardownMode.TERMINATE

        if mode == fixture_interface.TeardownMode.KILL:
            signal = self.pb.Signals.Value("KILL")
        elif mode == fixture_interface.TeardownMode.TERMINATE:
            signal = self.pb.Signals.Value("TERMINATE")
        elif mode == fixture_interface.TeardownMode.ABORT:
            signal = self.pb.Signals.Value("ABRT")
        else:
            raise errors.ProcessError(
                "Process wrapper given unrecognized teardown mode: " +
                mode.value)

        signal_process = self.pb.SignalProcess(ProcessID=self._id,
                                               signal=signal)
        val = self._stub.Signal(signal_process)
        JASPER_PIDS.discard(self.pid)
        if not val.success \
                and "cannot signal a process that has terminated" not in val.text \
                and "os: process already finished" not in val.text:
            raise OSError(
                "Failed to signal Jasper process with pid {}: {}".format(
                    self.pid, val.text))
Exemplo n.º 2
0
    def stop(self, mode=None):  # pylint: disable=too-many-branches
        """Terminate the process."""
        if mode is None:
            mode = fixture_interface.TeardownMode.TERMINATE

        if sys.platform == "win32":

            # Attempt to cleanly shutdown mongod.
            if mode != fixture_interface.TeardownMode.KILL and self.args and self.args[
                    0].find("mongod") != -1:
                mongo_signal_handle = None
                try:
                    mongo_signal_handle = win32event.OpenEvent(
                        win32event.EVENT_MODIFY_STATE, False,
                        "Global\\Mongo_" + str(self._process.pid))

                    if not mongo_signal_handle:
                        # The process has already died.
                        return
                    win32event.SetEvent(mongo_signal_handle)
                    # Wait 60 seconds for the program to exit.
                    status = win32event.WaitForSingleObject(
                        self._process._handle, 60 * 1000)
                    if status == win32event.WAIT_OBJECT_0:
                        return
                except win32process.error as err:
                    # ERROR_FILE_NOT_FOUND (winerror=2)
                    # ERROR_ACCESS_DENIED (winerror=5)
                    # ERROR_INVALID_HANDLE (winerror=6)
                    # One of the above errors is received if the process has
                    # already died.
                    if err.winerror not in (2, 5, 6):
                        raise
                finally:
                    win32api.CloseHandle(mongo_signal_handle)

                print("Failed to cleanly exit the program, calling TerminateProcess() on PID: " +\
                    str(self._process.pid))

            # Adapted from implementation of Popen.terminate() in subprocess.py of Python 2.7
            # because earlier versions do not catch exceptions.
            try:
                # Have the process exit with code 0 if it is terminated by us to simplify the
                # success-checking logic later on.
                win32process.TerminateProcess(self._process._handle, 0)
            except win32process.error as err:
                # ERROR_ACCESS_DENIED (winerror=5) is received when the process
                # has already died.
                if err.winerror != winerror.ERROR_ACCESS_DENIED:
                    raise
                return_code = win32process.GetExitCodeProcess(
                    self._process._handle)
                if return_code == win32con.STILL_ACTIVE:
                    raise
        else:
            try:
                if mode == fixture_interface.TeardownMode.KILL:
                    self._process.kill()
                elif mode == fixture_interface.TeardownMode.TERMINATE:
                    self._process.terminate()
                elif mode == fixture_interface.TeardownMode.ABORT:
                    self._process.send_signal(mode.value)
                else:
                    raise errors.ProcessError(
                        "Process wrapper given unrecognized teardown mode: " +
                        mode.value)

            except OSError as err:
                # ESRCH (errno=3) is received when the process has already died.
                if err.errno != 3:
                    raise