github.com/nmstate/kubernetes-nmstate@v0.82.0/test/e2e/handler/nns_update_timestamp_test.go (about)

     1  /*
     2  Copyright The Kubernetes NMState Authors.
     3  
     4  
     5  Licensed under the Apache License, Version 2.0 (the "License");
     6  you may not use this file except in compliance with the License.
     7  You may obtain a copy of the License at
     8  
     9      http://www.apache.org/licenses/LICENSE-2.0
    10  
    11  Unless required by applicable law or agreed to in writing, software
    12  distributed under the License is distributed on an "AS IS" BASIS,
    13  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  See the License for the specific language governing permissions and
    15  limitations under the License.
    16  */
    17  
    18  package handler
    19  
    20  import (
    21  	"fmt"
    22  	"time"
    23  
    24  	. "github.com/onsi/ginkgo/v2"
    25  	. "github.com/onsi/gomega"
    26  
    27  	"k8s.io/apimachinery/pkg/types"
    28  
    29  	nmstatev1beta1 "github.com/nmstate/kubernetes-nmstate/api/v1beta1"
    30  	nmstatenode "github.com/nmstate/kubernetes-nmstate/pkg/node"
    31  	"github.com/nmstate/kubernetes-nmstate/test/e2e/policy"
    32  )
    33  
    34  const expectedDummyName = "dummy0"
    35  
    36  var _ = Describe("[nns] NNS LastSuccessfulUpdateTime", func() {
    37  	var (
    38  		originalNNSs map[string]nmstatev1beta1.NodeNetworkState
    39  	)
    40  	BeforeEach(func() {
    41  		originalNNSs = map[string]nmstatev1beta1.NodeNetworkState{}
    42  		for _, node := range allNodes {
    43  			key := types.NamespacedName{Name: node}
    44  			originalNNSs[node] = nodeNetworkState(key)
    45  		}
    46  	})
    47  	Context("when network configuration is not changed by a NNCP", func() {
    48  		It("nns should not be updated after reconcile", func() {
    49  			// Give enough time for the NNS to be reconcile(2 interval times)
    50  			interval := 2 * nmstatenode.NetworkStateRefresh
    51  			timeout := 4 * interval
    52  			Eventually(func() error {
    53  				for node, originalNNS := range originalNNSs {
    54  					key := types.NamespacedName{Name: node}
    55  					currentStatus := nodeNetworkState(key).Status
    56  					originalStatus := originalNNS.Status
    57  					if currentStatus.CurrentState.String() == originalStatus.CurrentState.String() {
    58  						Byf("Check LastSuccessfulUpdateTime changed at %s", node)
    59  						Expect(currentStatus.LastSuccessfulUpdateTime).To(Equal(originalStatus.LastSuccessfulUpdateTime))
    60  					} else {
    61  						return fmt.Errorf("Network configuration changed, sending and error to retry")
    62  					}
    63  				}
    64  				return nil
    65  			}, timeout, interval).Should(Succeed())
    66  		})
    67  	})
    68  	Context("when network configuration is changed externally", func() {
    69  		BeforeEach(func() {
    70  			createDummyConnectionAtAllNodes(expectedDummyName)
    71  		})
    72  		AfterEach(func() {
    73  			deleteConnectionAndWait(allNodes, expectedDummyName)
    74  		})
    75  		It("should update it with according to network state refresh duration", func() {
    76  			for node, originalNNS := range originalNNSs {
    77  				Byf("Checking timestamp against original one %s", originalNNS.Status.LastSuccessfulUpdateTime)
    78  				Eventually(
    79  					func() time.Time {
    80  						currentNNS := nodeNetworkState(types.NamespacedName{Name: node})
    81  						return currentNNS.Status.LastSuccessfulUpdateTime.Time
    82  					},
    83  					2*nmstatenode.NetworkStateRefresh,
    84  					10*time.Second,
    85  				).Should(
    86  					BeTemporally(">", originalNNS.Status.LastSuccessfulUpdateTime.Time), "should update it at %s", node,
    87  				)
    88  			}
    89  		})
    90  
    91  	})
    92  	Context("when network configuration is changed by a NNCP", func() {
    93  		BeforeEach(func() {
    94  			// We want to test all the NNS so we apply policies to control-plane and workers
    95  			// (use linuxBrUpNoPorts to not affect the nodes secondary interfaces state)
    96  			setDesiredStateWithPolicyWithoutNodeSelector(TestPolicy, linuxBrUpNoPorts(bridge1))
    97  			policy.WaitForAvailableTestPolicy()
    98  		})
    99  		AfterEach(func() {
   100  			setDesiredStateWithPolicyWithoutNodeSelector(TestPolicy, linuxBrAbsent(bridge1))
   101  			policy.WaitForAvailableTestPolicy()
   102  			deletePolicy(TestPolicy)
   103  		})
   104  		It("should be immediately updated", func() {
   105  			for node, originalNNS := range originalNNSs {
   106  				key := types.NamespacedName{Name: node}
   107  
   108  				Eventually(func() time.Time {
   109  					updatedTime := nodeNetworkState(key).Status.LastSuccessfulUpdateTime
   110  					return updatedTime.Time
   111  				}, time.Second*5, time.Second).Should(BeTemporally(">", originalNNS.Status.LastSuccessfulUpdateTime.Time))
   112  			}
   113  		})
   114  	})
   115  
   116  })