Esempio n. 1
0
def alice_invite(reactor, alice, temp_dir, request):
    node_dir = join(temp_dir, 'alice')

    with start_action(action_type=u"integration:alice:magic_folder:create"):
        # FIXME XXX by the time we see "client running" in the logs, the
        # storage servers aren't "really" ready to roll yet (uploads fairly
        # consistently fail if we don't hack in this pause...)
        import time
        time.sleep(5)
        proto = _CollectOutputProtocol()
        reactor.spawnProcess(proto, sys.executable, [
            sys.executable,
            '-m',
            'allmydata.scripts.runner',
            'magic-folder',
            'create',
            '--poll-interval',
            '2',
            '--basedir',
            node_dir,
            'magik:',
            'alice',
            join(temp_dir, 'magic-alice'),
        ])
        pytest_twisted.blockon(proto.done)

    with start_action(
            action_type=u"integration:alice:magic_folder:invite") as a:
        proto = _CollectOutputProtocol()
        reactor.spawnProcess(proto, sys.executable, [
            sys.executable,
            '-m',
            'allmydata.scripts.runner',
            'magic-folder',
            'invite',
            '--basedir',
            node_dir,
            'magik:',
            'bob',
        ])
        pytest_twisted.blockon(proto.done)
        invite = proto.output.getvalue()
        a.add_success_fields(invite=invite)

    with start_action(action_type=u"integration:alice:magic_folder:restart"):
        # before magic-folder works, we have to stop and restart (this is
        # crappy for the tests -- can we fix it in magic-folder?)
        try:
            alice.signalProcess('TERM')
            pytest_twisted.blockon(alice.exited)
        except ProcessExitedAlready:
            pass
        with start_action(
                action_type=u"integration:alice:magic_folder:magic-text"):
            magic_text = 'Completed initial Magic Folder scan successfully'
            pytest_twisted.blockon(
                _run_node(reactor, node_dir, request, magic_text))
    return invite
def test_daemon_inititialize(request, reactor, temp_dir):
    """
    'magic-folder init' happy-path works
    """

    node_dir = join(temp_dir, "daemon")
    tahoe_dir = join(temp_dir, "tahoe")
    mkdir(tahoe_dir)
    with open(join(tahoe_dir, "tahoe.cfg"), "w") as f:
        f.write("# a fake config\n")
    with open(join(tahoe_dir, "node.url"), "w") as f:
        f.write('http://localhost:1234/')

    proto = util._CollectOutputProtocol()
    util._magic_folder_runner(
        proto,
        reactor,
        request,
        [
            "--config",
            node_dir,
            "init",
            "--listen-endpoint",
            "tcp:1234",
            "--node-directory",
            tahoe_dir,
        ],
    )
    yield proto.done

    proto = util._CollectOutputProtocol()
    util._magic_folder_runner(
        proto,
        reactor,
        request,
        [
            "--config",
            node_dir,
            "show-config",
        ],
    )
    output = yield proto.done
    config = loads(output)

    assert config["api_endpoint"] == "tcp:1234"
    assert config["tahoe_node_directory"] == tahoe_dir
    assert config["magic_folders"] == dict()
    # the API token should at least be base64-decodable and result in 32 bytes of entropy
    assert len(base64.urlsafe_b64decode(
        config["api_token"].encode("utf8"))) == 32
Esempio n. 3
0
def alice_invite(reactor, alice, temp_dir, request):
    node_dir = join(temp_dir, 'alice')

    with start_action(action_type=u"integration:alice:magic_folder:create"):
        # FIXME XXX by the time we see "client running" in the logs, the
        # storage servers aren't "really" ready to roll yet (uploads fairly
        # consistently fail if we don't hack in this pause...)
        import time ; time.sleep(5)
        proto = _CollectOutputProtocol()
        reactor.spawnProcess(
            proto,
            sys.executable,
            [
                sys.executable, '-m', 'allmydata.scripts.runner',
                'magic-folder', 'create',
                '--poll-interval', '2',
                '--basedir', node_dir, 'magik:', 'alice',
                join(temp_dir, 'magic-alice'),
            ]
        )
        pytest_twisted.blockon(proto.done)

    with start_action(action_type=u"integration:alice:magic_folder:invite") as a:
        proto = _CollectOutputProtocol()
        reactor.spawnProcess(
            proto,
            sys.executable,
            [
                sys.executable, '-m', 'allmydata.scripts.runner',
                'magic-folder', 'invite',
                '--basedir', node_dir, 'magik:', 'bob',
            ]
        )
        pytest_twisted.blockon(proto.done)
        invite = proto.output.getvalue()
        a.add_success_fields(invite=invite)

    with start_action(action_type=u"integration:alice:magic_folder:restart"):
        # before magic-folder works, we have to stop and restart (this is
        # crappy for the tests -- can we fix it in magic-folder?)
        try:
            alice.signalProcess('TERM')
            pytest_twisted.blockon(alice.exited)
        except ProcessExitedAlready:
            pass
        with start_action(action_type=u"integration:alice:magic_folder:magic-text"):
            magic_text = 'Completed initial Magic Folder scan successfully'
            pytest_twisted.blockon(_run_node(reactor, node_dir, request, magic_text))
    return invite
