コード例 #1
0
ファイル: test_temporary.py プロジェクト: invenia/testre
def test_exception():
    """
    An exception during temporary directory
    """
    from testre.temporary import temporary_directory

    class CustomException(Exception):
        """
        You know, for testing
        """

    with assert_raises(CustomException):
        with temporary_directory() as tempdir:
            temp = tempdir

            assert_true(temp.exists())

            for filename in ('foo', 'bar', 'baz'):
                filepath = temp / filename

                with filepath.open('w') as f_out:
                    f_out.write(u'read me')

                assert_true(filepath.exists())

            raise CustomException

    assert_false(temp.exists())
コード例 #2
0
ファイル: test_temporary.py プロジェクト: invenia/testre
def test_empty():
    """
    Empty temporary directory
    """
    from testre.temporary import temporary_directory

    with temporary_directory() as tempdir:
        temp = tempdir

        assert_true(temp.exists())

    assert_false(temp.exists())
コード例 #3
0
ファイル: test_runner.py プロジェクト: invenia/testre
def test_copied_data():
    """
    db with copied data
    """
    from testre.runner import run
    from testre.temporary import temporary_directory

    with temporary_directory() as tempdir:
        with run(path=tempdir, port=11111) as port:
            assert_equals(port, 11111)

            original = rethinkdb.connect(port=port)

            result = rethinkdb.db('test').table_create('testre').run(original)
            assert_equals(result['tables_created'], 1)

        # we now have a non-empty db to copy
        with run(data_directory=tempdir, port=11112):
            copy = rethinkdb.connect(port=11112)

            assert_equals(
                rethinkdb.db('test').table_list().run(copy),
                ['testre']
            )

            result = rethinkdb.db('test').table_create('table2').run(copy)
            assert_equals(result['tables_created'], 1)

        # we did an actual copy, right
        with run(path=tempdir, port=11111):
            original = rethinkdb.connect(port=11111)

            assert_equals(
                rethinkdb.db('test').table_list().run(original),
                ['testre']
            )

            # while we're here, might as well connect to a bound port
            with assert_raises(OSError):
                with run(port=11111):
                    raise AssertionError

            # everything still cool?
            assert_equals(
                rethinkdb.db('test').table_list().run(original),
                ['testre']
            )
コード例 #4
0
ファイル: test_temporary.py プロジェクト: invenia/testre
def test_non_empty():
    """
    Temporary directory with files
    """
    from testre.temporary import temporary_directory

    with temporary_directory() as tempdir:
        temp = tempdir

        assert_true(temp.exists())

        for filename in ('foo', 'bar', 'baz'):
            filepath = temp / filename

            with filepath.open('w') as f_out:
                f_out.write(u"It's a file!")

            assert_true(filepath.exists())

    assert_false(temp.exists())
コード例 #5
0
ファイル: test_temporary.py プロジェクト: invenia/testre
def test_nested():
    """
    Nested temporary directories
    """
    from testre.temporary import temporary_directory

    with temporary_directory() as tempdir:
        temp = tempdir

        assert_true(temp.exists())

        directory = temp / 'alpha'

        directory.mkdir()

        for filename in ('bravo', 'beta', 'getti'):
            filepath = directory / filename

            with filepath.open('w') as f_out:
                f_out.write(u'content')

            assert_true(filepath.exists())

    assert_false(temp.exists())
