File: test_seek.py

package info (click to toggle)
python-rarfile 4.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,308 kB
  • sloc: python: 4,180; makefile: 201; sh: 88; awk: 14
file content (134 lines) | stat: -rw-r--r-- 2,706 bytes parent folder | download
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
"""Test seeking on files.
"""

import io

import pytest

import rarfile

ARC = "test/files/seektest.rar"

_WHENCE = 0


def do_seek(f, pos, lim, size=None):
    global _WHENCE
    ofs = pos * 4
    fsize = lim * 4

    if ofs < 0:
        exp = 0
    elif ofs > fsize:
        exp = fsize
    else:
        exp = ofs

    if size:
        cur = f.tell()
        if _WHENCE == 0:
            f.seek(ofs, _WHENCE)
        elif _WHENCE == 1:
            f.seek(ofs - cur, _WHENCE)
        else:
            assert _WHENCE == 2
            f.seek(ofs - size, _WHENCE)
        _WHENCE = (_WHENCE + 1) % 3
    else:
        f.seek(ofs)

    got = f.tell()

    assert got == exp
    ln = f.read(4)
    if got == fsize and ln:
        raise ValueError("unexpected read")
    if not ln and got < fsize:
        raise ValueError("unexpected read failure")
    if ln:
        spos = int(ln)
        assert spos * 4 == got


def run_seek(rf, fn):
    inf = rf.getinfo(fn)
    cnt = int(inf.file_size / 4)
    f = rf.open(fn)

    with pytest.raises(ValueError):
        f.seek(0, -1)
    with pytest.raises(ValueError):
        f.seek(0, 3)

    do_seek(f, int(cnt / 2), cnt)
    do_seek(f, 0, cnt)

    for i in range(int(cnt / 2)):
        do_seek(f, i * 2, cnt, inf.file_size)

    for i in range(cnt):
        do_seek(f, i * 2 - int(cnt / 2), cnt, inf.file_size)

    for i in range(cnt + 10):
        do_seek(f, cnt - i - 5, cnt, inf.file_size)

    f.close()


def run_arc(arc, desc):
    files = ["stest1.txt", "stest2.txt"]
    rf = rarfile.RarFile(arc)
    for fn in files:
        run_seek(rf, fn)


def test_seek_filename():
    run_arc(ARC, "fn")


def test_seek_bytesio():
    # filelike: io.BytesIO, io.open()
    with open(ARC, "rb") as f:
        data = f.read()
    run_arc(io.BytesIO(data), "io.BytesIO")


def test_seek_open():
    # filelike: file()
    with open(ARC, "rb") as f:
        run_arc(f, "open")


def test_seek_ioopen():
    # filelike: io.open()
    with io.open(ARC, "rb") as f:
        run_arc(f, "io.open")


def run_seek_middle(fn, entry):
    rar = rarfile.RarFile(fn)
    file = rar.open(entry)
    assert file.read(1) == b"0"
    assert file.read(1) == b"0"
    assert file.read(1) == b"0"
    assert file.read(1) == b"\n"
    file.read()

    file.seek(0)
    assert file.read(1) == b"0"
    assert file.read(1) == b"0"
    assert file.read(1) == b"0"
    assert file.read(1) == b"\n"
    file.read()

    file.seek(2)
    assert file.read(1) == b"0"
    assert file.read(1) == b"\n"
    file.read()

def test_seek_middle1():
    run_seek_middle("test/files/seektest.rar", "stest1.txt")

def test_seek_middle2():
    run_seek_middle("test/files/seektest.rar", "stest2.txt")