Esempio n. 4
0
def magic_folder(reactor, alice_invite, alice, bob, temp_dir, request):
    print("pairing magic-folder")
    bob_dir = join(temp_dir, 'bob')
    proto = _CollectOutputProtocol()
    reactor.spawnProcess(proto, sys.executable, [
        sys.executable,
        '-m',
        'allmydata.scripts.runner',
        'magic-folder',
        'join',
        '--poll-interval',
        '2',
        '--basedir',
        bob_dir,
        alice_invite,
        join(temp_dir, 'magic-bob'),
    ])
    pytest_twisted.blockon(proto.done)

    # before magic-folder works, we have to stop and restart (this is
    # crappy for the tests -- can we fix it in magic-folder?)
    try:
        print("Sending TERM to Bob")
        bob.signalProcess('TERM')
        pytest_twisted.blockon(bob.exited)
    except ProcessExitedAlready:
        pass

    magic_text = 'Completed initial Magic Folder scan successfully'
    pytest_twisted.blockon(_run_node(reactor, bob_dir, request, magic_text))
    return (join(temp_dir, 'magic-alice'), join(temp_dir, 'magic-bob'))
Esempio n. 5
0
def magic_folder(reactor, alice_invite, alice, bob, temp_dir, request):
    print("pairing magic-folder")
    bob_dir = join(temp_dir, 'bob')
    proto = _CollectOutputProtocol()
    transport = reactor.spawnProcess(
        proto,
        sys.executable,
        [
            sys.executable, '-m', 'allmydata.scripts.runner',
            'magic-folder', 'join',
            '--poll-interval', '2',
            '--basedir', bob_dir,
            alice_invite,
            join(temp_dir, 'magic-bob'),
        ]
    )
    pytest.blockon(proto.done)

    # before magic-folder works, we have to stop and restart (this is
    # crappy for the tests -- can we fix it in magic-folder?)
    try:
        print("Sending TERM to Bob")
        bob.signalProcess('TERM')
        pytest.blockon(bob.exited)
    except ProcessExitedAlready:
        pass

    magic_text = 'Completed initial Magic Folder scan successfully'
    pytest.blockon(_run_node(reactor, bob_dir, request, magic_text))
    return (join(temp_dir, 'magic-alice'), join(temp_dir, 'magic-bob'))
Esempio n. 6
0
def magic_folder(reactor, alice_invite, alice, bob, temp_dir, request):
    print("pairing magic-folder")
    bob_dir = join(temp_dir, 'bob')
    proto = _CollectOutputProtocol()
    _tahoe_runner_optional_coverage(proto, reactor, request, [
        'magic-folder',
        'join',
        '--poll-interval',
        '1',
        '--basedir',
        bob_dir,
        alice_invite,
        join(temp_dir, 'magic-bob'),
    ])
    pytest_twisted.blockon(proto.done)

    # before magic-folder works, we have to stop and restart (this is
    # crappy for the tests -- can we fix it in magic-folder?)
    try:
        print("Sending TERM to Bob")
        bob.transport.signalProcess('TERM')
        pytest_twisted.blockon(bob.transport.exited)
    except ProcessExitedAlready:
        pass

    magic_text = 'Completed initial Magic Folder scan successfully'
    pytest_twisted.blockon(_run_node(reactor, bob_dir, request, magic_text))
    await_client_ready(bob)
    return (join(temp_dir, 'magic-alice'), join(temp_dir, 'magic-bob'))
def test_upload_immutable(reactor, temp_dir, introducer_furl, flog_gatherer, storage_nodes, request):

    edna = yield util._create_node(
        reactor, request, temp_dir, introducer_furl, flog_gatherer, "edna",
        web_port="tcp:9983:interface=localhost",
        storage=False,
        needed=3,
        happy=7,
        total=10,
    )
    util.await_client_ready(edna)

    node_dir = join(temp_dir, 'edna')

    # upload a file, which should fail because we have don't have 7
    # storage servers (but happiness is set to 7)
    proto = util._CollectOutputProtocol()
    reactor.spawnProcess(
        proto,
        sys.executable,
        [
            sys.executable, '-m', 'allmydata.scripts.runner',
            '-d', node_dir,
            'put', __file__,
        ]
    )
    try:
        yield proto.done
        assert False, "should raise exception"
    except Exception as e:
        assert isinstance(e, ProcessTerminated)

    output = proto.output.getvalue()
    assert "shares could be placed on only" in output
