Skip to content

Commit 1580b2c

Browse files
committed
test(*): add unit test related to watermark
1 parent 917c1b9 commit 1580b2c

File tree

6 files changed

+1187
-0
lines changed

6 files changed

+1187
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
Copyright 2022 The Katalyst Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package userwatermark
18+
19+
import (
20+
"testing"
21+
22+
"github.com/stretchr/testify/assert"
23+
cliflag "k8s.io/component-base/cli/flag"
24+
25+
dynamicuserwm "github.com/kubewharf/katalyst-core/pkg/config/agent/dynamic/userwatermark"
26+
)
27+
28+
func TestNewUserWatermarkOptions(t *testing.T) {
29+
t.Parallel()
30+
31+
opts := NewUserWatermarkOptions()
32+
assert.NotNil(t, opts)
33+
assert.NotNil(t, opts.DefaultOptions)
34+
}
35+
36+
func TestUserWatermarkOptions_AddFlags(t *testing.T) {
37+
t.Parallel()
38+
39+
opts := NewUserWatermarkOptions()
40+
fss := &cliflag.NamedFlagSets{}
41+
42+
opts.AddFlags(fss)
43+
fs := fss.FlagSet("user-watermark")
44+
assert.NotNil(t, fs.Lookup("enable-user-watermark-reclaimer"))
45+
assert.NotNil(t, fs.Lookup("user-watermark-reconcile-interval"))
46+
assert.NotNil(t, fs.Lookup("user-watermark-pod-service-label"))
47+
}
48+
49+
func TestUserWatermarkOptions_ApplyTo(t *testing.T) {
50+
t.Parallel()
51+
52+
opts := &UserWatermarkOptions{
53+
EnableReclaimer: true,
54+
ReconcileInterval: 10,
55+
ServiceLabel: "service-label",
56+
DefaultOptions: NewUserWatermarkOptions().DefaultOptions,
57+
}
58+
59+
conf := dynamicuserwm.NewUserWatermarkConfiguration()
60+
err := opts.ApplyTo(conf)
61+
62+
assert.NoError(t, err)
63+
assert.True(t, conf.EnableReclaimer)
64+
assert.Equal(t, int64(10), conf.ReconcileInterval)
65+
assert.Equal(t, "service-label", conf.ServiceLabel)
66+
assert.NotNil(t, conf.DefaultConfig)
67+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
Copyright 2022 The Katalyst Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package userwatermarkdefault
18+
19+
import (
20+
"testing"
21+
22+
"github.com/stretchr/testify/assert"
23+
cliflag "k8s.io/component-base/cli/flag"
24+
25+
v1alpha1 "github.com/kubewharf/katalyst-api/pkg/apis/config/v1alpha1"
26+
dynamicuserwm "github.com/kubewharf/katalyst-core/pkg/config/agent/dynamic/userwatermark"
27+
)
28+
29+
func TestNewDefaultOptions(t *testing.T) {
30+
t.Parallel()
31+
32+
opts := NewDefaultOptions()
33+
assert.NotNil(t, opts)
34+
}
35+
36+
func TestDefaultOptions_AddFlags(t *testing.T) {
37+
t.Parallel()
38+
39+
opts := NewDefaultOptions()
40+
fss := &cliflag.NamedFlagSets{}
41+
42+
opts.AddFlags(fss)
43+
44+
fs := fss.FlagSet("user-watermark")
45+
46+
assert.NotNil(t, fs.Lookup("enable-user-watermark-memory-reclaim"))
47+
assert.NotNil(t, fs.Lookup("user-watermark-reclaim-interval"))
48+
assert.NotNil(t, fs.Lookup("user-watermark-scale-factor"))
49+
assert.NotNil(t, fs.Lookup("user-watermark-single-reclaim-size"))
50+
assert.NotNil(t, fs.Lookup("user-watermark-single-reclaim-factor"))
51+
assert.NotNil(t, fs.Lookup("user-watermark-backoff-duration"))
52+
53+
assert.NotNil(t, fs.Lookup("user-watermark-feedback-policy"))
54+
assert.NotNil(t, fs.Lookup("user-watermark-reclaim-failed-threshold"))
55+
assert.NotNil(t, fs.Lookup("user-watermark-failure-freeze-period"))
56+
assert.NotNil(t, fs.Lookup("user-watermark-psi-avg60-threshold"))
57+
assert.NotNil(t, fs.Lookup("user-watermark-reclaim-accuracy-target"))
58+
assert.NotNil(t, fs.Lookup("user-watermark-reclaim-scan-efficiency-target"))
59+
}
60+
61+
func TestDefaultOptions_ApplyTo(t *testing.T) {
62+
t.Parallel()
63+
64+
opts := &DefaultOptions{
65+
EnableMemoryReclaim: true,
66+
ReclaimInterval: 5,
67+
ScaleFactor: 200,
68+
SingleReclaimFactor: 0.5,
69+
SingleReclaimSize: 1 << 20,
70+
BackoffDuration: 10,
71+
FeedbackPolicy: string(v1alpha1.UserWatermarkPolicyNamePSI),
72+
73+
ReclaimFailedThreshold: 3,
74+
FailureFreezePeriod: 20,
75+
PsiAvg60Threshold: 1.0,
76+
ReclaimAccuracyTarget: 0.8,
77+
ReclaimScanEfficiencyTarget: 0.5,
78+
}
79+
80+
conf := &dynamicuserwm.UserWatermarkDefaultConfiguration{}
81+
err := opts.ApplyTo(conf)
82+
83+
assert.NoError(t, err)
84+
assert.True(t, conf.EnableMemoryReclaim)
85+
assert.Equal(t, int64(5), conf.ReclaimInterval)
86+
assert.Equal(t, uint64(200), conf.ScaleFactor)
87+
assert.Equal(t, 0.5, conf.SingleReclaimFactor)
88+
assert.Equal(t, uint64(1<<20), conf.SingleReclaimSize)
89+
assert.Equal(t, opts.BackoffDuration, conf.BackoffDuration)
90+
assert.Equal(t, v1alpha1.UserWatermarkPolicyNamePSI, conf.FeedbackPolicy)
91+
assert.Equal(t, uint64(3), conf.ReclaimFailedThreshold)
92+
assert.Equal(t, opts.FailureFreezePeriod, conf.FailureFreezePeriod)
93+
assert.Equal(t, opts.PsiAvg60Threshold, conf.PsiAvg60Threshold)
94+
assert.Equal(t, opts.ReclaimAccuracyTarget, conf.ReclaimAccuracyTarget)
95+
assert.Equal(t, opts.ReclaimScanEfficiencyTarget, conf.ReclaimScanEfficiencyTarget)
96+
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
Copyright 2022 The Katalyst Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package userwatermark
18+
19+
import (
20+
"sync"
21+
"testing"
22+
23+
"github.com/stretchr/testify/assert"
24+
25+
"github.com/kubewharf/katalyst-core/pkg/util/cgroup/common"
26+
)
27+
28+
const (
29+
TestCGroupPath = "/sys/fs/cgroup/test"
30+
31+
TestWatermarkScaleFactor = 100
32+
TestSingleReclaimFactor = 0.25
33+
TestSingleReclaimSize = 4096
34+
)
35+
36+
var calculatorMutex sync.Mutex
37+
38+
func NewDefaultMemoryWatermarkCalculator() *WatermarkCalculator {
39+
return NewMemoryWatermarkCalculator(TestCGroupPath, TestWatermarkScaleFactor, TestSingleReclaimFactor, TestSingleReclaimSize)
40+
}
41+
42+
func TestNewMemoryWatermarkCalculator(t *testing.T) {
43+
t.Parallel()
44+
45+
calc := NewMemoryWatermarkCalculator(TestCGroupPath, TestWatermarkScaleFactor, TestSingleReclaimFactor, TestSingleReclaimSize)
46+
assert.Equal(t, TestCGroupPath, calc.CGroupPath)
47+
assert.Equal(t, uint64(TestWatermarkScaleFactor), calc.WatermarkScaleFactor)
48+
assert.Equal(t, TestSingleReclaimFactor, calc.SingleReclaimFactor)
49+
assert.Equal(t, uint64(TestSingleReclaimSize), calc.SingleReclaimSize)
50+
}
51+
52+
func TestWatermarkCalculator_GetLowAndHighWatermark(t *testing.T) {
53+
t.Parallel()
54+
55+
wmc := NewDefaultMemoryWatermarkCalculator()
56+
capacity := uint64(1024 * 1024 * 1024) // 1GiB
57+
low := wmc.GetLowWatermark(capacity)
58+
high := wmc.GetHighWatermark(capacity)
59+
60+
expectedLow := uint64(float64(capacity * wmc.WatermarkScaleFactor / 10000))
61+
expectedHigh := uint64(float64(capacity * 2 * wmc.WatermarkScaleFactor / 10000))
62+
63+
assert.Equal(t, expectedLow, low)
64+
assert.Equal(t, expectedHigh, high)
65+
assert.True(t, high >= low)
66+
}
67+
68+
func TestWatermarkCalculator_GetReclaimTarget(t *testing.T) {
69+
t.Parallel()
70+
71+
wmc := NewDefaultMemoryWatermarkCalculator()
72+
memLimit := uint64(1000)
73+
74+
// case 1: reclaimTarget > reclaimableMax
75+
memUsage := uint64(950)
76+
reclaimableMax := uint64(300)
77+
78+
high := wmc.GetHighWatermark(memLimit)
79+
free := memLimit - memUsage
80+
expected := high - free
81+
82+
if expected > reclaimableMax {
83+
expected = reclaimableMax
84+
}
85+
got := wmc.GetReclaimTarget(memLimit, memUsage, reclaimableMax)
86+
assert.Equal(t, expected, got)
87+
88+
// case 2: reclaimTarget < reclaimableMax
89+
memUsage = 900
90+
reclaimableMax = 999
91+
92+
high = wmc.GetHighWatermark(memLimit)
93+
free = memLimit - memUsage
94+
expected = high - free
95+
96+
if expected > reclaimableMax {
97+
expected = reclaimableMax
98+
}
99+
100+
got = wmc.GetReclaimTarget(memLimit, memUsage, reclaimableMax)
101+
assert.Equal(t, expected, got)
102+
103+
// case 3: reclaimTarget == reclaimableMax
104+
memUsage = 800
105+
reclaimableMax = 900
106+
107+
high = wmc.GetHighWatermark(memLimit)
108+
free = memLimit - memUsage
109+
expected = high - free
110+
111+
if expected > reclaimableMax {
112+
expected = reclaimableMax
113+
}
114+
115+
got = wmc.GetReclaimTarget(memLimit, memUsage, reclaimableMax)
116+
assert.Equal(t, expected, got)
117+
}
118+
119+
func TestWatermarkCalculator_GetWatermark(t *testing.T) {
120+
t.Parallel()
121+
122+
wmc := &WatermarkCalculator{WatermarkScaleFactor: 100}
123+
124+
capacity := uint64(1024)
125+
126+
low, high := wmc.GetWatermark(capacity)
127+
assert.Equal(t, wmc.GetLowWatermark(capacity), low)
128+
assert.Equal(t, wmc.GetHighWatermark(capacity), high)
129+
}
130+
131+
func TestWatermarkCalculator_GetReclaimMax(t *testing.T) {
132+
t.Parallel()
133+
134+
memStats := common.MemoryStats{
135+
InactiveFile: 100,
136+
ActiveFile: 50,
137+
InactiveAnno: 200,
138+
ActiveAnno: 70,
139+
}
140+
141+
wmc := &WatermarkCalculator{SwapEnabled: false}
142+
assert.Equal(t, uint64(150), wmc.GetReclaimMax(memStats))
143+
144+
wmc.SwapEnabled = true
145+
assert.Equal(t, uint64(420), wmc.GetReclaimMax(memStats))
146+
}

0 commit comments

Comments
 (0)