...

Source file src/github.com/linkerd/linkerd2/pkg/k8s/api_test.go

Documentation: github.com/linkerd/linkerd2/pkg/k8s

     1  package k8s
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	corev1 "k8s.io/api/core/v1"
     8  )
     9  
    10  func TestGetPodStatus(t *testing.T) {
    11  	scenarios := []struct {
    12  		desc     string
    13  		pod      string
    14  		expected string
    15  	}{
    16  		{
    17  			desc:     "Pod is running",
    18  			expected: "Running",
    19  			pod: `
    20  apiVersion: v1
    21  kind: Pod
    22  metadata:
    23    name: emoji
    24    namespace: emojivoto
    25    labels:
    26      app: emoji-svc
    27      linkerd.io/control-plane-ns: linkerd
    28  status:
    29    phase: Running
    30  `,
    31  		},
    32  		{
    33  			desc:     "Pod with proxy native sidecar is running",
    34  			expected: "Running",
    35  			pod: `
    36  apiVersion: v1
    37  kind: Pod
    38  metadata:
    39    name: emoji
    40    namespace: emojivoto
    41    labels:
    42      app: emoji-svc
    43      linkerd.io/control-plane-ns: linkerd
    44  spec:
    45      initContainers:
    46      - name: linkerd-proxy
    47        restartPolicy: Always
    48  status:
    49    phase: Running
    50    initContainerStatuses:
    51    - name: linkerd-proxy
    52      ready: true
    53      started: true
    54  `,
    55  		},
    56  		{
    57  			desc:     "Pod's reason is filled",
    58  			expected: "podReason",
    59  			pod: `
    60  apiVersion: v1
    61  kind: Pod
    62  metadata:
    63    name: emoji
    64    namespace: emojivoto
    65    labels:
    66      app: emoji-svc
    67      linkerd.io/control-plane-ns: linkerd
    68  status:
    69    phase: Pending
    70    reason: podReason
    71  `,
    72  		},
    73  		{
    74  			desc:     "Pod waiting is filled",
    75  			expected: "CrashLoopBackOff",
    76  			pod: `
    77  apiVersion: v1
    78  kind: Pod
    79  metadata:
    80    name: emoji
    81    namespace: emojivoto
    82    labels:
    83      app: emoji-svc
    84      linkerd.io/control-plane-ns: linkerd
    85  status:
    86    phase: Pending
    87    reason: podReason
    88    containerStatuses:
    89    - state:
    90        waiting:
    91          reason: CrashLoopBackOff
    92  `,
    93  		},
    94  		{
    95  			desc:     "Pod is terminated",
    96  			expected: "podTerminated",
    97  			pod: `
    98  apiVersion: v1
    99  kind: Pod
   100  metadata:
   101    name: emoji
   102    namespace: emojivoto
   103    labels:
   104      app: emoji-svc
   105      linkerd.io/control-plane-ns: linkerd
   106  status:
   107    phase: Pending
   108    reason: podReason
   109    containerStatuses:
   110    - state:
   111        terminated:
   112          reason: podTerminated
   113          exitCode: 2
   114  `,
   115  		},
   116  		{
   117  			desc:     "Pod terminated with signal",
   118  			expected: "Signal:9",
   119  			pod: `
   120  apiVersion: v1
   121  kind: Pod
   122  metadata:
   123    name: emoji
   124    namespace: emojivoto
   125    labels:
   126      app: emoji-svc
   127      linkerd.io/control-plane-ns: linkerd
   128  status:
   129    phase: Pending
   130    reason: podReason
   131    containerStatuses:
   132    - state:
   133        terminated:
   134          signal: 9
   135  `,
   136  		},
   137  		{
   138  			desc:     "Pod terminated with exti code",
   139  			expected: "ExitCode:2",
   140  			pod: `
   141  apiVersion: v1
   142  kind: Pod
   143  metadata:
   144    name: emoji
   145    namespace: emojivoto
   146    labels:
   147      app: emoji-svc
   148      linkerd.io/control-plane-ns: linkerd
   149  status:
   150    phase: Pending
   151    reason: podReason
   152    containerStatuses:
   153    - state:
   154        terminated:
   155          exitCode: 2
   156  `,
   157  		},
   158  		{
   159  			desc:     "Pod has a running container",
   160  			expected: "Running",
   161  			pod: `
   162  apiVersion: v1
   163  kind: Pod
   164  metadata:
   165    name: emoji
   166    namespace: emojivoto
   167    labels:
   168      app: emoji-svc
   169      linkerd.io/control-plane-ns: linkerd
   170  status:
   171    phase: Running
   172    reason: Completed
   173    containerStatuses:
   174    - ready: true
   175      state:
   176        running:
   177          startedAt: 1995-02-10T00:42:42Z
   178  `,
   179  		},
   180  		{
   181  			desc:     "Pod init container terminated with exit code 0",
   182  			expected: "Running",
   183  			pod: `
   184  apiVersion: v1
   185  kind: Pod
   186  metadata:
   187    name: emoji
   188    namespace: emojivoto
   189    labels:
   190      app: emoji-svc
   191      linkerd.io/control-plane-ns: linkerd
   192  spec:
   193      initContainers:
   194      - name: foo
   195  status:
   196    phase: Running
   197    containerStatuses:
   198    - state:
   199        running:
   200          startedAt: 1995-02-10T00:42:42Z
   201    initContainerStatuses:
   202    - name: foo
   203      state:
   204        terminated:
   205          exitCode: 0
   206          reason: Completed
   207  `,
   208  		},
   209  		{
   210  			desc:     "Pod init container terminated with exit code 2",
   211  			expected: "Init:ExitCode:2",
   212  			pod: `
   213  apiVersion: v1
   214  kind: Pod
   215  metadata:
   216    name: emoji
   217    namespace: emojivoto
   218    labels:
   219      app: emoji-svc
   220      linkerd.io/control-plane-ns: linkerd
   221  spec:
   222      initContainers:
   223      - name: foo
   224      containers:
   225      - name: bar
   226  status:
   227    phase: Running
   228    containerStatuses:
   229    - name: bar
   230      state:
   231        running:
   232          startedAt: 1995-02-10T00:42:42Z
   233    initContainerStatuses:
   234    - name: foo
   235      state:
   236        terminated:
   237          exitCode: 2
   238  `,
   239  		},
   240  		{
   241  			desc:     "Pod init container terminated with signal",
   242  			expected: "Init:Signal:9",
   243  			pod: `
   244  apiVersion: v1
   245  kind: Pod
   246  metadata:
   247    name: emoji
   248    namespace: emojivoto
   249    labels:
   250      app: emoji-svc
   251      linkerd.io/control-plane-ns: linkerd
   252  spec:
   253      initContainers:
   254      - name: foo
   255      containers:
   256      - name: bar
   257  status:
   258    phase: Running
   259    containerStatuses:
   260    - name: bar
   261      state:
   262        running:
   263          startedAt: 1995-02-10T00:42:42Z
   264    initContainerStatuses:
   265    - name: foo
   266      state:
   267        terminated:
   268          signal: 9
   269  `,
   270  		},
   271  		{
   272  			desc:     "Pod init container in CrashLooBackOff",
   273  			expected: "Init:CrashLoopBackOff",
   274  			pod: `
   275  apiVersion: v1
   276  kind: Pod
   277  metadata:
   278    name: emoji
   279    namespace: emojivoto
   280    labels:
   281      app: emoji-svc
   282      linkerd.io/control-plane-ns: linkerd
   283  spec:
   284      initContainers:
   285      - name: foo
   286  status:
   287    phase: Pending
   288    initContainerStatuses:
   289    - name: foo
   290      state:
   291        terminated:
   292          exitCode: 2
   293          reason: CrashLoopBackOff
   294  `,
   295  		},
   296  		{
   297  			desc:     "Pod init container waiting for someReason",
   298  			expected: "Init:someReason",
   299  			pod: `
   300  apiVersion: v1
   301  kind: Pod
   302  metadata:
   303    name: emoji
   304    namespace: emojivoto
   305    labels:
   306      app: emoji-svc
   307      linkerd.io/control-plane-ns: linkerd
   308  spec:
   309      initContainers:
   310      - name: foo
   311  status:
   312    phase: Pending
   313    initContainerStatuses:
   314    - name: foo
   315      state:
   316        waiting:
   317          reason: someReason
   318  `,
   319  		},
   320  		{
   321  			desc:     "Pod init container is waiting on PodInitializing",
   322  			expected: "Init:0/1",
   323  			pod: `
   324  apiVersion: v1
   325  kind: Pod
   326  metadata:
   327    name: emoji
   328    namespace: emojivoto
   329    labels:
   330      app: emoji-svc
   331      linkerd.io/control-plane-ns: linkerd
   332  spec:
   333      initContainers:
   334      - name: foo
   335  status:
   336    phase: Pending
   337    initContainerStatuses:
   338    - name: foo
   339      state:
   340        waiting:
   341          reason: PodInitializing
   342  `,
   343  		},
   344  	}
   345  	for _, s := range scenarios {
   346  		obj, err := ToRuntimeObject(s.pod)
   347  		if err != nil {
   348  			t.Fatalf("could not decode yml: %s", err)
   349  		}
   350  		pod, ok := obj.(*corev1.Pod)
   351  		if !ok {
   352  			t.Fatalf("could not convert returned object to pod")
   353  		}
   354  
   355  		got := GetPodStatus(*pod)
   356  		if s.expected != got {
   357  			t.Fatalf("Wrong pod status on '%s'. Expected '%s', got '%s'", s.desc, s.expected, got)
   358  		}
   359  	}
   360  }
   361  
   362  func TestGetPodsFor(t *testing.T) {
   363  
   364  	configs := []string{
   365  		// pod-1
   366  		`apiVersion: v1
   367  kind: Pod
   368  metadata:
   369    name: pod-1
   370    namespace: ns
   371    uid: pod-1
   372    labels:
   373      app: foo
   374    ownerReferences:
   375    - apiVersion: apps/v1
   376      controller: true
   377      kind: ReplicaSet
   378      name: rs-1
   379      uid: rs-1
   380  `,
   381  		// rs-1
   382  		`apiVersion: apps/v1
   383  kind: ReplicaSet
   384  metadata:
   385    name: rs-1
   386    namespace: ns
   387    uid: rs-1
   388    labels:
   389      app: foo
   390    ownerReferences:
   391    - apiVersion: apps/v1
   392      controller: true
   393      kind: Deployment
   394      name: deploy-1
   395      uid: deploy-1
   396  spec:
   397    selector:
   398      matchLabels:
   399        app: foo
   400  `,
   401  		// deploy-1
   402  		`apiVersion: apps/v1
   403  kind: Deployment
   404  metadata:
   405    name: deploy-1
   406    namespace: ns
   407    uid: deploy-1
   408  spec:
   409    selector:
   410      matchLabels:
   411        app: foo
   412  `,
   413  		// pod-2
   414  		`apiVersion: v1
   415  kind: Pod
   416  metadata:
   417    name: pod-2
   418    namespace: ns
   419    uid: pod-2
   420    labels:
   421      app: foo
   422    ownerReferences:
   423    - apiVersion: apps/v1
   424      controller: true
   425      kind: ReplicaSet
   426      name: rs-2
   427      uid: rs-2
   428  `,
   429  		// rs-2
   430  		`apiVersion: apps/v1
   431  kind: ReplicaSet
   432  metadata:
   433    name: rs-2
   434    namespace: ns
   435    uid: rs-2
   436    labels:
   437      app: foo
   438    ownerReferences:
   439    - apiVersion: apps/v1
   440      controller: true
   441      kind: Deployment
   442      name: deploy-2
   443      uid: deploy-2
   444  spec:
   445    selector:
   446      matchLabels:
   447       app: foo
   448  `,
   449  		// deploy-2
   450  		`apiVersion: apps/v1
   451  kind: Deployment
   452  metadata:
   453    name: deploy-2
   454    namespace: ns
   455    uid: deploy-2
   456  spec:
   457    selector:
   458      matchLabels:
   459        app: foo
   460  `}
   461  
   462  	k8sClient, err := NewFakeAPI(configs...)
   463  	if err != nil {
   464  		t.Fatalf("Unexpected error %s", err)
   465  	}
   466  
   467  	// Both pod-1 and pod-2 have labels which match deploy-1's selector.
   468  	// However, only pod-1 is owned by deploy-1 according to the owner references.
   469  	// Owner references should be considered authoritative to resolve ambiguity
   470  	// when deployments have overlapping seletors.
   471  	pods, err := GetPodsFor(context.Background(), k8sClient, "ns", "deploy/deploy-1")
   472  	if err != nil {
   473  		t.Fatalf("Unexpected error %s", err)
   474  	}
   475  
   476  	if len(pods) != 1 {
   477  		for _, p := range pods {
   478  			t.Logf("%s/%s", p.Namespace, p.Name)
   479  		}
   480  		t.Fatalf("Expected 1 pod, got %d", len(pods))
   481  	}
   482  }
   483  

View as plain text