Eliminate dependencies on pywin32, even via Twisted. refs #1274

This commit is contained in:
david-sarah 2011-01-19 20:32:38 -08:00
parent d4969259c6
commit 6dd8b6f471
4 changed files with 132 additions and 137 deletions

View File

@ -59,18 +59,6 @@ if sys.version_info < (2, 5):
# pysqlite v2.0.5 was shipped in Ubuntu 6.06 LTS "dapper" and Nexenta NCP 1.
install_requires.append("pysqlite >= 2.0.5")
## The following block is commented-out because there is not currently a pywin32 package which
## can be easy_install'ed and also which actually makes "import win32api" succeed.
## See http://sourceforge.net/tracker/index.php?func=detail&aid=1799934&group_id=78018&atid=551954
## Users have to manually install pywin32 on Windows before installing Tahoe.
##import platform
##if platform.system() == "Windows":
## # Twisted requires pywin32 if it is going to offer process management functionality, or if
## # it is going to offer iocp reactor. We currently require process management. It would be
## # better if Twisted would declare that it requires pywin32 if it is going to offer process
## # management. That is twisted ticket #3238 -- http://twistedmatrix.com/trac/ticket/3238 .
## install_requires.append('pywin32')
if hasattr(sys, 'frozen'): # for py2exe
install_requires=[]
del sys # clean up namespace

View File