Esempio n. 8
0
def test_onion_service_storage(reactor, request, temp_dir, flog_gatherer,
                               tor_network, tor_introducer_furl):
    yield _create_anonymous_node(reactor, 'carol', 8008, request, temp_dir,
                                 flog_gatherer, tor_network,
                                 tor_introducer_furl)
    yield _create_anonymous_node(reactor, 'dave', 8009, request, temp_dir,
                                 flog_gatherer, tor_network,
                                 tor_introducer_furl)
    # ensure both nodes are connected to "a grid" by uploading
    # something via carol, and retrieve it using dave.
    gold_path = join(temp_dir, "gold")
    with open(gold_path, "w") as f:
        f.write("The object-capability model is a computer security model. A "
                "capability describes a transferable right to perform one (or "
                "more) operations on a given object.")
    # XXX could use treq or similar to POST these to their respective
    # WUIs instead ...

    proto = util._CollectOutputProtocol()
    reactor.spawnProcess(proto, sys.executable, (
        sys.executable,
        '-m',
        'allmydata.scripts.runner',
        '-d',
        join(temp_dir, 'carol'),
        'put',
        gold_path,
    ))
    yield proto.done
    cap = proto.output.getvalue().strip().split()[-1]
    print("TEH CAP!", cap)

    proto = util._CollectOutputProtocol()
    reactor.spawnProcess(proto, sys.executable, (
        sys.executable,
        '-m',
        'allmydata.scripts.runner',
        '-d',
        join(temp_dir, 'dave'),
        'get',
        cap,
    ))
    yield proto.done

    dave_got = proto.output.getvalue().strip()
    assert dave_got == open(gold_path, 'r').read().strip()
Esempio n. 9
0
def test_onion_service_storage(reactor, request, temp_dir, flog_gatherer, tor_network, tor_introducer_furl):
    yield _create_anonymous_node(reactor, 'carol', 8008, request, temp_dir, flog_gatherer, tor_network, tor_introducer_furl)
    yield _create_anonymous_node(reactor, 'dave', 8009, request, temp_dir, flog_gatherer, tor_network, tor_introducer_furl)
    # ensure both nodes are connected to "a grid" by uploading
    # something via carol, and retrieve it using dave.
    gold_path = join(temp_dir, "gold")
    with open(gold_path, "w") as f:
        f.write(
            "The object-capability model is a computer security model. A "
            "capability describes a transferable right to perform one (or "
            "more) operations on a given object."
        )
    # XXX could use treq or similar to POST these to their respective
    # WUIs instead ...

    proto = util._CollectOutputProtocol()
    reactor.spawnProcess(
        proto,
        sys.executable,
        (
            sys.executable, '-m', 'allmydata.scripts.runner',
            '-d', join(temp_dir, 'carol'),
            'put', gold_path,
        )
    )
    yield proto.done
    cap = proto.output.getvalue().strip().split()[-1]
    print("TEH CAP!", cap)

    proto = util._CollectOutputProtocol()
    reactor.spawnProcess(
        proto,
        sys.executable,
        (
            sys.executable, '-m', 'allmydata.scripts.runner',
            '-d', join(temp_dir, 'dave'),
            'get', cap,
        )
    )
    yield proto.done

    dave_got = proto.output.getvalue().strip()
    assert dave_got == open(gold_path, 'r').read().strip()
Esempio n. 10
0
def test_add(request, reactor, temp_dir, alice):
    """
    'magic-folder add' happy-path works
    """

    proto = util._CollectOutputProtocol()
    util._magic_folder_runner(
        proto,
        reactor,
        request,
        [
            "--config",
            alice.magic_config_directory,
            "add",
            "--name",
            "test",
            "--author",
            "laptop",
            alice.magic_directory,
        ],
    )
    yield proto.done

    proto = util._CollectOutputProtocol()
    util._magic_folder_runner(
        proto,
        reactor,
        request,
        [
            "--config",
            alice.magic_config_directory,
            "show-config",
        ],
    )
    output = yield proto.done
    config = loads(output)

    assert "test" in config["magic_folders"]
    mf_config = config["magic_folders"]["test"]
    assert mf_config["name"] == "test"
    assert mf_config["author_name"] == "laptop"
    expected_keys = ["stash_path", "author_private_key"]
    assert all(k in mf_config for k in expected_keys)
