Example #1
0
def test_temp_folder():
    cwd = os.getcwd()

    with runez.CaptureOutput(
            anchors=[os.path.join("/tmp"),
                     os.path.join("/etc")]) as logged:
        with runez.TempFolder() as tmp:
            assert os.path.isdir(tmp)
            assert tmp != runez.system.SYMBOLIC_TMP
        assert not os.path.isdir(tmp)
        assert os.getcwd() == cwd

        assert runez.short(os.path.join("/tmp", "some-file")) == "some-file"
        assert runez.short(os.path.join("/etc", "some-file")) == "some-file"

        assert not logged

    symbolic = os.path.join(runez.system.SYMBOLIC_TMP, "some-file")
    with runez.CaptureOutput(dryrun=True) as logged:
        assert os.getcwd() == cwd
        with runez.TempFolder() as tmp:
            assert tmp == runez.system.SYMBOLIC_TMP
            assert runez.short(symbolic) == "some-file"

        assert os.getcwd() == cwd
        with runez.TempFolder(anchor=False) as tmp:
            assert tmp == runez.system.SYMBOLIC_TMP
            assert runez.short(symbolic) == symbolic

        assert not logged

    assert os.getcwd() == cwd
Example #2
0
def test_temp():
    cwd = os.getcwd()

    with runez.CaptureOutput(anchors=["/tmp", "/etc"]) as logged:
        with runez.TempFolder() as tmp:
            assert os.path.isdir(tmp)
            assert tmp != runez.convert.SYMBOLIC_TMP
        assert not os.path.isdir(tmp)
        assert os.getcwd() == cwd

        assert runez.short("/tmp/some-file") == "some-file"
        assert runez.short("/etc/some-file") == "some-file"

        assert not logged

    symbolic = "%s/some-file" % runez.convert.SYMBOLIC_TMP
    with runez.CaptureOutput(dryrun=True) as logged:
        assert os.getcwd() == cwd
        with runez.TempFolder() as tmp:
            assert tmp == runez.convert.SYMBOLIC_TMP
            assert runez.short(symbolic) == "some-file"

        assert os.getcwd() == cwd
        with runez.TempFolder(anchor=False) as tmp:
            assert tmp == runez.convert.SYMBOLIC_TMP
            assert runez.short(symbolic) == symbolic

        assert not logged

    assert os.getcwd() == cwd
Example #3
0
def test_setup(temp_log):
    fmt = "%(asctime)s %(context)s%(levelname)s - %(message)s"
    assert runez.log.is_using_format("", fmt) is False
    assert runez.log.is_using_format("%(lineno)d", fmt) is False
    assert runez.log.is_using_format("%(context)s", fmt) is True
    assert runez.log.is_using_format("%(context)s %(lineno)d", fmt) is True
    assert runez.log.is_using_format("%(context)s", "") is False

    # signum=None is equivalent to disabling faulthandler
    runez.log.enable_faulthandler(signum=None)
    assert runez.log.faulthandler_signum is None
    # We didn't call setup, so enabling faulthandler will do nothing
    runez.log.enable_faulthandler()
    assert runez.log.faulthandler_signum is None

    cwd = os.getcwd()
    assert not runez.DRYRUN
    with runez.TempFolder(dryrun=False):
        runez.log.setup(dryrun=True, level=logging.INFO)

        # Auto-debug on dryrun
        logging.debug("hello")
        assert "hello" in temp_log.stderr

        with pytest.raises(Exception):
            # SHouldn't call setup() twice
            runez.log.setup()

        if runez.log.faulthandler:
            # Available only in python3
            runez.log.enable_faulthandler()
            assert runez.log.faulthandler_signum

    assert not runez.DRYRUN
    assert os.getcwd() == cwd
