2015-10-19 23:03:14 +00:00
/ *
2016-06-03 00:25:58 +00:00
Copyright 2014 The Kubernetes Authors .
2015-10-19 23:03:14 +00:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package pod
import (
2015-11-27 18:19:36 +00:00
"reflect"
2015-10-19 23:03:14 +00:00
"testing"
2017-01-13 17:48:50 +00:00
"k8s.io/apimachinery/pkg/api/errors"
2017-01-11 14:09:48 +00:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
2017-01-13 16:12:25 +00:00
genericapirequest "k8s.io/apiserver/pkg/request"
2015-10-19 23:03:14 +00:00
"k8s.io/kubernetes/pkg/api"
2016-12-19 21:02:48 +00:00
"k8s.io/kubernetes/pkg/api/resource"
2015-10-29 16:34:59 +00:00
apitesting "k8s.io/kubernetes/pkg/api/testing"
2016-01-17 19:59:56 +00:00
"k8s.io/kubernetes/pkg/fields"
2015-10-19 23:03:14 +00:00
)
2016-01-17 19:59:56 +00:00
func TestMatchPod ( t * testing . T ) {
testCases := [ ] struct {
in * api . Pod
fieldSelector fields . Selector
expectMatch bool
} {
{
in : & api . Pod {
Spec : api . PodSpec { NodeName : "nodeA" } ,
} ,
fieldSelector : fields . ParseSelectorOrDie ( "spec.nodeName=nodeA" ) ,
expectMatch : true ,
} ,
{
in : & api . Pod {
Spec : api . PodSpec { NodeName : "nodeB" } ,
} ,
fieldSelector : fields . ParseSelectorOrDie ( "spec.nodeName=nodeA" ) ,
expectMatch : false ,
} ,
{
in : & api . Pod {
Spec : api . PodSpec { RestartPolicy : api . RestartPolicyAlways } ,
} ,
fieldSelector : fields . ParseSelectorOrDie ( "spec.restartPolicy=Always" ) ,
expectMatch : true ,
} ,
{
in : & api . Pod {
Spec : api . PodSpec { RestartPolicy : api . RestartPolicyAlways } ,
} ,
fieldSelector : fields . ParseSelectorOrDie ( "spec.restartPolicy=Never" ) ,
expectMatch : false ,
} ,
{
in : & api . Pod {
Status : api . PodStatus { Phase : api . PodRunning } ,
} ,
fieldSelector : fields . ParseSelectorOrDie ( "status.phase=Running" ) ,
expectMatch : true ,
} ,
{
in : & api . Pod {
Status : api . PodStatus { Phase : api . PodRunning } ,
} ,
fieldSelector : fields . ParseSelectorOrDie ( "status.phase=Pending" ) ,
expectMatch : false ,
} ,
}
for _ , testCase := range testCases {
2016-08-23 03:41:21 +00:00
m := MatchPod ( labels . Everything ( ) , testCase . fieldSelector )
result , err := m . Matches ( testCase . in )
2016-01-17 19:59:56 +00:00
if err != nil {
t . Errorf ( "Unexpected error %v" , err )
}
if result != testCase . expectMatch {
t . Errorf ( "Result %v, Expected %v, Selector: %v, Pod: %v" , result , testCase . expectMatch , testCase . fieldSelector . String ( ) , testCase . in )
}
}
}
2016-12-19 21:02:48 +00:00
func getResourceList ( cpu , memory string ) api . ResourceList {
res := api . ResourceList { }
if cpu != "" {
res [ api . ResourceCPU ] = resource . MustParse ( cpu )
}
if memory != "" {
res [ api . ResourceMemory ] = resource . MustParse ( memory )
}
return res
}
func addResource ( rName , value string , rl api . ResourceList ) api . ResourceList {
rl [ api . ResourceName ( rName ) ] = resource . MustParse ( value )
return rl
}
func getResourceRequirements ( requests , limits api . ResourceList ) api . ResourceRequirements {
res := api . ResourceRequirements { }
res . Requests = requests
res . Limits = limits
return res
}
func newContainer ( name string , requests api . ResourceList , limits api . ResourceList ) api . Container {
return api . Container {
Name : name ,
Resources : getResourceRequirements ( requests , limits ) ,
}
}
func newPod ( name string , containers [ ] api . Container ) * api . Pod {
return & api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2016-12-19 21:02:48 +00:00
Name : name ,
} ,
Spec : api . PodSpec {
Containers : containers ,
} ,
}
}
func TestGetPodQOS ( t * testing . T ) {
testCases := [ ] struct {
pod * api . Pod
expected api . PodQOSClass
} {
{
pod : newPod ( "guaranteed" , [ ] api . Container {
newContainer ( "guaranteed" , getResourceList ( "100m" , "100Mi" ) , getResourceList ( "100m" , "100Mi" ) ) ,
} ) ,
expected : api . PodQOSGuaranteed ,
} ,
{
pod : newPod ( "best-effort" , [ ] api . Container {
newContainer ( "best-effort" , getResourceList ( "" , "" ) , getResourceList ( "" , "" ) ) ,
} ) ,
expected : api . PodQOSBestEffort ,
} ,
{
pod : newPod ( "burstable" , [ ] api . Container {
newContainer ( "burstable" , getResourceList ( "100m" , "100Mi" ) , getResourceList ( "" , "" ) ) ,
} ) ,
expected : api . PodQOSBurstable ,
} ,
}
for id , testCase := range testCases {
Strategy . PrepareForCreate ( genericapirequest . NewContext ( ) , testCase . pod )
actual := testCase . pod . Status . QOSClass
if actual != testCase . expected {
t . Errorf ( "[%d]: invalid qos pod %s, expected: %s, actual: %s" , id , testCase . pod . Name , testCase . expected , actual )
}
}
}
2015-10-19 23:03:14 +00:00
func TestCheckGracefulDelete ( t * testing . T ) {
defaultGracePeriod := int64 ( 30 )
tcs := [ ] struct {
in * api . Pod
gracePeriod int64
} {
{
in : & api . Pod {
Spec : api . PodSpec { NodeName : "something" } ,
Status : api . PodStatus { Phase : api . PodPending } ,
} ,
gracePeriod : defaultGracePeriod ,
} ,
{
in : & api . Pod {
Spec : api . PodSpec { NodeName : "something" } ,
Status : api . PodStatus { Phase : api . PodFailed } ,
} ,
gracePeriod : 0 ,
} ,
{
in : & api . Pod {
Spec : api . PodSpec { } ,
Status : api . PodStatus { Phase : api . PodPending } ,
} ,
gracePeriod : 0 ,
} ,
{
in : & api . Pod {
Spec : api . PodSpec { } ,
Status : api . PodStatus { Phase : api . PodSucceeded } ,
} ,
gracePeriod : 0 ,
} ,
{
in : & api . Pod {
Spec : api . PodSpec { } ,
Status : api . PodStatus { } ,
} ,
gracePeriod : 0 ,
} ,
}
for _ , tc := range tcs {
out := & api . DeleteOptions { GracePeriodSeconds : & defaultGracePeriod }
2017-01-02 14:07:36 +00:00
Strategy . CheckGracefulDelete ( genericapirequest . NewContext ( ) , tc . in , out )
2015-10-19 23:03:14 +00:00
if out . GracePeriodSeconds == nil {
t . Errorf ( "out grace period was nil but supposed to be %v" , tc . gracePeriod )
}
if * ( out . GracePeriodSeconds ) != tc . gracePeriod {
t . Errorf ( "out grace period was %v but was expected to be %v" , * out , tc . gracePeriod )
}
}
}
2015-11-27 18:19:36 +00:00
type mockPodGetter struct {
pod * api . Pod
}
2017-01-02 14:07:36 +00:00
func ( g mockPodGetter ) Get ( genericapirequest . Context , string , * metav1 . GetOptions ) ( runtime . Object , error ) {
2015-11-27 18:19:36 +00:00
return g . pod , nil
}
func TestCheckLogLocation ( t * testing . T ) {
2017-01-02 14:07:36 +00:00
ctx := genericapirequest . NewDefaultContext ( )
2015-11-27 18:19:36 +00:00
tcs := [ ] struct {
in * api . Pod
opts * api . PodLogOptions
expectedErr error
} {
{
in : & api . Pod {
Spec : api . PodSpec { } ,
Status : api . PodStatus { } ,
} ,
opts : & api . PodLogOptions { } ,
expectedErr : errors . NewBadRequest ( "a container name must be specified for pod test" ) ,
} ,
{
in : & api . Pod {
Spec : api . PodSpec {
Containers : [ ] api . Container {
{ Name : "mycontainer" } ,
} ,
} ,
Status : api . PodStatus { } ,
} ,
opts : & api . PodLogOptions { } ,
expectedErr : nil ,
} ,
{
in : & api . Pod {
Spec : api . PodSpec {
Containers : [ ] api . Container {
{ Name : "container1" } ,
{ Name : "container2" } ,
} ,
} ,
Status : api . PodStatus { } ,
} ,
opts : & api . PodLogOptions { } ,
2016-01-11 14:26:44 +00:00
expectedErr : errors . NewBadRequest ( "a container name must be specified for pod test, choose one of: [container1 container2]" ) ,
2015-11-27 18:19:36 +00:00
} ,
2016-06-09 12:08:43 +00:00
{
in : & api . Pod {
Spec : api . PodSpec {
Containers : [ ] api . Container {
{ Name : "container1" } ,
{ Name : "container2" } ,
} ,
InitContainers : [ ] api . Container {
{ Name : "initcontainer1" } ,
} ,
} ,
Status : api . PodStatus { } ,
} ,
opts : & api . PodLogOptions { } ,
expectedErr : errors . NewBadRequest ( "a container name must be specified for pod test, choose one of: [container1 container2] or one of the init containers: [initcontainer1]" ) ,
} ,
2015-11-27 18:19:36 +00:00
{
in : & api . Pod {
Spec : api . PodSpec {
Containers : [ ] api . Container {
{ Name : "container1" } ,
{ Name : "container2" } ,
} ,
} ,
Status : api . PodStatus { } ,
} ,
opts : & api . PodLogOptions {
Container : "unknown" ,
} ,
expectedErr : errors . NewBadRequest ( "container unknown is not valid for pod test" ) ,
} ,
{
in : & api . Pod {
Spec : api . PodSpec {
Containers : [ ] api . Container {
{ Name : "container1" } ,
{ Name : "container2" } ,
} ,
} ,
Status : api . PodStatus { } ,
} ,
opts : & api . PodLogOptions {
Container : "container2" ,
} ,
expectedErr : nil ,
} ,
}
for _ , tc := range tcs {
getter := & mockPodGetter { tc . in }
_ , _ , err := LogLocation ( getter , nil , ctx , "test" , tc . opts )
if ! reflect . DeepEqual ( err , tc . expectedErr ) {
t . Errorf ( "expected %v, got %v" , tc . expectedErr , err )
}
}
}
2015-10-29 16:34:59 +00:00
func TestSelectableFieldLabelConversions ( t * testing . T ) {
apitesting . TestSelectableFieldLabelConversionsOfKind ( t ,
2017-01-12 18:17:43 +00:00
api . Registry . GroupOrDie ( api . GroupName ) . GroupVersion . String ( ) ,
2015-10-29 16:34:59 +00:00
"Pod" ,
2016-08-12 18:50:51 +00:00
PodToSelectableFields ( & api . Pod { } ) ,
2015-10-29 16:34:59 +00:00
nil ,
)
}