Esempio n. 11
0
def flog_gatherer(reactor, temp_dir, flog_binary, request):
    out_protocol = _CollectOutputProtocol()
    gather_dir = join(temp_dir, 'flog_gather')
    reactor.spawnProcess(out_protocol, flog_binary, (
        'flogtool',
        'create-gatherer',
        '--location',
        'tcp:localhost:3117',
        '--port',
        '3117',
        gather_dir,
    ))
    pytest_twisted.blockon(out_protocol.done)

    twistd_protocol = _MagicTextProtocol("Gatherer waiting at")
    twistd_process = reactor.spawnProcess(
        twistd_protocol,
        which('twistd')[0],
        (
            'twistd',
            '--nodaemon',
            '--python',
            join(gather_dir, 'gatherer.tac'),
        ),
        path=gather_dir,
    )
    pytest_twisted.blockon(twistd_protocol.magic_seen)

    def cleanup():
        _cleanup_tahoe_process(twistd_process, twistd_protocol.exited)

        flog_file = mktemp('.flog_dump')
        flog_protocol = _DumpOutputProtocol(open(flog_file, 'w'))
        flog_dir = join(temp_dir, 'flog_gather')
        flogs = [x for x in listdir(flog_dir) if x.endswith('.flog')]

        print("Dumping {} flogtool logfiles to '{}'".format(
            len(flogs), flog_file))
        reactor.spawnProcess(
            flog_protocol,
            flog_binary,
            ('flogtool', 'dump', join(temp_dir, 'flog_gather', flogs[0])),
        )
        print("Waiting for flogtool to complete")
        try:
            pytest_twisted.blockon(flog_protocol.done)
        except ProcessTerminated as e:
            print("flogtool exited unexpectedly: {}".format(str(e)))
        print("Flogtool completed")

    request.addfinalizer(cleanup)

    with open(join(gather_dir, 'log_gatherer.furl'), 'r') as f:
        furl = f.read().strip()
    return furl
Esempio n. 12
0
def flog_gatherer(reactor, temp_dir, flog_binary, request):
    out_protocol = _CollectOutputProtocol()
    gather_dir = join(temp_dir, 'flog_gather')
    reactor.spawnProcess(
        out_protocol,
        flog_binary,
        (
            'flogtool', 'create-gatherer',
            '--location', 'tcp:localhost:3117',
            '--port', '3117',
            gather_dir,
        )
    )
    pytest_twisted.blockon(out_protocol.done)

    twistd_protocol = _MagicTextProtocol("Gatherer waiting at")
    twistd_process = reactor.spawnProcess(
        twistd_protocol,
        which('twistd')[0],
        (
            'twistd', '--nodaemon', '--python',
            join(gather_dir, 'gatherer.tac'),
        ),
        path=gather_dir,
    )
    pytest_twisted.blockon(twistd_protocol.magic_seen)

    def cleanup():
        _cleanup_twistd_process(twistd_process, twistd_protocol.exited)

        flog_file = mktemp('.flog_dump')
        flog_protocol = _DumpOutputProtocol(open(flog_file, 'w'))
        flog_dir = join(temp_dir, 'flog_gather')
        flogs = [x for x in listdir(flog_dir) if x.endswith('.flog')]

        print("Dumping {} flogtool logfiles to '{}'".format(len(flogs), flog_file))
        reactor.spawnProcess(
            flog_protocol,
            flog_binary,
            (
                'flogtool', 'dump', join(temp_dir, 'flog_gather', flogs[0])
            ),
        )
        print("Waiting for flogtool to complete")
        try:
            pytest_twisted.blockon(flog_protocol.done)
        except ProcessTerminated as e:
            print("flogtool exited unexpectedly: {}".format(str(e)))
        print("Flogtool completed")

    request.addfinalizer(cleanup)

    with open(join(gather_dir, 'log_gatherer.furl'), 'r') as f:
        furl = f.read().strip()
    return furl
def test_daemon_migrate(request, reactor, alice, temp_dir):
    """
    'magic-folder migrate' happy-path works
    """

    node_dir = join(temp_dir, "test-daemon-migrate")

    # if we're depending on a "new" tahoe (which we should) then
    # there's no "tahoe magic-folder" to create "legacy" config for us
    # to migrate. So, we create an (empty) config.
    with open(join(alice.node_directory, "private", "magic_folders.yaml"),
              "w") as f:
        f.write("magic-folders: {}\n")

    proto = util._DumpOutputProtocol(None)
    util._magic_folder_runner(
        proto,
        reactor,
        request,
        [
            "--config",
            node_dir,
            "migrate",
            "--listen-endpoint",
            "tcp:1234",
            "--node-directory",
            alice.node_directory,
            "--author",
            "test",
        ],
    )
    yield proto.done

    proto = util._CollectOutputProtocol()
    util._magic_folder_runner(
        proto,
        reactor,
        request,
        [
            "--config",
            node_dir,
            "show-config",
        ],
    )
    output = yield proto.done
    config = loads(output)

    assert config["api_endpoint"] == "tcp:1234"
    assert config["magic_folders"] == dict()
    # the API token should at least be base64-decodable and result in 32 bytes of entropy
    assert len(base64.urlsafe_b64decode(
        config["api_token"].encode("utf8"))) == 32
Esempio n. 14
0
 def cleanup():
     print("Tearing down Chutney Tor network")
     proto = _CollectOutputProtocol()
     reactor.spawnProcess(
         proto,
         sys.executable,
         (
             sys.executable, '-m', 'chutney.TorNet', 'stop',
             join(chutney_dir, 'networks', 'basic'),
         ),
         path=join(chutney_dir),
         env={"PYTHONPATH": join(chutney_dir, "lib")},
     )
     pytest.blockon(proto.done)
