1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package ioutil
16
17 import (
18 "math/rand"
19 "testing"
20
21 "github.com/stretchr/testify/assert"
22 )
23
24 func TestPageWriterRandom(t *testing.T) {
25
26 defaultBufferBytes = 8 * 1024
27 pageBytes := 128
28 buf := make([]byte, 4*defaultBufferBytes)
29 cw := &checkPageWriter{pageBytes: pageBytes, t: t}
30 w := NewPageWriter(cw, pageBytes, 0)
31 n := 0
32 for i := 0; i < 4096; i++ {
33 c, err := w.Write(buf[:rand.Intn(len(buf))])
34 if err != nil {
35 t.Fatal(err)
36 }
37 n += c
38 }
39 if cw.writeBytes > n {
40 t.Fatalf("wrote %d bytes to io.Writer, but only wrote %d bytes", cw.writeBytes, n)
41 }
42 if maxPendingBytes := pageBytes + defaultBufferBytes; n-cw.writeBytes > maxPendingBytes {
43 t.Fatalf("got %d bytes pending, expected less than %d bytes", n-cw.writeBytes, maxPendingBytes)
44 }
45 t.Logf("total writes: %d", cw.writes)
46 t.Logf("total write bytes: %d (of %d)", cw.writeBytes, n)
47 }
48
49
50
51 func TestPageWriterPartialSlack(t *testing.T) {
52 defaultBufferBytes = 1024
53 pageBytes := 128
54 buf := make([]byte, defaultBufferBytes)
55 cw := &checkPageWriter{pageBytes: 64, t: t}
56 w := NewPageWriter(cw, pageBytes, 0)
57
58 if _, err := w.Write(buf[:64]); err != nil {
59 t.Fatal(err)
60 }
61 if err := w.Flush(); err != nil {
62 t.Fatal(err)
63 }
64 if cw.writes != 1 {
65 t.Fatalf("got %d writes, expected 1", cw.writes)
66 }
67
68 if _, err := w.Write(buf[:1022]); err != nil {
69 t.Fatal(err)
70 }
71
72 if _, err := w.Write(buf[:8]); err != nil {
73 t.Fatal(err)
74 }
75 if cw.writes != 1 {
76 t.Fatalf("got %d writes, expected 1", cw.writes)
77 }
78
79 if _, err := w.Write(buf[:128]); err != nil {
80 t.Fatal(err)
81 }
82 if cw.writes != 2 {
83 t.Fatalf("got %d writes, expected 2", cw.writes)
84 }
85 }
86
87
88 func TestPageWriterOffset(t *testing.T) {
89 defaultBufferBytes = 1024
90 pageBytes := 128
91 buf := make([]byte, defaultBufferBytes)
92 cw := &checkPageWriter{pageBytes: 64, t: t}
93 w := NewPageWriter(cw, pageBytes, 0)
94 if _, err := w.Write(buf[:64]); err != nil {
95 t.Fatal(err)
96 }
97 if err := w.Flush(); err != nil {
98 t.Fatal(err)
99 }
100 if w.pageOffset != 64 {
101 t.Fatalf("w.pageOffset expected 64, got %d", w.pageOffset)
102 }
103
104 w = NewPageWriter(cw, w.pageOffset, pageBytes)
105 if _, err := w.Write(buf[:64]); err != nil {
106 t.Fatal(err)
107 }
108 if err := w.Flush(); err != nil {
109 t.Fatal(err)
110 }
111 if w.pageOffset != 0 {
112 t.Fatalf("w.pageOffset expected 0, got %d", w.pageOffset)
113 }
114 }
115
116 func TestPageWriterPageBytes(t *testing.T) {
117 cases := []struct {
118 name string
119 pageBytes int
120 expectPanic bool
121 }{
122 {
123 name: "normal page bytes",
124 pageBytes: 4096,
125 expectPanic: false,
126 },
127 {
128 name: "negative page bytes",
129 pageBytes: -1,
130 expectPanic: true,
131 },
132 {
133 name: "zero page bytes",
134 pageBytes: 0,
135 expectPanic: true,
136 },
137 }
138
139 for _, tc := range cases {
140 t.Run(tc.name, func(t *testing.T) {
141 defaultBufferBytes = 1024
142 cw := &checkPageWriter{pageBytes: tc.pageBytes, t: t}
143 if tc.expectPanic {
144 assert.Panicsf(t, func() {
145 NewPageWriter(cw, tc.pageBytes, 0)
146 }, "expected panic when pageBytes is %d", tc.pageBytes)
147 } else {
148 pw := NewPageWriter(cw, tc.pageBytes, 0)
149 assert.NotEqual(t, pw, nil)
150 }
151 })
152 }
153 }
154
155
156 type checkPageWriter struct {
157 pageBytes int
158 writes int
159 writeBytes int
160 t *testing.T
161 }
162
163 func (cw *checkPageWriter) Write(p []byte) (int, error) {
164 if len(p)%cw.pageBytes != 0 {
165 cw.t.Fatalf("got write len(p) = %d, expected len(p) == k*cw.pageBytes", len(p))
166 }
167 cw.writes++
168 cw.writeBytes += len(p)
169 return len(p), nil
170 }
171
View as plain text