From 2e2bd1bb5f0ef0eb8cff7426700777f26df0155c Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Sun, 27 Sep 2015 10:43:25 -0700 Subject: [PATCH] tests: split blocking out to its own file also clean up the output when pip-e -vs- entrypoint -vs- Versioneer makes the entrypoint script refuse to run from a version mismatch. --- src/wormhole/test/test_blocking.py | 96 ++++++++++++++++++++++++++++++ src/wormhole/test/test_scripts.py | 43 ++++++++++++- src/wormhole/test/test_twisted.py | 92 ---------------------------- 3 files changed, 136 insertions(+), 95 deletions(-) create mode 100644 src/wormhole/test/test_blocking.py diff --git a/src/wormhole/test/test_blocking.py b/src/wormhole/test/test_blocking.py new file mode 100644 index 0000000..e299d9e --- /dev/null +++ b/src/wormhole/test/test_blocking.py @@ -0,0 +1,96 @@ +import json +from twisted.trial import unittest +from twisted.internet import defer +from twisted.internet.threads import deferToThread +from ..blocking.transcribe import Wormhole as BlockingWormhole, UsageError +from .common import ServerBase + +class Blocking(ServerBase, unittest.TestCase): + # we need Twisted to run the server, but we run the sender and receiver + # with deferToThread() + + def test_basic(self): + appid = "appid" + w1 = BlockingWormhole(appid, self.relayurl) + w2 = BlockingWormhole(appid, self.relayurl) + d = deferToThread(w1.get_code) + def _got_code(code): + w2.set_code(code) + d1 = deferToThread(w1.get_data, "data1") + d2 = deferToThread(w2.get_data, "data2") + return defer.DeferredList([d1,d2], fireOnOneErrback=False) + d.addCallback(_got_code) + def _done(dl): + ((success1, dataX), (success2, dataY)) = dl + r1,r2 = dl + self.assertTrue(success1, dataX) + self.assertTrue(success2, dataY) + self.assertEqual(dataX, "data2") + self.assertEqual(dataY, "data1") + d.addCallback(_done) + return d + + def test_fixed_code(self): + appid = "appid" + w1 = BlockingWormhole(appid, self.relayurl) + w2 = BlockingWormhole(appid, self.relayurl) + w1.set_code("123-purple-elephant") + w2.set_code("123-purple-elephant") + d1 = deferToThread(w1.get_data, "data1") + d2 = deferToThread(w2.get_data, "data2") + d = defer.DeferredList([d1,d2], fireOnOneErrback=False) + def _done(dl): + ((success1, dataX), (success2, dataY)) = dl + r1,r2 = dl + self.assertTrue(success1, dataX) + self.assertTrue(success2, dataY) + self.assertEqual(dataX, "data2") + self.assertEqual(dataY, "data1") + d.addCallback(_done) + return d + + def test_errors(self): + appid = "appid" + w1 = BlockingWormhole(appid, self.relayurl) + self.assertRaises(UsageError, w1.get_verifier) + self.assertRaises(UsageError, w1.get_data, "data") + w1.set_code("123-purple-elephant") + self.assertRaises(UsageError, w1.set_code, "123-nope") + self.assertRaises(UsageError, w1.get_code) + w2 = BlockingWormhole(appid, self.relayurl) + d = deferToThread(w2.get_code) + def _done(code): + self.assertRaises(UsageError, w2.get_code) + d.addCallback(_done) + return d + + def test_serialize(self): + appid = "appid" + w1 = BlockingWormhole(appid, self.relayurl) + self.assertRaises(UsageError, w1.serialize) # too early + w2 = BlockingWormhole(appid, self.relayurl) + d = deferToThread(w1.get_code) + def _got_code(code): + self.assertRaises(UsageError, w2.serialize) # too early + w2.set_code(code) + w2.serialize() # ok + s = w1.serialize() + self.assertEqual(type(s), type("")) + unpacked = json.loads(s) # this is supposed to be JSON + self.assertEqual(type(unpacked), dict) + new_w1 = BlockingWormhole.from_serialized(s) + d1 = deferToThread(new_w1.get_data, "data1") + d2 = deferToThread(w2.get_data, "data2") + return defer.DeferredList([d1,d2], fireOnOneErrback=False) + d.addCallback(_got_code) + def _done(dl): + ((success1, dataX), (success2, dataY)) = dl + r1,r2 = dl + self.assertTrue(success1, dataX) + self.assertTrue(success2, dataY) + self.assertEqual(dataX, "data2") + self.assertEqual(dataY, "data1") + self.assertRaises(UsageError, w2.serialize) # too late + d.addCallback(_done) + return d + test_serialize.skip = "not yet implemented for the blocking flavor" diff --git a/src/wormhole/test/test_scripts.py b/src/wormhole/test/test_scripts.py index 52503ae..7131fc3 100644 --- a/src/wormhole/test/test_scripts.py +++ b/src/wormhole/test/test_scripts.py @@ -5,9 +5,7 @@ from twisted.internet.utils import getProcessOutputAndValue from .. import __version__ from .common import ServerBase -class Scripts(ServerBase, unittest.TestCase): - # we need Twisted to run the server, but we run the sender and receiver - # with deferToThread() +class ScriptsBase: def find_executable(self): # to make sure we're running the right executable (in a virtualenv), # we require that our "wormhole" lives in the same directory as our @@ -24,6 +22,32 @@ class Scripts(ServerBase, unittest.TestCase): % (wormhole, sys.executable)) return wormhole + def is_runnable(self): + # One property of Versioneer is that many changes to the source tree + # (making a commit, dirtying a previously-clean tree) will change the + # version string. Entrypoint scripts frequently insist upon importing + # a library version that matches the script version (whatever was + # reported when 'pip install' was run), and throw a + # DistributionNotFound error when they don't match. This is really + # annoying in a workspace created with "pip install -e .", as you + # must re-run pip after each commit. + + # So let's report just one error in this case (from test_version), + # and skip the other tests that we know will fail. + + wormhole = self.find_executable() + d = getProcessOutputAndValue(wormhole, ["--version"]) + def _check(res): + out, err, rc = res + if rc != 0: + raise unittest.SkipTest("wormhole is not runnable in this tree") + d.addCallback(_check) + return d + +class ScriptVersion(ServerBase, ScriptsBase, unittest.TestCase): + # we need Twisted to run the server, but we run the sender and receiver + # with deferToThread() + def test_version(self): # "wormhole" must be on the path, so e.g. "pip install -e ." in a # virtualenv @@ -32,11 +56,24 @@ class Scripts(ServerBase, unittest.TestCase): def _check(res): out, err, rc = res self.failUnlessEqual(out, "") + if "DistributionNotFound" in err: + log.msg("stderr was %s" % err) + last = err.strip().split("\n")[-1] + self.fail("wormhole not runnable: %s" % last) self.failUnlessEqual(err, "magic-wormhole %s\n" % __version__) self.failUnlessEqual(rc, 0) d.addCallback(_check) return d +class Scripts(ServerBase, ScriptsBase, unittest.TestCase): + # we need Twisted to run the server, but we run the sender and receiver + # with deferToThread() + + def setUp(self): + d = self.is_runnable() + d.addCallback(lambda _: ServerBase.setUp(self)) + return d + def test_send_text_pre_generated_code(self): wormhole = self.find_executable() server_args = ["--relay-url", self.relayurl] diff --git a/src/wormhole/test/test_twisted.py b/src/wormhole/test/test_twisted.py index f459853..9376f86 100644 --- a/src/wormhole/test/test_twisted.py +++ b/src/wormhole/test/test_twisted.py @@ -1,9 +1,7 @@ import json from twisted.trial import unittest from twisted.internet import defer -from twisted.internet.threads import deferToThread from ..twisted.transcribe import Wormhole, UsageError -from ..blocking.transcribe import Wormhole as BlockingWormhole from .common import ServerBase #from twisted.python import log #import sys @@ -92,93 +90,3 @@ class Basic(ServerBase, unittest.TestCase): self.assertRaises(UsageError, w2.serialize) # too late d.addCallback(_done) return d - -class Blocking(ServerBase, unittest.TestCase): - # we need Twisted to run the server, but we run the sender and receiver - # with deferToThread() - - def test_basic(self): - appid = "appid" - w1 = BlockingWormhole(appid, self.relayurl) - w2 = BlockingWormhole(appid, self.relayurl) - d = deferToThread(w1.get_code) - def _got_code(code): - w2.set_code(code) - d1 = deferToThread(w1.get_data, "data1") - d2 = deferToThread(w2.get_data, "data2") - return defer.DeferredList([d1,d2], fireOnOneErrback=False) - d.addCallback(_got_code) - def _done(dl): - ((success1, dataX), (success2, dataY)) = dl - r1,r2 = dl - self.assertTrue(success1, dataX) - self.assertTrue(success2, dataY) - self.assertEqual(dataX, "data2") - self.assertEqual(dataY, "data1") - d.addCallback(_done) - return d - - def test_fixed_code(self): - appid = "appid" - w1 = BlockingWormhole(appid, self.relayurl) - w2 = BlockingWormhole(appid, self.relayurl) - w1.set_code("123-purple-elephant") - w2.set_code("123-purple-elephant") - d1 = deferToThread(w1.get_data, "data1") - d2 = deferToThread(w2.get_data, "data2") - d = defer.DeferredList([d1,d2], fireOnOneErrback=False) - def _done(dl): - ((success1, dataX), (success2, dataY)) = dl - r1,r2 = dl - self.assertTrue(success1, dataX) - self.assertTrue(success2, dataY) - self.assertEqual(dataX, "data2") - self.assertEqual(dataY, "data1") - d.addCallback(_done) - return d - - def test_errors(self): - appid = "appid" - w1 = BlockingWormhole(appid, self.relayurl) - self.assertRaises(UsageError, w1.get_verifier) - self.assertRaises(UsageError, w1.get_data, "data") - w1.set_code("123-purple-elephant") - self.assertRaises(UsageError, w1.set_code, "123-nope") - self.assertRaises(UsageError, w1.get_code) - w2 = BlockingWormhole(appid, self.relayurl) - d = deferToThread(w2.get_code) - def _done(code): - self.assertRaises(UsageError, w2.get_code) - d.addCallback(_done) - return d - - def test_serialize(self): - appid = "appid" - w1 = BlockingWormhole(appid, self.relayurl) - self.assertRaises(UsageError, w1.serialize) # too early - w2 = BlockingWormhole(appid, self.relayurl) - d = deferToThread(w1.get_code) - def _got_code(code): - self.assertRaises(UsageError, w2.serialize) # too early - w2.set_code(code) - w2.serialize() # ok - s = w1.serialize() - self.assertEqual(type(s), type("")) - unpacked = json.loads(s) # this is supposed to be JSON - self.assertEqual(type(unpacked), dict) - new_w1 = BlockingWormhole.from_serialized(s) - d1 = deferToThread(new_w1.get_data, "data1") - d2 = deferToThread(w2.get_data, "data2") - return defer.DeferredList([d1,d2], fireOnOneErrback=False) - d.addCallback(_got_code) - def _done(dl): - ((success1, dataX), (success2, dataY)) = dl - r1,r2 = dl - self.assertTrue(success1, dataX) - self.assertTrue(success2, dataY) - self.assertEqual(dataX, "data2") - self.assertEqual(dataY, "data1") - self.assertRaises(UsageError, w2.serialize) # too late - d.addCallback(_done) - return d - test_serialize.skip = "not yet implemented for the blocking flavor"