Esempio n. 15
0
 def cleanup():
     print("Tearing down Chutney Tor network")
     proto = _CollectOutputProtocol()
     reactor.spawnProcess(
         proto,
         sys.executable,
         (
             sys.executable, '-m', 'chutney.TorNet', 'stop',
             join(chutney_dir, 'networks', 'basic'),
         ),
         path=join(chutney_dir),
         env=env,
     )
     pytest_twisted.blockon(proto.done)
Esempio n. 16
0
def test_upload_immutable(reactor, temp_dir, introducer_furl, flog_gatherer,
                          storage_nodes, request):

    # hmm, for some reason this still gets storage enabled ...
    process = yield util._create_node(
        reactor,
        request,
        temp_dir,
        introducer_furl,
        flog_gatherer,
        "edna",
        web_port="tcp:9983:interface=localhost",
        storage=False,
        needed=3,
        happy=10,
        total=10,
    )

    node_dir = join(temp_dir, 'edna')

    print("waiting 5 seconds unil we're maybe ready")
    yield task.deferLater(reactor, 5, lambda: None)

    # upload a file, which should fail because we have don't have 7
    # storage servers (but happiness is set to 7)
    proto = util._CollectOutputProtocol()
    transport = reactor.spawnProcess(proto, sys.executable, [
        sys.executable,
        '-m',
        'allmydata.scripts.runner',
        '-d',
        node_dir,
        'put',
        __file__,
    ])
    try:
        yield proto.done
        assert False, "should raise exception"
    except Exception as e:
        assert isinstance(e, ProcessTerminated)

    output = proto.output.getvalue()
    assert "shares could be placed on only" in output
Esempio n. 17
0
 def cleanup():
     print("Tearing down Chutney Tor network")
     proto = _CollectOutputProtocol()
     reactor.spawnProcess(
         proto,
         sys.executable,
         (
             sys.executable,
             '-m',
             'chutney.TorNet',
             'stop',
             join(chutney_dir, 'networks', 'basic'),
         ),
         path=join(chutney_dir),
         env=env,
     )
     try:
         block_with_timeout(proto.done, reactor)
     except ProcessTerminated:
         # If this doesn't exit cleanly, that's fine, that shouldn't fail
         # the test suite.
         pass
def test_upload_immutable(reactor, temp_dir, introducer_furl, flog_gatherer, storage_nodes, request):

    yield util._create_node(
        reactor, request, temp_dir, introducer_furl, flog_gatherer, "edna",
        web_port="tcp:9983:interface=localhost",
        storage=False,
        needed=3,
        happy=7,
        total=10,
    )


    node_dir = join(temp_dir, 'edna')

    print("waiting 10 seconds unil we're maybe ready")
    yield task.deferLater(reactor, 10, lambda: None)

    # upload a file, which should fail because we have don't have 7
    # storage servers (but happiness is set to 7)
    proto = util._CollectOutputProtocol()
    reactor.spawnProcess(
        proto,
        sys.executable,
        [
            sys.executable, '-m', 'allmydata.scripts.runner',
            '-d', node_dir,
            'put', __file__,
        ]
    )
    try:
        yield proto.done
        assert False, "should raise exception"
    except Exception as e:
        assert isinstance(e, ProcessTerminated)

    output = proto.output.getvalue()
    assert "shares could be placed on only" in output
Esempio n. 19
0
def test_web_port_required(request, reactor, temp_dir, introducer_furl):
    """
    'magic-folder run' requires --web-port option
    """

    # enough of a node-dir for "magic-folder" to run .. maybe we
    # should create a real one?
    node_dir = join(temp_dir, "webport")
    mkdir(node_dir)
    with open(join(node_dir, "tahoe.cfg"), "w") as f:
        f.write('')
    with open(join(node_dir, "node.url"), "w") as f:
        f.write('http://localhost/')

    # run "magic-folder run" without --web-port which should error
    proto = util._CollectOutputProtocol()
    proc = util._magic_folder_runner(
        proto,
        reactor,
        request,
        [
            "--node-directory",
            node_dir,
            "run",
        ],
    )
    try:
        yield proto.done
    except ProcessTerminated as e:
        assert e.exitCode != 0
        assert u"Must specify a listening endpoint with --web-port" in proto.output.getvalue(
        )
        return

    assert False, "Expected an error from magic-folder"
    print("output: '{}'".format(proto.output.getvalue()))
