cubefs

Форк
0
/
buf_test.go 
205 строк · 5.7 Кб
1
// Copyright 2022 The CubeFS Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12
// implied. See the License for the specific language governing
13
// permissions and limitations under the License.
14

15
package ec_test
16

17
import (
18
	"crypto/rand"
19
	mrand "math/rand"
20
	"testing"
21
	"time"
22

23
	"github.com/stretchr/testify/require"
24

25
	"github.com/cubefs/cubefs/blobstore/common/codemode"
26
	"github.com/cubefs/cubefs/blobstore/common/ec"
27
	rp "github.com/cubefs/cubefs/blobstore/common/resourcepool"
28
	_ "github.com/cubefs/cubefs/blobstore/testing/nolog"
29
)
30

31
const (
32
	kb    = 1 << 10
33
	kb4   = 1 << 12
34
	kb64  = 1 << 16
35
	kb512 = 1 << 19
36
	mb    = 1 << 20
37
)
38

39
var memPool = rp.NewMemPool(map[int]int{kb64: 1, mb: 1})
40

41
func init() {
42
	mrand.Seed(time.Now().Unix())
43
}
44

45
func TestNewBuffer(t *testing.T) {
46
	cm := codemode.EC6P6.Tactic()
47
	buffer, err := ec.NewBuffer(kb, cm, memPool)
48
	require.NoError(t, err)
49
	defer buffer.Release()
50
	require.Equal(t, kb, len(buffer.DataBuf))
51
	require.Equal(t, kb64, cap(buffer.DataBuf))
52
	require.Equal(t, cap(buffer.ECDataBuf), cap(buffer.DataBuf))
53

54
	// mb pool
55
	cm = codemode.EC16P20L2.Tactic()
56
	buffer, err = ec.NewBuffer(kb64, cm, memPool)
57
	require.NoError(t, err)
58
	defer buffer.Release()
59
	require.Equal(t, kb64, len(buffer.DataBuf))
60
	require.Equal(t, mb, cap(buffer.DataBuf))
61
	require.Equal(t, cap(buffer.ECDataBuf), cap(buffer.DataBuf))
62

63
	// alloc new bytes when no suitable pool, do not put back
64
	buffer, err = ec.NewBuffer(kb512, cm, memPool)
65
	shardSize := (kb512 + cm.N - 1) / cm.N
66
	require.NoError(t, err)
67
	require.Equal(t, kb512, len(buffer.DataBuf))
68
	require.Equal(t, shardSize*(cm.N+cm.M+cm.L), cap(buffer.DataBuf))
69
	require.Equal(t, shardSize*cm.N, len(buffer.ECDataBuf))
70
	require.Equal(t, shardSize*(cm.N+cm.M+cm.L), cap(buffer.ECDataBuf))
71
}
72

73
func TestNewRangedBuffer(t *testing.T) {
74
	cm := codemode.EC6P6.Tactic()
75
	buffer, err := ec.NewBuffer(kb, cm, memPool)
76
	require.NoError(t, err)
77
	require.Equal(t, kb, len(buffer.DataBuf))
78
	require.NotNil(t, buffer.ECDataBuf)
79
	require.Equal(t, kb64, cap(buffer.DataBuf))
80
	buffer.Release()
81

82
	// kb pool in ranged
83
	cm = codemode.EC16P20L2.Tactic()
84
	buffer, err = ec.NewRangeBuffer(kb4, kb, 2*kb+2, cm, memPool)
85
	require.NoError(t, err)
86
	require.Equal(t, kb+2, len(buffer.DataBuf))
87
	require.Nil(t, buffer.ECDataBuf)
88
	require.Equal(t, kb64, cap(buffer.DataBuf))
89
	buffer.Release()
90
}
91

