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
f1e4ec8e
Unverified
Commit
f1e4ec8e
authored
Nov 16, 2018
by
k8s-ci-robot
Committed by
GitHub
Nov 16, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #71076 from liggitt/preserve-stack
Propagate panics up handler chain
parents
c9a31e49
0952c9ee
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
64 additions
and
18 deletions
+64
-18
rest.go
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go
+11
-3
rest_test.go
.../src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go
+53
-15
No files found.
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go
View file @
f1e4ec8e
...
...
@@ -23,6 +23,8 @@ import (
"io/ioutil"
"net/http"
"net/url"
goruntime
"runtime"
"strings"
"time"
"k8s.io/klog"
...
...
@@ -33,7 +35,6 @@ import (
metav1beta1
"k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
...
...
@@ -182,10 +183,17 @@ func finishRequest(timeout time.Duration, fn resultFunc) (result runtime.Object,
panicCh
:=
make
(
chan
interface
{},
1
)
go
func
()
{
// panics don't cross goroutine boundaries, so we have to handle ourselves
defer
utilruntime
.
HandleCrash
(
func
(
panicReason
interface
{})
{
defer
func
()
{
panicReason
:=
recover
()
if
panicReason
!=
nil
{
const
size
=
64
<<
10
buf
:=
make
([]
byte
,
size
)
buf
=
buf
[
:
goruntime
.
Stack
(
buf
,
false
)]
panicReason
=
strings
.
TrimSuffix
(
fmt
.
Sprintf
(
"%v
\n
%s"
,
panicReason
,
string
(
buf
)),
"
\n
"
)
}
// Propagate to parent goroutine
panicCh
<-
panicReason
})
}
(
)
if
result
,
err
:=
fn
();
err
!=
nil
{
errCh
<-
err
...
...
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go
View file @
f1e4ec8e
...
...
@@ -22,6 +22,7 @@ import (
"fmt"
"net/http"
"reflect"
"strings"
"testing"
"time"
...
...
@@ -835,13 +836,15 @@ func TestFinishRequest(t *testing.T) {
successStatusObj
:=
&
metav1
.
Status
{
Status
:
metav1
.
StatusSuccess
,
Message
:
"success message"
}
errorStatusObj
:=
&
metav1
.
Status
{
Status
:
metav1
.
StatusFailure
,
Message
:
"error message"
}
testcases
:=
[]
struct
{
timeout
time
.
Duration
fn
resultFunc
expectedObj
runtime
.
Object
expectedErr
error
name
string
timeout
time
.
Duration
fn
resultFunc
expectedObj
runtime
.
Object
expectedErr
error
expectedPanic
string
}{
{
// Expected obj is returned.
name
:
"Expected obj is returned"
,
timeout
:
time
.
Second
,
fn
:
func
()
(
runtime
.
Object
,
error
)
{
return
exampleObj
,
nil
...
...
@@ -850,7 +853,7 @@ func TestFinishRequest(t *testing.T) {
expectedErr
:
nil
,
},
{
// Expected error is returned.
name
:
"Expected error is returned"
,
timeout
:
time
.
Second
,
fn
:
func
()
(
runtime
.
Object
,
error
)
{
return
nil
,
exampleErr
...
...
@@ -859,7 +862,7 @@ func TestFinishRequest(t *testing.T) {
expectedErr
:
exampleErr
,
},
{
// Successful status object is returned as expected.
name
:
"Successful status object is returned as expected"
,
timeout
:
time
.
Second
,
fn
:
func
()
(
runtime
.
Object
,
error
)
{
return
successStatusObj
,
nil
...
...
@@ -868,7 +871,7 @@ func TestFinishRequest(t *testing.T) {
expectedErr
:
nil
,
},
{
// Error status object is converted to StatusError.
name
:
"Error status object is converted to StatusError"
,
timeout
:
time
.
Second
,
fn
:
func
()
(
runtime
.
Object
,
error
)
{
return
errorStatusObj
,
nil
...
...
@@ -876,15 +879,50 @@ func TestFinishRequest(t *testing.T) {
expectedObj
:
nil
,
expectedErr
:
apierrors
.
FromObject
(
errorStatusObj
),
},
{
name
:
"Panic is propagated up"
,
timeout
:
time
.
Second
,
fn
:
func
()
(
runtime
.
Object
,
error
)
{
panic
(
"my panic"
)
return
nil
,
nil
},
expectedObj
:
nil
,
expectedErr
:
nil
,
expectedPanic
:
"my panic"
,
},
{
name
:
"Panic is propagated with stack"
,
timeout
:
time
.
Second
,
fn
:
func
()
(
runtime
.
Object
,
error
)
{
panic
(
"my panic"
)
return
nil
,
nil
},
expectedObj
:
nil
,
expectedErr
:
nil
,
expectedPanic
:
"rest_test.go"
,
},
}
for
i
,
tc
:=
range
testcases
{
obj
,
err
:=
finishRequest
(
tc
.
timeout
,
tc
.
fn
)
if
(
err
==
nil
&&
tc
.
expectedErr
!=
nil
)
||
(
err
!=
nil
&&
tc
.
expectedErr
==
nil
)
||
(
err
!=
nil
&&
tc
.
expectedErr
!=
nil
&&
err
.
Error
()
!=
tc
.
expectedErr
.
Error
())
{
t
.
Errorf
(
"%d: unexpected err. expected: %v, got: %v"
,
i
,
tc
.
expectedErr
,
err
)
}
if
!
apiequality
.
Semantic
.
DeepEqual
(
obj
,
tc
.
expectedObj
)
{
t
.
Errorf
(
"%d: unexpected obj. expected %#v, got %#v"
,
i
,
tc
.
expectedObj
,
obj
)
}
t
.
Run
(
tc
.
name
,
func
(
t
*
testing
.
T
)
{
defer
func
()
{
r
:=
recover
()
switch
{
case
r
==
nil
&&
len
(
tc
.
expectedPanic
)
>
0
:
t
.
Errorf
(
"expected panic containing '%s', got none"
,
tc
.
expectedPanic
)
case
r
!=
nil
&&
len
(
tc
.
expectedPanic
)
==
0
:
t
.
Errorf
(
"unexpected panic: %v"
,
r
)
case
r
!=
nil
&&
len
(
tc
.
expectedPanic
)
>
0
&&
!
strings
.
Contains
(
fmt
.
Sprintf
(
"%v"
,
r
),
tc
.
expectedPanic
)
:
t
.
Errorf
(
"expected panic containing '%s', got '%v'"
,
tc
.
expectedPanic
,
r
)
}
}()
obj
,
err
:=
finishRequest
(
tc
.
timeout
,
tc
.
fn
)
if
(
err
==
nil
&&
tc
.
expectedErr
!=
nil
)
||
(
err
!=
nil
&&
tc
.
expectedErr
==
nil
)
||
(
err
!=
nil
&&
tc
.
expectedErr
!=
nil
&&
err
.
Error
()
!=
tc
.
expectedErr
.
Error
())
{
t
.
Errorf
(
"%d: unexpected err. expected: %v, got: %v"
,
i
,
tc
.
expectedErr
,
err
)
}
if
!
apiequality
.
Semantic
.
DeepEqual
(
obj
,
tc
.
expectedObj
)
{
t
.
Errorf
(
"%d: unexpected obj. expected %#v, got %#v"
,
i
,
tc
.
expectedObj
,
obj
)
}
})
}
}
...
...
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