github.com/m-lab/locate@v0.17.6/cmd/heartbeat/health/kubernetes-client_test.go (about)

     1  package health
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"net/url"
     7  	"testing"
     8  
     9  	"github.com/go-test/deep"
    10  	"github.com/m-lab/go/testingx"
    11  	v1 "k8s.io/api/core/v1"
    12  	"k8s.io/client-go/kubernetes"
    13  	"k8s.io/client-go/kubernetes/fake"
    14  )
    15  
    16  var (
    17  	runningPod = &v1.Pod{
    18  		Status: v1.PodStatus{
    19  			Phase: "Running",
    20  		},
    21  	}
    22  	readyNode = &v1.Node{
    23  		Status: v1.NodeStatus{
    24  			Conditions: []v1.NodeCondition{
    25  				{Type: "Ready", Status: "True"},
    26  			},
    27  		},
    28  	}
    29  	healthyClientset = fake.NewSimpleClientset(
    30  		runningPod, readyNode,
    31  	)
    32  )
    33  
    34  func TestKubernetesClient_MustNewKubernetesClient(t *testing.T) {
    35  	u := &url.URL{
    36  		Scheme: "https",
    37  		Host:   "localhost:1234",
    38  	}
    39  	defConfig := getDefaultClientConfig(u, "testdata/")
    40  	restConfig, err := defConfig.ClientConfig()
    41  	testingx.Must(t, err, "failed to create kubernetes config")
    42  	clientset, err := kubernetes.NewForConfig(restConfig)
    43  	testingx.Must(t, err, "failed to create kubernetes clientset")
    44  
    45  	want := &KubernetesClient{
    46  		pod:       "pod",
    47  		node:      "node",
    48  		namespace: "namespace",
    49  		clientset: clientset,
    50  	}
    51  
    52  	got := MustNewKubernetesClient(u, "pod", "node", "namespace", "testdata/")
    53  
    54  	if diff := deep.Equal(got, want); diff != nil {
    55  		t.Errorf("MustNewKubernetesClient() got: %+v, want:: %+v", got, want)
    56  	}
    57  }
    58  
    59  func TestKubernetesClient_isHealthy(t *testing.T) {
    60  	tests := []struct {
    61  		name      string
    62  		clientset kubernetes.Interface
    63  		want      bool
    64  	}{
    65  		{
    66  			name:      "healthy",
    67  			clientset: healthyClientset,
    68  			want:      true,
    69  		},
    70  		{
    71  			name: "pod-not-running",
    72  			clientset: fake.NewSimpleClientset(
    73  				&v1.Pod{
    74  					Status: v1.PodStatus{
    75  						Phase: "Pending",
    76  					},
    77  				},
    78  				readyNode,
    79  			),
    80  			want: false,
    81  		},
    82  		{
    83  			name: "node-not-ready",
    84  			clientset: fake.NewSimpleClientset(
    85  				runningPod,
    86  				&v1.Node{
    87  					Status: v1.NodeStatus{
    88  						Conditions: []v1.NodeCondition{
    89  							{Type: "Ready", Status: "False"},
    90  						},
    91  					},
    92  				},
    93  			),
    94  			want: false,
    95  		},
    96  		{
    97  			name: "node-in-maintenance",
    98  			clientset: fake.NewSimpleClientset(
    99  				runningPod,
   100  				&v1.Node{
   101  					Status: v1.NodeStatus{
   102  						Conditions: []v1.NodeCondition{
   103  							{Type: "Ready", Status: "True"},
   104  						},
   105  					},
   106  					Spec: v1.NodeSpec{
   107  						Taints: []v1.Taint{
   108  							{Key: "lame-duck"},
   109  						},
   110  					},
   111  				},
   112  			),
   113  			want: false,
   114  		},
   115  		{
   116  			name: "pod-call-fail",
   117  			clientset: fake.NewSimpleClientset(
   118  				readyNode,
   119  			),
   120  			want: true,
   121  		},
   122  		{
   123  			name: "node-call-fail",
   124  			clientset: fake.NewSimpleClientset(
   125  				runningPod,
   126  			),
   127  			want: true,
   128  		},
   129  	}
   130  
   131  	for _, tt := range tests {
   132  		t.Run(tt.name, func(t *testing.T) {
   133  			c := &KubernetesClient{
   134  				clientset: tt.clientset,
   135  			}
   136  			if got := c.isHealthy(context.Background()); got != tt.want {
   137  				t.Errorf("KubernetesClient.isHealthy() = %v, want %v", got, tt.want)
   138  			}
   139  		})
   140  	}
   141  }
   142  
   143  func Test_extractError(t *testing.T) {
   144  	tests := []struct {
   145  		name string
   146  		err  error
   147  		want string
   148  	}{
   149  		{
   150  			name: "base-error-only",
   151  			err:  errors.New("context deadline exceeded"),
   152  			want: "context deadline exceeded",
   153  		},
   154  		{
   155  			name: "error-with-pod-info",
   156  			err:  errors.New("Get 'https://api-platform-cluster.mlab-sandbox.measurementlab.net:6443/api/v1/namespaces/default/pods/ndt-virtual-7qzzs': context deadline exceeded"),
   157  			want: "context deadline exceeded",
   158  		},
   159  		{
   160  			name: "unrecognized-error-format",
   161  			err:  errors.New("error 1: error 2: error 3"),
   162  			want: "error 3",
   163  		},
   164  	}
   165  	for _, tt := range tests {
   166  		t.Run(tt.name, func(t *testing.T) {
   167  			if got := extractError(tt.err); got != tt.want {
   168  				t.Errorf("extractError() = %v, want %v", got, tt.want)
   169  			}
   170  		})
   171  	}
   172  }