-
Notifications
You must be signed in to change notification settings - Fork 4
/
seekinghttp_test.go
121 lines (102 loc) · 2.94 KB
/
seekinghttp_test.go
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
package seekinghttp
import (
"bytes"
"fmt"
"io"
"net/http"
"strconv"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
type logger struct {
t *testing.T
}
func (l logger) Infof(format string, args ...interface{}) {
l.t.Logf(fmt.Sprintf("[INFO] %s", format), args...)
}
func (l logger) Debugf(format string, args ...interface{}) {
l.t.Logf(fmt.Sprintf("[DEBUG] %s", format), args...)
}
// MockHTTPClient is a mock implementation of the http.Client interface for testing purposes.
type MockHTTPClient struct {
str string
numReq int
}
func (c *MockHTTPClient) Do(req *http.Request) (*http.Response, error) {
x := strings.Split(req.Header["Range"][0], "=")
y := strings.Split(x[1], "-")
start, _ := strconv.Atoi(y[0])
end, _ := strconv.Atoi(y[1])
if end > len(c.str) {
end = len(c.str)
}
if start > end {
start = end
}
// Create a mock response for testing purposes.
resp := &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewReader([]byte(c.str[start:end]))),
}
c.numReq++
return resp, nil
}
func TestReadAt(t *testing.T) {
// Create a new SeekingHTTP instance with a mock HTTP client.
s := New("https://example.com")
m := &MockHTTPClient{str: "Mock HTTP response body"}
s.Client = m
s.Logger = &logger{t: t}
// Define test cases.
testCases := []struct {
offset int64
bufSize int
expectLen int
expectErr error
}{
{0, 10, 10, nil},
{10, 1, 1, nil},
{30, 30, 0, nil},
{-1, 0, 0, io.EOF},
}
for _, tc := range testCases {
buf := make([]byte, tc.bufSize)
n, err := s.ReadAt(buf, tc.offset)
assert.ErrorIs(t, tc.expectErr, err, "ReadAt(offset=%d, bufSize=%d) error = %v, expected error = %v", tc.offset, tc.bufSize, err, tc.expectErr)
assert.Equal(t, tc.expectLen, n, "ReadAt(offset=%d, bufSize=%d) len = %d, expected len = %d", tc.offset, tc.bufSize, n, tc.expectLen)
}
// expect 2 reads: one to load the cache, and one to look for bytes past the end for the seek to 30.
assert.Equal(t, 2, m.numReq)
}
func TestReadNothing(t *testing.T) {
// Create a new SeekingHTTP instance with a mock HTTP client.
s := New("https://example.com")
s.Client = &MockHTTPClient{str: ""}
s.Logger = &logger{t: t}
buf := make([]byte, 10)
n, err := s.Read(buf)
assert.ErrorIs(t, err, nil)
assert.Equal(t, 0, n)
}
func TestReadOffEnd(t *testing.T) {
// Create a new SeekingHTTP instance with a mock HTTP client.
s := New("https://example.com")
s.Client = &MockHTTPClient{str: "0123456789abcdefghij"}
s.Logger = &logger{t: t}
buf := make([]byte, 10)
n, err := s.Read(buf)
assert.ErrorIs(t, err, nil)
assert.Equal(t, n, len(buf))
assert.Equal(t, "0123456789", string(buf))
assert.Equal(t, int64(10), s.offset)
n, err = s.Read(buf)
assert.ErrorIs(t, err, nil)
assert.Equal(t, n, len(buf))
assert.Equal(t, "abcdefghij", string(buf))
assert.Equal(t, int64(20), s.offset)
n, err = s.Read(buf)
assert.ErrorIs(t, err, nil)
assert.Equal(t, 0, n)
assert.Equal(t, int64(20), s.offset)
}