Skip to content

Commit 875407a

Browse files
committed
add flowcontrol integration test to import whitelist
1 parent 30bc0fc commit 875407a

File tree

3 files changed

+44
-41
lines changed

3 files changed

+44
-41
lines changed

staging/src/k8s.io/component-base/metrics/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ package_group(
9393
"//staging/src/k8s.io/apiserver/pkg/util/flowcontrol/metrics",
9494
"//staging/src/k8s.io/component-base/metrics/...",
9595
"//test/e2e_node",
96+
"//test/integration/apiserver/flowcontrol",
9697
"//vendor/...",
9798
],
9899
)

test/integration/apiserver/flowcontrol/BUILD

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ go_test(
2121
"//test/integration/framework:go_default_library",
2222
"//vendor/github.com/prometheus/common/expfmt:go_default_library",
2323
"//vendor/github.com/prometheus/common/model:go_default_library",
24-
"//vendor/github.com/stretchr/testify/assert:go_default_library",
2524
"//vendor/github.com/stretchr/testify/require:go_default_library",
2625
],
2726
)

test/integration/apiserver/flowcontrol/concurrency_test.go

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@ import (
2222
"io"
2323
"net/http/httptest"
2424
"strings"
25-
"sync"
2625
"testing"
2726
"time"
2827

2928
"github.com/prometheus/common/expfmt"
3029
"github.com/prometheus/common/model"
31-
"github.com/stretchr/testify/assert"
3230
"github.com/stretchr/testify/require"
3331

3432
flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1"
@@ -78,32 +76,39 @@ func TestPriorityLevelIsolation(t *testing.T) {
7876
noxu1Client := getClientFor(loopbackConfig, "noxu1")
7977
noxu2Client := getClientFor(loopbackConfig, "noxu2")
8078

81-
priorityLevelNoxu1, _, err := createPriorityLevelAndBindingFlowSchemaForUser(loopbackClient, "noxu1")
79+
queueLength := 50
80+
concurrencyShares := 1
81+
82+
priorityLevelNoxu1, _, err := createPriorityLevelAndBindingFlowSchemaForUser(
83+
loopbackClient, "noxu1", concurrencyShares, queueLength)
8284
require.NoError(t, err)
83-
priorityLevelNoxu2, _, err := createPriorityLevelAndBindingFlowSchemaForUser(loopbackClient, "noxu2")
85+
priorityLevelNoxu2, _, err := createPriorityLevelAndBindingFlowSchemaForUser(
86+
loopbackClient, "noxu2", concurrencyShares, queueLength)
8487
require.NoError(t, err)
8588

86-
wg := &sync.WaitGroup{}
89+
stopCh := make(chan struct{})
90+
defer close(stopCh)
8791
// "elephant"
88-
streamRequests(wg, 10, 100, func() {
89-
_, err := noxu1Client.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
92+
streamRequests(concurrencyShares+queueLength, func() {
93+
_, err := noxu1Client.CoreV1().Namespaces().List(context.Background(), metav1.ListOptions{})
9094
require.NoError(t, err)
91-
})
92-
93-
streamRequests(nil, 1, 100, func() {
94-
_, err := noxu2Client.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
95+
}, stopCh)
96+
// "mouse"
97+
streamRequests(1, func() {
98+
_, err := noxu2Client.CoreV1().Namespaces().List(context.Background(), metav1.ListOptions{})
9599
require.NoError(t, err)
96-
})
100+
}, stopCh)
97101

98-
wg.Wait()
102+
time.Sleep(time.Second * 10) // running in background for a while
99103

100-
dispatchedCountNoxu1, err := getRequestCountOfPriorityLevel(loopbackClient, priorityLevelNoxu1.Name)
101-
require.NoError(t, err)
102-
dispatchedCountNoxu2, err := getRequestCountOfPriorityLevel(loopbackClient, priorityLevelNoxu2.Name)
103-
require.NoError(t, err)
104+
reqCounts, err := getRequestCountOfPriorityLevel(loopbackClient)
104105

105-
assert.Equal(t, 1000, dispatchedCountNoxu1)
106-
assert.Equal(t, 100, dispatchedCountNoxu2)
106+
noxu1RequestCount := reqCounts[priorityLevelNoxu1.Name]
107+
noxu2RequestCount := reqCounts[priorityLevelNoxu2.Name]
108+
109+
if (noxu1RequestCount / 2) > noxu2RequestCount {
110+
t.Errorf("total requests made by noxu2 should at least half of noxu1: (%d:%d)", noxu1RequestCount, noxu2RequestCount)
111+
}
107112
}
108113

109114
func getClientFor(loopbackConfig *rest.Config, username string) clientset.Interface {
@@ -118,14 +123,14 @@ func getClientFor(loopbackConfig *rest.Config, username string) clientset.Interf
118123
return clientset.NewForConfigOrDie(config)
119124
}
120125

121-
func getRequestCountOfPriorityLevel(c clientset.Interface, priorityLevelName string) (int, error) {
126+
func getRequestCountOfPriorityLevel(c clientset.Interface) (map[string]int, error) {
122127
resp, err := c.CoreV1().
123128
RESTClient().
124129
Get().
125130
RequestURI("/metrics").
126-
DoRaw(context.TODO())
131+
DoRaw(context.Background())
127132
if err != nil {
128-
return 0, err
133+
return nil, err
129134
}
130135

131136
dec := expfmt.NewDecoder(strings.NewReader(string(resp)), expfmt.FmtText)
@@ -134,41 +139,40 @@ func getRequestCountOfPriorityLevel(c clientset.Interface, priorityLevelName str
134139
Opts: &expfmt.DecodeOptions{},
135140
}
136141

142+
reqCounts := make(map[string]int)
137143
for {
138144
var v model.Vector
139145
if err := decoder.Decode(&v); err != nil {
140146
if err == io.EOF {
141147
// Expected loop termination condition.
142-
return 0, fmt.Errorf("no dispatched-count metrics found for priorityLevel %v", priorityLevelName)
148+
return reqCounts, nil
143149
}
144-
return 0, fmt.Errorf("failed decoding metrics: %v", err)
150+
return nil, fmt.Errorf("failed decoding metrics: %v", err)
145151
}
146152
for _, metric := range v {
147153
switch name := string(metric.Metric[model.MetricNameLabel]); name {
148154
case dispatchedRequestCountMetricsName:
149-
if priorityLevelName == string(metric.Metric[dispatchedRequestCountMetricsLabelPriorityLevel]) {
150-
return int(metric.Value), nil
151-
}
155+
reqCounts[string(metric.Metric[dispatchedRequestCountMetricsLabelPriorityLevel])] = int(metric.Value)
152156
}
153157
}
154158
}
155159
}
156160

157-
func createPriorityLevelAndBindingFlowSchemaForUser(c clientset.Interface, username string) (*flowcontrolv1alpha1.PriorityLevelConfiguration, *flowcontrolv1alpha1.FlowSchema, error) {
158-
pl, err := c.FlowcontrolV1alpha1().PriorityLevelConfigurations().Create(context.TODO(), &flowcontrolv1alpha1.PriorityLevelConfiguration{
161+
func createPriorityLevelAndBindingFlowSchemaForUser(c clientset.Interface, username string, concurrencyShares, queuelength int) (*flowcontrolv1alpha1.PriorityLevelConfiguration, *flowcontrolv1alpha1.FlowSchema, error) {
162+
pl, err := c.FlowcontrolV1alpha1().PriorityLevelConfigurations().Create(context.Background(), &flowcontrolv1alpha1.PriorityLevelConfiguration{
159163
ObjectMeta: metav1.ObjectMeta{
160164
Name: username,
161165
},
162166
Spec: flowcontrolv1alpha1.PriorityLevelConfigurationSpec{
163167
Type: flowcontrolv1alpha1.PriorityLevelEnablementLimited,
164168
Limited: &flowcontrolv1alpha1.LimitedPriorityLevelConfiguration{
165-
AssuredConcurrencyShares: 10,
169+
AssuredConcurrencyShares: int32(concurrencyShares),
166170
LimitResponse: flowcontrolv1alpha1.LimitResponse{
167171
Type: flowcontrolv1alpha1.LimitResponseTypeQueue,
168172
Queuing: &flowcontrolv1alpha1.QueuingConfiguration{
169173
Queues: 100,
170174
HandSize: 1,
171-
QueueLengthLimit: 10,
175+
QueueLengthLimit: int32(queuelength),
172176
},
173177
},
174178
},
@@ -232,17 +236,16 @@ func createPriorityLevelAndBindingFlowSchemaForUser(c clientset.Interface, usern
232236
})
233237
}
234238

235-
func streamRequests(wg *sync.WaitGroup, parallel, times int, request func()) {
239+
func streamRequests(parallel int, request func(), stopCh <-chan struct{}) {
236240
for i := 0; i < parallel; i++ {
237-
if wg != nil {
238-
wg.Add(1)
239-
}
240241
go func() {
241-
for j := 0; j < times; j++ {
242-
request()
243-
}
244-
if wg != nil {
245-
wg.Done()
242+
for {
243+
select {
244+
case <-stopCh:
245+
return
246+
default:
247+
request()
248+
}
246249
}
247250
}()
248251
}

0 commit comments

Comments
 (0)