-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathintegration_test.go
More file actions
131 lines (126 loc) · 4.45 KB
/
integration_test.go
File metadata and controls
131 lines (126 loc) · 4.45 KB
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
// Copyright 2023-2025 Roel Harbers.
// Use of this source code is governed by the MIT license
// that can be found in the LICENSE file.
package multee_test
import (
"encoding/binary"
"fmt"
"io"
"math/rand"
"sync"
"testing"
"github.com/ComaVN/multee"
)
func Test_multee_smoketest(t *testing.T) {
const (
NumberOfReads = 1024
ReadLength = 4096
)
inputR, inputW := io.Pipe()
go func() {
// Generate an infinite stream of bytes, each 8 bytes containing their 64-bit offset in the stream.
buf := make([]byte, 8)
offs := uint64(0)
for {
binary.LittleEndian.PutUint64(buf, offs)
l, err := inputW.Write(buf)
if l != len(buf) || err != nil {
panic(fmt.Errorf("failed to write the full uint64 (%d, only %d bytes written, err: %v)", offs, l, err))
}
offs += uint64(l)
}
}()
mr := multee.NewMulteeReader(inputR)
r := mr.NewReader()
// This reads a random number of randomly sized chunks
// and checks if the read bytes match their offset, as the writer wrote them.
defer r.Close()
var prevBuf []byte // This keeps the remainder of bytes, that aren't in a multiple of 8.
offs := uint64(0)
for i := 0; i < NumberOfReads; i++ {
buf := make([]byte, len(prevBuf)+ReadLength)
copy(buf, prevBuf)
l, err := io.ReadFull(r, buf[len(prevBuf):])
if l != len(buf)-len(prevBuf) || err != nil {
t.Errorf("failed to read the full buffer (len %d, %d bytes read, err: %v)", len(buf), l, err)
}
bufOffs := 0
for ; bufOffs <= len(buf)-8; bufOffs += 8 {
got := binary.LittleEndian.Uint64(buf[bufOffs : bufOffs+8])
if got != offs {
t.Errorf("expected to read offset %d, got %d", offs, got)
return
}
offs += 8
}
prevBuf = buf[bufOffs:]
}
}
func Test_multee_monkeytest(t *testing.T) {
const (
NumberOfSeeds = 20 // Run the test with this many different, predictable seeds.
MinNumberOfReaders = 0 // Use at least this many readers.
MaxNumberOfReaders = 20 // Use at most this many readers.
MinNumberOfReads = 0 // Do at least this many reads.
MaxNumberOfReads = 20 // Do at most this many reads.
MinReadLength = 1 // Read at least this many bytes at a time.
MaxReadLength = 65536 // Read at most this many bytes at a time.
)
for rndSeed := int64(0); rndSeed < NumberOfSeeds; rndSeed++ {
t.Run(fmt.Sprintf("Monkey_test_with_rnd_seed_%d", rndSeed), func(t *testing.T) {
rnd := rand.New(rand.NewSource(rndSeed))
inputR, inputW := io.Pipe()
go func(rndSeed int64) {
// Generate an infinite stream of bytes, each 8 bytes containing their 64-bit offset in the stream.
buf := make([]byte, 8)
offs := uint64(0)
for {
binary.LittleEndian.PutUint64(buf, offs)
l, err := inputW.Write(buf)
if l != len(buf) || err != nil {
panic(fmt.Errorf("rnd seed %d: failed to write the full uint64 (%d, only %d bytes written, err: %v)", rndSeed, offs, l, err))
}
offs += uint64(l)
}
}(rndSeed)
mr := multee.NewMulteeReader(inputR)
readers := make([]io.ReadCloser, MinNumberOfReaders+rnd.Intn(MaxNumberOfReaders-MinNumberOfReaders+1))
for idx := range readers {
readers[idx] = mr.NewReader()
}
var wg sync.WaitGroup
wg.Add(len(readers))
for rdrIdx, r := range readers {
numReads := MinNumberOfReads + rnd.Intn(MaxNumberOfReads-MinNumberOfReads+1)
readLen := MinReadLength + rnd.Intn(MaxReadLength-MinReadLength+1)
go func(r io.ReadCloser, rndSeed int64, rdrIdx int) {
// This reads a random number of randomly sized chunks
// and checks if the read bytes match their offset, as the writer wrote them.
defer wg.Done()
defer r.Close()
var prevBuf []byte // This keeps the remainder of bytes, that aren't in a multiple of 8.
offs := uint64(0)
for i := 0; i < numReads; i++ {
buf := make([]byte, len(prevBuf)+readLen)
copy(buf, prevBuf)
l, err := io.ReadFull(r, buf[len(prevBuf):])
if l != len(buf)-len(prevBuf) || err != nil {
t.Errorf("rnd seed %d, reader index: %d: failed to read the full buffer (len %d, %d bytes read, err: %v)", rndSeed, rdrIdx, len(buf), l, err)
}
bufOffs := 0
for ; bufOffs <= len(buf)-8; bufOffs += 8 {
got := binary.LittleEndian.Uint64(buf[bufOffs : bufOffs+8])
if got != offs {
t.Errorf("rnd seed %d, reader index: %d: expected to read offset %d, got %d", rndSeed, rdrIdx, offs, got)
return
}
offs += 8
}
prevBuf = buf[bufOffs:]
}
}(r, rndSeed, rdrIdx)
}
wg.Wait()
})
}
}