@@ -16,6 +16,7 @@ import (
1616 "github.com/codeready-toolchain/toolchain-common/pkg/cluster"
1717 "github.com/codeready-toolchain/toolchain-common/pkg/condition"
1818 "github.com/codeready-toolchain/toolchain-common/pkg/test"
19+ "gopkg.in/h2non/gock.v1"
1920 "k8s.io/apimachinery/pkg/types"
2021 "sigs.k8s.io/controller-runtime/pkg/log/zap"
2122
@@ -46,6 +47,7 @@ const (
4647 RestartCountWithinThresholdContainer2 = 24
4748 RestartCountOverThreshold = 52
4849 TestIdlerTimeOutSeconds = 540
50+ apiEndpoint = "https://api.openshift.com:6443"
4951)
5052
5153func TestReconcile (t * testing.T ) {
@@ -217,9 +219,9 @@ func TestEnsureIdling(t *testing.T) {
217219 StatefulSetScaledUp (podsTooEarlyToKill .statefulSet ).
218220 StatefulSetScaledUp (noise .statefulSet ).
219221 StatefulSetScaledUp (podsCrashLoopingWithinThreshold .statefulSet ).
220- VMRunning (podsRunningForTooLong .virtualmachine ).
221- VMRunning (podsTooEarlyToKill .virtualmachine ).
222- VMRunning (noise .virtualmachine )
222+ VMRunning (podsRunningForTooLong .vmStopCallCounter ).
223+ VMRunning (podsTooEarlyToKill .vmStopCallCounter ).
224+ VMRunning (noise .vmStopCallCounter )
223225
224226 // after golang 1.22 upgrade can use slices.Concat(podsTooEarlyToKill.allPods, podsRunningForTooLong.allPods, podsCrashLooping.allPods, podsCrashLoopingWithinThreshold.allPods)
225227 // Tracked pods
@@ -273,9 +275,9 @@ func TestEnsureIdling(t *testing.T) {
273275 StatefulSetScaledUp (podsTooEarlyToKill .statefulSet ).
274276 StatefulSetScaledUp (noise .statefulSet ).
275277 StatefulSetScaledUp (podsCrashLoopingWithinThreshold .statefulSet ).
276- VMStopped (podsRunningForTooLong .virtualmachine ).
277- VMRunning (podsTooEarlyToKill .virtualmachine ).
278- VMRunning (noise .virtualmachine )
278+ VMStopped (podsRunningForTooLong .vmStopCallCounter ).
279+ VMRunning (podsTooEarlyToKill .vmStopCallCounter ).
280+ VMRunning (noise .vmStopCallCounter )
279281
280282 // Only tracks pods that have not been deleted
281283 memberoperatortest .AssertThatIdler (t , idler .Name , cl ).
@@ -624,6 +626,9 @@ func TestEnsureIdlingFailed(t *testing.T) {
624626 assertCanNotUpdateObject := func (inaccessible runtime.Object , errMsg string ) {
625627 // given
626628 reconciler , req , cl , allCl , dynamicCl := prepareReconcileWithPodsRunningTooLong (t , idler )
629+ gock .Off ()
630+ // mock stop call
631+ mockStopVMCalls (".*" , ".*" , http .StatusInternalServerError )
627632
628633 update := allCl .MockUpdate
629634 defer func () { allCl .MockUpdate = update }()
@@ -661,7 +666,7 @@ func TestEnsureIdlingFailed(t *testing.T) {
661666 assertCanNotUpdateObject (& appsv1.StatefulSet {}, "can't update statefulset" )
662667 assertCanNotUpdateObject (& openshiftappsv1.DeploymentConfig {}, "can't update deploymentconfig" )
663668 assertCanNotUpdateObject (& corev1.ReplicationController {}, "can't update replicationcontroller" )
664- assertCanNotUpdateObject (vm , "can't patch virtualmachine" )
669+ assertCanNotUpdateObject (vm , "an error on the server ( \" \" ) has prevented the request from succeeding (put virtualmachines.authentication.k8s.io alex-stage- virtualmachine) " )
665670 })
666671
667672 t .Run ("can't delete payloads" , func (t * testing.T ) {
@@ -1173,6 +1178,7 @@ type payloads struct {
11731178 replicationController * corev1.ReplicationController
11741179 job * batchv1.Job
11751180 virtualmachine * unstructured.Unstructured
1181+ vmStopCallCounter * int
11761182 virtualmachineinstance * unstructured.Unstructured
11771183}
11781184
@@ -1319,6 +1325,9 @@ func preparePayloads(t *testing.T, r *Reconciler, namespace, namePrefix string,
13191325 _ , err = r .DynamicClient .Resource (vmGVR ).Namespace (namespace ).Create (context .TODO (), vm , metav1.CreateOptions {})
13201326 require .NoError (t , err )
13211327
1328+ // mock stop call
1329+ stopCallCounter := mockStopVMCalls (namespace , vm .GetName (), http .StatusAccepted )
1330+
13221331 // VirtualMachineInstance
13231332 vmstartTime := metav1 .NewTime (startTimes .vmStartTime )
13241333 vmi := & unstructured.Unstructured {}
@@ -1379,10 +1388,30 @@ func preparePayloads(t *testing.T, r *Reconciler, namespace, namePrefix string,
13791388 replicationController : standaloneRC ,
13801389 job : job ,
13811390 virtualmachine : vm ,
1391+ vmStopCallCounter : stopCallCounter ,
13821392 virtualmachineinstance : vmi ,
13831393 }
13841394}
13851395
1396+ func mockStopVMCalls (namespace , name string , reply int ) * int {
1397+ expPath := fmt .Sprintf ("/apis/subresources.kubevirt.io/v1/namespaces/%s/virtualmachines/%s/stop" , namespace , name )
1398+ stopCallCounter := new (int )
1399+ gock .New (apiEndpoint ).
1400+ Put (expPath ).
1401+ Persist ().
1402+ AddMatcher (func (request * http.Request , request2 * gock.Request ) (bool , error ) {
1403+ // the matcher function is called before checking the path,
1404+ // so we need to verify that it's really the same VM
1405+ if request .URL .Path == expPath {
1406+ * stopCallCounter ++
1407+ }
1408+ return true , nil
1409+ }).
1410+ Reply (reply ).
1411+ BodyString ("" )
1412+ return stopCallCounter
1413+ }
1414+
13861415func preparePayloadsSinglePod (t * testing.T , r * Reconciler , namespace , namePrefix string , startTime time.Time , conditions ... corev1.PodCondition ) payloads {
13871416 sTime := metav1 .NewTime (startTime )
13881417
@@ -1563,10 +1592,18 @@ func prepareReconcile(t *testing.T, name string, getHostClusterFunc func(fakeCli
15631592 return true , obj , nil
15641593 })
15651594
1595+ restClient , err := test .NewRESTClient ("dummy-token" , apiEndpoint )
1596+ require .NoError (t , err )
1597+ restClient .Client .Transport = gock .DefaultTransport
1598+ t .Cleanup (func () {
1599+ gock .OffAll ()
1600+ })
1601+
15661602 r := & Reconciler {
15671603 Client : fakeClient ,
15681604 AllNamespacesClient : allNamespacesClient ,
15691605 DynamicClient : dynamicClient ,
1606+ RestClient : restClient ,
15701607 ScalesClient : & scalesClient ,
15711608 Scheme : s ,
15721609 GetHostCluster : getHostClusterFunc (fakeClient ),
0 commit comments