@ -2,7 +2,8 @@
from twisted.trial import unittest
from twisted.python import usage, runtime
from twisted.internet import utils
from twisted.internet import threads
import os.path, re, sys, subprocess
from cStringIO import StringIO
from allmydata.util import fileutil, pollmixin
@ -39,10 +40,8 @@ if sys.platform == "win32":
bintahoe = alt_bintahoe
class SkipMixin:
class RunBinTahoeMixin:
def skip_if_cannot_run_bintahoe(self):
if "cygwin" in sys.platform.lower():
raise unittest.SkipTest("We don't know how to make this test work on cygwin: spawnProcess seems to hang forever. We don't know if 'bin/tahoe start' can be run on cygwin.")
if not os.path.exists(bintahoe):
raise unittest.SkipTest("The bin/tahoe script isn't to be found in the expected location (%s), and I don't want to test a 'tahoe' executable that I find somewhere else, in case it isn't the right executable for this version of Tahoe. Perhaps running 'setup.py build' again will help." % (bintahoe,))
@ -52,8 +51,22 @@ class SkipMixin:
# twistd on windows doesn't daemonize. cygwin should work normally.
raise unittest.SkipTest("twistd does not fork under windows")
def run_bintahoe(self, args, stdin=None, python_options=[], env=None):
self.skip_if_cannot_run_bintahoe()
command = [sys.executable] + python_options + [bintahoe] + args
if stdin is None:
stdin_stream = None
else:
stdin_stream = subprocess.PIPE
class BinTahoe(common_util.SignalMixin, unittest.TestCase, SkipMixin):
def _run():
p = subprocess.Popen(command, stdin=stdin_stream, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
(out, err) = p.communicate(stdin)
return (out, err, p.returncode)
return threads.deferToThread(_run)
class BinTahoe(common_util.SignalMixin, unittest.TestCase, RunBinTahoeMixin):
def _check_right_code(self, file_to_check):
root_to_check = get_root_from_file(file_to_check)
cwd = os.path.normcase(os.path.realpath("."))
@ -91,20 +104,19 @@ class BinTahoe(common_util.SignalMixin, unittest.TestCase, SkipMixin):
self._check_right_code(srcfile)
def test_import_in_repl(self):
self.skip_if_cannot_run_bintahoe()
p = subprocess.Popen([sys.executable, bintahoe, "debug", "repl"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(out, err) = p.communicate("import allmydata; print; print allmydata.__file__")
self.failUnlessEqual(p.returncode, 0)
lines = out.splitlines()
self.failUnlessIn('>>>', lines[0], (out, err))
self._check_right_code(lines[1])
d = self.run_bintahoe(["debug", "repl"],
stdin="import allmydata; print; print allmydata.__file__")
def _cb(res):
out, err, rc_or_sig = res
self.failUnlessEqual(rc_or_sig, 0, str(res))
lines = out.splitlines()
self.failUnlessIn('>>>', lines[0], str(res))
self._check_right_code(lines[1])
d.addCallback(_cb)
return d
def test_path(self):
self.skip_if_cannot_run_bintahoe()
d = utils.getProcessOutputAndValue(bintahoe, args=["--version-and-path"], env=os.environ)
d = self.run_bintahoe(["--version-and-path"])
def _cb(res):
out, err, rc_or_sig = res
self.failUnlessEqual(rc_or_sig, 0, str(res))
@ -151,7 +163,7 @@ class BinTahoe(common_util.SignalMixin, unittest.TestCase, SkipMixin):
except UnicodeEncodeError:
raise unittest.SkipTest("A non-ASCII argument/output could not be encoded on this platform.")
d = utils.getProcessOutputAndValue(bintahoe, args=[tricky_arg], env=os.environ)
d = self.run_bintahoe([tricky_arg])
def _cb(res):
out, err, rc_or_sig = res
self.failUnlessEqual(rc_or_sig, 1, str(res))
@ -163,8 +175,7 @@ class BinTahoe(common_util.SignalMixin, unittest.TestCase, SkipMixin):
self.skip_if_cannot_run_bintahoe()
# -t is a harmless option that warns about tabs.
d = utils.getProcessOutputAndValue(sys.executable, args=['-t', bintahoe, '--version'],
env=os.environ)
d = self.run_bintahoe(["--version"], python_options=["-t"])
def _cb(res):
out, err, rc_or_sig = res
self.failUnlessEqual(rc_or_sig, 0, str(res))
@ -180,7 +191,7 @@ class BinTahoe(common_util.SignalMixin, unittest.TestCase, SkipMixin):
except pkg_resources.VersionConflict:
raise unittest.SkipTest("We pass this test only with Twisted >= v9.0.0")
d = utils.getProcessOutputAndValue(bintahoe, args=["--version"], env=os.environ)
d = self.run_bintahoe(["--version"])
def _cb(res):
out, err, rc_or_sig = res
self.failUnlessEqual(rc_or_sig, 0, str(res))
@ -307,7 +318,7 @@ class CreateNode(unittest.TestCase):
class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
SkipMixin):
RunBinTahoeMixin):
# exercise "tahoe start", for both introducer, client node, and
# key-generator, by spawning "tahoe start" as a subprocess. This doesn't
# get us figleaf-based line-level coverage, but it does a better job of
@ -333,7 +344,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
TWISTD_PID_FILE = os.path.join(c1, "twistd.pid")
INTRODUCER_FURL_FILE = os.path.join(c1, "introducer.furl")
d = utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "create-introducer", "--basedir", c1], env=os.environ)
d = self.run_bintahoe(["--quiet", "create-introducer", "--basedir", c1])
def _cb(res):
out, err, rc_or_sig = res
self.failUnlessEqual(rc_or_sig, 0)
@ -345,7 +356,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
d.addCallback(_cb)
def _then_start_the_node(res):
return utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "start", c1], env=os.environ)
return self.run_bintahoe(["--quiet", "start", c1])
d.addCallback(_then_start_the_node)
def _cb2(res):
@ -376,7 +387,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
self.failUnless(os.path.exists(TWISTD_PID_FILE))
# rm this so we can detect when the second incarnation is ready
os.unlink(INTRODUCER_FURL_FILE)
return utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "restart", c1], env=os.environ)
return self.run_bintahoe(["--quiet", "restart", c1])
d.addCallback(_started)
def _then(res):
@ -399,7 +410,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
open(HOTLINE_FILE, "w").write("")
self.failUnless(os.path.exists(TWISTD_PID_FILE))
return utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "stop", c1], env=os.environ)
return self.run_bintahoe(["--quiet", "stop", c1])
d.addCallback(_stop)
def _after_stopping(res):
@ -436,7 +447,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
TWISTD_PID_FILE = os.path.join(c1, "twistd.pid")
PORTNUMFILE = os.path.join(c1, "client.port")
d = utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "create-client", "--basedir", c1, "--webport", "0"], env=os.environ)
d = self.run_bintahoe(["--quiet", "create-client", "--basedir", c1, "--webport", "0"])
def _cb(res):
out, err, rc_or_sig = res
errstr = "cc=%d, OUT: '%s', ERR: '%s'" % (rc_or_sig, out, err)
@ -451,7 +462,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
d.addCallback(_cb)
def _start(res):
return utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "start", c1], env=os.environ)
return self.run_bintahoe(["--quiet", "start", c1])
d.addCallback(_start)
def _cb2(res):
@ -485,7 +496,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
# 'tahoe stop' command takes a while.
def _stop(res):
self.failUnless(os.path.exists(TWISTD_PID_FILE), (TWISTD_PID_FILE, os.listdir(os.path.dirname(TWISTD_PID_FILE))))
return utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "stop", c1], env=os.environ)
return self.run_bintahoe(["--quiet", "stop", c1])
d.addCallback(_stop)
return d
@ -497,7 +508,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
TWISTD_PID_FILE = os.path.join(c1, "twistd.pid")
PORTNUMFILE = os.path.join(c1, "client.port")
d = utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "create-node", "--basedir", c1, "--webport", "0"], env=os.environ)
d = self.run_bintahoe(["--quiet", "create-node", "--basedir", c1, "--webport", "0"])
def _cb(res):
out, err, rc_or_sig = res
self.failUnlessEqual(rc_or_sig, 0)
@ -510,7 +521,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
d.addCallback(_cb)
def _start(res):
return utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "start", c1], env=os.environ)
return self.run_bintahoe(["--quiet", "start", c1])
d.addCallback(_start)
def _cb2(res):
@ -541,7 +552,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
# rm this so we can detect when the second incarnation is ready
os.unlink(PORTNUMFILE)
return utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "restart", c1], env=os.environ)
return self.run_bintahoe(["--quiet", "restart", c1])
d.addCallback(_started)
def _cb3(res):
@ -564,7 +575,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
def _stop(res):
open(HOTLINE_FILE, "w").write("")
self.failUnless(os.path.exists(TWISTD_PID_FILE), (TWISTD_PID_FILE, os.listdir(os.path.dirname(TWISTD_PID_FILE))))
return utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "stop", c1], env=os.environ)
return self.run_bintahoe(["--quiet", "stop", c1])
d.addCallback(_stop)
def _cb4(res):
@ -592,7 +603,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
basedir = self.workdir("test_baddir")
fileutil.make_dirs(basedir)
d = utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "start", "--basedir", basedir], env=os.environ)
d = self.run_bintahoe(["--quiet", "start", "--basedir", basedir])
def _cb(res):
out, err, rc_or_sig = res
self.failUnlessEqual(rc_or_sig, 1)
@ -600,7 +611,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
d.addCallback(_cb)
def _then_stop_it(res):
return utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "stop", "--basedir", basedir], env=os.environ)
return self.run_bintahoe(["--quiet", "stop", "--basedir", basedir])
d.addCallback(_then_stop_it)
def _cb2(res):
@ -611,7 +622,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
def _then_start_in_bogus_basedir(res):
not_a_dir = os.path.join(basedir, "bogus")
return utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "start", "--basedir", not_a_dir], env=os.environ)
return self.run_bintahoe(["--quiet", "start", "--basedir", not_a_dir])
d.addCallback(_then_start_in_bogus_basedir)
def _cb3(res):
@ -628,14 +639,14 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
TWISTD_PID_FILE = os.path.join(c1, "twistd.pid")
KEYGEN_FURL_FILE = os.path.join(c1, "key_generator.furl")
d = utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "create-key-generator", "--basedir", c1], env=os.environ)
d = self.run_bintahoe(["--quiet", "create-key-generator", "--basedir", c1])
def _cb(res):
out, err, rc_or_sig = res
self.failUnlessEqual(rc_or_sig, 0)
d.addCallback(_cb)
def _start(res):
return utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "start", c1], env=os.environ)
return self.run_bintahoe(["--quiet", "start", c1])
d.addCallback(_start)
def _cb2(res):
@ -663,7 +674,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
self.failUnless(os.path.exists(TWISTD_PID_FILE))
# rm this so we can detect when the second incarnation is ready
os.unlink(KEYGEN_FURL_FILE)
return utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "restart", c1], env=os.environ)
return self.run_bintahoe(["--quiet", "restart", c1])
d.addCallback(_started)
def _cb3(res):
@ -683,7 +694,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
# 'tahoe stop' command takes a while.
def _stop(res):
self.failUnless(os.path.exists(TWISTD_PID_FILE))
return utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "stop", c1], env=os.environ)
return self.run_bintahoe(["--quiet", "stop", c1])
d.addCallback(_stop)
def _cb4(res):

