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
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
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
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))
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
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)
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)
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)
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
def temp_folder(): with runez.TempFolder() as tmp: yield tmp