diff --git a/setup.py b/setup.py index 4ae6eeb91..6d6004653 100644 --- a/setup.py +++ b/setup.py @@ -173,51 +173,6 @@ class Trial(Command): sys.exit(rc) -class MakeExecutable(Command): - description = "make the 'bin%stahoe' scripts" % (os.sep,) - user_options = install.install.user_options - - def initialize_options(self): - pass - def finalize_options(self): - pass - def run(self): - # A bin/tahoe (or bin/tahoe-script.py) is only necessary for the - # test_runner tests which exercise CLI invocation of a brand new - # tahoe process. It is also handy for users who are accustomed to - # running bin/tahoe (and have not yet gotten used to the new - # virtualenv-based "just run tahoe" world). Eventually this will be - # removed. - - # This must be run *after* a 'pip install' (hopefully inside a - # virtualenv), because it needs to locate the tahoe executable (named - # 'tahoe' or 'tahoe.exe' or 'tahoe-script.py' or something) on $PATH. - - # This is safe because we're run after 'install', which installed - # Twisted. It would not be safe to run before that. Note that this - # uses $PATHEXT for a list of executable suffixes. - from twisted.python.procutils import which - - installed_tahoes = which("tahoe") - if not installed_tahoes: - err = ("Cannot find installed 'tahoe' binary " - "('setup.py make_executable' must be run after" - " 'setup.py install')") - raise RuntimeError(err) - - if not os.path.isdir("bin"): - os.mkdir("bin") - - installed_tahoe = installed_tahoes[0] - bin_tahoe = os.path.join("bin", "tahoe") - with open(installed_tahoe, "rb") as inf: - with open(bin_tahoe, "wb") as outf: - outf.write(inf.read()) - - # copy file mode - os.chmod(bin_tahoe, os.stat(installed_tahoe).st_mode) - - GIT_VERSION_BODY = ''' # This _version.py is generated from git metadata by the tahoe setup.py. @@ -410,7 +365,6 @@ setup(name=APPNAME, url='https://tahoe-lafs.org/', license='GNU GPL', # see README.rst -- there is an alternative licence cmdclass={"trial": Trial, - "make_executable": MakeExecutable, "update_version": UpdateVersion, "sdist": MySdist, }, diff --git a/src/allmydata/test/test_runner.py b/src/allmydata/test/test_runner.py index 244531866..48c481764 100644 --- a/src/allmydata/test/test_runner.py +++ b/src/allmydata/test/test_runner.py @@ -5,6 +5,7 @@ from twisted.trial import unittest from twisted.python import usage, runtime from twisted.internet import threads +from twisted.internet.defer import inlineCallbacks, returnValue from allmydata.util import fileutil, pollmixin from allmydata.util.encodingutil import unicode_to_argv, unicode_to_output, get_filesystem_encoding @@ -48,6 +49,11 @@ if sys.platform == "win32" and not os.path.exists(bintahoe): break +# This memoizes find_import_location(), so we don't have to run +# --version-and-path multiple times for the same binary. In practice, this +# will only ever have one entry. +CACHED_IMPORT_PATH = {} + class RunBinTahoeMixin: def skip_if_cannot_run_bintahoe(self): if not os.path.exists(bintahoe): @@ -59,6 +65,19 @@ class RunBinTahoeMixin: # twistd on windows doesn't daemonize. cygwin should work normally. raise unittest.SkipTest("twistd does not fork under windows") + @inlineCallbacks + def find_import_location(self): + if bintahoe in CACHED_IMPORT_PATH: + returnValue(CACHED_IMPORT_PATH[bintahoe]) + res = yield self.run_bintahoe(["--version-and-path"]) + out, err, rc_or_sig = res + self.assertEqual(rc_or_sig, 0, res) + lines = out.splitlines() + tahoe_pieces = lines[0].split() + self.assertEqual(tahoe_pieces[0], "allmydata-tahoe:", (tahoe_pieces, res)) + CACHED_IMPORT_PATH[bintahoe] = tahoe_pieces[-1].strip("()") + returnValue(CACHED_IMPORT_PATH[bintahoe]) + def run_bintahoe(self, args, stdin=None, python_options=[], env=None): self.skip_if_cannot_run_bintahoe() @@ -82,67 +101,30 @@ class RunBinTahoeMixin: 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) - if os.path.basename(root_to_check) == 'dist': - root_to_check = os.path.dirname(root_to_check) + @inlineCallbacks + def test_the_right_code(self): + # running "tahoe" in a subprocess should find the same code that + # holds this test file, else something is weird + test_path = os.path.dirname(os.path.dirname(os.path.normcase(os.path.realpath(srcfile)))) + bintahoe_import_path = yield self.find_import_location() - cwd = os.path.normcase(os.path.realpath(".")) - root_from_cwd = os.path.dirname(cwd) - if os.path.basename(root_from_cwd) == 'src': - root_from_cwd = os.path.dirname(root_from_cwd) - - # This is needed if we are running in a temporary directory created by 'make tmpfstest'. - if os.path.basename(root_from_cwd).startswith('tmp'): - root_from_cwd = os.path.dirname(root_from_cwd) - - same = (root_from_cwd == root_to_check) + same = (bintahoe_import_path == test_path) if not same: - try: - same = os.path.samefile(root_from_cwd, root_to_check) - except AttributeError, e: - e # hush pyflakes + msg = ("My tests and my 'tahoe' executable are using different paths.\n" + "tahoe: %r\n" + "tests: %r\n" + "( according to the test source filename %r)\n" % + (bintahoe_import_path, test_path, srcfile)) - if not same: - msg = ("We seem to be testing the code at %r,\n" - "(according to the source filename %r),\n" - "but expected to be testing the code at %r.\n" - % (root_to_check, file_to_check, root_from_cwd)) - - root_from_cwdu = os.path.dirname(os.path.normcase(os.path.normpath(os.getcwdu()))) - if os.path.basename(root_from_cwdu) == u'src': - root_from_cwdu = os.path.dirname(root_from_cwdu) - - # This is needed if we are running in a temporary directory created by 'make tmpfstest'. - if os.path.basename(root_from_cwdu).startswith(u'tmp'): - root_from_cwdu = os.path.dirname(root_from_cwdu) - - if not isinstance(root_from_cwd, unicode) and root_from_cwd.decode(get_filesystem_encoding(), 'replace') != root_from_cwdu: - msg += ("However, this may be a false alarm because the current directory path\n" - "is not representable in the filesystem encoding. Please run the tests\n" - "from the root of the Tahoe-LAFS distribution at a non-Unicode path.") + if (not isinstance(rootdir, unicode) and + rootdir.decode(get_filesystem_encoding(), 'replace') != rootdir): + msg += ("However, this may be a false alarm because the import path\n" + "is not representable in the filesystem encoding.") raise unittest.SkipTest(msg) else: - msg += "Please run the tests from the root of the Tahoe-LAFS distribution." + msg += "Please run the tests in a virtualenv that includes both the Tahoe-LAFS library and the 'tahoe' executable." self.fail(msg) - def test_the_right_code(self): - self._check_right_code(srcfile) - - def test_import_in_repl(self): - 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 - # The timeout was exceeded on FreeStorm's CentOS5-i386. - test_import_in_repl.timeout = 480 - def test_path(self): d = self.run_bintahoe(["--version-and-path"]) def _cb(res): diff --git a/tox.ini b/tox.ini index 1c118be15..c8c9289df 100644 --- a/tox.ini +++ b/tox.ini @@ -11,14 +11,7 @@ passenv = USERPROFILE HOMEDRIVE HOMEPATH commands = # remove this after we move to Versioneer python setup.py update_version - # This step should be removed after we get rid of bin/tahoe. It's - # currently needed because test_runner.(BinTahoe,RunNode) and part - # of test_system.SystemTest depends upon $checkout/bin/tahoe . In - # the future, users will just use 'tahoe' from $PATH (which, in the - # virtualenv, will be venv/bin/tahoe), and those tests will probably - # be deleted. - python setup.py make_executable - trial --rterrors allmydata + trial --rterrors {posargs:allmydata} [testenv:deprecations] passenv = USERPROFILE HOMEDRIVE HOMEPATH @@ -26,13 +19,11 @@ setenv = PYTHONWARNINGS=default::DeprecationWarnings commands = python setup.py update_version - python setup.py make_executable - trial --rterrors allmydata + trial --rterrors {posargs:allmydata} [testenv:checkmemory] commands = python setup.py update_version - python setup.py make_executable rm -rf _test_memory python src/allmydata/test/check_memory.py upload python src/allmydata/test/check_memory.py upload-self