Merge PR349 (in rebased form)

closes tahoe-lafs/tahoe-lafs#349
This commit is contained in:
Brian Warner 2016-09-26 13:33:57 -07:00
commit f8d800a3eb
5 changed files with 74 additions and 68 deletions

View File

@ -28,6 +28,7 @@ install:
script: script:
- tox -e codechecks - tox -e codechecks
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then tox; else tox -e coverage; fi - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then tox; else tox -e coverage; fi
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then tox -e integration; fi
after_success: after_success:
coveralls coveralls
notifications: notifications:

View File

@ -65,14 +65,6 @@ def temp_dir(request):
return tmp return tmp
@pytest.fixture(scope='session')
def tahoe_binary():
"""
Finds the 'tahoe' binary, yields complete path
"""
return which('tahoe')
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def flog_binary(): def flog_binary():
return which('flogtool') return which('flogtool')
@ -224,7 +216,7 @@ def flog_gatherer(reactor, temp_dir, flog_binary, request):
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def introducer(reactor, temp_dir, tahoe_binary, flog_gatherer, request): def introducer(reactor, temp_dir, flog_gatherer, request):
config = ''' config = '''
[node] [node]
nickname = introducer0 nickname = introducer0
@ -240,8 +232,14 @@ log_gatherer.furl = {log_furl}
done_proto = _ProcessExitedProtocol() done_proto = _ProcessExitedProtocol()
reactor.spawnProcess( reactor.spawnProcess(
done_proto, done_proto,
tahoe_binary, sys.executable,
('tahoe', 'create-introducer', intro_dir), (
sys.executable, '-m', 'allmydata.scripts.runner',
'create-introducer',
'--listen=tcp',
'--hostname=localhost',
intro_dir,
),
) )
pytest.blockon(done_proto.done) pytest.blockon(done_proto.done)
@ -255,8 +253,12 @@ log_gatherer.furl = {log_furl}
protocol = _MagicTextProtocol('introducer running') protocol = _MagicTextProtocol('introducer running')
process = reactor.spawnProcess( process = reactor.spawnProcess(
protocol, protocol,
tahoe_binary, sys.executable,
('tahoe', 'run', intro_dir), (
sys.executable, '-m', 'allmydata.scripts.runner',
'run',
intro_dir,
),
) )
def cleanup(): def cleanup():
@ -281,7 +283,7 @@ def introducer_furl(introducer, temp_dir):
return furl return furl
def _run_node(reactor, tahoe_binary, node_dir, request, magic_text): def _run_node(reactor, node_dir, request, magic_text):
if magic_text is None: if magic_text is None:
magic_text = "client running" magic_text = "client running"
protocol = _MagicTextProtocol(magic_text) protocol = _MagicTextProtocol(magic_text)
@ -291,9 +293,14 @@ def _run_node(reactor, tahoe_binary, node_dir, request, magic_text):
# between platforms. # between platforms.
process = reactor.spawnProcess( process = reactor.spawnProcess(
protocol, protocol,
tahoe_binary, sys.executable,
('tahoe', 'run', node_dir), (
sys.executable, '-m', 'allmydata.scripts.runner',
'run',
node_dir,
),
) )
process.exited = protocol.exited
def cleanup(): def cleanup():
try: try:
@ -309,7 +316,7 @@ def _run_node(reactor, tahoe_binary, node_dir, request, magic_text):
return protocol.magic_seen return protocol.magic_seen
def _create_node(reactor, request, temp_dir, tahoe_binary, introducer_furl, flog_gatherer, name, web_port, storage=True, magic_text=None): def _create_node(reactor, request, temp_dir, introducer_furl, flog_gatherer, name, web_port, storage=True, magic_text=None):
""" """
Helper to create a single node, run it and return the instance Helper to create a single node, run it and return the instance
spawnProcess returned (ITransport) spawnProcess returned (ITransport)
@ -322,10 +329,12 @@ def _create_node(reactor, request, temp_dir, tahoe_binary, introducer_furl, flog
mkdir(node_dir) mkdir(node_dir)
done_proto = _ProcessExitedProtocol() done_proto = _ProcessExitedProtocol()
args = [ args = [
'tahoe', sys.executable, '-m', 'allmydata.scripts.runner',
'create-node', 'create-node',
'--nickname', name, '--nickname', name,
'--introducer', introducer_furl, '--introducer', introducer_furl,
'--hostname', 'localhost',
'--listen', 'tcp',
] ]
if not storage: if not storage:
args.append('--no-storage') args.append('--no-storage')
@ -333,7 +342,7 @@ def _create_node(reactor, request, temp_dir, tahoe_binary, introducer_furl, flog
reactor.spawnProcess( reactor.spawnProcess(
done_proto, done_proto,
tahoe_binary, sys.executable,
args, args,
) )
pytest.blockon(done_proto.done) pytest.blockon(done_proto.done)
@ -360,11 +369,11 @@ shares.total = 4
'log_furl': flog_gatherer, 'log_furl': flog_gatherer,
}) })
return _run_node(reactor, tahoe_binary, node_dir, request, magic_text) return _run_node(reactor, node_dir, request, magic_text)
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def storage_nodes(reactor, temp_dir, tahoe_binary, introducer, introducer_furl, flog_gatherer, request): def storage_nodes(reactor, temp_dir, introducer, introducer_furl, flog_gatherer, request):
nodes = [] nodes = []
# start all 5 nodes in parallel # start all 5 nodes in parallel
for x in range(5): for x in range(5):
@ -373,7 +382,7 @@ def storage_nodes(reactor, temp_dir, tahoe_binary, introducer, introducer_furl,
nodes.append( nodes.append(
pytest.blockon( pytest.blockon(
_create_node( _create_node(
reactor, request, temp_dir, tahoe_binary, introducer_furl, flog_gatherer, name, reactor, request, temp_dir, introducer_furl, flog_gatherer, name,
web_port=None, storage=True, web_port=None, storage=True,
) )
) )
@ -383,7 +392,7 @@ def storage_nodes(reactor, temp_dir, tahoe_binary, introducer, introducer_furl,
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def alice(reactor, temp_dir, tahoe_binary, introducer_furl, flog_gatherer, storage_nodes, request): def alice(reactor, temp_dir, introducer_furl, flog_gatherer, storage_nodes, request):
try: try:
mkdir(join(temp_dir, 'magic-alice')) mkdir(join(temp_dir, 'magic-alice'))
except OSError: except OSError:
@ -391,7 +400,7 @@ def alice(reactor, temp_dir, tahoe_binary, introducer_furl, flog_gatherer, stora
process = pytest.blockon( process = pytest.blockon(
_create_node( _create_node(
reactor, request, temp_dir, tahoe_binary, introducer_furl, flog_gatherer, "alice", reactor, request, temp_dir, introducer_furl, flog_gatherer, "alice",
web_port="tcp:9980:interface=localhost", web_port="tcp:9980:interface=localhost",
storage=False, storage=False,
) )
@ -400,7 +409,7 @@ def alice(reactor, temp_dir, tahoe_binary, introducer_furl, flog_gatherer, stora
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def bob(reactor, temp_dir, tahoe_binary, introducer_furl, flog_gatherer, storage_nodes, request): def bob(reactor, temp_dir, introducer_furl, flog_gatherer, storage_nodes, request):
try: try:
mkdir(join(temp_dir, 'magic-bob')) mkdir(join(temp_dir, 'magic-bob'))
except OSError: except OSError:
@ -408,7 +417,7 @@ def bob(reactor, temp_dir, tahoe_binary, introducer_furl, flog_gatherer, storage
process = pytest.blockon( process = pytest.blockon(
_create_node( _create_node(
reactor, request, temp_dir, tahoe_binary, introducer_furl, flog_gatherer, "bob", reactor, request, temp_dir, introducer_furl, flog_gatherer, "bob",
web_port="tcp:9981:interface=localhost", web_port="tcp:9981:interface=localhost",
storage=False, storage=False,
) )
@ -417,7 +426,7 @@ def bob(reactor, temp_dir, tahoe_binary, introducer_furl, flog_gatherer, storage
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def alice_invite(reactor, alice, tahoe_binary, temp_dir, request): def alice_invite(reactor, alice, temp_dir, request):
node_dir = join(temp_dir, 'alice') node_dir = join(temp_dir, 'alice')
# FIXME XXX by the time we see "client running" in the logs, the # FIXME XXX by the time we see "client running" in the logs, the
@ -427,9 +436,10 @@ def alice_invite(reactor, alice, tahoe_binary, temp_dir, request):
proto = _CollectOutputProtocol() proto = _CollectOutputProtocol()
transport = reactor.spawnProcess( transport = reactor.spawnProcess(
proto, proto,
tahoe_binary, sys.executable,
[ [
'tahoe', 'magic-folder', 'create', sys.executable, '-m', 'allmydata.scripts.runner',
'magic-folder', 'create',
'--basedir', node_dir, 'magik:', 'alice', '--basedir', node_dir, 'magik:', 'alice',
join(temp_dir, 'magic-alice'), join(temp_dir, 'magic-alice'),
] ]
@ -439,9 +449,10 @@ def alice_invite(reactor, alice, tahoe_binary, temp_dir, request):
proto = _CollectOutputProtocol() proto = _CollectOutputProtocol()
transport = reactor.spawnProcess( transport = reactor.spawnProcess(
proto, proto,
tahoe_binary, sys.executable,
[ [
'tahoe', 'magic-folder', 'invite', sys.executable, '-m', 'allmydata.scripts.runner',
'magic-folder', 'invite',
'--basedir', node_dir, 'magik:', 'bob', '--basedir', node_dir, 'magik:', 'bob',
] ]
) )
@ -451,31 +462,27 @@ def alice_invite(reactor, alice, tahoe_binary, temp_dir, request):
# before magic-folder works, we have to stop and restart (this is # before magic-folder works, we have to stop and restart (this is
# crappy for the tests -- can we fix it in magic-folder?) # crappy for the tests -- can we fix it in magic-folder?)
proto = _CollectOutputProtocol() try:
transport = reactor.spawnProcess( alice.signalProcess('TERM')
proto, pytest.blockon(alice.exited)
tahoe_binary, except ProcessExitedAlready:
[ pass
'tahoe', 'stop', node_dir
]
)
pytest.blockon(proto.done)
magic_text = 'Completed initial Magic Folder scan successfully' magic_text = 'Completed initial Magic Folder scan successfully'
pytest.blockon(_run_node(reactor, tahoe_binary, node_dir, request, magic_text)) pytest.blockon(_run_node(reactor, node_dir, request, magic_text))
return invite return invite
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def magic_folder(reactor, alice_invite, alice, bob, tahoe_binary, temp_dir, request): def magic_folder(reactor, alice_invite, alice, bob, temp_dir, request):
print("pairing magic-folder") print("pairing magic-folder")
bob_dir = join(temp_dir, 'bob') bob_dir = join(temp_dir, 'bob')
proto = _CollectOutputProtocol() proto = _CollectOutputProtocol()
transport = reactor.spawnProcess( transport = reactor.spawnProcess(
proto, proto,
tahoe_binary, sys.executable,
[ [
'tahoe', 'magic-folder', 'join', sys.executable, '-m', 'allmydata.scripts.runner',
'magic-folder', 'join',
'--basedir', bob_dir, '--basedir', bob_dir,
alice_invite, alice_invite,
join(temp_dir, 'magic-bob'), join(temp_dir, 'magic-bob'),
@ -485,16 +492,13 @@ def magic_folder(reactor, alice_invite, alice, bob, tahoe_binary, temp_dir, requ
# before magic-folder works, we have to stop and restart (this is # before magic-folder works, we have to stop and restart (this is
# crappy for the tests -- can we fix it in magic-folder?) # crappy for the tests -- can we fix it in magic-folder?)
proto = _CollectOutputProtocol() try:
transport = reactor.spawnProcess( print("Sending TERM to Bob")
proto, bob.signalProcess('TERM')
tahoe_binary, pytest.blockon(bob.exited)
[ except ProcessExitedAlready:
'tahoe', 'stop', bob_dir pass
]
)
pytest.blockon(proto.done)
magic_text = 'Completed initial Magic Folder scan successfully' magic_text = 'Completed initial Magic Folder scan successfully'
pytest.blockon(_run_node(reactor, tahoe_binary, bob_dir, request, magic_text)) pytest.blockon(_run_node(reactor, bob_dir, request, magic_text))
return (join(temp_dir, 'magic-alice'), join(temp_dir, 'magic-bob')) return (join(temp_dir, 'magic-alice'), join(temp_dir, 'magic-bob'))

View File

@ -114,9 +114,6 @@ def test_bob_creates_alice_deletes_bob_restores(magic_folder):
"bob wrote this again, because reasons", "bob wrote this again, because reasons",
) )
# fix the conflict
shutil.move(join(alice_dir, "boom.conflict"), join(alice_dir, "boom"))
def test_bob_creates_alice_deletes_alice_restores(magic_folder): def test_bob_creates_alice_deletes_alice_restores(magic_folder):
alice_dir, bob_dir = magic_folder alice_dir, bob_dir = magic_folder
@ -177,7 +174,7 @@ def test_bob_conflicts_with_alice_preexisting(magic_folder):
# this one by giving him a massive head start # this one by giving him a massive head start
with open(join(bob_dir, 'beta'), 'w') as f: with open(join(bob_dir, 'beta'), 'w') as f:
f.write("this is bob's beta\n") f.write("this is bob's beta\n")
time.sleep(0.2) time.sleep(0.5)
with open(join(alice_dir, 'beta'), 'w') as f: with open(join(alice_dir, 'beta'), 'w') as f:
f.write("this is alice's beta\n") f.write("this is alice's beta\n")

View File

@ -2,18 +2,22 @@ import time
from os.path import exists from os.path import exists
def await_file_contents(path, contents, timeout=10): def await_file_contents(path, contents, timeout=15):
start_time = time.time() start_time = time.time()
while time.time() - start_time < timeout: while time.time() - start_time < timeout:
print(" waiting for '{}'".format(path)) print(" waiting for '{}'".format(path))
if exists(path): if exists(path):
with open(path, 'r') as f: try:
current = f.read() with open(path, 'r') as f:
if current == contents: current = f.read()
return True except IOError:
print(" file contents still mismatched") print("IOError; trying again")
print(" wanted: {}".format(contents.replace('\n', ' '))) else:
print(" got: {}".format(current.replace('\n', ' '))) if current == contents:
return True
print(" file contents still mismatched")
print(" wanted: {}".format(contents.replace('\n', ' ')))
print(" got: {}".format(current.replace('\n', ' ')))
time.sleep(1) time.sleep(1)
if exists(path): if exists(path):
raise Exception("Contents of '{}' mismatched after {}s".format(path, timeout)) raise Exception("Contents of '{}' mismatched after {}s".format(path, timeout))

View File

@ -18,7 +18,7 @@ commands =
[testenv:integration] [testenv:integration]
commands = commands =
echo 'run with "py.test --keep-tempdir -s -v integration/" to debug failures' # NOTE: 'run with "py.test --keep-tempdir -s -v integration/" to debug failures'
py.test -v integration/ py.test -v integration/
[testenv:coverage] [testenv:coverage]