Esempio n. 20
0
def tor_network(reactor, temp_dir, chutney, request):
    # this is the actual "chutney" script at the root of a chutney checkout
    chutney_dir = chutney
    chut = join(chutney_dir, 'chutney')

    # now, as per Chutney's README, we have to create the network
    # ./chutney configure networks/basic
    # ./chutney start networks/basic

    env = environ.copy()
    env.update({"PYTHONPATH": join(chutney_dir, "lib")})
    proto = _DumpOutputProtocol(None)
    reactor.spawnProcess(
        proto,
        sys.executable,
        (
            sys.executable,
            '-m',
            'chutney.TorNet',
            'configure',
            join(chutney_dir, 'networks', 'basic'),
        ),
        path=join(chutney_dir),
        env=env,
    )
    pytest_twisted.blockon(proto.done)

    proto = _DumpOutputProtocol(None)
    reactor.spawnProcess(
        proto,
        sys.executable,
        (
            sys.executable,
            '-m',
            'chutney.TorNet',
            'start',
            join(chutney_dir, 'networks', 'basic'),
        ),
        path=join(chutney_dir),
        env=env,
    )
    pytest_twisted.blockon(proto.done)

    # print some useful stuff
    proto = _CollectOutputProtocol()
    reactor.spawnProcess(
        proto,
        sys.executable,
        (
            sys.executable,
            '-m',
            'chutney.TorNet',
            'status',
            join(chutney_dir, 'networks', 'basic'),
        ),
        path=join(chutney_dir),
        env=env,
    )
    try:
        pytest_twisted.blockon(proto.done)
    except ProcessTerminated:
        print("Chutney.TorNet status failed (continuing):")
        print(proto.output.getvalue())

    def cleanup():
        print("Tearing down Chutney Tor network")
        proto = _CollectOutputProtocol()
        reactor.spawnProcess(
            proto,
            sys.executable,
            (
                sys.executable,
                '-m',
                'chutney.TorNet',
                'stop',
                join(chutney_dir, 'networks', 'basic'),
            ),
            path=join(chutney_dir),
            env=env,
        )
        pytest_twisted.blockon(proto.done)

    request.addfinalizer(cleanup)

    return chut
Esempio n. 21
0
def test_edmond_uploads_then_restarts(reactor, request, temp_dir, introducer_furl, flog_gatherer, storage_nodes):
    """
    ticket 2880: if a magic-folder client uploads something, then
    re-starts a spurious .backup file should not appear
    """

    edmond_dir = join(temp_dir, 'edmond')
    edmond = yield util._create_node(
        reactor, request, temp_dir, introducer_furl, flog_gatherer,
        "edmond", web_port="tcp:9985:interface=localhost",
        storage=False,
    )


    magic_folder = join(temp_dir, 'magic-edmond')
    mkdir(magic_folder)
    created = False
    # create a magic-folder
    # (how can we know that the grid is ready?)
    for _ in range(10):  # try 10 times
        try:
            proto = util._CollectOutputProtocol()
            transport = reactor.spawnProcess(
                proto,
                sys.executable,
                [
                    sys.executable, '-m', 'allmydata.scripts.runner',
                    'magic-folder', 'create',
                    '--poll-interval', '2',
                    '--basedir', edmond_dir,
                    'magik:',
                    'edmond_magic',
                    magic_folder,
                ]
            )
            yield proto.done
            created = True
            break
        except Exception as e:
            print("failed to create magic-folder: {}".format(e))
            time.sleep(1)

    assert created, "Didn't create a magic-folder"

    # to actually-start the magic-folder we have to re-start
    edmond.signalProcess('TERM')
    yield edmond._protocol.exited
    time.sleep(1)
    edmond = yield util._run_node(reactor, edmond._node_dir, request, 'Completed initial Magic Folder scan successfully')

    # add a thing to the magic-folder
    with open(join(magic_folder, "its_a_file"), "w") as f:
        f.write("edmond wrote this")

    # fixme, do status-update attempts in a loop below
    time.sleep(5)

    # let it upload; poll the HTTP magic-folder status API until it is
    # uploaded
    from allmydata.scripts.magic_folder_cli import _get_json_for_fragment

    with open(join(edmond_dir, u'private', u'api_auth_token'), 'rb') as f:
        token = f.read()

    uploaded = False
    for _ in range(10):
        options = {
            "node-url": open(join(edmond_dir, u'node.url'), 'r').read().strip(),
        }
        try:
            magic_data = _get_json_for_fragment(
                options,
                'magic_folder?t=json',
                method='POST',
                post_args=dict(
                    t='json',
                    name='default',
                    token=token,
                )
            )
            for mf in magic_data:
                if mf['status'] == u'success' and mf['path'] == u'its_a_file':
                    uploaded = True
                    break
        except Exception as e:
            time.sleep(1)

    assert uploaded, "expected to upload 'its_a_file'"

    # re-starting edmond right now would "normally" trigger the 2880 bug

    # kill edmond
    edmond.signalProcess('TERM')
    yield edmond._protocol.exited
    time.sleep(1)
    edmond = yield util._run_node(reactor, edmond._node_dir, request, 'Completed initial Magic Folder scan successfully')

    # XXX how can we say for sure if we've waited long enough? look at
    # tail of logs for magic-folder ... somethingsomething?
    print("waiting 20 seconds to see if a .backup appears")
    for _ in range(20):
        assert exists(join(magic_folder, "its_a_file"))
        assert not exists(join(magic_folder, "its_a_file.backup"))
        time.sleep(1)
