Skip to content

Commit

Permalink
stopping command terminates all processes that match regex instead of
Browse files Browse the repository at this point in the history
just the first one found
  • Loading branch information
tctimmeh committed Nov 24, 2015
1 parent 29232e5 commit c15f82d
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 26 deletions.
2 changes: 1 addition & 1 deletion docs/configure.rst
Expand Up @@ -19,7 +19,7 @@ For example::

[KEY_BLUE]
process = steam
search = .local/share/Steam/.+/steam
search = .local/share/Steam/.+/steam$
needsKill = true


Expand Down
4 changes: 2 additions & 2 deletions htpclauncher/__init__.py
Expand Up @@ -2,8 +2,8 @@
PROJECT_NAME = 'htpc-launcher'

VERSION_MAJOR = 1
VERSION_MINOR = 0
VERSION_RELEASE = 1
VERSION_MINOR = 1
VERSION_RELEASE = 0

VERSION_SHORT = '%d.%d' % (VERSION_MAJOR, VERSION_MINOR)
VERSION = '%s.%d' % (VERSION_SHORT, VERSION_RELEASE)
Expand Down
15 changes: 8 additions & 7 deletions htpclauncher/command.py
Expand Up @@ -45,18 +45,19 @@ def run(self):
self._waitForProcess()

def stop(self):
pid = self.ostools.findPid(self.search)
if not pid:
pids = self.ostools.findPids(self.search)
if not pids:
return

self.log.info('Stopping %s', self)
if self.needsKill:
self.ostools.kill(pid)
else:
self.ostools.terminate(pid)
for pid in pids:
if self.needsKill:
self.ostools.kill(pid)
else:
self.ostools.terminate(pid)

def isRunning(self):
pid = self.ostools.findPid(self.search)
pid = self.ostools.findPids(self.search)
return pid is not None

def _waitForProcess(self):
Expand Down
18 changes: 12 additions & 6 deletions htpclauncher/ostools.py
Expand Up @@ -10,15 +10,21 @@ def runProcess(self, command):
self.log.info('Running process: %s', command)
return subprocess.Popen(command, shell = True)

def findPid(self, regex):
def findPids(self, regex):
self.log.debug('Searching for Process with regex: %s', regex)
findProc = subprocess.Popen('ps -ef | grep -P "%s" | grep -v grep' % regex, shell = True, stdout = subprocess.PIPE)
findOut = findProc.communicate()[0]
if not findOut:
return None
stdout_data, stderr_data = findProc.communicate()
lines = stdout_data.split('\n')

pids = []
for line in lines:
line = line.strip()
if not line:
continue
self.log.debug('Found proccess: %s', line)
pids.append(line.split()[1])

self.log.debug('Found proccess: %s', findOut)
return findOut.split()[1]
return pids

def terminate(self, pid):
self.log.debug('Terminating pid %s', str(pid))
Expand Down
27 changes: 17 additions & 10 deletions test/test_command.py
Expand Up @@ -9,15 +9,15 @@ class TestCommand:
def setup_method(self, method):
self.ostools = Mock(OsTools)
self.pid = '1234'
self.ostools.findPid.return_value = self.pid
self.ostools.findPids.return_value = [self.pid]
self.command = Command('something', search = 'whatever', ostools = self.ostools)

def testCommandIsRun(self):
self.ostools.findPid.return_value = None
self.ostools.findPids.return_value = None
run = threading.Thread(target = self.command.run)
run.start()
time.sleep(0.1)
self.ostools.findPid.return_value = 123
self.ostools.findPids.return_value = [123]
run.join()

self.ostools.runProcess.assert_called_with('something')
Expand All @@ -26,14 +26,21 @@ def testPidIsKilledWhenStopped(self):
self.command.stop()
self.ostools.terminate.assert_called_with(self.pid)

def testAllPidsStoppedWhenTerminateAllOptionSet(self):
pid2 = '5678'
self.ostools.findPids.return_value = [self.pid, pid2]
self.command.stop()
self.ostools.terminate.assert_any_call(self.pid)
self.ostools.terminate.assert_any_call(pid2)

def testNothingKilledWhenPreviousProcessNotRunning(self):
self.ostools.findPid.return_value = None
self.ostools.findPids.return_value = None
self.command.stop()
assert not self.ostools.terminate.called
assert not self.ostools.kill.called

def testNothingStartedWhenProcessAlreadyRunning(self):
self.ostools.findPid.return_value = self.pid
self.ostools.findPids.return_value = [self.pid]
self.command.run()
assert not self.ostools.runProcess.called

Expand All @@ -43,30 +50,30 @@ def testCommandTerminatedWithSigKillIfOptionSet(self):
self.ostools.kill.assert_called_with(self.pid)

def testFocusCalledWhenProcessAlreadyRunning(self):
self.ostools.findPid.return_value = self.pid
self.ostools.findPids.return_value = [self.pid]
self.ostools.doesWindowExist('something').return_value = True
self.command.run()
assert self.ostools.focus.called

def testCommandErrorRaisedIfProgramFailsToStart(self):
self.command.startTimeout = 0
self.ostools.findPid.return_value = None
self.ostools.findPids.return_value = None
with pytest.raises(CommandError):
self.command.run()

def testCheckForWindowIsCalledIfProcessIsRunning(self):
self.ostools.findPid.return_value = self.pid
self.ostools.findPids.return_value = [self.pid]
self.command.run()
self.ostools.doesWindowExist.assert_called_with('something')

def testCommandTerminatedIfNoWindowExists(self):
self.ostools.findPid.return_value = self.pid
self.ostools.findPids.return_value = [self.pid]
self.ostools.doesWindowExist.return_value = False
self.command.run()
assert self.ostools.terminate.called

def testCommandStartedIfNoWindowExists(self):
self.ostools.findPid.return_value = self.pid
self.ostools.findPids.return_value = [self.pid]
self.ostools.doesWindowExist.return_value = False
run = threading.Thread(target = self.command.run)
run.start()
Expand Down

0 comments on commit c15f82d

Please sign in to comment.