Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
fcdf32f3
Commit
fcdf32f3
authored
Nov 24, 2015
by
k8s-merge-robot
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #17674 from gmarek/fix-test
Auto commit by PR queue bot
parents
87315036
a5300a0c
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
43 additions
and
25 deletions
+43
-25
handlers_test.go
pkg/apiserver/handlers_test.go
+43
-25
No files found.
pkg/apiserver/handlers_test.go
View file @
fcdf32f3
...
...
@@ -57,22 +57,39 @@ func pathWithPrefix(prefix, resource, namespace, name string) string {
return
testapi
.
Default
.
ResourcePathWithPrefix
(
prefix
,
resource
,
namespace
,
name
)
}
// Tests that MaxInFlightLimit works, i.e.
// - "long" requests such as proxy or watch, identified by regexp are not accounted despite
// hanging for the long time,
// - "short" requests are correctly accounted, i.e. there can be only size of channel passed to the
// constructor in flight at any given moment,
// - subsequent "short" requests are rejected instantly with apropriate error,
// - subsequent "long" requests are handled normally,
// - we correctly recover after some "short" requests finish, i.e. we can process new ones.
func
TestMaxInFlight
(
t
*
testing
.
T
)
{
const
Iterations
=
3
const
AllowedInflightRequestsNo
=
3
// Size of inflightRequestsChannel determines how many concurent inflight requests
// are allowed.
inflightRequestsChannel
:=
make
(
chan
bool
,
AllowedInflightRequestsNo
)
// notAccountedPathsRegexp specifies paths requests to which we don't account into
// requests in flight.
notAccountedPathsRegexp
:=
regexp
.
MustCompile
(
".*
\\
/watch"
)
// Calls is used to wait until all server calls are received. We are sending
// AllowedInflightRequestsNo of 'long' not-accounted requests and the same number of
// 'short' accounted ones.
calls
:=
&
sync
.
WaitGroup
{}
calls
.
Add
(
AllowedInflightRequestsNo
*
2
)
// Block is used to keep requests in flight for as long as we need to. All requests will
// be unblocked at the same time.
block
:=
sync
.
WaitGroup
{}
block
.
Add
(
1
)
oneAccountedFinished
:=
sync
.
WaitGroup
{}
oneAccountedFinished
.
Add
(
1
)
var
once
sync
.
Once
sem
:=
make
(
chan
bool
,
Iterations
)
re
:=
regexp
.
MustCompile
(
"[.*
\\
/watch][^
\\
/proxy.*]"
)
// Calls verifies that the server is actually blocked up before running the rest of the test
calls
:=
&
sync
.
WaitGroup
{}
calls
.
Add
(
Iterations
*
3
)
server
:=
httptest
.
NewServer
(
MaxInFlightLimit
(
sem
,
re
,
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
server
:=
httptest
.
NewServer
(
MaxInFlightLimit
(
inflightRequestsChannel
,
notAccountedPathsRegexp
,
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
// A short, accounted request that does not wait for block WaitGroup.
if
strings
.
Contains
(
r
.
URL
.
Path
,
"dontwait"
)
{
return
}
...
...
@@ -80,48 +97,49 @@ func TestMaxInFlight(t *testing.T) {
calls
.
Done
()
}
block
.
Wait
()
})))
}),
),
)
defer
server
.
Close
()
// These should hang, but not affect accounting.
for
i
:=
0
;
i
<
Iterations
;
i
++
{
for
i
:=
0
;
i
<
AllowedInflightRequestsNo
;
i
++
{
// These should hang waiting on block...
go
func
()
{
expectHTTP
(
server
.
URL
+
"/foo/bar/watch"
,
http
.
StatusOK
,
t
)
}()
}
// These should hang, but not affect accounting.
for
i
:=
0
;
i
<
Iterations
;
i
++
{
// These should hang waiting on block...
go
func
()
{
expectHTTP
(
server
.
URL
+
"/proxy/foo/bar"
,
http
.
StatusOK
,
t
)
}()
}
// Check that sever is not saturated by not-accounted calls
expectHTTP
(
server
.
URL
+
"/dontwait"
,
http
.
StatusOK
,
t
)
oneAccountedFinished
:=
sync
.
WaitGroup
{}
oneAccountedFinished
.
Add
(
1
)
var
once
sync
.
Once
for
i
:=
0
;
i
<
Iterations
;
i
++
{
// These should hang and be accounted, i.e. saturate the server
for
i
:=
0
;
i
<
AllowedInflightRequestsNo
;
i
++
{
// These should hang waiting on block...
go
func
()
{
expectHTTP
(
server
.
URL
,
http
.
StatusOK
,
t
)
once
.
Do
(
oneAccountedFinished
.
Done
)
}()
}
// We wait for all calls to be received by the server
calls
.
Wait
()
// Disable calls notifications in the server
calls
=
nil
// Do this multiple times to show that it rate limit rejected requests don't block.
for
i
:=
0
;
i
<
2
;
i
++
{
expectHTTP
(
server
.
URL
,
errors
.
StatusTooManyRequests
,
t
)
}
// Validate that non-accounted URLs still work
expectHTTP
(
server
.
URL
+
"/dontwait/watch"
,
http
.
StatusOK
,
t
)
// Let all hanging requests finish
block
.
Done
()
// Show that we recover from being blocked up.
//
However, we should
until at least one of the requests really finishes.
//
Too avoid flakyness we need to wait
until at least one of the requests really finishes.
oneAccountedFinished
.
Wait
()
expectHTTP
(
server
.
URL
,
http
.
StatusOK
,
t
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment