wal-g

Форк
0
/
compression_structures_test.go 
186 строк · 5.3 Кб
1
package internal_test
2

3
import (
4
	"bytes"
5
	"errors"
6
	"io"
7
	"math/rand"
8
	"testing"
9

10
	"github.com/stretchr/testify/assert"
11
	"github.com/wal-g/wal-g/internal"
12
	"github.com/wal-g/wal-g/internal/compression"
13
	"github.com/wal-g/wal-g/internal/compression/lz4"
14
	"github.com/wal-g/wal-g/testtools"
15
	"github.com/wal-g/wal-g/utility"
16
)
17

18
func GetLz4Compressor() compression.Compressor {
19
	return compression.Compressors[lz4.AlgorithmName]
20
}
21

22
var tests = []struct {
23
	testString string
24
	testLength int
25
	written    int
26
}{
27
	{"testing123456789", 16, 4},
28
}
29

30
func TestCascadeFileCloser(t *testing.T) {
31
	for _, testCase := range tests {
32
		b := &testtools.BufCloser{Buffer: bytes.NewBufferString(testCase.testString), Err: false}
33
		lz := &utility.CascadeWriteCloser{
34
			WriteCloser: GetLz4Compressor().NewWriter(b),
35
			Underlying:  b,
36
		}
37

38
		random := make([]byte, testCase.written)
39
		_, err := rand.Read(random)
40
		if err != nil {
41
			t.Log(err)
42
		}
43

44
		n, err := lz.Write(random)
45
		assert.NoErrorf(t, err, "compress: CascadeWriteCloser expected `<nil>` but got %v", err)
46
		assert.Equalf(t, n, testCase.written,
47
			"compress: CascadeWriteCloser expected %d bytes written but got %d", testCase.written, n)
48

49
		err = lz.Close()
50
		assert.NoErrorf(t, err, "compress: CascadeWriteCloser expected `<nil>` but got %v", err)
51

52
		b.Err = true
53

54
		err = lz.Close()
55
		assert.Errorf(t, err, "compress: Underlying writer expected to close with error but got `<nil>`")
56

57
	}
58
}
59

60
func TestCascadeFileCloserError(t *testing.T) {
61
	mock := &testtools.ErrorWriteCloser{}
62
	lz := &utility.CascadeWriteCloser{
63
		WriteCloser: GetLz4Compressor().NewWriter(mock),
64
		Underlying:  mock,
65
	}
66

67
	_, err := lz.Write([]byte{byte('a')})
68
	assert.Errorf(t, err, "compress: CascadeWriteCloser expected error on write but got `<nil>`")
69

70
	err = lz.Close()
71
	assert.Errorf(t, err, "compress: CascadeWriteCloser expected error on close but got `<nil>`")
72
}
73

74
func TestCompressAndEncrypt(t *testing.T) {
75
	for _, testCase := range tests {
76
		in := &testtools.BufCloser{Buffer: bytes.NewBufferString(testCase.testString), Err: false}
77
		compressor := GetLz4Compressor()
78
		compressed := internal.CompressAndEncrypt(in, compressor, nil)
79

80
		decompressor := compression.GetDecompressorByCompressor(compressor)
81
		decompressed, err := decompressor.Decompress(compressed)
82
		if err != nil {
83
			t.Logf("%+v\n", err)
84
		}
85
		defer decompressed.Close()
86
		out := &testtools.BufCloser{Buffer: &bytes.Buffer{}, Err: false}
87
		_, err = io.Copy(out, decompressed)
88
		assert.NoError(t, err)
89

90
		assert.Equalf(t, testCase.testString, out.String(),
91
			"compress: CascadeWriteCloser expected '%s' to be written but got '%s'",
92
			testCase.testString, out)
93
	}
94

95
}
96

97
func TestCompressAndEncryptBigChunk(t *testing.T) {
98
	L := 1024 * 1024 // 1Mb
99
	b := make([]byte, L)
100
	rand.Read(b)
101
	in := &testtools.BufCloser{Buffer: bytes.NewBuffer(b), Err: false}
102

103
	compressor := GetLz4Compressor()
104
	compressed := internal.CompressAndEncrypt(in, compressor, nil)
105

106
	decompressor := compression.GetDecompressorByCompressor(compressor)
107
	decompressed, err := decompressor.Decompress(compressed)
108
	if err != nil {
109
		t.Logf("%+v\n", err)
110
	}
111
	defer decompressed.Close()
112
	out := &testtools.BufCloser{Buffer: &bytes.Buffer{}, Err: false}
113
	_, err = io.Copy(out, decompressed)
114
	assert.NoError(t, err)
115

116
	assert.Equalf(t, b, out.Bytes(), "Incorrect decompression")
117

118
}
119

120
type DelayedErrorReader struct {
121
	underlying io.Reader
122
	n          int
123
}
124

125
func (er *DelayedErrorReader) Read(p []byte) (int, error) {
126
	x, err := er.underlying.Read(p)
127
	if err != nil {
128
		return 0, err
129
	}
130
	er.n -= x
131
	if er.n < 0 {
132
		return 0, errors.New("mock reader: read error")
133
	} else {
134
		return x, nil
135
	}
136
}
137

138
func testCompressAndEncryptErrorPropagation(compressor compression.Compressor, t *testing.T) {
139
	L := 1 << 20
140
	b := make([]byte, L)
141
	rand.Read(b)
142
	in := &testtools.BufCloser{Buffer: bytes.NewBuffer(b), Err: false}
143

144
	compressed := internal.CompressAndEncrypt(in, compressor, nil)
145

146
	decompressor := compression.GetDecompressorByCompressor(compressor)
147
	decompressed, err := decompressor.Decompress(&DelayedErrorReader{compressed, L})
148
	assert.NoError(t, err)
149
	_, err = io.ReadAll(decompressed)
150
	assert.Errorf(t, err, "%v did not propagate error of the buffer", compressor.FileExtension())
151
}
152

153
func TestCompressAndEncryptErrorPropagation(t *testing.T) {
154
	for _, compressor := range compression.Compressors {
155
		go testCompressAndEncryptErrorPropagation(compressor, t)
156
	}
157
}
158

159
func TestCompressAndEncryptError(t *testing.T) {
160
	compressor := GetLz4Compressor()
161
	compressed := internal.CompressAndEncrypt(&testtools.ErrorReader{}, compressor, nil)
162

163
	_, err := io.ReadAll(compressed)
164
	assert.Errorf(t, err, "compress: CompressingPipeWriter expected error but got `<nil>`")
165
	if re, ok := err.(internal.CompressAndEncryptError); !ok {
166
		t.Errorf("compress: CompressingPipeWriter expected CompressAndEncryptError but got %v", re)
167
	}
168
}
169

170
func TestCompressAndEncryptWithNoCompression(t *testing.T) {
171
	for _, testCase := range tests {
172
		in := &testtools.BufCloser{Buffer: bytes.NewBufferString(testCase.testString), Err: false}
173
		compressed := internal.CompressAndEncrypt(in, nil, nil)
174

175
		decompressed := &testtools.BufCloser{Buffer: &bytes.Buffer{}, Err: false}
176
		_, err := decompressed.ReadFrom(compressed)
177
		if err != nil {
178
			t.Logf("%+v\n", err)
179
		}
180

181
		assert.Equalf(t, testCase.testString, decompressed.String(),
182
			"compress: CascadeWriteCloser expected '%s' to be written but got '%s'",
183
			testCase.testString, decompressed)
184
	}
185

186
}
187

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.