Esempio n. 22
0
def tor_network(reactor, temp_dir, chutney, request):
    # this is the actual "chutney" script at the root of a chutney checkout
    chutney_dir = chutney
    chut = join(chutney_dir, 'chutney')

    # now, as per Chutney's README, we have to create the network
    # ./chutney configure networks/basic
    # ./chutney start networks/basic

    proto = _DumpOutputProtocol(None)
    reactor.spawnProcess(
        proto,
        sys.executable,
        (
            sys.executable, '-m', 'chutney.TorNet', 'configure',
            join(chutney_dir, 'networks', 'basic'),
        ),
        path=join(chutney_dir),
        env={"PYTHONPATH": join(chutney_dir, "lib")},
    )
    pytest.blockon(proto.done)

    proto = _DumpOutputProtocol(None)
    reactor.spawnProcess(
        proto,
        sys.executable,
        (
            sys.executable, '-m', 'chutney.TorNet', 'start',
            join(chutney_dir, 'networks', 'basic'),
        ),
        path=join(chutney_dir),
        env={"PYTHONPATH": join(chutney_dir, "lib")},
    )
    pytest.blockon(proto.done)

    # print some useful stuff
    proto = _CollectOutputProtocol()
    reactor.spawnProcess(
        proto,
        sys.executable,
        (
            sys.executable, '-m', 'chutney.TorNet', 'status',
            join(chutney_dir, 'networks', 'basic'),
        ),
        path=join(chutney_dir),
        env={"PYTHONPATH": join(chutney_dir, "lib")},
    )
    pytest.blockon(proto.done)

    def cleanup():
        print("Tearing down Chutney Tor network")
        proto = _CollectOutputProtocol()
        reactor.spawnProcess(
            proto,
            sys.executable,
            (
                sys.executable, '-m', 'chutney.TorNet', 'stop',
                join(chutney_dir, 'networks', 'basic'),
            ),
            path=join(chutney_dir),
            env={"PYTHONPATH": join(chutney_dir, "lib")},
        )
        pytest.blockon(proto.done)
    request.addfinalizer(cleanup)

    return chut
Esempio n. 23
0
def tor_network(reactor, temp_dir, chutney, request):
    # this is the actual "chutney" script at the root of a chutney checkout
    chutney_dir = chutney
    chut = join(chutney_dir, 'chutney')

    # now, as per Chutney's README, we have to create the network
    # ./chutney configure networks/basic
    # ./chutney start networks/basic

    proto = _DumpOutputProtocol(None)
    reactor.spawnProcess(
        proto,
        sys.executable,
        (
            sys.executable,
            '-m',
            'chutney.TorNet',
            'configure',
            join(chutney_dir, 'networks', 'basic'),
        ),
        path=join(chutney_dir),
        env={"PYTHONPATH": join(chutney_dir, "lib")},
    )
    pytest.blockon(proto.done)

    proto = _DumpOutputProtocol(None)
    reactor.spawnProcess(
        proto,
        sys.executable,
        (
            sys.executable,
            '-m',
            'chutney.TorNet',
            'start',
            join(chutney_dir, 'networks', 'basic'),
        ),
        path=join(chutney_dir),
        env={"PYTHONPATH": join(chutney_dir, "lib")},
    )
    pytest.blockon(proto.done)

    # print some useful stuff
    proto = _CollectOutputProtocol()
    reactor.spawnProcess(
        proto,
        sys.executable,
        (
            sys.executable,
            '-m',
            'chutney.TorNet',
            'status',
            join(chutney_dir, 'networks', 'basic'),
        ),
        path=join(chutney_dir),
        env={"PYTHONPATH": join(chutney_dir, "lib")},
    )
    pytest.blockon(proto.done)

    def cleanup():
        print("Tearing down Chutney Tor network")
        proto = _CollectOutputProtocol()
        reactor.spawnProcess(
            proto,
            sys.executable,
            (
                sys.executable,
                '-m',
                'chutney.TorNet',
                'stop',
                join(chutney_dir, 'networks', 'basic'),
            ),
            path=join(chutney_dir),
            env={"PYTHONPATH": join(chutney_dir, "lib")},
        )
        pytest.blockon(proto.done)

    request.addfinalizer(cleanup)

    return chut
