2015-03-20 16:37:08 +00:00
/ *
2016-06-03 00:25:58 +00:00
Copyright 2014 The Kubernetes Authors .
2015-03-20 16:37:08 +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 .
* /
2015-09-11 19:22:01 +00:00
package status
2015-03-20 16:37:08 +00:00
import (
2015-06-22 19:31:46 +00:00
"fmt"
2015-03-20 16:37:08 +00:00
"math/rand"
"strconv"
2016-12-07 20:56:06 +00:00
"strings"
2015-03-20 16:37:08 +00:00
"testing"
2015-05-09 05:01:43 +00:00
"time"
2015-03-20 16:37:08 +00:00
2015-10-29 21:04:00 +00:00
"github.com/stretchr/testify/assert"
2017-06-22 18:24:23 +00:00
"k8s.io/api/core/v1"
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/runtime"
2016-12-07 20:56:06 +00:00
"k8s.io/apimachinery/pkg/runtime/schema"
2017-06-23 20:56:37 +00:00
clientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"
2017-01-25 20:07:10 +00:00
core "k8s.io/client-go/testing"
2017-04-17 17:56:40 +00:00
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
2017-11-08 22:34:54 +00:00
api "k8s.io/kubernetes/pkg/apis/core"
2017-05-25 21:23:57 +00:00
kubeconfigmap "k8s.io/kubernetes/pkg/kubelet/configmap"
2015-11-10 22:00:12 +00:00
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
2015-10-29 21:04:00 +00:00
kubepod "k8s.io/kubernetes/pkg/kubelet/pod"
2016-02-25 23:40:44 +00:00
podtest "k8s.io/kubernetes/pkg/kubelet/pod/testing"
2016-12-13 10:32:12 +00:00
kubesecret "k8s.io/kubernetes/pkg/kubelet/secret"
2017-02-10 23:08:03 +00:00
statustest "k8s.io/kubernetes/pkg/kubelet/status/testing"
2015-10-29 21:04:00 +00:00
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
2015-03-20 16:37:08 +00:00
)
2016-01-15 09:54:58 +00:00
// Generate new instance of test pod with the same initial value.
2016-11-18 20:50:58 +00:00
func getTestPod ( ) * v1 . Pod {
return & v1 . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2016-01-15 09:54:58 +00:00
UID : "12345678" ,
Name : "foo" ,
Namespace : "new" ,
} ,
}
2015-03-24 23:52:38 +00:00
}
2015-03-20 16:37:08 +00:00
2015-12-09 03:13:09 +00:00
// After adding reconciliation, if status in pod manager is different from the cached status, a reconciliation
// will be triggered, which will mess up all the old unit test.
// To simplify the implementation of unit test, we add testSyncBatch() here, it will make sure the statuses in
// pod manager the same with cached ones before syncBatch() so as to avoid reconciling.
func ( m * manager ) testSyncBatch ( ) {
for uid , status := range m . podStatuses {
pod , ok := m . podManager . GetPodByUID ( uid )
if ok {
pod . Status = status . status
}
pod , ok = m . podManager . GetMirrorPodByPod ( pod )
if ok {
pod . Status = status . status
}
}
m . syncBatch ( )
}
2016-02-01 22:30:47 +00:00
func newTestManager ( kubeClient clientset . Interface ) * manager {
2017-05-25 21:23:57 +00:00
podManager := kubepod . NewBasicPodManager ( podtest . NewFakeMirrorClient ( ) , kubesecret . NewFakeManager ( ) , kubeconfigmap . NewFakeManager ( ) )
2016-01-15 09:54:58 +00:00
podManager . AddPod ( getTestPod ( ) )
2017-02-10 23:08:03 +00:00
return NewManager ( kubeClient , podManager , & statustest . FakePodDeletionSafetyProvider { } ) . ( * manager )
2015-03-20 16:37:08 +00:00
}
func generateRandomMessage ( ) string {
return strconv . Itoa ( rand . Int ( ) )
}
2016-11-18 20:50:58 +00:00
func getRandomPodStatus ( ) v1 . PodStatus {
return v1 . PodStatus {
2015-03-20 16:37:08 +00:00
Message : generateRandomMessage ( ) ,
}
}
2017-04-03 18:32:53 +00:00
func verifyActions ( t * testing . T , manager * manager , expectedActions [ ] core . Action ) {
manager . consumeUpdates ( )
actions := manager . kubeClient . ( * fake . Clientset ) . Actions ( )
defer manager . kubeClient . ( * fake . Clientset ) . ClearActions ( )
2015-03-20 16:37:08 +00:00
if len ( actions ) != len ( expectedActions ) {
2016-01-20 00:16:06 +00:00
t . Fatalf ( "unexpected actions, got: %+v expected: %+v" , actions , expectedActions )
2015-03-20 16:37:08 +00:00
return
}
for i := 0 ; i < len ( actions ) ; i ++ {
2015-08-03 13:21:11 +00:00
e := expectedActions [ i ]
a := actions [ i ]
2016-04-13 22:33:15 +00:00
if ! a . Matches ( e . GetVerb ( ) , e . GetResource ( ) . Resource ) || a . GetSubresource ( ) != e . GetSubresource ( ) {
2016-01-20 00:16:06 +00:00
t . Errorf ( "unexpected actions, got: %+v expected: %+v" , actions , expectedActions )
2015-03-20 16:37:08 +00:00
}
}
}
2015-09-11 19:22:01 +00:00
func verifyUpdates ( t * testing . T , manager * manager , expectedUpdates int ) {
2015-03-25 16:32:16 +00:00
// Consume all updates in the channel.
2017-04-03 18:32:53 +00:00
numUpdates := manager . consumeUpdates ( )
if numUpdates != expectedUpdates {
t . Errorf ( "unexpected number of updates %d, expected %d" , numUpdates , expectedUpdates )
}
}
func ( m * manager ) consumeUpdates ( ) int {
updates := 0
2015-03-25 16:32:16 +00:00
for {
select {
2017-04-03 18:32:53 +00:00
case syncRequest := <- m . podStatusChannel :
m . syncPod ( syncRequest . podUID , syncRequest . status )
updates ++
2015-03-25 16:32:16 +00:00
default :
2017-04-03 18:32:53 +00:00
return updates
2015-03-25 16:32:16 +00:00
}
}
}
2015-03-20 16:37:08 +00:00
func TestNewStatus ( t * testing . T ) {
2016-02-01 22:30:47 +00:00
syncer := newTestManager ( & fake . Clientset { } )
2016-01-15 09:54:58 +00:00
testPod := getTestPod ( )
2015-03-24 23:52:38 +00:00
syncer . SetPodStatus ( testPod , getRandomPodStatus ( ) )
2015-03-25 16:32:16 +00:00
verifyUpdates ( t , syncer , 1 )
2015-05-09 05:01:43 +00:00
2015-12-04 23:40:33 +00:00
status := expectPodStatus ( t , syncer , testPod )
2015-05-09 05:01:43 +00:00
if status . StartTime . IsZero ( ) {
t . Errorf ( "SetPodStatus did not set a proper start time value" )
}
}
func TestNewStatusPreservesPodStartTime ( t * testing . T ) {
2016-02-01 22:30:47 +00:00
syncer := newTestManager ( & fake . Clientset { } )
2016-11-18 20:50:58 +00:00
pod := & v1 . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2015-05-09 05:01:43 +00:00
UID : "12345678" ,
Name : "foo" ,
Namespace : "new" ,
} ,
2016-11-18 20:50:58 +00:00
Status : v1 . PodStatus { } ,
2015-05-09 05:01:43 +00:00
}
2016-12-03 18:57:26 +00:00
now := metav1 . Now ( )
startTime := metav1 . NewTime ( now . Time . Add ( - 1 * time . Minute ) )
2015-05-09 05:01:43 +00:00
pod . Status . StartTime = & startTime
syncer . SetPodStatus ( pod , getRandomPodStatus ( ) )
2015-12-04 23:40:33 +00:00
status := expectPodStatus ( t , syncer , pod )
2015-05-09 05:01:43 +00:00
if ! status . StartTime . Time . Equal ( startTime . Time ) {
t . Errorf ( "Unexpected start time, expected %v, actual %v" , startTime , status . StartTime )
}
2015-03-20 16:37:08 +00:00
}
2016-11-18 20:50:58 +00:00
func getReadyPodStatus ( ) v1 . PodStatus {
return v1 . PodStatus {
Conditions : [ ] v1 . PodCondition {
2015-09-29 20:04:08 +00:00
{
2016-11-18 20:50:58 +00:00
Type : v1 . PodReady ,
Status : v1 . ConditionTrue ,
2015-09-29 20:04:08 +00:00
} ,
} ,
}
}
func TestNewStatusSetsReadyTransitionTime ( t * testing . T ) {
2016-02-01 22:30:47 +00:00
syncer := newTestManager ( & fake . Clientset { } )
2015-09-29 20:04:08 +00:00
podStatus := getReadyPodStatus ( )
2016-11-18 20:50:58 +00:00
pod := & v1 . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2015-09-29 20:04:08 +00:00
UID : "12345678" ,
Name : "foo" ,
Namespace : "new" ,
} ,
2016-11-18 20:50:58 +00:00
Status : v1 . PodStatus { } ,
2015-09-29 20:04:08 +00:00
}
syncer . SetPodStatus ( pod , podStatus )
verifyUpdates ( t , syncer , 1 )
2015-12-04 23:40:33 +00:00
status := expectPodStatus ( t , syncer , pod )
2017-04-17 17:56:40 +00:00
readyCondition := podutil . GetPodReadyCondition ( status )
2015-09-29 20:04:08 +00:00
if readyCondition . LastTransitionTime . IsZero ( ) {
t . Errorf ( "Unexpected: last transition time not set" )
}
}
2015-03-20 16:37:08 +00:00
func TestChangedStatus ( t * testing . T ) {
2016-02-01 22:30:47 +00:00
syncer := newTestManager ( & fake . Clientset { } )
2016-01-15 09:54:58 +00:00
testPod := getTestPod ( )
2015-03-24 23:52:38 +00:00
syncer . SetPodStatus ( testPod , getRandomPodStatus ( ) )
syncer . SetPodStatus ( testPod , getRandomPodStatus ( ) )
2015-03-25 16:32:16 +00:00
verifyUpdates ( t , syncer , 2 )
2015-03-20 16:37:08 +00:00
}
2015-05-09 05:01:43 +00:00
func TestChangedStatusKeepsStartTime ( t * testing . T ) {
2016-02-01 22:30:47 +00:00
syncer := newTestManager ( & fake . Clientset { } )
2016-01-15 09:54:58 +00:00
testPod := getTestPod ( )
2016-12-03 18:57:26 +00:00
now := metav1 . Now ( )
2015-05-09 05:01:43 +00:00
firstStatus := getRandomPodStatus ( )
firstStatus . StartTime = & now
syncer . SetPodStatus ( testPod , firstStatus )
syncer . SetPodStatus ( testPod , getRandomPodStatus ( ) )
verifyUpdates ( t , syncer , 2 )
2015-12-04 23:40:33 +00:00
finalStatus := expectPodStatus ( t , syncer , testPod )
2015-05-09 05:01:43 +00:00
if finalStatus . StartTime . IsZero ( ) {
t . Errorf ( "StartTime should not be zero" )
}
2016-02-18 02:15:11 +00:00
expected := now . Rfc3339Copy ( )
2017-08-04 15:04:14 +00:00
if ! finalStatus . StartTime . Equal ( & expected ) {
2016-02-18 02:15:11 +00:00
t . Errorf ( "Expected %v, but got %v" , expected , finalStatus . StartTime )
2015-05-09 05:01:43 +00:00
}
}
2015-09-29 20:04:08 +00:00
func TestChangedStatusUpdatesLastTransitionTime ( t * testing . T ) {
2016-02-01 22:30:47 +00:00
syncer := newTestManager ( & fake . Clientset { } )
2015-09-29 20:04:08 +00:00
podStatus := getReadyPodStatus ( )
2016-11-18 20:50:58 +00:00
pod := & v1 . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2015-09-29 20:04:08 +00:00
UID : "12345678" ,
Name : "foo" ,
Namespace : "new" ,
} ,
2016-11-18 20:50:58 +00:00
Status : v1 . PodStatus { } ,
2015-09-29 20:04:08 +00:00
}
syncer . SetPodStatus ( pod , podStatus )
verifyUpdates ( t , syncer , 1 )
2015-12-04 23:40:33 +00:00
oldStatus := expectPodStatus ( t , syncer , pod )
2015-09-29 20:04:08 +00:00
anotherStatus := getReadyPodStatus ( )
2016-11-18 20:50:58 +00:00
anotherStatus . Conditions [ 0 ] . Status = v1 . ConditionFalse
2015-09-29 20:04:08 +00:00
syncer . SetPodStatus ( pod , anotherStatus )
verifyUpdates ( t , syncer , 1 )
2015-12-04 23:40:33 +00:00
newStatus := expectPodStatus ( t , syncer , pod )
2015-09-29 20:04:08 +00:00
2017-04-17 17:56:40 +00:00
oldReadyCondition := podutil . GetPodReadyCondition ( oldStatus )
newReadyCondition := podutil . GetPodReadyCondition ( newStatus )
2015-09-29 20:04:08 +00:00
if newReadyCondition . LastTransitionTime . IsZero ( ) {
t . Errorf ( "Unexpected: last transition time not set" )
}
2017-08-04 15:04:14 +00:00
if newReadyCondition . LastTransitionTime . Before ( & oldReadyCondition . LastTransitionTime ) {
2015-12-09 03:13:09 +00:00
t . Errorf ( "Unexpected: new transition time %s, is before old transition time %s" , newReadyCondition . LastTransitionTime , oldReadyCondition . LastTransitionTime )
2015-09-29 20:04:08 +00:00
}
}
2015-03-20 16:37:08 +00:00
func TestUnchangedStatus ( t * testing . T ) {
2016-02-01 22:30:47 +00:00
syncer := newTestManager ( & fake . Clientset { } )
2016-01-15 09:54:58 +00:00
testPod := getTestPod ( )
2015-03-20 16:37:08 +00:00
podStatus := getRandomPodStatus ( )
2015-03-24 23:52:38 +00:00
syncer . SetPodStatus ( testPod , podStatus )
syncer . SetPodStatus ( testPod , podStatus )
2015-03-25 16:32:16 +00:00
verifyUpdates ( t , syncer , 1 )
}
2015-09-29 20:04:08 +00:00
func TestUnchangedStatusPreservesLastTransitionTime ( t * testing . T ) {
2016-02-01 22:30:47 +00:00
syncer := newTestManager ( & fake . Clientset { } )
2015-09-29 20:04:08 +00:00
podStatus := getReadyPodStatus ( )
2016-11-18 20:50:58 +00:00
pod := & v1 . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2015-09-29 20:04:08 +00:00
UID : "12345678" ,
Name : "foo" ,
Namespace : "new" ,
} ,
2016-11-18 20:50:58 +00:00
Status : v1 . PodStatus { } ,
2015-09-29 20:04:08 +00:00
}
syncer . SetPodStatus ( pod , podStatus )
verifyUpdates ( t , syncer , 1 )
2015-12-04 23:40:33 +00:00
oldStatus := expectPodStatus ( t , syncer , pod )
2015-09-29 20:04:08 +00:00
anotherStatus := getReadyPodStatus ( )
syncer . SetPodStatus ( pod , anotherStatus )
// No update.
verifyUpdates ( t , syncer , 0 )
2015-12-04 23:40:33 +00:00
newStatus := expectPodStatus ( t , syncer , pod )
2015-09-29 20:04:08 +00:00
2017-04-17 17:56:40 +00:00
oldReadyCondition := podutil . GetPodReadyCondition ( oldStatus )
newReadyCondition := podutil . GetPodReadyCondition ( newStatus )
2015-09-29 20:04:08 +00:00
if newReadyCondition . LastTransitionTime . IsZero ( ) {
t . Errorf ( "Unexpected: last transition time not set" )
}
2017-08-04 15:04:14 +00:00
if ! oldReadyCondition . LastTransitionTime . Equal ( & newReadyCondition . LastTransitionTime ) {
2015-09-29 20:04:08 +00:00
t . Errorf ( "Unexpected: new transition time %s, is not equal to old transition time %s" , newReadyCondition . LastTransitionTime , oldReadyCondition . LastTransitionTime )
}
}
2017-04-03 18:32:53 +00:00
func TestSyncPodIgnoresNotFound ( t * testing . T ) {
2016-02-01 22:30:47 +00:00
client := fake . Clientset { }
2015-10-29 21:04:00 +00:00
syncer := newTestManager ( & client )
2016-02-01 22:30:47 +00:00
client . AddReactor ( "get" , "pods" , func ( action core . Action ) ( bool , runtime . Object , error ) {
2015-12-10 18:32:29 +00:00
return true , nil , errors . NewNotFound ( api . Resource ( "pods" ) , "test-pod" )
2015-10-24 01:23:47 +00:00
} )
2016-01-15 09:54:58 +00:00
syncer . SetPodStatus ( getTestPod ( ) , getRandomPodStatus ( ) )
2017-04-03 18:32:53 +00:00
verifyActions ( t , syncer , [ ] core . Action { getAction ( ) } )
2015-07-28 20:06:05 +00:00
}
2017-04-03 18:32:53 +00:00
func TestSyncPod ( t * testing . T ) {
2016-02-01 22:30:47 +00:00
syncer := newTestManager ( & fake . Clientset { } )
2016-01-15 09:54:58 +00:00
testPod := getTestPod ( )
2016-02-01 22:30:47 +00:00
syncer . kubeClient = fake . NewSimpleClientset ( testPod )
2015-03-25 16:32:16 +00:00
syncer . SetPodStatus ( testPod , getRandomPodStatus ( ) )
2017-04-03 18:32:53 +00:00
verifyActions ( t , syncer , [ ] core . Action { getAction ( ) , updateAction ( ) } )
2015-03-20 16:37:08 +00:00
}
2015-06-22 19:31:46 +00:00
2017-04-03 18:32:53 +00:00
func TestSyncPodChecksMismatchedUID ( t * testing . T ) {
2016-02-01 22:30:47 +00:00
syncer := newTestManager ( & fake . Clientset { } )
2016-01-15 09:54:58 +00:00
pod := getTestPod ( )
2015-10-29 21:04:00 +00:00
pod . UID = "first"
2016-01-15 09:54:58 +00:00
syncer . podManager . AddPod ( pod )
differentPod := getTestPod ( )
2015-07-28 20:06:05 +00:00
differentPod . UID = "second"
2016-01-15 09:54:58 +00:00
syncer . podManager . AddPod ( differentPod )
2016-02-01 22:30:47 +00:00
syncer . kubeClient = fake . NewSimpleClientset ( pod )
2016-01-15 09:54:58 +00:00
syncer . SetPodStatus ( differentPod , getRandomPodStatus ( ) )
2017-04-03 18:32:53 +00:00
verifyActions ( t , syncer , [ ] core . Action { getAction ( ) } )
2015-07-28 20:06:05 +00:00
}
2017-04-03 18:32:53 +00:00
func TestSyncPodNoDeadlock ( t * testing . T ) {
2016-02-01 22:30:47 +00:00
client := & fake . Clientset { }
2015-10-29 21:04:00 +00:00
m := newTestManager ( client )
2016-01-15 09:54:58 +00:00
pod := getTestPod ( )
2015-10-24 01:23:47 +00:00
// Setup fake client.
2017-03-13 18:30:20 +00:00
var ret * v1 . Pod
2015-10-24 01:23:47 +00:00
var err error
2016-02-01 22:30:47 +00:00
client . AddReactor ( "*" , "pods" , func ( action core . Action ) ( bool , runtime . Object , error ) {
2015-10-29 21:04:00 +00:00
switch action := action . ( type ) {
2016-02-01 22:30:47 +00:00
case core . GetAction :
2016-01-15 09:54:58 +00:00
assert . Equal ( t , pod . Name , action . GetName ( ) , "Unexpeted GetAction: %+v" , action )
2016-02-01 22:30:47 +00:00
case core . UpdateAction :
2016-11-18 20:50:58 +00:00
assert . Equal ( t , pod . Name , action . GetObject ( ) . ( * v1 . Pod ) . Name , "Unexpeted UpdateAction: %+v" , action )
2015-10-29 21:04:00 +00:00
default :
assert . Fail ( t , "Unexpected Action: %+v" , action )
}
2017-03-13 18:30:20 +00:00
return true , ret , err
2015-10-24 01:23:47 +00:00
} )
2016-11-18 20:50:58 +00:00
pod . Status . ContainerStatuses = [ ] v1 . ContainerStatus { { State : v1 . ContainerState { Running : & v1 . ContainerStateRunning { } } } }
2015-10-24 01:23:47 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Pod not found." )
2017-03-13 18:30:20 +00:00
ret = nil
2015-12-10 18:32:29 +00:00
err = errors . NewNotFound ( api . Resource ( "pods" ) , pod . Name )
2015-10-24 01:23:47 +00:00
m . SetPodStatus ( pod , getRandomPodStatus ( ) )
2017-04-03 18:32:53 +00:00
verifyActions ( t , m , [ ] core . Action { getAction ( ) } )
2015-10-24 01:23:47 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Pod was recreated." )
2017-03-13 18:30:20 +00:00
ret = getTestPod ( )
2015-10-24 01:23:47 +00:00
ret . UID = "other_pod"
err = nil
m . SetPodStatus ( pod , getRandomPodStatus ( ) )
2017-04-03 18:32:53 +00:00
verifyActions ( t , m , [ ] core . Action { getAction ( ) } )
2015-10-24 01:23:47 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Pod not deleted (success case)." )
2017-03-13 18:30:20 +00:00
ret = getTestPod ( )
2015-10-24 01:23:47 +00:00
m . SetPodStatus ( pod , getRandomPodStatus ( ) )
2017-04-03 18:32:53 +00:00
verifyActions ( t , m , [ ] core . Action { getAction ( ) , updateAction ( ) } )
2015-10-24 01:23:47 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Pod is terminated, but still running." )
2016-12-03 18:57:26 +00:00
pod . DeletionTimestamp = new ( metav1 . Time )
2015-10-24 01:23:47 +00:00
m . SetPodStatus ( pod , getRandomPodStatus ( ) )
2017-04-03 18:32:53 +00:00
verifyActions ( t , m , [ ] core . Action { getAction ( ) , updateAction ( ) } )
2015-10-24 01:23:47 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Pod is terminated successfully." )
2015-10-24 01:23:47 +00:00
pod . Status . ContainerStatuses [ 0 ] . State . Running = nil
2016-11-18 20:50:58 +00:00
pod . Status . ContainerStatuses [ 0 ] . State . Terminated = & v1 . ContainerStateTerminated { }
2015-10-24 01:23:47 +00:00
m . SetPodStatus ( pod , getRandomPodStatus ( ) )
2017-04-03 18:32:53 +00:00
verifyActions ( t , m , [ ] core . Action { getAction ( ) , updateAction ( ) } )
2015-10-24 01:23:47 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Error case." )
2017-03-13 18:30:20 +00:00
ret = nil
2015-10-24 01:23:47 +00:00
err = fmt . Errorf ( "intentional test error" )
m . SetPodStatus ( pod , getRandomPodStatus ( ) )
2017-04-03 18:32:53 +00:00
verifyActions ( t , m , [ ] core . Action { getAction ( ) } )
2015-10-24 01:23:47 +00:00
}
func TestStaleUpdates ( t * testing . T ) {
2016-01-15 09:54:58 +00:00
pod := getTestPod ( )
2016-02-01 22:30:47 +00:00
client := fake . NewSimpleClientset ( pod )
2015-10-29 21:04:00 +00:00
m := newTestManager ( client )
2015-10-24 01:23:47 +00:00
2016-11-18 20:50:58 +00:00
status := v1 . PodStatus { Message : "initial status" }
2016-01-15 09:54:58 +00:00
m . SetPodStatus ( pod , status )
2015-10-24 01:23:47 +00:00
status . Message = "first version bump"
2016-01-15 09:54:58 +00:00
m . SetPodStatus ( pod , status )
2015-10-24 01:23:47 +00:00
status . Message = "second version bump"
2016-01-15 09:54:58 +00:00
m . SetPodStatus ( pod , status )
2015-10-24 01:23:47 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "sync batch before syncPods pushes latest status, so we should see three statuses in the channel, but only one update" )
m . syncBatch ( )
verifyUpdates ( t , m , 3 )
verifyActions ( t , m , [ ] core . Action { getAction ( ) , updateAction ( ) } )
t . Logf ( "Nothing left in the channel to sync" )
verifyActions ( t , m , [ ] core . Action { } )
2015-10-24 01:23:47 +00:00
t . Log ( "Unchanged status should not send an update." )
2016-01-15 09:54:58 +00:00
m . SetPodStatus ( pod , status )
2015-10-24 01:23:47 +00:00
verifyUpdates ( t , m , 0 )
t . Log ( "... unless it's stale." )
2017-08-08 12:04:08 +00:00
mirrorPodUID := kubetypes . MirrorPodUID ( pod . UID )
m . apiStatusVersions [ mirrorPodUID ] = m . apiStatusVersions [ mirrorPodUID ] - 1
2015-10-24 01:23:47 +00:00
2016-01-15 09:54:58 +00:00
m . SetPodStatus ( pod , status )
2017-04-03 18:32:53 +00:00
m . syncBatch ( )
verifyActions ( t , m , [ ] core . Action { getAction ( ) , updateAction ( ) } )
2015-10-24 01:23:47 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Nothing stuck in the pipe." )
2015-10-24 01:23:47 +00:00
verifyUpdates ( t , m , 0 )
}
2015-06-22 19:31:46 +00:00
// shuffle returns a new shuffled list of container statuses.
2016-11-18 20:50:58 +00:00
func shuffle ( statuses [ ] v1 . ContainerStatus ) [ ] v1 . ContainerStatus {
2015-06-22 19:31:46 +00:00
numStatuses := len ( statuses )
randIndexes := rand . Perm ( numStatuses )
2016-11-18 20:50:58 +00:00
shuffled := make ( [ ] v1 . ContainerStatus , numStatuses )
2015-06-22 19:31:46 +00:00
for i := 0 ; i < numStatuses ; i ++ {
shuffled [ i ] = statuses [ randIndexes [ i ] ]
}
return shuffled
}
func TestStatusEquality ( t * testing . T ) {
2016-11-18 20:50:58 +00:00
pod := v1 . Pod {
Spec : v1 . PodSpec { } ,
2016-06-06 10:30:56 +00:00
}
2016-11-18 20:50:58 +00:00
containerStatus := [ ] v1 . ContainerStatus { }
2015-06-22 19:31:46 +00:00
for i := 0 ; i < 10 ; i ++ {
2016-11-18 20:50:58 +00:00
s := v1 . ContainerStatus {
2015-06-22 19:31:46 +00:00
Name : fmt . Sprintf ( "container%d" , i ) ,
}
containerStatus = append ( containerStatus , s )
}
2016-11-18 20:50:58 +00:00
podStatus := v1 . PodStatus {
2015-06-22 19:31:46 +00:00
ContainerStatuses : containerStatus ,
}
for i := 0 ; i < 10 ; i ++ {
2016-11-18 20:50:58 +00:00
oldPodStatus := v1 . PodStatus {
2015-06-22 19:31:46 +00:00
ContainerStatuses : shuffle ( podStatus . ContainerStatuses ) ,
}
2016-06-06 10:30:56 +00:00
normalizeStatus ( & pod , & oldPodStatus )
normalizeStatus ( & pod , & podStatus )
2015-06-22 19:31:46 +00:00
if ! isStatusEqual ( & oldPodStatus , & podStatus ) {
2016-02-18 02:15:11 +00:00
t . Fatalf ( "Order of container statuses should not affect normalized equality." )
2015-06-22 19:31:46 +00:00
}
}
}
2015-10-29 21:04:00 +00:00
2016-12-07 20:56:06 +00:00
func TestStatusNormalizationEnforcesMaxBytes ( t * testing . T ) {
pod := v1 . Pod {
Spec : v1 . PodSpec { } ,
}
containerStatus := [ ] v1 . ContainerStatus { }
for i := 0 ; i < 48 ; i ++ {
s := v1 . ContainerStatus {
Name : fmt . Sprintf ( "container%d" , i ) ,
LastTerminationState : v1 . ContainerState {
Terminated : & v1 . ContainerStateTerminated {
Message : strings . Repeat ( "abcdefgh" , int ( 24 + i % 3 ) ) ,
} ,
} ,
}
containerStatus = append ( containerStatus , s )
}
podStatus := v1 . PodStatus {
InitContainerStatuses : containerStatus [ : 24 ] ,
ContainerStatuses : containerStatus [ 24 : ] ,
}
result := normalizeStatus ( & pod , & podStatus )
count := 0
for _ , s := range result . InitContainerStatuses {
l := len ( s . LastTerminationState . Terminated . Message )
if l < 192 || l > 256 {
t . Errorf ( "container message had length %d" , l )
}
count += l
}
if count > kubecontainer . MaxPodTerminationMessageLogLength {
t . Errorf ( "message length not truncated" )
}
}
2016-09-07 21:30:42 +00:00
func TestStaticPod ( t * testing . T ) {
2016-01-15 09:54:58 +00:00
staticPod := getTestPod ( )
2015-10-29 21:04:00 +00:00
staticPod . Annotations = map [ string ] string { kubetypes . ConfigSourceAnnotationKey : "file" }
2016-01-15 09:54:58 +00:00
mirrorPod := getTestPod ( )
2015-10-29 21:04:00 +00:00
mirrorPod . UID = "mirror-12345678"
mirrorPod . Annotations = map [ string ] string {
kubetypes . ConfigSourceAnnotationKey : "api" ,
kubetypes . ConfigMirrorAnnotationKey : "mirror" ,
}
2016-02-01 22:30:47 +00:00
client := fake . NewSimpleClientset ( mirrorPod )
2015-10-29 21:04:00 +00:00
m := newTestManager ( client )
2016-09-07 21:30:42 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Create the static pod" )
2016-01-15 09:54:58 +00:00
m . podManager . AddPod ( staticPod )
assert . True ( t , kubepod . IsStaticPod ( staticPod ) , "SetUp error: staticPod" )
2015-10-29 21:04:00 +00:00
status := getRandomPodStatus ( )
2016-12-03 18:57:26 +00:00
now := metav1 . Now ( )
2015-10-29 21:04:00 +00:00
status . StartTime = & now
2016-01-15 09:54:58 +00:00
m . SetPodStatus ( staticPod , status )
2016-09-07 21:30:42 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Should be able to get the static pod status from status manager" )
2016-01-15 09:54:58 +00:00
retrievedStatus := expectPodStatus ( t , m , staticPod )
2016-06-06 10:30:56 +00:00
normalizeStatus ( staticPod , & status )
2015-10-29 21:04:00 +00:00
assert . True ( t , isStatusEqual ( & status , & retrievedStatus ) , "Expected: %+v, Got: %+v" , status , retrievedStatus )
2016-09-07 21:30:42 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Should not sync pod in syncBatch because there is no corresponding mirror pod for the static pod." )
m . syncBatch ( )
assert . Equal ( t , len ( m . kubeClient . ( * fake . Clientset ) . Actions ( ) ) , 0 , "Expected no updates after syncBatch, got %+v" , m . kubeClient . ( * fake . Clientset ) . Actions ( ) )
2016-09-07 21:30:42 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Create the mirror pod" )
2016-09-07 21:30:42 +00:00
m . podManager . AddPod ( mirrorPod )
assert . True ( t , kubepod . IsMirrorPod ( mirrorPod ) , "SetUp error: mirrorPod" )
2017-08-08 12:04:08 +00:00
assert . Equal ( t , m . podManager . TranslatePodUID ( mirrorPod . UID ) , kubetypes . ResolvedPodUID ( staticPod . UID ) )
2016-09-07 21:30:42 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Should be able to get the mirror pod status from status manager" )
2015-10-29 21:04:00 +00:00
retrievedStatus , _ = m . GetPodStatus ( mirrorPod . UID )
assert . True ( t , isStatusEqual ( & status , & retrievedStatus ) , "Expected: %+v, Got: %+v" , status , retrievedStatus )
2016-09-07 21:30:42 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Should sync pod because the corresponding mirror pod is created" )
verifyActions ( t , m , [ ] core . Action { getAction ( ) , updateAction ( ) } )
2015-10-29 21:04:00 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "syncBatch should not sync any pods because nothing is changed." )
2015-12-09 03:13:09 +00:00
m . testSyncBatch ( )
2017-04-03 18:32:53 +00:00
verifyActions ( t , m , [ ] core . Action { } )
2015-11-14 02:09:17 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Change mirror pod identity." )
2016-01-15 09:54:58 +00:00
m . podManager . DeletePod ( mirrorPod )
2015-11-14 02:09:17 +00:00
mirrorPod . UID = "new-mirror-pod"
2016-11-18 20:50:58 +00:00
mirrorPod . Status = v1 . PodStatus { }
2016-01-15 09:54:58 +00:00
m . podManager . AddPod ( mirrorPod )
2016-06-02 01:47:08 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "Should not update to mirror pod, because UID has changed." )
m . syncBatch ( )
verifyActions ( t , m , [ ] core . Action { getAction ( ) } )
2015-10-29 21:04:00 +00:00
}
2015-11-10 22:00:12 +00:00
2017-02-14 21:36:20 +00:00
func TestTerminatePod ( t * testing . T ) {
syncer := newTestManager ( & fake . Clientset { } )
testPod := getTestPod ( )
2017-04-03 18:32:53 +00:00
t . Logf ( "update the pod's status to Failed. TerminatePod should preserve this status update." )
2017-02-14 21:36:20 +00:00
firstStatus := getRandomPodStatus ( )
firstStatus . Phase = v1 . PodFailed
syncer . SetPodStatus ( testPod , firstStatus )
2017-04-03 18:32:53 +00:00
t . Logf ( "set the testPod to a pod with Phase running, to simulate a stale pod" )
2017-02-14 21:36:20 +00:00
testPod . Status = getRandomPodStatus ( )
testPod . Status . Phase = v1 . PodRunning
syncer . TerminatePod ( testPod )
2017-04-03 18:32:53 +00:00
t . Logf ( "we expect the container statuses to have changed to terminated" )
2017-02-14 21:36:20 +00:00
newStatus := expectPodStatus ( t , syncer , testPod )
for i := range newStatus . ContainerStatuses {
assert . False ( t , newStatus . ContainerStatuses [ i ] . State . Terminated == nil , "expected containers to be terminated" )
}
for i := range newStatus . InitContainerStatuses {
assert . False ( t , newStatus . InitContainerStatuses [ i ] . State . Terminated == nil , "expected init containers to be terminated" )
}
2017-04-03 18:32:53 +00:00
t . Logf ( "we expect the previous status update to be preserved." )
2017-02-14 21:36:20 +00:00
assert . Equal ( t , newStatus . Phase , firstStatus . Phase )
assert . Equal ( t , newStatus . Message , firstStatus . Message )
}
2015-11-10 22:00:12 +00:00
func TestSetContainerReadiness ( t * testing . T ) {
2016-03-23 23:45:24 +00:00
cID1 := kubecontainer . ContainerID { Type : "test" , ID : "1" }
cID2 := kubecontainer . ContainerID { Type : "test" , ID : "2" }
2016-11-18 20:50:58 +00:00
containerStatuses := [ ] v1 . ContainerStatus {
2015-12-04 23:40:33 +00:00
{
Name : "c1" ,
ContainerID : cID1 . String ( ) ,
Ready : false ,
} , {
Name : "c2" ,
ContainerID : cID2 . String ( ) ,
Ready : false ,
} ,
2015-11-10 22:00:12 +00:00
}
2016-11-18 20:50:58 +00:00
status := v1 . PodStatus {
2015-12-04 23:40:33 +00:00
ContainerStatuses : containerStatuses ,
2016-11-18 20:50:58 +00:00
Conditions : [ ] v1 . PodCondition { {
Type : v1 . PodReady ,
Status : v1 . ConditionFalse ,
2015-12-04 23:40:33 +00:00
} } ,
}
2016-01-15 09:54:58 +00:00
pod := getTestPod ( )
2016-11-18 20:50:58 +00:00
pod . Spec . Containers = [ ] v1 . Container { { Name : "c1" } , { Name : "c2" } }
2015-12-04 23:40:33 +00:00
// Verify expected readiness of containers & pod.
2016-11-18 20:50:58 +00:00
verifyReadiness := func ( step string , status * v1 . PodStatus , c1Ready , c2Ready , podReady bool ) {
2015-12-04 23:40:33 +00:00
for _ , c := range status . ContainerStatuses {
switch c . ContainerID {
case cID1 . String ( ) :
if c . Ready != c1Ready {
t . Errorf ( "[%s] Expected readiness of c1 to be %v but was %v" , step , c1Ready , c . Ready )
}
case cID2 . String ( ) :
if c . Ready != c2Ready {
t . Errorf ( "[%s] Expected readiness of c2 to be %v but was %v" , step , c2Ready , c . Ready )
}
default :
t . Fatalf ( "[%s] Unexpected container: %+v" , step , c )
}
}
2016-11-18 20:50:58 +00:00
if status . Conditions [ 0 ] . Type != v1 . PodReady {
2015-12-04 23:40:33 +00:00
t . Fatalf ( "[%s] Unexpected condition: %+v" , step , status . Conditions [ 0 ] )
2016-11-18 20:50:58 +00:00
} else if ready := ( status . Conditions [ 0 ] . Status == v1 . ConditionTrue ) ; ready != podReady {
2015-12-04 23:40:33 +00:00
t . Errorf ( "[%s] Expected readiness of pod to be %v but was %v" , step , podReady , ready )
}
2015-11-10 22:00:12 +00:00
}
2016-02-01 22:30:47 +00:00
m := newTestManager ( & fake . Clientset { } )
2016-02-12 05:02:31 +00:00
// Add test pod because the container spec has been changed.
m . podManager . AddPod ( pod )
2015-11-10 22:00:12 +00:00
t . Log ( "Setting readiness before status should fail." )
2016-02-12 05:02:31 +00:00
m . SetContainerReadiness ( pod . UID , cID1 , true )
2015-11-10 22:00:12 +00:00
verifyUpdates ( t , m , 0 )
2015-12-04 23:40:33 +00:00
if status , ok := m . GetPodStatus ( pod . UID ) ; ok {
t . Errorf ( "Unexpected PodStatus: %+v" , status )
}
2015-11-10 22:00:12 +00:00
t . Log ( "Setting initial status." )
2015-12-04 23:40:33 +00:00
m . SetPodStatus ( pod , status )
2015-11-10 22:00:12 +00:00
verifyUpdates ( t , m , 1 )
2015-12-04 23:40:33 +00:00
status = expectPodStatus ( t , m , pod )
verifyReadiness ( "initial" , & status , false , false , false )
2015-11-10 22:00:12 +00:00
t . Log ( "Setting unchanged readiness should do nothing." )
2016-02-12 05:02:31 +00:00
m . SetContainerReadiness ( pod . UID , cID1 , false )
2015-11-10 22:00:12 +00:00
verifyUpdates ( t , m , 0 )
2015-12-04 23:40:33 +00:00
status = expectPodStatus ( t , m , pod )
verifyReadiness ( "unchanged" , & status , false , false , false )
t . Log ( "Setting container readiness should generate update but not pod readiness." )
2016-02-12 05:02:31 +00:00
m . SetContainerReadiness ( pod . UID , cID1 , true )
2015-12-04 23:40:33 +00:00
verifyUpdates ( t , m , 1 )
status = expectPodStatus ( t , m , pod )
verifyReadiness ( "c1 ready" , & status , true , false , false )
2015-11-10 22:00:12 +00:00
2015-12-04 23:40:33 +00:00
t . Log ( "Setting both containers to ready should update pod readiness." )
2016-02-12 05:02:31 +00:00
m . SetContainerReadiness ( pod . UID , cID2 , true )
2015-11-10 22:00:12 +00:00
verifyUpdates ( t , m , 1 )
2015-12-04 23:40:33 +00:00
status = expectPodStatus ( t , m , pod )
verifyReadiness ( "all ready" , & status , true , true , true )
2015-11-10 22:00:12 +00:00
2016-08-02 22:13:54 +00:00
t . Log ( "Setting non-existent container readiness should fail." )
2016-03-23 23:45:24 +00:00
m . SetContainerReadiness ( pod . UID , kubecontainer . ContainerID { Type : "test" , ID : "foo" } , true )
2015-11-10 22:00:12 +00:00
verifyUpdates ( t , m , 0 )
2015-12-04 23:40:33 +00:00
status = expectPodStatus ( t , m , pod )
2016-08-02 22:13:54 +00:00
verifyReadiness ( "ignore non-existent" , & status , true , true , true )
2015-11-10 22:00:12 +00:00
}
2015-11-25 02:27:43 +00:00
func TestSyncBatchCleanupVersions ( t * testing . T ) {
2016-02-01 22:30:47 +00:00
m := newTestManager ( & fake . Clientset { } )
2016-01-15 09:54:58 +00:00
testPod := getTestPod ( )
mirrorPod := getTestPod ( )
2015-11-25 02:27:43 +00:00
mirrorPod . UID = "mirror-uid"
mirrorPod . Name = "mirror_pod"
mirrorPod . Annotations = map [ string ] string {
kubetypes . ConfigSourceAnnotationKey : "api" ,
kubetypes . ConfigMirrorAnnotationKey : "mirror" ,
}
2017-04-03 18:32:53 +00:00
t . Logf ( "Orphaned pods should be removed." )
2017-08-08 12:04:08 +00:00
m . apiStatusVersions [ kubetypes . MirrorPodUID ( testPod . UID ) ] = 100
m . apiStatusVersions [ kubetypes . MirrorPodUID ( mirrorPod . UID ) ] = 200
2017-04-03 18:32:53 +00:00
m . syncBatch ( )
2017-08-08 12:04:08 +00:00
if _ , ok := m . apiStatusVersions [ kubetypes . MirrorPodUID ( testPod . UID ) ] ; ok {
2015-11-25 02:27:43 +00:00
t . Errorf ( "Should have cleared status for testPod" )
}
2017-08-08 12:04:08 +00:00
if _ , ok := m . apiStatusVersions [ kubetypes . MirrorPodUID ( mirrorPod . UID ) ] ; ok {
2015-11-25 02:27:43 +00:00
t . Errorf ( "Should have cleared status for mirrorPod" )
}
2017-04-03 18:32:53 +00:00
t . Logf ( "Non-orphaned pods should not be removed." )
2015-11-25 02:27:43 +00:00
m . SetPodStatus ( testPod , getRandomPodStatus ( ) )
2016-01-15 09:54:58 +00:00
m . podManager . AddPod ( mirrorPod )
2015-11-25 02:27:43 +00:00
staticPod := mirrorPod
staticPod . UID = "static-uid"
staticPod . Annotations = map [ string ] string { kubetypes . ConfigSourceAnnotationKey : "file" }
2016-01-15 09:54:58 +00:00
m . podManager . AddPod ( staticPod )
2017-08-08 12:04:08 +00:00
m . apiStatusVersions [ kubetypes . MirrorPodUID ( testPod . UID ) ] = 100
m . apiStatusVersions [ kubetypes . MirrorPodUID ( mirrorPod . UID ) ] = 200
2015-12-09 03:13:09 +00:00
m . testSyncBatch ( )
2017-08-08 12:04:08 +00:00
if _ , ok := m . apiStatusVersions [ kubetypes . MirrorPodUID ( testPod . UID ) ] ; ! ok {
2015-11-25 02:27:43 +00:00
t . Errorf ( "Should not have cleared status for testPod" )
}
2017-08-08 12:04:08 +00:00
if _ , ok := m . apiStatusVersions [ kubetypes . MirrorPodUID ( mirrorPod . UID ) ] ; ! ok {
2015-11-25 02:27:43 +00:00
t . Errorf ( "Should not have cleared status for mirrorPod" )
}
}
2015-12-04 23:40:33 +00:00
2015-12-09 03:13:09 +00:00
func TestReconcilePodStatus ( t * testing . T ) {
2016-01-15 09:54:58 +00:00
testPod := getTestPod ( )
2016-02-01 22:30:47 +00:00
client := fake . NewSimpleClientset ( testPod )
2015-12-09 03:13:09 +00:00
syncer := newTestManager ( client )
syncer . SetPodStatus ( testPod , getRandomPodStatus ( ) )
2017-04-03 18:32:53 +00:00
t . Logf ( "Call syncBatch directly to test reconcile" )
2015-12-09 03:13:09 +00:00
syncer . syncBatch ( ) // The apiStatusVersions should be set now
2017-04-03 18:32:53 +00:00
client . ClearActions ( )
2015-12-09 03:13:09 +00:00
podStatus , ok := syncer . GetPodStatus ( testPod . UID )
if ! ok {
2016-06-14 12:04:38 +00:00
t . Fatalf ( "Should find pod status for pod: %#v" , testPod )
2015-12-09 03:13:09 +00:00
}
testPod . Status = podStatus
2017-04-03 18:32:53 +00:00
t . Logf ( "If the pod status is the same, a reconciliation is not needed and syncBatch should do nothing" )
2015-12-09 03:13:09 +00:00
syncer . podManager . UpdatePod ( testPod )
if syncer . needsReconcile ( testPod . UID , podStatus ) {
t . Errorf ( "Pod status is the same, a reconciliation is not needed" )
}
syncer . syncBatch ( )
2017-04-03 18:32:53 +00:00
verifyActions ( t , syncer , [ ] core . Action { } )
2015-12-09 03:13:09 +00:00
// If the pod status is the same, only the timestamp is in Rfc3339 format (lower precision without nanosecond),
// a reconciliation is not needed, syncBatch should do nothing.
// The StartTime should have been set in SetPodStatus().
// TODO(random-liu): Remove this later when api becomes consistent for timestamp.
2017-04-03 18:32:53 +00:00
t . Logf ( "Syncbatch should do nothing, as a reconciliation is not required" )
2015-12-09 03:13:09 +00:00
normalizedStartTime := testPod . Status . StartTime . Rfc3339Copy ( )
testPod . Status . StartTime = & normalizedStartTime
syncer . podManager . UpdatePod ( testPod )
if syncer . needsReconcile ( testPod . UID , podStatus ) {
t . Errorf ( "Pod status only differs for timestamp format, a reconciliation is not needed" )
}
syncer . syncBatch ( )
2017-04-03 18:32:53 +00:00
verifyActions ( t , syncer , [ ] core . Action { } )
2015-12-09 03:13:09 +00:00
2017-04-03 18:32:53 +00:00
t . Logf ( "If the pod status is different, a reconciliation is needed, syncBatch should trigger an update" )
2015-12-09 03:13:09 +00:00
testPod . Status = getRandomPodStatus ( )
syncer . podManager . UpdatePod ( testPod )
if ! syncer . needsReconcile ( testPod . UID , podStatus ) {
t . Errorf ( "Pod status is different, a reconciliation is needed" )
}
syncer . syncBatch ( )
2017-04-03 18:32:53 +00:00
verifyActions ( t , syncer , [ ] core . Action { getAction ( ) , updateAction ( ) } )
2015-12-09 03:13:09 +00:00
}
2016-11-18 20:50:58 +00:00
func expectPodStatus ( t * testing . T , m * manager , pod * v1 . Pod ) v1 . PodStatus {
2015-12-04 23:40:33 +00:00
status , ok := m . GetPodStatus ( pod . UID )
if ! ok {
t . Fatalf ( "Expected PodStatus for %q not found" , pod . UID )
}
return status
}
2016-01-20 00:16:06 +00:00
func TestDeletePods ( t * testing . T ) {
pod := getTestPod ( )
2017-04-03 18:32:53 +00:00
t . Logf ( "Set the deletion timestamp." )
2016-12-03 18:57:26 +00:00
pod . DeletionTimestamp = new ( metav1 . Time )
2016-02-01 22:30:47 +00:00
client := fake . NewSimpleClientset ( pod )
2016-01-20 00:16:06 +00:00
m := newTestManager ( client )
m . podManager . AddPod ( pod )
status := getRandomPodStatus ( )
2016-12-03 18:57:26 +00:00
now := metav1 . Now ( )
2016-01-20 00:16:06 +00:00
status . StartTime = & now
m . SetPodStatus ( pod , status )
2017-04-03 18:32:53 +00:00
t . Logf ( "Expect to see a delete action." )
verifyActions ( t , m , [ ] core . Action { getAction ( ) , updateAction ( ) , deleteAction ( ) } )
2016-01-20 00:16:06 +00:00
}
func TestDoNotDeleteMirrorPods ( t * testing . T ) {
staticPod := getTestPod ( )
staticPod . Annotations = map [ string ] string { kubetypes . ConfigSourceAnnotationKey : "file" }
mirrorPod := getTestPod ( )
mirrorPod . UID = "mirror-12345678"
mirrorPod . Annotations = map [ string ] string {
kubetypes . ConfigSourceAnnotationKey : "api" ,
kubetypes . ConfigMirrorAnnotationKey : "mirror" ,
}
2017-04-03 18:32:53 +00:00
t . Logf ( "Set the deletion timestamp." )
2016-12-03 18:57:26 +00:00
mirrorPod . DeletionTimestamp = new ( metav1 . Time )
2016-02-01 22:30:47 +00:00
client := fake . NewSimpleClientset ( mirrorPod )
2016-01-20 00:16:06 +00:00
m := newTestManager ( client )
m . podManager . AddPod ( staticPod )
m . podManager . AddPod ( mirrorPod )
2017-04-03 18:32:53 +00:00
t . Logf ( "Verify setup." )
2016-01-20 00:16:06 +00:00
assert . True ( t , kubepod . IsStaticPod ( staticPod ) , "SetUp error: staticPod" )
assert . True ( t , kubepod . IsMirrorPod ( mirrorPod ) , "SetUp error: mirrorPod" )
2017-08-08 12:04:08 +00:00
assert . Equal ( t , m . podManager . TranslatePodUID ( mirrorPod . UID ) , kubetypes . ResolvedPodUID ( staticPod . UID ) )
2016-01-20 00:16:06 +00:00
status := getRandomPodStatus ( )
2016-12-03 18:57:26 +00:00
now := metav1 . Now ( )
2016-01-20 00:16:06 +00:00
status . StartTime = & now
m . SetPodStatus ( staticPod , status )
2017-04-03 18:32:53 +00:00
t . Logf ( "Expect not to see a delete action." )
verifyActions ( t , m , [ ] core . Action { getAction ( ) , updateAction ( ) } )
}
func getAction ( ) core . GetAction {
return core . GetActionImpl { ActionImpl : core . ActionImpl { Verb : "get" , Resource : schema . GroupVersionResource { Resource : "pods" } } }
}
func updateAction ( ) core . UpdateAction {
return core . UpdateActionImpl { ActionImpl : core . ActionImpl { Verb : "update" , Resource : schema . GroupVersionResource { Resource : "pods" } , Subresource : "status" } }
}
func deleteAction ( ) core . DeleteAction {
return core . DeleteActionImpl { ActionImpl : core . ActionImpl { Verb : "delete" , Resource : schema . GroupVersionResource { Resource : "pods" } } }
2016-01-20 00:16:06 +00:00
}