From: david-sarah Date: Thu, 20 Jan 2011 04:32:38 +0000 (-0800) Subject: Eliminate dependencies on pywin32, even via Twisted. refs #1274 X-Git-Tag: allmydata-tahoe-1.8.2b1~29 X-Git-Url: https://git.rkrishnan.org/pf/content/en/?a=commitdiff_plain;h=6dd8b6f47126fdc09222d34bfb326c2058bfe092;p=tahoe-lafs%2Ftahoe-lafs.git Eliminate dependencies on pywin32, even via Twisted. refs #1274 --- diff --git a/src/allmydata/_auto_deps.py b/src/allmydata/_auto_deps.py index f77db1c0..b784b8bc 100644 --- a/src/allmydata/_auto_deps.py +++ b/src/allmydata/_auto_deps.py @@ -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 diff --git a/src/allmydata/test/test_runner.py b/src/allmydata/test/test_runner.py index f13b8196..86d31f50 100644 --- a/src/allmydata/test/test_runner.py +++ b/src/allmydata/test/test_runner.py @@ -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 + + 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, SkipMixin): +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): diff --git a/src/allmydata/test/test_system.py b/src/allmydata/test/test_system.py index 006d7bdb..ed615981 100644 --- a/src/allmydata/test/test_system.py +++ b/src/allmydata/test/test_system.py @@ -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) diff --git a/src/allmydata/util/iputil.py b/src/allmydata/util/iputil.py index 0d8b9a4e..efec11c9 100644 --- a/src/allmydata/util/iputil.py +++ b/src/allmydata/util/iputil.py @@ -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 = []