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
c558d2a3
Commit
c558d2a3
authored
Nov 07, 2017
by
Dr. Stefan Schimanski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
apiserver: add validating admission tests
- in endpoint tests - in generic registry - in patch handler - in admission chain
parent
33f873db
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
276 additions
and
135 deletions
+276
-135
chain_test.go
staging/src/k8s.io/apiserver/pkg/admission/chain_test.go
+36
-9
apiserver_test.go
staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go
+121
-94
rest_test.go
.../src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go
+76
-25
store_test.go
....io/apiserver/pkg/registry/generic/registry/store_test.go
+43
-7
No files found.
staging/src/k8s.io/apiserver/pkg/admission/chain_test.go
View file @
c558d2a3
...
...
@@ -39,22 +39,23 @@ func (h *FakeHandler) Admit(a Attributes) (err error) {
}
func
(
h
*
FakeHandler
)
Validate
(
a
Attributes
)
(
err
error
)
{
h
.
admit
Called
=
true
if
h
.
admit
{
h
.
validate
Called
=
true
if
h
.
validate
{
return
nil
}
return
fmt
.
Errorf
(
"Don't
admit
"
)
return
fmt
.
Errorf
(
"Don't
validate
"
)
}
func
makeHandler
(
name
string
,
a
dmi
t
bool
,
ops
...
Operation
)
Interface
{
func
makeHandler
(
name
string
,
a
ccep
t
bool
,
ops
...
Operation
)
Interface
{
return
&
FakeHandler
{
name
:
name
,
admit
:
admit
,
Handler
:
NewHandler
(
ops
...
),
name
:
name
,
admit
:
accept
,
validate
:
accept
,
Handler
:
NewHandler
(
ops
...
),
}
}
func
TestAdmit
(
t
*
testing
.
T
)
{
func
TestAdmit
AndValidate
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
name
string
operation
Operation
...
...
@@ -108,6 +109,7 @@ func TestAdmit(t *testing.T) {
},
}
for
_
,
test
:=
range
tests
{
// call admit and check that validate was not called at all
err
:=
test
.
chain
.
Admit
(
NewAttributesRecord
(
nil
,
nil
,
schema
.
GroupVersionKind
{},
""
,
""
,
schema
.
GroupVersionResource
{},
""
,
test
.
operation
,
nil
))
accepted
:=
(
err
==
nil
)
if
accepted
!=
test
.
accept
{
...
...
@@ -117,9 +119,34 @@ func TestAdmit(t *testing.T) {
fake
:=
h
.
(
*
FakeHandler
)
_
,
shouldBeCalled
:=
test
.
calls
[
fake
.
name
]
if
shouldBeCalled
!=
fake
.
admitCalled
{
t
.
Errorf
(
"%s: handler %s not called as expected: %v"
,
test
.
name
,
fake
.
name
,
fake
.
admitCalled
)
t
.
Errorf
(
"%s: admit handler %s not called as expected: %v"
,
test
.
name
,
fake
.
name
,
fake
.
admitCalled
)
continue
}
if
fake
.
validateCalled
{
t
.
Errorf
(
"%s: validate handler %s called during admit"
,
test
.
name
,
fake
.
name
)
}
// reset value for validation test
fake
.
admitCalled
=
false
}
// call validate and check that admit was not called at all
err
=
test
.
chain
.
Validate
(
NewAttributesRecord
(
nil
,
nil
,
schema
.
GroupVersionKind
{},
""
,
""
,
schema
.
GroupVersionResource
{},
""
,
test
.
operation
,
nil
))
accepted
=
(
err
==
nil
)
if
accepted
!=
test
.
accept
{
t
.
Errorf
(
"%s: unexpected result of validate call: %v
\n
"
,
test
.
name
,
accepted
)
}
for
_
,
h
:=
range
test
.
chain
{
fake
:=
h
.
(
*
FakeHandler
)
_
,
shouldBeCalled
:=
test
.
calls
[
fake
.
name
]
if
shouldBeCalled
!=
fake
.
validateCalled
{
t
.
Errorf
(
"%s: validate handler %s not called as expected: %v"
,
test
.
name
,
fake
.
name
,
fake
.
validateCalled
)
continue
}
if
fake
.
admitCalled
{
t
.
Errorf
(
"%s: admit handler %s called during admit"
,
test
.
name
,
fake
.
name
)
}
}
}
}
...
...
staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go
View file @
c558d2a3
...
...
@@ -82,13 +82,23 @@ func (alwaysAdmit) Handles(operation admission.Operation) bool {
return
true
}
type
alwaysDeny
struct
{}
type
always
Mutating
Deny
struct
{}
func
(
alwaysDeny
)
Admit
(
a
admission
.
Attributes
)
(
err
error
)
{
return
admission
.
NewForbidden
(
a
,
errors
.
New
(
"
A
dmission control is denying all modifications"
))
func
(
always
Mutating
Deny
)
Admit
(
a
admission
.
Attributes
)
(
err
error
)
{
return
admission
.
NewForbidden
(
a
,
errors
.
New
(
"
Mutating a
dmission control is denying all modifications"
))
}
func
(
alwaysDeny
)
Handles
(
operation
admission
.
Operation
)
bool
{
func
(
alwaysMutatingDeny
)
Handles
(
operation
admission
.
Operation
)
bool
{
return
true
}
type
alwaysValidatingDeny
struct
{}
func
(
alwaysValidatingDeny
)
Validate
(
a
admission
.
Attributes
)
(
err
error
)
{
return
admission
.
NewForbidden
(
a
,
errors
.
New
(
"Validating admission control is denying all modifications"
))
}
func
(
alwaysValidatingDeny
)
Handles
(
operation
admission
.
Operation
)
bool
{
return
true
}
...
...
@@ -258,11 +268,6 @@ func handle(storage map[string]rest.Storage) http.Handler {
return
handleInternal
(
storage
,
admissionControl
,
selfLinker
,
nil
)
}
// tests with a deny admission controller
func
handleDeny
(
storage
map
[
string
]
rest
.
Storage
)
http
.
Handler
{
return
handleInternal
(
storage
,
alwaysDeny
{},
selfLinker
,
nil
)
}
// tests using the new namespace scope mechanism
func
handleNamespaced
(
storage
map
[
string
]
rest
.
Storage
)
http
.
Handler
{
return
handleInternal
(
storage
,
admissionControl
,
selfLinker
,
nil
)
...
...
@@ -529,6 +534,9 @@ func (storage *SimpleRESTStorage) Create(ctx request.Context, obj runtime.Object
if
storage
.
injectedFunction
!=
nil
{
obj
,
err
=
storage
.
injectedFunction
(
obj
)
}
if
err
:=
createValidation
(
obj
);
err
!=
nil
{
return
nil
,
err
}
return
obj
,
err
}
...
...
@@ -545,6 +553,9 @@ func (storage *SimpleRESTStorage) Update(ctx request.Context, name string, objIn
if
storage
.
injectedFunction
!=
nil
{
obj
,
err
=
storage
.
injectedFunction
(
obj
)
}
if
err
:=
updateValidation
(
&
storage
.
item
,
obj
);
err
!=
nil
{
return
nil
,
false
,
err
}
return
obj
,
false
,
err
}
...
...
@@ -725,6 +736,9 @@ func (storage *NamedCreaterRESTStorage) Create(ctx request.Context, name string,
if
storage
.
injectedFunction
!=
nil
{
obj
,
err
=
storage
.
injectedFunction
(
obj
)
}
if
err
:=
createValidation
(
obj
);
err
!=
nil
{
return
nil
,
err
}
return
obj
,
err
}
...
...
@@ -2813,22 +2827,27 @@ func TestLegacyDeleteIgnoresOptions(t *testing.T) {
}
func
TestDeleteInvokesAdmissionControl
(
t
*
testing
.
T
)
{
storage
:=
map
[
string
]
rest
.
Storage
{}
simpleStorage
:=
SimpleRESTStorage
{}
ID
:=
"id"
storage
[
"simple"
]
=
&
simpleStorage
handler
:=
handleDeny
(
storage
)
server
:=
httptest
.
NewServer
(
handler
)
defer
server
.
Close
()
// TODO: remove mutating deny when we removed it from the endpoint implementation and ported all plugins
for
_
,
admit
:=
range
[]
admission
.
Interface
{
alwaysMutatingDeny
{},
alwaysValidatingDeny
{}}
{
t
.
Logf
(
"Testing %T"
,
admit
)
client
:=
http
.
Client
{}
request
,
err
:=
http
.
NewRequest
(
"DELETE"
,
server
.
URL
+
"/"
+
prefix
+
"/"
+
testGroupVersion
.
Group
+
"/"
+
testGroupVersion
.
Version
+
"/namespaces/default/simple/"
+
ID
,
nil
)
response
,
err
:=
client
.
Do
(
request
)
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
if
response
.
StatusCode
!=
http
.
StatusForbidden
{
t
.
Errorf
(
"Unexpected response %#v"
,
response
)
storage
:=
map
[
string
]
rest
.
Storage
{}
simpleStorage
:=
SimpleRESTStorage
{}
ID
:=
"id"
storage
[
"simple"
]
=
&
simpleStorage
handler
:=
handleInternal
(
storage
,
admit
,
selfLinker
,
nil
)
server
:=
httptest
.
NewServer
(
handler
)
defer
server
.
Close
()
client
:=
http
.
Client
{}
request
,
err
:=
http
.
NewRequest
(
"DELETE"
,
server
.
URL
+
"/"
+
prefix
+
"/"
+
testGroupVersion
.
Group
+
"/"
+
testGroupVersion
.
Version
+
"/namespaces/default/simple/"
+
ID
,
nil
)
response
,
err
:=
client
.
Do
(
request
)
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
if
response
.
StatusCode
!=
http
.
StatusForbidden
{
t
.
Errorf
(
"Unexpected response %#v"
,
response
)
}
}
}
...
...
@@ -2971,38 +2990,42 @@ func TestUpdate(t *testing.T) {
}
func
TestUpdateInvokesAdmissionControl
(
t
*
testing
.
T
)
{
storage
:=
map
[
string
]
rest
.
Storage
{}
simpleStorage
:=
SimpleRESTStorage
{}
ID
:=
"id"
storage
[
"simple"
]
=
&
simpleStorage
handler
:=
handleDeny
(
storage
)
server
:=
httptest
.
NewServer
(
handler
)
defer
server
.
Close
()
for
_
,
admit
:=
range
[]
admission
.
Interface
{
alwaysMutatingDeny
{},
alwaysValidatingDeny
{}}
{
t
.
Logf
(
"Testing %T"
,
admit
)
item
:=
&
genericapitesting
.
Simple
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
ID
,
Namespace
:
metav1
.
NamespaceDefault
,
},
Other
:
"bar"
,
}
body
,
err
:=
runtime
.
Encode
(
testCodec
,
item
)
if
err
!=
nil
{
// The following cases will fail, so die now
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
storage
:=
map
[
string
]
rest
.
Storage
{}
simpleStorage
:=
SimpleRESTStorage
{}
ID
:=
"id"
storage
[
"simple"
]
=
&
simpleStorage
handler
:=
handleInternal
(
storage
,
admit
,
selfLinker
,
nil
)
server
:=
httptest
.
NewServer
(
handler
)
defer
server
.
Close
()
client
:=
http
.
Client
{}
request
,
err
:=
http
.
NewRequest
(
"PUT"
,
server
.
URL
+
"/"
+
prefix
+
"/"
+
testGroupVersion
.
Group
+
"/"
+
testGroupVersion
.
Version
+
"/namespaces/default/simple/"
+
ID
,
bytes
.
NewReader
(
body
))
response
,
err
:=
client
.
Do
(
request
)
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
dump
,
_
:=
httputil
.
DumpResponse
(
response
,
true
)
t
.
Log
(
string
(
dump
))
item
:=
&
genericapitesting
.
Simple
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
ID
,
Namespace
:
metav1
.
NamespaceDefault
,
},
Other
:
"bar"
,
}
body
,
err
:=
runtime
.
Encode
(
testCodec
,
item
)
if
err
!=
nil
{
// The following cases will fail, so die now
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
if
response
.
StatusCode
!=
http
.
StatusForbidden
{
t
.
Errorf
(
"Unexpected response %#v"
,
response
)
client
:=
http
.
Client
{}
request
,
err
:=
http
.
NewRequest
(
"PUT"
,
server
.
URL
+
"/"
+
prefix
+
"/"
+
testGroupVersion
.
Group
+
"/"
+
testGroupVersion
.
Version
+
"/namespaces/default/simple/"
+
ID
,
bytes
.
NewReader
(
body
))
response
,
err
:=
client
.
Do
(
request
)
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
dump
,
_
:=
httputil
.
DumpResponse
(
response
,
true
)
t
.
Log
(
string
(
dump
))
if
response
.
StatusCode
!=
http
.
StatusForbidden
{
t
.
Errorf
(
"Unexpected response %#v"
,
response
)
}
}
}
...
...
@@ -3602,49 +3625,53 @@ func TestCreateInNamespace(t *testing.T) {
}
}
func
TestCreateInvokesAdmissionControl
(
t
*
testing
.
T
)
{
storage
:=
SimpleRESTStorage
{
injectedFunction
:
func
(
obj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
time
.
Sleep
(
5
*
time
.
Millisecond
)
return
obj
,
nil
},
}
selfLinker
:=
&
setTestSelfLinker
{
t
:
t
,
name
:
"bar"
,
namespace
:
"other"
,
expectedSet
:
"/"
+
prefix
+
"/"
+
testGroupVersion
.
Group
+
"/"
+
testGroupVersion
.
Version
+
"/namespaces/other/foo/bar"
,
}
handler
:=
handleInternal
(
map
[
string
]
rest
.
Storage
{
"foo"
:
&
storage
},
alwaysDeny
{},
selfLinker
,
nil
)
server
:=
httptest
.
NewServer
(
handler
)
defer
server
.
Close
()
client
:=
http
.
Client
{}
func
TestCreateInvokeAdmissionControl
(
t
*
testing
.
T
)
{
for
_
,
admit
:=
range
[]
admission
.
Interface
{
alwaysMutatingDeny
{},
alwaysValidatingDeny
{}}
{
t
.
Logf
(
"Testing %T"
,
admit
)
simple
:=
&
genericapitesting
.
Simple
{
Other
:
"bar"
,
}
data
,
err
:=
runtime
.
Encode
(
testCodec
,
simple
)
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
request
,
err
:=
http
.
NewRequest
(
"POST"
,
server
.
URL
+
"/"
+
prefix
+
"/"
+
testGroupVersion
.
Group
+
"/"
+
testGroupVersion
.
Version
+
"/namespaces/other/foo"
,
bytes
.
NewBuffer
(
data
))
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
storage
:=
SimpleRESTStorage
{
injectedFunction
:
func
(
obj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
time
.
Sleep
(
5
*
time
.
Millisecond
)
return
obj
,
nil
},
}
selfLinker
:=
&
setTestSelfLinker
{
t
:
t
,
name
:
"bar"
,
namespace
:
"other"
,
expectedSet
:
"/"
+
prefix
+
"/"
+
testGroupVersion
.
Group
+
"/"
+
testGroupVersion
.
Version
+
"/namespaces/other/foo/bar"
,
}
handler
:=
handleInternal
(
map
[
string
]
rest
.
Storage
{
"foo"
:
&
storage
},
admit
,
selfLinker
,
nil
)
server
:=
httptest
.
NewServer
(
handler
)
defer
server
.
Close
()
client
:=
http
.
Client
{}
wg
:=
sync
.
WaitGroup
{}
wg
.
Add
(
1
)
var
response
*
http
.
Response
go
func
()
{
response
,
err
=
client
.
Do
(
request
)
wg
.
Done
()
}()
wg
.
Wait
()
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
if
response
.
StatusCode
!=
http
.
StatusForbidden
{
t
.
Errorf
(
"Unexpected status: %d, Expected: %d, %#v"
,
response
.
StatusCode
,
http
.
StatusForbidden
,
response
)
simple
:=
&
genericapitesting
.
Simple
{
Other
:
"bar"
,
}
data
,
err
:=
runtime
.
Encode
(
testCodec
,
simple
)
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
request
,
err
:=
http
.
NewRequest
(
"POST"
,
server
.
URL
+
"/"
+
prefix
+
"/"
+
testGroupVersion
.
Group
+
"/"
+
testGroupVersion
.
Version
+
"/namespaces/other/foo"
,
bytes
.
NewBuffer
(
data
))
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
wg
:=
sync
.
WaitGroup
{}
wg
.
Add
(
1
)
var
response
*
http
.
Response
go
func
()
{
response
,
err
=
client
.
Do
(
request
)
wg
.
Done
()
}()
wg
.
Wait
()
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
if
response
.
StatusCode
!=
http
.
StatusForbidden
{
t
.
Errorf
(
"Unexpected status: %d, Expected: %d, %#v"
,
response
.
StatusCode
,
http
.
StatusForbidden
,
response
)
}
}
}
...
...
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go
View file @
c558d2a3
...
...
@@ -186,6 +186,16 @@ func (p *testPatcher) Update(ctx request.Context, name string, objInfo rest.Upda
return
nil
,
false
,
apierrors
.
NewConflict
(
example
.
Resource
(
"pods"
),
inPod
.
Name
,
fmt
.
Errorf
(
"existing %v, new %v"
,
p
.
updatePod
.
ResourceVersion
,
inPod
.
ResourceVersion
))
}
if
currentPod
==
nil
{
if
err
:=
createValidation
(
currentPod
);
err
!=
nil
{
return
nil
,
false
,
err
}
}
else
{
if
err
:=
updateValidation
(
currentPod
,
inPod
);
err
!=
nil
{
return
nil
,
false
,
err
}
}
return
inPod
,
false
,
nil
}
...
...
@@ -236,7 +246,7 @@ type patchTestCase struct {
// admission chain to use, nil is fine
admissionMutation
mutateObjectUpdateFunc
admissionValidation
rest
.
ValidateObjectUpdateFunc
// TODO: add test for this
admissionValidation
rest
.
ValidateObjectUpdateFunc
// startingPod is used as the starting point for the first Update
startingPod
*
example
.
Pod
...
...
@@ -557,35 +567,76 @@ func TestPatchWithAdmissionRejection(t *testing.T) {
fifteen
:=
int64
(
15
)
thirty
:=
int64
(
30
)
tc
:=
&
patchTestCase
{
name
:
"TestPatchWithAdmissionRejection"
,
admissionMutation
:
func
(
updatedObject
runtime
.
Object
,
currentObject
runtime
.
Object
)
error
{
return
errors
.
New
(
"admission failure"
)
type
Test
struct
{
name
string
admissionMutation
mutateObjectUpdateFunc
admissionValidation
rest
.
ValidateObjectUpdateFunc
expectedError
string
}
for
_
,
test
:=
range
[]
Test
{
{
name
:
"TestPatchWithMutatingAdmissionRejection"
,
admissionMutation
:
func
(
updatedObject
runtime
.
Object
,
currentObject
runtime
.
Object
)
error
{
return
errors
.
New
(
"mutating admission failure"
)
},
admissionValidation
:
rest
.
ValidateAllObjectUpdateFunc
,
expectedError
:
"mutating admission failure"
,
},
{
name
:
"TestPatchWithValidatingAdmissionRejection"
,
admissionMutation
:
rest
.
ValidateAllObjectUpdateFunc
,
admissionValidation
:
func
(
updatedObject
runtime
.
Object
,
currentObject
runtime
.
Object
)
error
{
return
errors
.
New
(
"validating admission failure"
)
},
expectedError
:
"validating admission failure"
,
},
{
name
:
"TestPatchWithBothAdmissionRejections"
,
admissionMutation
:
func
(
updatedObject
runtime
.
Object
,
currentObject
runtime
.
Object
)
error
{
return
errors
.
New
(
"mutating admission failure"
)
},
admissionValidation
:
func
(
updatedObject
runtime
.
Object
,
currentObject
runtime
.
Object
)
error
{
return
errors
.
New
(
"validating admission failure"
)
},
expectedError
:
"mutating admission failure"
,
},
}
{
tc
:=
&
patchTestCase
{
name
:
test
.
name
,
startingPod
:
&
example
.
Pod
{},
changedPod
:
&
example
.
Pod
{},
updatePod
:
&
example
.
Pod
{},
expectedError
:
"admission failure"
,
}
admissionMutation
:
test
.
admissionMutation
,
admissionValidation
:
test
.
admissionValidation
,
tc
.
startingPod
.
Name
=
name
tc
.
startingPod
.
Namespace
=
namespace
tc
.
startingPod
.
UID
=
uid
tc
.
startingPod
.
ResourceVersion
=
"1"
tc
.
startingPod
.
APIVersion
=
examplev1
.
SchemeGroupVersion
.
String
()
tc
.
startingPod
.
Spec
.
ActiveDeadlineSeconds
=
&
fifteen
startingPod
:
&
example
.
Pod
{},
changedPod
:
&
example
.
Pod
{},
updatePod
:
&
example
.
Pod
{},
tc
.
changedPod
.
Name
=
name
tc
.
changedPod
.
Namespace
=
namespace
tc
.
changedPod
.
UID
=
uid
tc
.
changedPod
.
ResourceVersion
=
"1"
tc
.
changedPod
.
APIVersion
=
examplev1
.
SchemeGroupVersion
.
String
()
tc
.
changedPod
.
Spec
.
ActiveDeadlineSeconds
=
&
thirty
expectedError
:
test
.
expectedError
,
}
tc
.
Run
(
t
)
tc
.
startingPod
.
Name
=
name
tc
.
startingPod
.
Namespace
=
namespace
tc
.
startingPod
.
UID
=
uid
tc
.
startingPod
.
ResourceVersion
=
"1"
tc
.
startingPod
.
APIVersion
=
examplev1
.
SchemeGroupVersion
.
String
()
tc
.
startingPod
.
Spec
.
ActiveDeadlineSeconds
=
&
fifteen
tc
.
changedPod
.
Name
=
name
tc
.
changedPod
.
Namespace
=
namespace
tc
.
changedPod
.
UID
=
uid
tc
.
changedPod
.
ResourceVersion
=
"1"
tc
.
changedPod
.
APIVersion
=
examplev1
.
SchemeGroupVersion
.
String
()
tc
.
changedPod
.
Spec
.
ActiveDeadlineSeconds
=
&
thirty
tc
.
updatePod
.
Name
=
name
tc
.
updatePod
.
Namespace
=
namespace
tc
.
updatePod
.
UID
=
uid
tc
.
updatePod
.
ResourceVersion
=
"1"
tc
.
updatePod
.
APIVersion
=
examplev1
.
SchemeGroupVersion
.
String
()
tc
.
updatePod
.
Spec
.
ActiveDeadlineSeconds
=
&
fifteen
tc
.
Run
(
t
)
}
}
func
TestPatchWithVersionConflictThenAdmissionFailure
(
t
*
testing
.
T
)
{
...
...
staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store_test.go
View file @
c558d2a3
...
...
@@ -311,8 +311,14 @@ func TestStoreCreate(t *testing.T) {
defaultDeleteStrategy
:=
testRESTStrategy
{
scheme
,
names
.
SimpleNameGenerator
,
true
,
false
,
true
}
registry
.
DeleteStrategy
=
testGracefulStrategy
{
defaultDeleteStrategy
}
// create the object with denying admission
objA
,
err
:=
registry
.
Create
(
testContext
,
podA
,
denyCreateValidation
,
false
)
if
err
==
nil
{
t
.
Errorf
(
"Expected admission error: %v"
,
err
)
}
// create the object
objA
,
err
:
=
registry
.
Create
(
testContext
,
podA
,
rest
.
ValidateAllObjectFunc
,
false
)
objA
,
err
=
registry
.
Create
(
testContext
,
podA
,
rest
.
ValidateAllObjectFunc
,
false
)
if
err
!=
nil
{
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
}
...
...
@@ -609,31 +615,53 @@ func TestStoreUpdate(t *testing.T) {
destroyFunc
,
registry
:=
NewTestGenericStoreRegistry
(
t
)
defer
destroyFunc
()
//
Test1 try to update a non-existing node
_
,
_
,
err
:=
registry
.
Update
(
testContext
,
podA
.
Name
,
rest
.
DefaultUpdatedObjectInfo
(
podA
),
rest
.
ValidateAllObjectFunc
,
rest
.
ValidateAllObjectUpdateFunc
)
//
try to update a non-existing node with denying admission, should still return NotFound
_
,
_
,
err
:=
registry
.
Update
(
testContext
,
podA
.
Name
,
rest
.
DefaultUpdatedObjectInfo
(
podA
),
denyCreateValidation
,
denyUpdateValidation
)
if
!
errors
.
IsNotFound
(
err
)
{
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
}
// Test2 createIfNotFound and verify
// try to update a non-existing node
_
,
_
,
err
=
registry
.
Update
(
testContext
,
podA
.
Name
,
rest
.
DefaultUpdatedObjectInfo
(
podA
),
rest
.
ValidateAllObjectFunc
,
rest
.
ValidateAllObjectUpdateFunc
)
if
!
errors
.
IsNotFound
(
err
)
{
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
}
// allow creation
registry
.
UpdateStrategy
.
(
*
testRESTStrategy
)
.
allowCreateOnUpdate
=
true
// createIfNotFound with denying create admission
_
,
_
,
err
=
registry
.
Update
(
testContext
,
podA
.
Name
,
rest
.
DefaultUpdatedObjectInfo
(
podA
),
denyCreateValidation
,
rest
.
ValidateAllObjectUpdateFunc
)
if
err
==
nil
{
t
.
Errorf
(
"expected admission error on create"
)
}
// createIfNotFound and verify
if
!
updateAndVerify
(
t
,
testContext
,
registry
,
podA
)
{
t
.
Errorf
(
"Unexpected error updating podA"
)
}
// forbid creation again
registry
.
UpdateStrategy
.
(
*
testRESTStrategy
)
.
allowCreateOnUpdate
=
false
//
Test3
outofDate
// outofDate
_
,
_
,
err
=
registry
.
Update
(
testContext
,
podAWithResourceVersion
.
Name
,
rest
.
DefaultUpdatedObjectInfo
(
podAWithResourceVersion
),
rest
.
ValidateAllObjectFunc
,
rest
.
ValidateAllObjectUpdateFunc
)
if
!
errors
.
IsConflict
(
err
)
{
t
.
Errorf
(
"Unexpected error updating podAWithResourceVersion: %v"
,
err
)
}
// Test4 normal update and verify
// try to update with denying admission
_
,
_
,
err
=
registry
.
Update
(
testContext
,
podA
.
Name
,
rest
.
DefaultUpdatedObjectInfo
(
podA
),
rest
.
ValidateAllObjectFunc
,
denyUpdateValidation
)
if
err
==
nil
{
t
.
Errorf
(
"expected admission error on update"
)
}
// normal update and verify
if
!
updateAndVerify
(
t
,
testContext
,
registry
,
podB
)
{
t
.
Errorf
(
"Unexpected error updating podB"
)
}
//
Test5
unconditional update
// unconditional update
// NOTE: The logic for unconditional updates doesn't make sense to me, and imho should be removed.
// doUnconditionalUpdate := resourceVersion == 0 && e.UpdateStrategy.AllowUnconditionalUpdate()
// ^^ That condition can *never be true due to the creation of root objects.
...
...
@@ -1969,3 +1997,11 @@ func TestQualifiedResource(t *testing.T) {
t
.
Fatalf
(
"Unexpected error: %#v"
,
err
)
}
}
func
denyCreateValidation
(
obj
runtime
.
Object
)
error
{
return
fmt
.
Errorf
(
"admission denied"
)
}
func
denyUpdateValidation
(
obj
,
old
runtime
.
Object
)
error
{
return
fmt
.
Errorf
(
"admission denied"
)
}
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