def test_diff_manifest_add_file_last(test_data, testname, monkeypatch):
    """Diff two fileinfo lists, one having an additional file as last item.

    The implementation of the corresponding command line tool used to
    have a flaw in this particular case, ref. #55.
    """
    monkeypatch.chdir(test_data)
    with Archive().open(Path("archive.tar")) as archive:
        manifest_ref = archive.manifest
    base_dir = Path("base")
    mtime_base = os.stat(base_dir).st_mtime
    p = base_dir / "zzz.dat"
    shutil.copy(gettestdata("rnd2.dat"), p)
    os.utime(base_dir, times=(mtime_base, mtime_base))
    fileinfos = get_fileinfos(base_dir)
    diff = list(filter(non_match, diff_manifest(fileinfos, manifest_ref)))
    assert len(diff) == 1
    status, fi_a, fi_b = diff[0]
    assert status == DiffStatus.MISSING_B
    assert fi_a.type == 'f'
    assert fi_a.path == p
    assert fi_b is None
    diff = list(filter(non_match, diff_manifest(manifest_ref, fileinfos)))
    assert len(diff) == 1
    status, fi_a, fi_b = diff[0]
    assert status == DiffStatus.MISSING_A
    assert fi_b.type == 'f'
    assert fi_b.path == p
    assert fi_a is None
def test_diff_manifest_mult(test_data, testname, monkeypatch):
    """Diff two fileinfo lists having multiple differences.
    """
    monkeypatch.chdir(test_data)
    with Archive().open(Path("archive.tar")) as archive:
        manifest_ref = archive.manifest
    base_dir = Path("base")
    mtime_base = os.stat(base_dir).st_mtime
    mtime_data = os.stat(base_dir / "data").st_mtime
    pm = base_dir / "data" / "rnd.dat"
    shutil.copy(gettestdata("rnd2.dat"), pm)
    p1 = base_dir / "msg.txt"
    p2 = base_dir / "o.txt"
    p1.rename(p2)
    os.utime(base_dir, times=(mtime_base, mtime_base))
    os.utime(base_dir / "data", times=(mtime_data, mtime_data))
    fileinfos = get_fileinfos(base_dir)
    diff = list(filter(non_match, diff_manifest(fileinfos, manifest_ref)))
    assert len(diff) == 3
    status, fi_a, fi_b = diff[0]
    assert status == DiffStatus.CONTENT
    assert fi_a.type == fi_b.type == 'f'
    assert fi_a.path == fi_b.path == pm
    status, fi_a, fi_b = diff[1]
    assert status == DiffStatus.MISSING_A
    assert fi_b.type == 'f'
    assert fi_b.path == p1
    assert fi_a is None
    status, fi_a, fi_b = diff[2]
    assert status == DiffStatus.MISSING_B
    assert fi_a.type == 'f'
    assert fi_a.path == p2
    assert fi_b is None
def test_diff_manifest_missing_files(test_data, testname, monkeypatch):
    """Diff two fileinfo lists having one file's name changed.
    """
    monkeypatch.chdir(test_data)
    with Archive().open(Path("archive.tar")) as archive:
        manifest_ref = archive.manifest
    base_dir = Path("base")
    mtime_base = os.stat(base_dir).st_mtime
    p1 = base_dir / "rnd.dat"
    p2 = base_dir / "a.dat"
    p1.rename(p2)
    os.utime(base_dir, times=(mtime_base, mtime_base))
    fileinfos = get_fileinfos(base_dir)
    diff = list(filter(non_match, diff_manifest(fileinfos, manifest_ref)))
    assert len(diff) == 2
    status, fi_a, fi_b = diff[0]
    assert status == DiffStatus.MISSING_B
    assert fi_a.type == 'f'
    assert fi_a.path == p2
    assert fi_b is None
    status, fi_a, fi_b = diff[1]
    assert status == DiffStatus.MISSING_A
    assert fi_b.type == 'f'
    assert fi_b.path == p1
    assert fi_a is None
def test_diff_manifest_equal(test_data, testname, monkeypatch):
    """Diff two fileinfo lists having equal content.
    """
    monkeypatch.chdir(test_data)
    with Archive().open(Path("archive.tar")) as archive:
        manifest_ref = archive.manifest
    base_dir = Path("base")
    fileinfos = get_fileinfos(base_dir)
    diff = list(filter(non_match, diff_manifest(fileinfos, manifest_ref)))
    assert diff == []
def test_diff_manifest_metadata(test_data, testname, monkeypatch):
    """Diff two fileinfo lists having one file's metadata modified.
    """
    monkeypatch.chdir(test_data)
    with Archive().open(Path("archive.tar")) as archive:
        manifest_ref = archive.manifest
    base_dir = Path("base")
    p = base_dir / "rnd.dat"
    p.chmod(0o0444)
    fileinfos = get_fileinfos(base_dir)
    diff = list(filter(non_match, diff_manifest(fileinfos, manifest_ref)))
    assert len(diff) == 1
    status, fi_a, fi_b = diff[0]
    assert status == DiffStatus.META
    assert fi_a.type == fi_b.type == 'f'
    assert fi_a.path == fi_b.path == p