コード例 #6
0
ファイル: runner.py プロジェクト: invenia/testre
def run(data_directory=None, port=28015, path=None, logger=None):
    """
    Temporarily run a rethink database

    data_directory: (optional, None) If given the path to a
        rethinkdb_data directory to duplicate and use.
    port: (optional, 28015) The port to run the database on.
    path: (optional, None) The location to store the data directory. If
        not given, a temporary directory will be used. If your tests
        involve writing to the database, you should instead use
        data_directory as it will guarantee your testing database
        remains in a pristine state.
    logger: (optional, None) The name of the logger to use.
    """
    with temporary_directory() as tempdir:
        if data_directory:
            if path:
                raise ValueError("cannot add data to existing path")

            path = tempdir / "rethinkdb_data"
            copytree(str(data_directory), str(path))
        elif path is None:
            path = tempdir

        # we want an empty log file so it is easier to parse. Make
        # our own log file
        logfile = tempdir / "log_file"

        pidfile = tempdir / "pidfile"

        try:
            # The reason we are using Popen instead of check_call here
            # is that the call writes some output to stdout and we don't
            # want that text to pollute our process' stdout. Sadly,
            # subprocess doesn't provide a clean way to /dev/null output
            # without using Popen directly.
            process = Popen(
                (
                    "rethinkdb",
                    "--no-http-admin",
                    "--no-update-check",
                    "--daemon",
                    "--directory",
                    str(path),
                    "--pid-file",
                    str(pidfile),
                    "--driver-port",
                    str(port),
                    "--log-file",
                    str(logfile),
                ),
                stdout=PIPE,
            )
            process.communicate()

            if process.returncode != 0:
                raise OSError("Could not start rethinkdb")

            getLogger(logger).info("rethinkdb running on {}".format(port))

            # wait for the log file to be generated
            while not logfile.exists():
                pass

            # don't yield until the db can receive connections
            available = False

            while not available:
                with logfile.open() as f_in:
                    for line in f_in:
                        if "Listening for client driver" in line:
                            available = True
                            break
                        elif "error: TCP socket creation failed" in line:
                            # The pidfile briefly exists while the
                            # daemon cleans itself up. pypy is fast
                            # enough that we may actually attempt to
                            # kill it in the finally clause. This will
                            # cause an error. We can't just skip that
                            # exists check in the finally as we then may
                            # get into a race condition between rethink
                            # shutting down and tempdir being deleted.
                            while pidfile.exists():
                                pass

                            raise OSError("Could not bind to port")

            yield port
        finally:
            # only try to kill the process if it exists.
            if pidfile.exists():
                with pidfile.open() as f_in:
                    pid = f_in.read()

                    try:
                        check_call(("kill", pid))
                    except CalledProcessError:
                        getLogger(logger).exception("could not kill process: {}".format(pid))

                        raise
                    else:
                        # we need to wait for the process to actually
                        # die or else there will be a race condition on
                        # the pidfile when deleting the temporary
                        # directory
                        running = True

                        while running:
                            # Popen because we want to silence the stderr
                            # message that pid doesn't exist. It is the
                            # entire reason we are running this command
                            # in the first place
                            process = Popen(("kill", "-0", pid), stderr=PIPE)
                            process.communicate()

                            running = process.returncode == 0

                        getLogger(logger).info("rethinkdb process ended")
            else:
                getLogger(logger).info("no rethinkdb running")
コード例 #7
0
def run(data_directory=None, port=28015, path=None, logger=None):
    """
    Temporarily run a rethink database

    data_directory: (optional, None) If given the path to a
        rethinkdb_data directory to duplicate and use.
    port: (optional, 28015) The port to run the database on.
    path: (optional, None) The location to store the data directory. If
        not given, a temporary directory will be used. If your tests
        involve writing to the database, you should instead use
        data_directory as it will guarantee your testing database
        remains in a pristine state.
    logger: (optional, None) The name of the logger to use.
    """
    with temporary_directory() as tempdir:
        if data_directory:
            if path:
                raise ValueError('cannot add data to existing path')

            path = tempdir / 'rethinkdb_data'
            copytree(str(data_directory), str(path))
        elif path is None:
            path = tempdir

        # we want an empty log file so it is easier to parse. Make
        # our own log file
        logfile = tempdir / 'log_file'

        pidfile = tempdir / 'pidfile'

        try:
            # The reason we are using Popen instead of check_call here
            # is that the call writes some output to stdout and we don't
            # want that text to pollute our process' stdout. Sadly,
            # subprocess doesn't provide a clean way to /dev/null output
            # without using Popen directly.
            process = Popen(
                ('rethinkdb', '--no-http-admin', '--no-update-check',
                 '--daemon', '--directory', str(path), '--pid-file',
                 str(pidfile), '--driver-port', str(port), '--log-file',
                 str(logfile)),
                stdout=PIPE)
            process.communicate()

            if process.returncode != 0:
                raise OSError("Could not start rethinkdb")

            getLogger(logger).info("rethinkdb running on {}".format(port))

            # wait for the log file to be generated
            while not logfile.exists():
                pass

            # don't yield until the db can receive connections
            available = False

            while not available:
                with logfile.open() as f_in:
                    for line in f_in:
                        if 'Listening for client driver' in line:
                            available = True
                            break
                        elif 'error: TCP socket creation failed' in line:
                            # The pidfile briefly exists while the
                            # daemon cleans itself up. pypy is fast
                            # enough that we may actually attempt to
                            # kill it in the finally clause. This will
                            # cause an error. We can't just skip that
                            # exists check in the finally as we then may
                            # get into a race condition between rethink
                            # shutting down and tempdir being deleted.
                            while pidfile.exists():
                                pass

                            raise OSError("Could not bind to port")

            yield port
        finally:
            # only try to kill the process if it exists.
            if pidfile.exists():
                with pidfile.open() as f_in:
                    pid = f_in.read()

                    try:
                        check_call(('kill', pid))
                    except CalledProcessError:
                        getLogger(logger).exception(
                            "could not kill process: {}".format(pid))

                        raise
                    else:
                        # we need to wait for the process to actually
                        # die or else there will be a race condition on
                        # the pidfile when deleting the temporary
                        # directory
                        running = True

                        while running:
                            # Popen because we want to silence the stderr
                            # message that pid doesn't exist. It is the
                            # entire reason we are running this command
                            # in the first place
                            process = Popen(('kill', '-0', pid), stderr=PIPE)
                            process.communicate()

                            running = (process.returncode == 0)

                        getLogger(logger).info("rethinkdb process ended")
            else:
                getLogger(logger).info("no rethinkdb running")