92
func TestGetBufferSize(t *testing.T) {
93
	cm := codemode.EC6P6.Tactic()
94
	sizes, err := ec.GetBufferSizes(kb, cm)
95
	shardSize := (kb + cm.N - 1) / cm.N
96
	if shardSize < cm.MinShardSize {
97
		shardSize = cm.MinShardSize
98
	}
99
	require.NoError(t, err)
100
	require.Equal(t, shardSize, sizes.ShardSize)
101
	require.Equal(t, kb, sizes.DataSize)
102
	require.Equal(t, shardSize*cm.N, sizes.ECDataSize)
103
	require.Equal(t, shardSize*(cm.N+cm.M+cm.L), sizes.ECSize)
104

105
	cm = codemode.EC16P20L2.Tactic()
106
	sizes, err = ec.GetBufferSizes(kb512, cm)
107
	shardSize = (kb512 + cm.N - 1) / cm.N
108
	if shardSize < cm.MinShardSize {
109
		shardSize = cm.MinShardSize
110
	}
111
	require.NoError(t, err)
112
	require.Equal(t, shardSize, sizes.ShardSize)
113
	require.Equal(t, kb512, sizes.DataSize)
114
	require.Equal(t, shardSize*cm.N, sizes.ECDataSize)
115
	require.Equal(t, shardSize*(cm.N+cm.M+cm.L), sizes.ECSize)
116

117
	_, err = ec.GetBufferSizes(0, cm)
118
	require.ErrorIs(t, ec.ErrShortData, err)
119
	_, err = ec.GetBufferSizes(-1, cm)
120
	require.ErrorIs(t, ec.ErrShortData, err)
121
}
122

123
func TestBufferResize(t *testing.T) {
124
	cm := codemode.EC6P6.Tactic()
125
	buffer, err := ec.NewBuffer(kb, cm, memPool)
126
	require.NoError(t, err)
127
	defer func() {
128
		buffer.Release()
129
	}()
130
	require.Equal(t, kb, len(buffer.DataBuf))
131
	require.Equal(t, kb64, cap(buffer.DataBuf))
132

133
	// // pool limited
134
	// _, err = ec.NewBuffer(kb, cm, memPool)
135
	// require.ErrorIs(t, rp.ErrPoolLimit, err)
136

137
	err = buffer.Resize(kb + 512)
138
	require.NoError(t, err)
139
	require.Equal(t, kb+512, len(buffer.DataBuf))
140
	require.Equal(t, kb64, cap(buffer.DataBuf))
141

142
	// // pool limited
143
	// _, err = ec.NewBuffer(kb, cm, memPool)
144
	// require.ErrorIs(t, rp.ErrPoolLimit, err)
145

146
	// mb pool, release kb64 pool
147
	err = buffer.Resize(kb64)
148
	require.NoError(t, err)
149
	require.Equal(t, kb64, len(buffer.DataBuf))
150
	require.Equal(t, mb, cap(buffer.DataBuf))
151

152
	// old kb64 pool was released
153
	buff, err := ec.NewBuffer(kb, cm, memPool)
154
	require.NoError(t, err)
155
	buff.Release()
156
}
157

158
func TestBufferRelease(t *testing.T) {
159
	{
160
		var buffer *ec.Buffer
161
		require.NoError(t, buffer.Release())
162
	}
163
	{
164
		buffer := &ec.Buffer{}
165
		require.NoError(t, buffer.Release())
166
	}
167
	{
168
		buffer, err := ec.NewBuffer(kb, codemode.EC6P6.Tactic(), memPool)
169
		require.NoError(t, err)
170
		require.NoError(t, buffer.Release())
171
	}
172
}
173

174
func TestBufferDataPadding(t *testing.T) {
175
	// new a mempool while resize will alloc oversize buffer
176
	memPool := rp.NewMemPool(map[int]int{kb64: 1, mb: 1})
177
	// random read
178
	for _, size := range []int{kb64, mb} {
179
		buf, err := memPool.Get(size)
180
		require.NoError(t, err)
181
		rand.Read(buf)
182
		memPool.Put(buf)
183
	}
184

185
	zero := make([]byte, mb)
186

187
	cm := codemode.EC6P6.Tactic()
188
	buffer, err := ec.NewBuffer(kb, cm, memPool)
189
	require.NoError(t, err)
190
	defer func() {
191
		buffer.Release()
192
	}()
193

194
	buf := buffer.DataBuf[:cap(buffer.DataBuf)]
195
	require.Equal(t, zero[:buffer.ShardSize*cm.N-buffer.DataSize],
196
		buf[buffer.DataSize:buffer.ShardSize*cm.N])
197

198
	for ii := 0; ii < 100; ii++ {
199
		err = buffer.Resize(mrand.Intn(mb*6) + 1)
200
		require.NoError(t, err)
201
		buf = buffer.DataBuf[:cap(buffer.DataBuf)]
202
		require.Equal(t, zero[:buffer.ShardSize*cm.N-buffer.DataSize],
203
			buf[buffer.DataSize:buffer.ShardSize*cm.N])
204
	}
205
}
206

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

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

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

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