View File

@ -4,7 +4,6 @@ from cStringIO import StringIO
from twisted.trial import unittest
from twisted.internet import defer
from twisted.internet import threads # CLI tests use deferToThread
from twisted.internet import utils
import allmydata
from allmydata import uri
@ -32,7 +31,7 @@ from twisted.web.error import Error
from allmydata.test.common import SystemTestMixin
# TODO: move these to common or common_util
from allmydata.test.test_runner import bintahoe, SkipMixin
from allmydata.test.test_runner import RunBinTahoeMixin
LARGE_DATA = """
This is some data to publish to the remote grid.., which needs to be large
@ -52,7 +51,7 @@ class CountingDataUploadable(upload.Data):
self.interrupt_after_d.callback(self)
return upload.Data.read(self, length)
class SystemTest(SystemTestMixin, SkipMixin, unittest.TestCase):
class SystemTest(SystemTestMixin, RunBinTahoeMixin, unittest.TestCase):
timeout = 3600 # It takes longer than 960 seconds on Zandr's ARM box.
def test_connections(self):
@ -1594,23 +1593,9 @@ class SystemTest(SystemTestMixin, SkipMixin, unittest.TestCase):
d.addCallback(_check_ls_rouri)
d.addCallback(run, "mv", "tahoe-file-stdin", "tahoe-moved-first-time")
d.addCallback(run, "mv", "tahoe-file-stdin", "tahoe-moved")
d.addCallback(run, "ls")
d.addCallback(_check_ls, ["tahoe-moved-first-time"], ["tahoe-file-stdin"])
def _mv_with_http_proxy(ign):
env = os.environ
env['http_proxy'] = env['HTTP_PROXY'] = "http://127.0.0.0:12345" # invalid address
return self._run_cli_in_subprocess(["mv"] + nodeargs + ["tahoe-moved-first-time", "tahoe-moved"], env=env)
d.addCallback(_mv_with_http_proxy)
def _check_mv_with_http_proxy(res):
out, err, rc_or_sig = res
self.failUnlessEqual(rc_or_sig, 0, str(res))
d.addCallback(_check_mv_with_http_proxy)
d.addCallback(run, "ls")
d.addCallback(_check_ls, ["tahoe-moved"], ["tahoe-moved-firsttime"])
d.addCallback(_check_ls, ["tahoe-moved"], ["tahoe-file-stdin"])
d.addCallback(run, "ln", "tahoe-moved", "newlink")
d.addCallback(run, "ls")
@ -1753,6 +1738,52 @@ class SystemTest(SystemTestMixin, SkipMixin, unittest.TestCase):
return d
def test_filesystem_with_cli_in_subprocess(self):
# We do this in a separate test so that test_filesystem doesn't skip if we can't run bin/tahoe.
self.basedir = "system/SystemTest/test_filesystem_with_cli_in_subprocess"
d = self.set_up_nodes()
def _new_happy_semantics(ign):
for c in self.clients:
c.DEFAULT_ENCODING_PARAMETERS['happy'] = 1
d.addCallback(_new_happy_semantics)
def _run_in_subprocess(ignored, verb, *args, **kwargs):
stdin = kwargs.get("stdin")
env = kwargs.get("env")
newargs = [verb, "--node-directory", self.getdir("client0")] + list(args)
return self.run_bintahoe(newargs, stdin=stdin, env=env)
def _check_succeeded(res, check_stderr=True):
out, err, rc_or_sig = res
self.failUnlessEqual(rc_or_sig, 0, str(res))
if check_stderr:
self.failUnlessEqual(err, "")
d.addCallback(_run_in_subprocess, "create-alias", "newalias")
d.addCallback(_check_succeeded)
STDIN_DATA = "This is the file to upload from stdin."
d.addCallback(_run_in_subprocess, "put", "-", "newalias:tahoe-file", stdin=STDIN_DATA)
d.addCallback(_check_succeeded, check_stderr=False)
def _mv_with_http_proxy(ign):
env = os.environ
env['http_proxy'] = env['HTTP_PROXY'] = "http://127.0.0.0:12345" # invalid address
return _run_in_subprocess(None, "mv", "newalias:tahoe-file", "newalias:tahoe-moved", env=env)
d.addCallback(_mv_with_http_proxy)
d.addCallback(_check_succeeded)
d.addCallback(_run_in_subprocess, "ls", "newalias:")
def _check_ls(res):
out, err, rc_or_sig = res
self.failUnlessEqual(rc_or_sig, 0, str(res))
self.failUnlessEqual(err, "", str(res))
self.failUnlessIn("tahoe-moved", out)
self.failIfIn("tahoe-file", out)
d.addCallback(_check_ls)
return d
def test_debug_trial(self):
def _check_for_line(lines, result, test):
for l in lines:
@ -1765,8 +1796,8 @@ class SystemTest(SystemTestMixin, SkipMixin, unittest.TestCase):
self.failUnlessIn(outcome, out, "output (prefixed with '##') does not contain %r:\n## %s"
% (outcome, "\n## ".join(lines)))
d = self._run_cli_in_subprocess(['debug', 'trial', '--reporter=verbose',
'allmydata.test.trialtest'])
d = self.run_bintahoe(['debug', 'trial', '--reporter=verbose',
'allmydata.test.trialtest'])
def _check_failure( (out, err, rc) ):
self.failUnlessEqual(rc, 1)
lines = out.split('\n')
@ -1779,8 +1810,8 @@ class SystemTest(SystemTestMixin, SkipMixin, unittest.TestCase):
d.addCallback(_check_failure)
# the --quiet argument regression-tests a problem in finding which arguments to pass to trial
d.addCallback(lambda ign: self._run_cli_in_subprocess(['--quiet', 'debug', 'trial', '--reporter=verbose',
'allmydata.test.trialtest.Success']))
d.addCallback(lambda ign: self.run_bintahoe(['--quiet', 'debug', 'trial', '--reporter=verbose',
'allmydata.test.trialtest.Success']))
def _check_success( (out, err, rc) ):
self.failUnlessEqual(rc, 0)
lines = out.split('\n')
@ -1801,15 +1832,6 @@ class SystemTest(SystemTestMixin, SkipMixin, unittest.TestCase):
d.addCallback(_done)
return d
def _run_cli_in_subprocess(self, argv, env=None):
self.skip_if_cannot_run_bintahoe()
if env is None:
env = os.environ
d = utils.getProcessOutputAndValue(sys.executable, args=[bintahoe] + argv,
env=env)
return d
def _test_checker(self, res):
ut = upload.Data("too big to be literal" * 200, convergence=None)
d = self._personal_node.add_file(u"big file", ut)

View File

@ -1,16 +1,12 @@
# from the Python Standard Library
import os, re, socket, sys
import os, re, socket, sys, subprocess
# from Twisted
from twisted.internet import defer
from twisted.internet import reactor
from twisted.internet import defer, threads, reactor
from twisted.internet.protocol import DatagramProtocol
from twisted.internet.utils import getProcessOutput
from twisted.python.procutils import which
from twisted.python import log
from allmydata.util import observer
try:
import resource
def increase_rlimits():
@ -193,39 +189,6 @@ _irix_path = '/usr/etc/ifconfig'
# Solaris 2.x
_sunos_path = '/usr/sbin/ifconfig'
class SequentialTrier(object):
""" I hold a list of executables to try and try each one in turn
until one gives me a list of IP addresses."""
def __init__(self, exebasename, args, regex):
assert not os.path.isabs(exebasename)
self.exes_left_to_try = which(exebasename)
self.exes_left_to_try.reverse()
self.args = args
self.regex = regex
self.o = observer.OneShotObserverList()
self._try_next()
def _try_next(self):
if not self.exes_left_to_try:
self.o.fire(None)
else:
exe = self.exes_left_to_try.pop()
d2 = _query(exe, self.args, self.regex)
def cb(res):
if res:
self.o.fire(res)
else:
self._try_next()
def eb(why):
self._try_next()
d2.addCallbacks(cb, eb)
def when_tried(self):
return self.o.when_fired()
# k: platform string as provided in the value of _platform_map
# v: tuple of (path_to_tool, args, regex,)
@ -237,7 +200,11 @@ _tool_map = {
"irix": (_irix_path, _netbsd_args, _netbsd_re,),
"sunos": (_sunos_path, _netbsd_args, _netbsd_re,),
}
def _find_addresses_via_config():
return threads.deferToThread(_synchronously_find_addresses_via_config)
def _synchronously_find_addresses_via_config():
# originally by Greg Smith, hacked by Zooko to conform to Brian's API
platform = _platform_map.get(sys.platform)
@ -254,23 +221,30 @@ def _find_addresses_via_config():
if os.path.isabs(pathtotool):
return _query(pathtotool, args, regex)
else:
return SequentialTrier(pathtotool, args, regex).when_tried()
exes_to_try = which(pathtotool)
for exe in exes_to_try:
try:
addresses = _query(exe, args, regex)
except Exception:
addresses = []
if addresses:
return addresses
return []
def _query(path, args, regex):
d = getProcessOutput(path, args)
def _parse(output):
addresses = []
outputsplit = output.split('\n')
for outline in outputsplit:
m = regex.match(outline)
if m:
addr = m.groupdict()['address']
if addr not in addresses:
addresses.append(addr)
p = subprocess.Popen([path] + list(args), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(output, err) = p.communicate()
return addresses
d.addCallback(_parse)
return d
addresses = []
outputsplit = output.split('\n')
for outline in outputsplit:
m = regex.match(outline)
if m:
addr = m.groupdict()['address']
if addr not in addresses:
addresses.append(addr)
return addresses
def _cygwin_hack_find_addresses(target):
addresses = []