def test_IndexedTarFile_readfile_sparse():
    import tarfile

    from oniontree.indexedtarfile import IndexedTarFile, create_index

    FIXTURE = os.path.join(os.path.dirname(__file__), "..", "fixtures", "sparse.tar")

    assert os.path.exists(FIXTURE)
    create_index(FIXTURE)

    with IndexedTarFile(FIXTURE, "r") as itf:
        f = itf.readfile("sparse")

        assert f.read(1024 ** 2) == b"\x00" * 1024 ** 2
        assert f.read(3) == b"1MB"
        assert f.read(1024 ** 2) == b"\x00" * 1024 ** 2
        assert f.read(3) == b"2MB"
        assert f.read(1024 ** 2) == b"\x00" * 1024 ** 2
        assert f.read(1) == b""
def test_IndexedTarFile_readfile(filename_tar):
    import tarfile
    from oniontree.indexedtarfile import IndexedTarFile, create_index

    tarfilename = ""
    randombuf = os.urandom(1024)

    with tarfile.open(filename_tar, "w") as tar:
        with tempfile.NamedTemporaryFile() as f:
            f.write(randombuf)
            f.file.flush()
            tarfilename = f.name
            tar.add(tarfilename)

    create_index(filename_tar)
    with IndexedTarFile(filename_tar, mode="r") as itf:
        innerfile = itf.readfile(tarfilename[1:])

        assert innerfile.read() == randombuf
def test_IndexedTarFile_create_index(filename_tar):
    from oniontree import __file__ as ROOTFILE
    from oniontree.indexedtarfile import IndexedTarFile, create_index
    from glob import glob
    import tarfile
    import shelve

    attrs = (
        "name",
        "mode",
        "uid",
        "gid",
        "size",
        "mtime",
        "chksum",
        "type",
        "linkname",
        "uname",
        "gname",
        "devmajor",
        "devminor",
        "offset",
        "offset_data",
        "sparse",
    )

    def members_to_set(members):
        s = set()

        for member in members:
            member_attrs = []
            for attr in attrs:
                member_attrs.append((attr, getattr(member, attr, None)))
            s.add(tuple(member_attrs))

        return s

    # Create the file
    tar = tarfile.open(filename_tar, mode="w")
    tar.add(os.path.dirname(ROOTFILE))
    tar.close()

    # Open the file so the tarinfo members are readed back.
    tar = tarfile.open(filename_tar, mode="r")

    create_index(filename_tar)

    assert glob(filename_tar + ".idx*")

    real_members = tar.getmembers()

    index_members = []
    with IndexedTarFile(filename_tar, mode="r") as itf:
        with itf._index() as idx:
            for name in idx.keys():
                index_members.append(itf.gettarinfo(name))

    real_members_attrs = members_to_set(real_members)
    index_members_attrs = members_to_set(index_members)

    assert real_members_attrs == index_members_attrs