Commit c61f41c5 authored by Satyam Zode's avatar Satyam Zode Committed by Jérémy Bobbio
Browse files

Improve diffoscope behaviour for .changes

Being able to know details about the build process is useful
when understanding why two different builds had not come up
with the same output. It may highlight which aspects of the
build environment were different.

In the particular context of comparing .changes, we know
that if all files listed are identical except the .buildinfo
file, the differences in the .buildinfo files are irrelevant.

We thus ignore .buildinfo differences if all the files
except .buildinfo files referenced in `Files` field and all
other fields of .changes are identical.
parent 156e891e
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ from diffoscope.changes import Changes
from diffoscope.difference import Difference
from diffoscope.comparators.utils import Container
from diffoscope.comparators.binary import File
from diffoscope import logger


DOT_CHANGES_FIELDS = [
@@ -145,6 +146,17 @@ class DotChangesFile(DebControlFile):
        file._deb822 = changes
        return True

    def compare(self, other, source=None):
        differences = super().compare(other, source)
        if differences is None:
            return None
        files_identical = all([x == y for x, y in zip(self.deb822.get('Files'), other.deb822.get('Files')) if not x['name'].endswith('.buildinfo')])
        if files_identical and len(differences.details) == 1 and differences.details[0].source1 == 'Files':
            logger.warning('Ignoring buildinfo file differences')
            return None
        else:
            return differences


class DotDscFile(DebControlFile):
    RE_FILE_EXTENSION = re.compile(r'\.dsc$')
+61 −2
Original line number Diff line number Diff line
@@ -37,6 +37,10 @@ except ImportError:

TEST_DOT_CHANGES_FILE1_PATH = data('test1.changes')
TEST_DOT_CHANGES_FILE2_PATH = data('test2.changes')
TEST_DOT_CHANGES_FILE3_PATH = data('test3.changes')
TEST_DOT_CHANGES_FILE4_PATH = data('test4.changes')
TEST_DOT_BUILDINFO_FILE1_PATH = data('test1.buildinfo')
TEST_DOT_BUILDINFO_FILE2_PATH = data('test2.buildinfo')
TEST_DEB_FILE1_PATH = data('test1.deb')
TEST_DEB_FILE2_PATH = data('test2.deb')

@@ -46,6 +50,7 @@ def dot_changes1(tmpdir):
    dot_changes_path = str(tmpdir.join('a/test_1.changes'))
    shutil.copy(TEST_DOT_CHANGES_FILE1_PATH, dot_changes_path)
    shutil.copy(TEST_DEB_FILE1_PATH, str(tmpdir.join('a/test_1_all.deb')))
    shutil.copy(TEST_DOT_BUILDINFO_FILE1_PATH, str(tmpdir.join('a/test_1.buildinfo')))
    return specialize(FilesystemFile(dot_changes_path))

@pytest.fixture
@@ -54,6 +59,25 @@ def dot_changes2(tmpdir):
    dot_changes_path = str(tmpdir.join('b/test_1.changes'))
    shutil.copy(TEST_DOT_CHANGES_FILE2_PATH, dot_changes_path)
    shutil.copy(TEST_DEB_FILE2_PATH, str(tmpdir.join('b/test_1_all.deb')))
    shutil.copy(TEST_DOT_BUILDINFO_FILE2_PATH, str(tmpdir.join('b/test_2.buildinfo')))
    return specialize(FilesystemFile(dot_changes_path))

@pytest.fixture
def dot_changes3(tmpdir):
    tmpdir.mkdir('c')
    dot_changes_path = str(tmpdir.join('c/test_3.changes'))
    shutil.copy(TEST_DOT_CHANGES_FILE3_PATH, dot_changes_path)
    shutil.copy(TEST_DEB_FILE1_PATH, str(tmpdir.join('c/test_1_all.deb')))
    shutil.copy(TEST_DOT_BUILDINFO_FILE2_PATH, str(tmpdir.join('c/test_2.buildinfo')))
    return specialize(FilesystemFile(dot_changes_path))

@pytest.fixture
def dot_changes4(tmpdir):
    tmpdir.mkdir('d')
    dot_changes_path = str(tmpdir.join('d/test_4.changes'))
    shutil.copy(TEST_DOT_CHANGES_FILE4_PATH, dot_changes_path)
    shutil.copy(TEST_DEB_FILE2_PATH, str(tmpdir.join('d/test_1_all.deb')))
    shutil.copy(TEST_DOT_BUILDINFO_FILE1_PATH, str(tmpdir.join('d/test_2.buildinfo')))
    return specialize(FilesystemFile(dot_changes_path))

def test_dot_changes_identification(dot_changes1):
@@ -96,6 +120,43 @@ def test_dot_changes_compare_non_existing(monkeypatch, dot_changes1):
    assert difference.source2 == '/nonexisting'
    assert difference.details[-1].source2 == '/dev/null'

@pytest.fixture
def dot_changes_differences_identical_contents_and_identical_files(dot_changes1, dot_changes3):
    difference = dot_changes1.compare(dot_changes3)
    output_text(difference, print_func=print)
    return difference.details

@pytest.fixture
def dot_changes_differences_identical_contents_and_different_files(dot_changes1, dot_changes4):
    difference = dot_changes1.compare(dot_changes4)
    output_text(difference, print_func=print)
    return difference.details

@pytest.fixture
def dot_changes_differences_different_contents_and_identical_files(dot_changes2, dot_changes4):
    difference = dot_changes4.compare(dot_changes2)
    output_text(difference, print_func=print)
    return difference.details

def test_dot_changes_no_differences_exclude_buildinfo(dot_changes1, dot_changes3):
    difference = dot_changes1.compare(dot_changes3)
    assert difference is None
@pytest.mark.skipif(miss_debian_module, reason='debian module is not installed')
def test_dot_changes_identical_contents_and_different_files(dot_changes_differences_identical_contents_and_different_files):
    assert dot_changes_differences_identical_contents_and_different_files[0]
    expected_diff = open(data('dot_changes_identical_contents_and_different_files_expected_diff')).read()
    assert dot_changes_differences_identical_contents_and_different_files[0].unified_diff == expected_diff

@pytest.mark.skipif(miss_debian_module, reason='debian module is not installed')
def test_dot_changes_different_contents_and_identical_files(dot_changes_differences_different_contents_and_identical_files):
    assert dot_changes_differences_different_contents_and_identical_files[0]
    assert dot_changes_differences_different_contents_and_identical_files[1]
    expected_diff_contents = open(data('dot_changes_description_expected_diff')).read()
    expected_diff_files = open(data('dot_changes_different_contents_and_identical_files_expected_diff')).read()
    assert dot_changes_differences_different_contents_and_identical_files[0].unified_diff == expected_diff_contents
    assert dot_changes_differences_different_contents_and_identical_files[1].unified_diff == expected_diff_files


TEST_DOT_DSC_FILE1_PATH = data('test1.dsc')
TEST_DOT_DSC_FILE2_PATH = data('test2.dsc')
TEST_DEB_SRC1_PATH = data('test1.debsrc.tar.gz')
@@ -151,8 +212,6 @@ def test_dot_dsc_compare_non_existing(monkeypatch, dot_dsc1):
    assert difference.source2 == '/nonexisting'
    assert difference.details[-1].source2 == '/dev/null'

TEST_DOT_BUILDINFO_FILE1_PATH = data('test1.buildinfo')
TEST_DOT_BUILDINFO_FILE2_PATH = data('test2.buildinfo')

@pytest.fixture
def dot_buildinfo1(tmpdir):
+5 −0
Original line number Diff line number Diff line
@@ -1,3 +1,3 @@
 
  d323c454462407fe3bfde31a74b23eba 2388 devel optional test_1_all.deb
- 40756b7e8aae2c1fcbcac099670b6db8 3780 web optional test_2.buildinfo
+ 9972d7c394228311ba92cbcbfe2d6cd9 3765 web optional test_2.buildinfo
+6 −0
Original line number Diff line number Diff line
@@ -1,3 +1,3 @@
 
- 660ad4713e5d8271df2e7e86bf246dc0 2262 devel optional test_1_all.deb
- 40756b7e8aae2c1fcbcac099670b6db8 3780 web optional test_1.buildinfo
+ d323c454462407fe3bfde31a74b23eba 2388 devel optional test_1_all.deb
+ 40756b7e8aae2c1fcbcac099670b6db8 3780 web optional test_2.buildinfo
+3 −0
Original line number Diff line number Diff line
@@ -16,7 +16,10 @@ Changes:
   * Test package.
Checksums-Sha1:
 b21eeec5004853c4955d5b856a6546068c2d7dc9 2262 test_1_all.deb
 e1cafb5f8db51f4ec477807d105b1e3cccf9a767 3780 test_1.buildinfo
Checksums-Sha256:
 d2b2ea8b9cf8ef645a328cdb882586ee465e141fc66a2dbe1ad29b29ac1e7920 2262 test_1_all.deb
 167d989223978a45a69af30dcd488baa00aec2045b66d0f74d7f03b08fd22365 3780 test_1.buildinfo
Files:
 660ad4713e5d8271df2e7e86bf246dc0 2262 devel optional test_1_all.deb
 40756b7e8aae2c1fcbcac099670b6db8 3780 web optional test_1.buildinfo
Loading