1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
#
# diffoscope: in-depth comparison of files, archives, and directories
#
# Copyright © 2015 Jérémy Bobbio <lunar@debian.org>
# Copyright © 2016-2020, 2022 Chris Lamb <lamby@debian.org>
#
# diffoscope is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# diffoscope is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with diffoscope. If not, see <https://www.gnu.org/licenses/>.
import os
import sys
import pytest
import signal
import tempfile
from diffoscope.main import main
TEST_TAR1_PATH = os.path.join(os.path.dirname(__file__), "data/test1.tar")
TEST_TAR2_PATH = os.path.join(os.path.dirname(__file__), "data/test2.tar")
TEST_TARS = (TEST_TAR1_PATH, TEST_TAR2_PATH)
def run(capsys, *args):
with pytest.raises(SystemExit) as exc:
main(args)
out, err = capsys.readouterr()
return exc.value.code, out, err
def test_non_existing_files(capsys):
ret, _, err = run(capsys, "/nonexisting1", "/nonexisting2")
assert ret == 2
assert "/nonexisting1: No such file or directory" in err
assert "/nonexisting2: No such file or directory" in err
def test_non_existing_left_with_new_file(capsys):
ret, out, _ = run(capsys, "--new-file", "/nonexisting1", __file__)
assert ret == 1
assert "--- /nonexisting1" in out
assert ("+++ %s" % __file__) in out
def test_non_existing_right_with_new_file(capsys):
ret, out, _ = run(capsys, "--new-file", __file__, "/nonexisting2")
assert ret == 1
assert ("--- %s" % __file__) in out
assert "+++ /nonexisting2" in out
def test_non_existing_files_with_new_file(capsys):
ret, out, _ = run(capsys, "--new-file", "/nonexisting1", "/nonexisting2")
assert ret == 1
assert "--- /nonexisting1" in out
assert "+++ /nonexisting2" in out
assert "Trying to compare two non-existing files." in out
def test_remove_temp_files_on_sigterm(capsys, tmpdir, monkeypatch):
pid = os.fork()
if pid == 0:
def suicide(*args):
os.kill(os.getpid(), signal.SIGTERM)
monkeypatch.setattr(
"diffoscope.comparators.text.TextFile.compare", suicide
)
tempfile.tempdir = str(tmpdir)
ret, _, _ = run(capsys, *TEST_TARS)
os._exit(ret)
else:
_, ret = os.waitpid(pid, 0)
assert (ret >> 8) == 2 # having received SIGTERM is trouble
assert os.listdir(str(tmpdir)) == []
def test_ctrl_c_handling(tmpdir, monkeypatch, capsys):
monkeypatch.setattr("tempfile.tempdir", str(tmpdir))
def interrupt(*args):
raise KeyboardInterrupt
monkeypatch.setattr(
"diffoscope.comparators.text.TextFile.compare", interrupt
)
ret, _, err = run(capsys, *TEST_TARS)
assert "" in err
assert ret == 2
assert os.listdir(str(tmpdir)) == []
def test_no_differences(capsys):
ret, out, err = run(capsys, TEST_TAR1_PATH, TEST_TAR1_PATH)
assert ret == 0
assert err == ""
assert out == ""
def test_no_differences_directories(capsys, tmpdir):
def create_dir(x):
path = str(tmpdir.mkdir(x))
os.utime(path, (0, 0)) # Ensure consistent mtime
return path
ret, out, err = run(capsys, create_dir("a"), create_dir("b"))
assert ret == 0
# if getfacl is not available there will be a warning message on stderr
# if it's available then err should be empty
assert err == "" or "getfacl" in err
assert out == ""
def test_list_tools(capsys):
ret, out, err = run(capsys, "--list-tools")
assert ret == 0
assert err == ""
assert "External-Tools-Required: " in out
assert "xxd," in out
def test_list_missing_tools(capsys):
ret, out, err = run(capsys, "--list-missing-tools")
assert ret == 0
assert err == ""
assert "External-Tools-Required: " in out
# No assertions about the contents of the output since we don't control
# what's installed in the test environment
def test_profiling(capsys):
ret, out, err = run(capsys, TEST_TAR1_PATH, TEST_TAR1_PATH, "--profile=-")
assert ret == 0
assert "Profiling output for" in out
assert err == ""
def test_non_unicode_filename(capsys, tmpdir):
# Bug reference: https://bugs.debian.org/898022
path = str(tmpdir.dirpath()).encode("utf-8")
a = os.path.join(path, b"\xf0\x28\x8c\x28")
b = os.path.join(path, b"\xf0\x28\x8c\x29")
with open(a, "w"), open(b, "w"):
pass
# sys.argv does pretty much this decoding to arguments
files = [x.decode("utf-8", errors="surrogateescape") for x in (a, b)]
ret, out, err = run(capsys, *files)
assert ret == 0
assert out == err == ""
def test_help(capsys, monkeypatch):
# Fake --help in sys.argv so that we include out file formats in the output
monkeypatch.setattr(sys, "argv", ["diffoscope", "--help"])
ret, out, err = run(capsys, "--help")
assert err == ""
assert "file formats supported:" in out
def test_usage(capsys):
ret, out, err = run(capsys, "--usage")
assert out == ""
assert "usage:" in err
|