Example #4
0
def diff(compact, untyped, tokens, implementations, samples):
    """Compare deserialization of 2 implementations"""
    stringify = runez.stringified if untyped else decode
    if compact is None:
        compact = len(samples) > 1

    with runez.TempFolder():
        generated_files = []
        for sample in samples:
            generated_files.append([sample])
            for impl in implementations:
                assert isinstance(impl, Implementation)
                data = impl.get_outcome(sample, tokens=tokens)
                rep = TestSettings.represented(data,
                                               size=None,
                                               stringify=stringify,
                                               dt=simplified_date)
                fname = "%s-%s.txt" % (impl.name, sample.basename)
                generated_files[-1].extend([fname, rep])
                if not compact:
                    with open(fname, "w") as fh:
                        fh.write(rep)
                        if not rep.endswith("\n"):
                            fh.write("\n")

        matches = 0
        failed = 0
        differ = 0
        for sample, n1, r1, n2, r2 in generated_files:
            if isinstance(r1, dict) and isinstance(
                    r2, dict) and r1.get("_error") and r2.get("_error"):
                matches += 1
                failed += 1
                print("%s: both failed" % sample)

            elif r1 == r2:
                matches += 1
                print("%s: OK" % sample)

            else:
                differ += 1
                if compact:
                    print("%s: differ" % sample)

        if not compact:
            for sample, n1, r1, n2, r2 in generated_files:
                if r1 != r2:
                    r = runez.run("diff", "-br", "-U1", n1, n2, fatal=None)
                    print("========  %s  ========" % sample)
                    print(r.full_output)
                    print()

        message = [
            runez.plural(samples, "sample"),
            TestSettings.colored_if_meaningful(matches, "match", runez.green),
            TestSettings.colored_if_meaningful(differ, "differ", runez.orange),
            TestSettings.colored_if_meaningful(failed, "failed", runez.red),
        ]
        print("\n%s" % ", ".join(message))
Example #5
0
def test_shortening():
    assert runez.short(None) == "None"
    assert runez.short("") == ""
    assert runez.short(5) == "5"
    assert runez.short(" some text ") == "some text"
    assert runez.short(" \n  some \n  long text", size=9) == "some l..."
    assert runez.short(" \n  some \n  long text", size=8) == "some ..."
    assert runez.short(" a \n\n  \n  b ") == "a b"

    assert runez.short([1, "b"]) == "[1, b]"
    assert runez.short((1, {
        "b": ["c", {"d", "e"}]
    })) == "(1, {b: [c, {d, e}]})"

    complex = {
        "a \n b":
        [1, None, "foo \n ,", {
            "a2": runez.abort,
            "c": runez.Anchored
        }],
        None: datetime.date(2019, 1, 1)
    }
    assert runez.short(
        complex
    ) == "{None: 2019-01-01, a b: [1, None, foo ,, {a2: function 'abort', c: class runez.system.Anchored}]}"
    assert runez.short(complex, size=32) == "{None: 2019-01-01, a b: [1, N..."

    assert runez.short(" some  text ", size=32) == "some text"
    assert runez.short(" some  text ", size=7) == "some..."
    assert runez.short(" some  text ", size=0) == "some text"

    # Verify that coloring is not randomly truncated
    assert runez.short("\033[38;2;255;0;0mfoo bar baz\033[39m",
                       size=6,
                       uncolor=True) == "foo..."

    with runez.TempFolder() as tmp:
        assert runez.short(os.path.join(tmp, "some-file")) == "some-file"

        user_path = runez.resolved_path("~/some-folder/bar")
        current_path = runez.resolved_path("./some-folder/bar")
        assert user_path != "~/some-folder/bar"
        assert runez.short(user_path) == "~/some-folder/bar"
        assert runez.short(current_path) == "some-folder/bar"

        with runez.Anchored(os.getcwd(), "./foo"):
            assert runez.short(current_path) == os.path.join(
                "some-folder", "bar")
            assert runez.short("./foo") == "./foo"
            assert runez.short(runez.resolved_path("foo")) == "foo"
            assert runez.short(runez.resolved_path("./foo/bar")) == "bar"

        assert not runez.Anchored._paths
