ceph-csi/internal/rbd/qos_test.go
Yite Gu 4774a82e88 rbd: support QoS based on capacity for rbd volume
1. QoS provides settings for rbd volume read/write iops
   and read/write bandwidth.
2. All QoS parameters are placed in the SC,
   send QoS parameters from SC to Cephcsi through PVC create request.
3. We need provide QoS parameters in the SC as below:
   - BaseReadIops
   - BaseWriteIops
   - BaseReadBytesPerSecond
   - BaseWriteBytesPerSecond
   - ReadIopsPerGB
   - WriteIopsPerGB
   - ReadBpsPerGB
   - WriteBpsPerGB
   - BaseVolSizeBytes
   There are 4 base qos parameters among them, when users apply for
   a volume capacity equal to or less than BaseVolSizebytes, use base
   qos limit. For the portion of capacity exceeding BaseVolSizebytes,
   QoS will be increased in steps set per GB. If the step size parameter
   per GB is not provided, only base QoS limit will be used and not associated
   with capacity size.
4. If PVC has resize request, adjust the QoS limit
   according to the QoS parameters after resizing.

Signed-off-by: Yite Gu <guyite@bytedance.com>
2024-12-20 13:05:06 +08:00

121 lines
2.8 KiB
Go

/*
Copyright 2024 The Ceph-CSI Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rbd
import (
"context"
"testing"
)
func checkQOS(
t *testing.T,
target map[string]string,
wants map[string]string,
) {
t.Helper()
for k, v := range wants {
if r, ok := target[k]; ok {
if v != r {
t.Errorf("SetQOS: %s: %s, want %s", k, target[k], v)
}
} else {
t.Errorf("SetQOS: missing qos %s", k)
}
}
}
func TestSetQOS(t *testing.T) {
t.Parallel()
ctx := context.TODO()
tests := map[string]string{
baseReadIops: "2000",
baseWriteIops: "1000",
}
wants := map[string]string{
readIopsLimit: "2000",
writeIopsLimit: "1000",
}
rv := rbdVolume{}
rv.VolSize = int64(oneGB)
err := rv.SetQOS(ctx, tests)
if err != nil {
t.Errorf("SetQOS failed: %v", err)
}
checkQOS(t, rv.QosParameters, wants)
tests = map[string]string{
baseReadIops: "2000",
baseWriteIops: "1000",
baseReadBytesPerSecond: "209715200",
baseWriteBytesPerSecond: "104857600",
}
wants = map[string]string{
readIopsLimit: "2000",
writeIopsLimit: "1000",
readBpsLimit: "209715200",
writeBpsLimit: "104857600",
}
rv = rbdVolume{}
rv.VolSize = int64(oneGB)
err = rv.SetQOS(ctx, tests)
if err != nil {
t.Errorf("SetQOS failed: %v", err)
}
checkQOS(t, rv.QosParameters, wants)
tests = map[string]string{
baseReadIops: "2000",
baseWriteIops: "1000",
baseReadBytesPerSecond: "209715200",
baseWriteBytesPerSecond: "104857600",
readIopsPerGB: "20",
writeIopsPerGB: "10",
readBpsPerGB: "2097152",
writeBpsPerGB: "1048576",
baseVolSizeBytes: "21474836480",
}
wants = map[string]string{
readIopsLimit: "2000",
writeIopsLimit: "1000",
readBpsLimit: "209715200",
writeBpsLimit: "104857600",
}
rv = rbdVolume{}
rv.VolSize = int64(oneGB) * 20
err = rv.SetQOS(ctx, tests)
if err != nil {
t.Errorf("SetQOS failed: %v", err)
}
checkQOS(t, rv.QosParameters, wants)
wants = map[string]string{
readIopsLimit: "3600",
writeIopsLimit: "1800",
readBpsLimit: "377487360",
writeBpsLimit: "188743680",
}
rv = rbdVolume{}
rv.VolSize = int64(oneGB) * 100
err = rv.SetQOS(ctx, tests)
if err != nil {
t.Errorf("SetQOS failed: %v", err)
}
checkQOS(t, rv.QosParameters, wants)
}