github.com/castai/kvisor@v1.7.1-0.20240516114728-b3572a2607b5/cmd/controller/state/imagescan/delta_test.go (about)

     1  package imagescan
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/google/uuid"
     7  	"github.com/stretchr/testify/require"
     8  	corev1 "k8s.io/api/core/v1"
     9  	"k8s.io/apimachinery/pkg/api/resource"
    10  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    11  	"k8s.io/apimachinery/pkg/types"
    12  )
    13  
    14  func TestDelta(t *testing.T) {
    15  	t.Run("upsert images state on delta changes", func(t *testing.T) {
    16  		r := require.New(t)
    17  
    18  		createNode := func(name string) *corev1.Node {
    19  			return &corev1.Node{
    20  				TypeMeta: metav1.TypeMeta{
    21  					Kind:       "Node",
    22  					APIVersion: "v1",
    23  				},
    24  				ObjectMeta: metav1.ObjectMeta{
    25  					Name: name,
    26  				},
    27  				Status: corev1.NodeStatus{
    28  					NodeInfo: corev1.NodeSystemInfo{
    29  						Architecture:    defaultImageArch,
    30  						OperatingSystem: defaultImageOs,
    31  					},
    32  					Allocatable: corev1.ResourceList{
    33  						corev1.ResourceCPU:    resource.MustParse("2"),
    34  						corev1.ResourceMemory: resource.MustParse("4Gi"),
    35  					},
    36  				},
    37  			}
    38  		}
    39  
    40  		createPod := func(imageName, imageID, nodeName string) *corev1.Pod {
    41  			return &corev1.Pod{
    42  				TypeMeta: metav1.TypeMeta{
    43  					Kind:       "Pod",
    44  					APIVersion: "v1",
    45  				},
    46  				ObjectMeta: metav1.ObjectMeta{
    47  					UID: types.UID(uuid.New().String()),
    48  				},
    49  				Spec: corev1.PodSpec{
    50  					Containers: []corev1.Container{
    51  						{
    52  							Name:  "cont",
    53  							Image: imageName,
    54  						},
    55  					},
    56  					NodeName: nodeName,
    57  				},
    58  				Status: corev1.PodStatus{
    59  					Phase: corev1.PodRunning,
    60  					ContainerStatuses: []corev1.ContainerStatus{
    61  						{
    62  							Name:    "cont",
    63  							Image:   imageName,
    64  							ImageID: imageID,
    65  						},
    66  					},
    67  				},
    68  			}
    69  		}
    70  
    71  		delta := newTestDelta()
    72  
    73  		pod1 := createPod("nginx1", "img1", "node1")
    74  		pod2 := createPod("nginx2", "img2", "node1")
    75  		pod3 := createPod("nginx1", "img1", "node2")
    76  
    77  		// Insert nodes.
    78  		delta.Upsert(createNode("node1"))
    79  		delta.Upsert(createNode("node2"))
    80  		// Insert new pods.
    81  		delta.Upsert(pod1)
    82  		delta.Upsert(pod2)
    83  		delta.Upsert(pod3)
    84  		r.Len(delta.images, 2)
    85  		img1 := delta.images["img1amd64nginx1"]
    86  		r.Equal("nginx1", img1.name)
    87  		r.Equal("img1", img1.id)
    88  		r.Len(img1.owners, 2)
    89  
    90  		// Delete single pod. It should be removed only from image nodes list.
    91  		delta.Delete(pod1)
    92  		r.Len(delta.images, 2)
    93  
    94  		// Delete one more pod for the same image. Image should be removed.
    95  		delta.Delete(pod3)
    96  		r.Len(delta.images, 1)
    97  	})
    98  
    99  	t.Run("cleans up image references", func(t *testing.T) {
   100  		r := require.New(t)
   101  		delta := newTestDelta()
   102  
   103  		node := &corev1.Node{
   104  			TypeMeta: metav1.TypeMeta{
   105  				Kind:       "Node",
   106  				APIVersion: "v1",
   107  			},
   108  			ObjectMeta: metav1.ObjectMeta{
   109  				Name: "node1",
   110  			},
   111  			Status: corev1.NodeStatus{
   112  				Allocatable: corev1.ResourceList{
   113  					corev1.ResourceCPU:    resource.MustParse("2"),
   114  					corev1.ResourceMemory: resource.MustParse("4Gi"),
   115  				},
   116  			},
   117  		}
   118  		delta.Upsert(node)
   119  
   120  		pod := &corev1.Pod{
   121  			TypeMeta: metav1.TypeMeta{
   122  				Kind:       "Pod",
   123  				APIVersion: "v1",
   124  			},
   125  			ObjectMeta: metav1.ObjectMeta{
   126  				UID: "123",
   127  			},
   128  			Spec: corev1.PodSpec{
   129  				Containers: []corev1.Container{
   130  					{
   131  						Name:  "test",
   132  						Image: "test",
   133  						Resources: corev1.ResourceRequirements{
   134  							Requests: corev1.ResourceList{
   135  								corev1.ResourceCPU:    resource.MustParse("1"),
   136  								corev1.ResourceMemory: resource.MustParse("2Gi"),
   137  							},
   138  						},
   139  					},
   140  				},
   141  				NodeName: "node1",
   142  			},
   143  			Status: corev1.PodStatus{
   144  				Phase: corev1.PodRunning,
   145  				ContainerStatuses: []corev1.ContainerStatus{
   146  					{
   147  						Name:    "test",
   148  						ImageID: "testid",
   149  					},
   150  				},
   151  			},
   152  		}
   153  
   154  		delta.Upsert(pod)
   155  		img, found := delta.images["testidamd64test"]
   156  		r.True(found)
   157  		r.Len(img.owners, 1)
   158  
   159  		delta.Delete(pod)
   160  		img, found = delta.images["testidamd64test"]
   161  		r.False(found)
   162  	})
   163  }
   164  
   165  func newTestDelta() *deltaState {
   166  	return newDeltaState(&mockKubeController{})
   167  }