Example #6
0
def test_with_tty(monkeypatch, logged):
    with patch("runez.prompt.input", side_effect=mocked_input):
        monkeypatch.setattr(runez.SYS_INFO.terminal, "is_stdout_tty", True)
        expected = {"value": "foo"}
        with runez.TempFolder() as tmp:
            assert ask_once("test",
                            "foo",
                            base=tmp,
                            serializer=custom_serializer) == expected

            assert runez.read_json("test.json", logger=None) == expected
            assert ask_once(
                "test", "bar",
                base=tmp) == expected  # Ask a 2nd time, same response

            # Verify that if `serializer` returns None, value is not returned/stored
            with pytest.raises(Exception) as exc:
                ask_once("test-invalid",
                         "invalid",
                         base=tmp,
                         serializer=custom_serializer,
                         fatal=True,
                         logger=None)
            assert "Invalid value provided for test-invalid" in str(exc)
            assert not os.path.exists("test-invalid.json")

            # Same, but don't raise exception (returns default)
            assert ask_once("test-invalid",
                            "invalid",
                            base=tmp,
                            serializer=custom_serializer) is None
            assert not logged  # Traced by default

            # Simulate no value provided
            with pytest.raises(Exception) as exc:
                ask_once("test-invalid",
                         "",
                         base=tmp,
                         serializer=custom_serializer,
                         fatal=True)
            assert "No value provided" in str(exc)
            assert "No value provided" in logged.pop()  # Logged if fatal=True

    with patch("runez.prompt.input", side_effect=KeyboardInterrupt):
        # Simulate CTRL+C
        with pytest.raises(Exception) as exc:
            ask_once("test2",
                     "test2",
                     base=tmp,
                     serializer=custom_serializer,
                     fatal=True)
        assert "Cancelled by user" in str(exc)
Example #7
0
    def __enter__(self, tmp=False):
        """Context manager to save and restore log setup, useful for testing"""
        WrappedHandler.isolation += 1
        self.old_handlers = logging.root.handlers
        logging.root.handlers = []

        if self.adjust_tmp:
            # Adjust log.spec.tmp, and leave logging.root without any predefined handlers
            # intent: underlying wants to perform their own log.setup()
            self.old_spec = runez.log.spec.tmp
            self.temp_folder = runez.TempFolder()
            runez.log.spec.tmp = self.temp_folder.__enter__()
            return runez.log.spec.tmp

        # If we're not adjusting tmp, then make sure we have at least one logging handler defined
        handler = logging.StreamHandler(stream=sys.stderr)
        handler.setFormatter(logging.Formatter("%(levelname)s %(message)s"))
        handler.setLevel(logging.DEBUG)
        logging.root.addHandler(handler)
Example #8
0
def textual_diff(kind, actual, expected):
    actual_error = isinstance(actual, dict) and actual.get("_error") or None
    expected_error = isinstance(expected,
                                dict) and expected.get("_error") or None
    if actual_error != expected_error:
        if actual_error:
            return diff_overview(kind, actual_error, expected_error,
                                 "deserialization failed")

        return diff_overview(kind, actual_error, expected_error,
                             "deserialization did NOT yield expected error")

    if type(actual) != type(expected):
        return diff_overview(kind, type(actual), type(expected),
                             "differing types")

    if kind == TestSamples.K_TOKEN:
        actual = "%s\n" % "\n".join(actual)
        expected = "%s\n" % "\n".join(expected)

    else:
        actual = runez.represented_json(actual,
                                        keep_none=True,
                                        none_key="-null-")
        expected = runez.represented_json(expected,
                                          keep_none=True,
                                          none_key="-null-")

    if actual != expected:
        with runez.TempFolder(dryrun=False):
            runez.write("actual", actual)
            runez.write("expected", expected)
            r = runez.run("diff",
                          "-br",
                          "-U1",
                          "expected",
                          "actual",
                          fatal=None,
                          dryrun=False)
            return formatted_diff(r.full_output)
