cubefs
144 строки · 3.1 Кб
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
15package resourcepool_test
16
17import (
18"context"
19"fmt"
20"runtime"
21"testing"
22
23"github.com/stretchr/testify/require"
24
25rp "github.com/cubefs/cubefs/blobstore/common/resourcepool"
26"github.com/cubefs/cubefs/blobstore/util/task"
27)
28
29func TestPoolBase(t *testing.T) {
30p := rp.NewPool(func() interface{} {
31return 1
32}, 2)
33
34require.Equal(t, 2, p.Cap())
35require.Equal(t, 0, p.Len())
36require.Equal(t, 2, p.Idle())
37
38_, err := p.Get()
39require.NoError(t, err)
40_, err = p.Get()
41require.NoError(t, err)
42
43require.Equal(t, 2, p.Len())
44require.Equal(t, 0, p.Idle())
45
46_, err = p.Get()
47require.Equal(t, rp.ErrPoolLimit, err)
48_, err = p.Get()
49require.Equal(t, rp.ErrPoolLimit, err)
50
51p.Put(1)
52_, err = p.Get()
53require.NoError(t, err)
54}
55
56func TestPoolNoLimit(t *testing.T) {
57{
58p := rp.NewPool(func() interface{} {
59return 1
60}, 0)
61require.Equal(t, 0, p.Cap())
62require.Equal(t, 0, p.Len())
63require.Equal(t, 0, p.Idle())
64
65_, err := p.Get()
66require.ErrorIs(t, rp.ErrPoolLimit, err)
67}
68{
69p := rp.NewPool(func() interface{} {
70return 1
71}, -10)
72require.Equal(t, -10, p.Cap())
73require.Equal(t, 0, p.Len())
74require.Equal(t, -1, p.Idle())
75
76tasks := make([]func() error, 0, 10000)
77for range [10000]struct{}{} {
78tasks = append(tasks, func() error {
79_, err := p.Get()
80return err
81})
82}
83
84err := task.Run(context.Background(), tasks...)
85require.NoError(t, err)
86}
87}
88
89func BenchmarkPoolGetPut(b *testing.B) {
90benchmarkPoolGetPut(b, func(size, capacity int) rp.Pool {
91return rp.NewPool(func() interface{} {
92return make([]byte, size)
93}, capacity)
94})
95}
96
97func benchmarkPoolGetPut(b *testing.B, newPool func(zize, capacity int) rp.Pool) {
98const kb = 1 << 10
99const mb = 1 << 20
100
101cases := []struct {
102size int
103}{
104{kb * 2},
105{kb * 64},
106{kb * 512},
107{mb},
108{mb * 2},
109{mb * 4},
110}
111
112for _, cs := range cases {
113runtime.GC()
114b.ResetTimer()
115b.Run(fmt.Sprintf("%s-%s", humman(cs.size), "unlimited"), func(b *testing.B) {
116pool := newPool(cs.size, -1)
117b.ResetTimer()
118for ii := 0; ii <= b.N; ii++ {
119if val, err := pool.Get(); err == nil {
120pool.Put(val)
121}
122}
123})
124
125b.ResetTimer()
126b.Run(fmt.Sprintf("%s-%s", humman(cs.size), "with_1m"), func(b *testing.B) {
127pool := newPool(cs.size, 1000000)
128b.ResetTimer()
129for ii := 0; ii <= b.N; ii++ {
130if val, err := pool.Get(); err == nil {
131pool.Put(val)
132}
133}
134})
135
136b.ResetTimer()
137b.Run(fmt.Sprintf("%s-%s", humman(cs.size), "make"), func(b *testing.B) {
138b.ResetTimer()
139for ii := 0; ii <= b.N; ii++ {
140_ = make([]byte, cs.size)
141}
142})
143}
144}
145