Esempio n. 24
0
def test_edmond_uploads_then_restarts(reactor, request, temp_dir,
                                      introducer_furl, flog_gatherer,
                                      storage_nodes):
    """
    ticket 2880: if a magic-folder client uploads something, then
    re-starts a spurious .backup file should not appear
    """

    edmond_dir = join(temp_dir, 'edmond')
    edmond = yield util._create_node(
        reactor,
        request,
        temp_dir,
        introducer_furl,
        flog_gatherer,
        "edmond",
        web_port="tcp:9985:interface=localhost",
        storage=False,
    )

    magic_folder = join(temp_dir, 'magic-edmond')
    mkdir(magic_folder)
    created = False
    # create a magic-folder
    # (how can we know that the grid is ready?)
    for _ in range(10):  # try 10 times
        try:
            proto = util._CollectOutputProtocol()
            transport = reactor.spawnProcess(proto, sys.executable, [
                sys.executable,
                '-m',
                'allmydata.scripts.runner',
                'magic-folder',
                'create',
                '--poll-interval',
                '2',
                '--basedir',
                edmond_dir,
                'magik:',
                'edmond_magic',
                magic_folder,
            ])
            yield proto.done
            created = True
            break
        except Exception as e:
            print("failed to create magic-folder: {}".format(e))
            time.sleep(1)

    assert created, "Didn't create a magic-folder"

    # to actually-start the magic-folder we have to re-start
    edmond.signalProcess('TERM')
    yield edmond._protocol.exited
    time.sleep(1)
    edmond = yield util._run_node(
        reactor, edmond._node_dir, request,
        'Completed initial Magic Folder scan successfully')

    # add a thing to the magic-folder
    with open(join(magic_folder, "its_a_file"), "w") as f:
        f.write("edmond wrote this")

    # fixme, do status-update attempts in a loop below
    time.sleep(5)

    # let it upload; poll the HTTP magic-folder status API until it is
    # uploaded
    from allmydata.scripts.magic_folder_cli import _get_json_for_fragment

    with open(join(edmond_dir, u'private', u'api_auth_token'), 'rb') as f:
        token = f.read()

    uploaded = False
    for _ in range(10):
        options = {
            "node-url": open(join(edmond_dir, u'node.url'),
                             'r').read().strip(),
        }
        try:
            magic_data = _get_json_for_fragment(options,
                                                'magic_folder?t=json',
                                                method='POST',
                                                post_args=dict(
                                                    t='json',
                                                    name='default',
                                                    token=token,
                                                ))
            for mf in magic_data:
                if mf['status'] == u'success' and mf['path'] == u'its_a_file':
                    uploaded = True
                    break
        except Exception as e:
            time.sleep(1)

    assert uploaded, "expected to upload 'its_a_file'"

    # re-starting edmond right now would "normally" trigger the 2880 bug

    # kill edmond
    edmond.signalProcess('TERM')
    yield edmond._protocol.exited
    time.sleep(1)
    edmond = yield util._run_node(
        reactor, edmond._node_dir, request,
        'Completed initial Magic Folder scan successfully')

    # XXX how can we say for sure if we've waited long enough? look at
    # tail of logs for magic-folder ... somethingsomething?
    print("waiting 20 seconds to see if a .backup appears")
    for _ in range(20):
        assert exists(join(magic_folder, "its_a_file"))
        assert not exists(join(magic_folder, "its_a_file.backup"))
        time.sleep(1)
Esempio n. 25
0
def test_list(request, reactor, temp_dir, introducer_furl, flog_gatherer):
    """
    'magic-folder list' happy-path works
    """

    with start_action(action_type=u"integration:test_list:zelda",
                      include_args=[],
                      include_result=False):
        zelda = yield util.MagicFolderEnabledNode.create(
            reactor,
            request,
            temp_dir,
            introducer_furl,
            flog_gatherer,
            name="zelda",
            tahoe_web_port="tcp:9982:interface=localhost",
            magic_folder_web_port="tcp:19982:interface=localhost",
            storage=True,
        )

    proto = util._CollectOutputProtocol()
    util._magic_folder_runner(
        proto,
        reactor,
        request,
        [
            "--config",
            zelda.magic_config_directory,
            "list",
        ],
    )
    output = yield proto.done
    assert output.strip() == "No magic-folders"

    magic_dir = FilePath(temp_dir).child("zelda-magic")
    magic_dir.makedirs()

    proto = util._CollectOutputProtocol()
    util._magic_folder_runner(
        proto,
        reactor,
        request,
        [
            "--config",
            zelda.magic_config_directory,
            "add",
            "--author",
            "laptop",
            "--name",
            "workstuff",
            magic_dir.path,
        ],
    )
    output = yield proto.done

    proto = util._CollectOutputProtocol()
    util._magic_folder_runner(
        proto,
        reactor,
        request,
        [
            "--config",
            zelda.magic_config_directory,
            "list",
            "--json",
        ],
    )
    output = yield proto.done
    data = json.loads(output)

    assert list(data.keys()) == ["workstuff"]
    assert data["workstuff"]["name"] == "workstuff"
    assert int(data["workstuff"]["poll_interval"]) == 60
    assert data["workstuff"]["magic_path"] == magic_dir.path
    assert data["workstuff"]["is_admin"] == True

    # make sure we didn't reveal secrets
    assert "signing_key" not in data["workstuff"]["author"]
    assert "upload_dircap" not in data["workstuff"]
    assert "collective_dircap" not in data["workstuff"]