Example #9
0
def test_setup(temp_log, monkeypatch):
    fmt = "%(asctime)s %(context)s%(levelname)s - %(message)s"
    assert runez.log.is_using_format("", fmt) is False
    assert runez.log.is_using_format("%(lineno)", fmt) is False
    assert runez.log.is_using_format("%(context)", fmt) is True
    assert runez.log.is_using_format("%(context) %(lineno)", fmt) is True
    assert runez.log.is_using_format("%(context)", "") is False

    if not runez.SYS_INFO.platform_id.is_windows:
        # signum=None is equivalent to disabling faulthandler
        runez.log.enable_faulthandler(signum=None)
        assert runez.log.faulthandler_signum is None
        # We didn't call setup, so enabling faulthandler will do nothing
        runez.log.enable_faulthandler()
        assert runez.log.faulthandler_signum is None

    cwd = os.getcwd()
    assert not runez.DRYRUN
    assert not runez.log.debug
    with runez.TempFolder(dryrun=False):
        assert not runez.log.debug

        # No auto-debug on dryrun
        runez.log.setup(dryrun=True, level=logging.INFO)
        runez.log.enable_trace(None)
        assert not runez.log.debug
        assert runez.DRYRUN
        logging.info("info")
        logging.debug("hello")
        runez.log.trace("some trace info")
        assert not temp_log.stdout
        assert "hello" not in temp_log
        assert "some trace info" not in temp_log  # Tracing not enabled
        assert "info" in temp_log.stderr.pop()

        # Second call without any customization is a no-op
        runez.log.setup()
        runez.log.enable_trace(False)
        assert not runez.log.debug
        assert runez.DRYRUN
        logging.debug("hello")
        runez.log.trace("some trace info")
        assert "some trace info" not in temp_log  # Tracing not enabled
        assert not temp_log

        # Change stream
        runez.log.setup(console_stream=sys.stdout, trace="SOME_ENV_VAR")
        logging.info("hello")
        runez.log.trace("some trace info")
        assert not temp_log.stderr
        assert "some trace info" not in temp_log  # Not tracing because env var not set
        assert "INFO hello" in temp_log.stdout.pop()

        # Change logging level
        runez.log.setup(console_level=logging.WARNING, trace=True)
        logging.info("hello")
        assert not temp_log
        logging.warning("hello")
        runez.log.trace("some trace %s", "info")
        assert ":: some trace info" in temp_log  # Tracing forcibly enabled
        assert "WARNING hello" in temp_log.stdout.pop()
        assert not temp_log.stderr

        # Change format and enable debug + tracing
        monkeypatch.setenv("SOME_ENV_VAR", "1")
        runez.log.setup(debug=True, console_format="%(levelname)s - %(message)s", trace="SOME_ENV_VAR+... ")
        assert runez.log.debug
        assert runez.log.console_handler.level == logging.DEBUG
        logging.debug("hello")
        runez.log.trace("some trace info")
        assert "... some trace info" in temp_log  # We're now tracing (because env var is set)
        assert "DEBUG - hello" in temp_log.stdout.pop()
        assert not temp_log.stderr

        if not runez.SYS_INFO.platform_id.is_windows and runez.logsetup.faulthandler:
            # Available only in python3
            runez.log.enable_faulthandler()
            assert runez.log.faulthandler_signum

        assert runez.log.debug is True
        assert runez.DRYRUN is True

    # Verify dryrun and current folder restored, but debug untouched
    assert runez.log.debug
    assert not runez.DRYRUN
    assert os.getcwd() == cwd
Example #10
0
def temp_folder():
    with runez.TempFolder() as tmp:
        yield tmp