def test_diff_manifest_modified_file(test_data, testname, monkeypatch):
    """Diff two fileinfo lists having one file's content modified.
    """
    monkeypatch.chdir(test_data)
    with Archive().open(Path("archive.tar")) as archive:
        manifest_ref = archive.manifest
    base_dir = Path("base")
    mtime_base = os.stat(base_dir).st_mtime
    p = base_dir / "rnd.dat"
    shutil.copy(gettestdata("rnd2.dat"), p)
    os.utime(base_dir, times=(mtime_base, mtime_base))
    fileinfos = get_fileinfos(base_dir)
    diff = list(filter(non_match, diff_manifest(fileinfos, manifest_ref)))
    assert len(diff) == 1
    status, fi_a, fi_b = diff[0]
    assert status == DiffStatus.CONTENT
    assert fi_a.type == fi_b.type == 'f'
    assert fi_a.path == fi_b.path == p
def test_diff_manifest_symlink_target(test_data, testname, monkeypatch):
    """Diff two fileinfo lists having one symlink's target modified.
    """
    monkeypatch.chdir(test_data)
    with Archive().open(Path("archive.tar")) as archive:
        manifest_ref = archive.manifest
    base_dir = Path("base")
    mtime_base = os.stat(base_dir).st_mtime
    p = base_dir / "s.dat"
    p.unlink()
    p.symlink_to(Path("msg.txt"))
    os.utime(base_dir, times=(mtime_base, mtime_base))
    fileinfos = get_fileinfos(base_dir)
    diff = list(filter(non_match, diff_manifest(fileinfos, manifest_ref)))
    assert len(diff) == 1
    status, fi_a, fi_b = diff[0]
    assert status == DiffStatus.SYMLNK_TARGET
    assert fi_a.type == fi_b.type == 'l'
    assert fi_a.path == fi_b.path == p
def test_diff_manifest_wrong_type(test_data, testname, monkeypatch):
    """Diff two fileinfo lists with one entry having a wrong type.
    """
    monkeypatch.chdir(test_data)
    with Archive().open(Path("archive.tar")) as archive:
        manifest_ref = archive.manifest
    base_dir = Path("base")
    mtime_base = os.stat(base_dir).st_mtime
    p = base_dir / "rnd.dat"
    p.unlink()
    p.symlink_to(Path("data", "rnd.dat"))
    os.utime(base_dir, times=(mtime_base, mtime_base))
    fileinfos = get_fileinfos(base_dir)
    diff = list(filter(non_match, diff_manifest(fileinfos, manifest_ref)))
    assert len(diff) == 1
    status, fi_a, fi_b = diff[0]
    assert status == DiffStatus.TYPE
    assert fi_a.type == 'l'
    assert fi_b.type == 'f'
    assert fi_a.path == fi_b.path == p
def test_diff_manifest_dircontent(test_data, testname, monkeypatch):
    """Diff two fileinfo lists with one subdirectory missing.
    """
    monkeypatch.chdir(test_data)
    with Archive().open(Path("archive.tar")) as archive:
        manifest_ref = archive.manifest
    base_dir = Path("base")
    mtime_base = os.stat(base_dir).st_mtime
    pd = base_dir / "data"
    shutil.rmtree(pd)
    os.utime(base_dir, times=(mtime_base, mtime_base))
    fileinfos = get_fileinfos(base_dir)
    diff = list(filter(non_match, diff_manifest(fileinfos, manifest_ref)))
    assert len(diff) == 2
    status, fi_a, fi_b = diff[0]
    assert status == DiffStatus.MISSING_A
    assert fi_b.type == 'd'
    assert fi_b.path == pd
    assert fi_a is None
    status, fi_a, fi_b = diff[1]
    assert status == DiffStatus.MISSING_A
    assert fi_b.type == 'f'
    assert fi_b.path == pd / "rnd.dat"
    assert fi_a is None
Exemple #10
0
def diff(args):
    archive1 = Archive().open(args.archive1)
    manifest1 = archive1.manifest
    archive1.close()
    archive2 = Archive().open(args.archive2)
    manifest2 = archive2.manifest
    archive2.close()
    algorithm = _common_checksum(manifest1, manifest2)
    diff = diff_manifest(manifest1, manifest2, algorithm)
    if args.skip_dir_content:
        diff = _skip_dir_filter(diff)
    status = 0
    for diff_stat, fi1, fi2 in diff:
        if diff_stat == DiffStatus.MISSING_A:
            print("Only in %s: %s" % (args.archive2, fi2.path))
            status = max(status, 102)
        elif diff_stat == DiffStatus.MISSING_B:
            print("Only in %s: %s" % (args.archive1, fi1.path))
            status = max(status, 102)
        elif diff_stat == DiffStatus.TYPE:
            print("Entries %s:%s and %s:%s have different type"
                  % (args.archive1, fi1.path, args.archive2, fi2.path))
            status = max(status, 102)
        elif diff_stat == DiffStatus.SYMLNK_TARGET:
            print("Symbol links %s:%s and %s:%s have different target"
                  % (args.archive1, fi1.path, args.archive2, fi2.path))
            status = max(status, 101)
        elif diff_stat == DiffStatus.CONTENT:
            print("Files %s:%s and %s:%s differ"
                  % (args.archive1, fi1.path, args.archive2, fi2.path))
            status = max(status, 101)
        elif diff_stat == DiffStatus.META and args.report_meta:
            print("File system metadata for %s:%s and %s:%s differ"
                  % (args.archive1, fi1.path, args.archive2, fi2.path))
            status = max(status, 100)
    return status
Exemple #11
0
def filter_fileinfos(base, fileinfos, algorithm):
    for stat, fi1, fi2 in diff_manifest(base, fileinfos, algorithm):
        if stat == DiffStatus.MISSING_B or stat == DiffStatus.MATCH:
            continue
        yield fi2