github.com/grahambrereton-form3/tilt@v0.10.18/internal/k8s/container_test.go (about)

     1  package k8s
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	v1 "k8s.io/api/core/v1"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  
    13  	"github.com/windmilleng/tilt/internal/container"
    14  )
    15  
    16  func TestFixContainerStatusImages(t *testing.T) {
    17  	pod := fakePod(expectedPod, blorgDevImgStr)
    18  	pod.Status = v1.PodStatus{
    19  		ContainerStatuses: []v1.ContainerStatus{
    20  			{
    21  				Name:  "default",
    22  				Image: blorgDevImgStr + "v2",
    23  				Ready: true,
    24  			},
    25  		},
    26  	}
    27  
    28  	assert.NotEqual(t,
    29  		pod.Spec.Containers[0].Image,
    30  		pod.Status.ContainerStatuses[0].Image)
    31  	FixContainerStatusImages(pod)
    32  	assert.Equal(t,
    33  		pod.Spec.Containers[0].Image,
    34  		pod.Status.ContainerStatuses[0].Image)
    35  }
    36  
    37  func TestWaitForContainerAlreadyAlive(t *testing.T) {
    38  	f := newClientTestFixture(t)
    39  
    40  	nt := container.MustParseSelector(blorgDevImgStr)
    41  	podData := fakePod(expectedPod, blorgDevImgStr)
    42  	podData.Status = v1.PodStatus{
    43  		ContainerStatuses: []v1.ContainerStatus{
    44  			{
    45  				ContainerID: "docker://container-id",
    46  				Image:       nt.String(),
    47  				Ready:       true,
    48  			},
    49  		},
    50  	}
    51  	f.addObject(podData)
    52  
    53  	ctx, cancel := context.WithTimeout(f.ctx, time.Second)
    54  	defer cancel()
    55  
    56  	pod, err := f.client.core.Pods("").Get(expectedPod.String(), metav1.GetOptions{})
    57  	if err != nil {
    58  		f.t.Fatal(err)
    59  	}
    60  
    61  	cStatus, err := WaitForContainerReady(ctx, f.client, pod, nt)
    62  	if err != nil {
    63  		t.Fatal(err)
    64  	}
    65  
    66  	cID, err := ContainerIDFromContainerStatus(cStatus)
    67  	if err != nil {
    68  		t.Fatal(err)
    69  	}
    70  
    71  	assert.Equal(t, "container-id", cID.String())
    72  }
    73  
    74  func TestWaitForContainerSuccess(t *testing.T) {
    75  	f := newClientTestFixture(t)
    76  	f.addObject(&fakePodList)
    77  
    78  	nt := container.MustParseTaggedSelector(blorgDevImgStr)
    79  	pod, err := f.client.core.Pods("").Get(expectedPod.String(), metav1.GetOptions{})
    80  	if err != nil {
    81  		f.t.Fatal(err)
    82  	}
    83  
    84  	ctx, cancel := context.WithTimeout(f.ctx, time.Second)
    85  	defer cancel()
    86  
    87  	result := make(chan error)
    88  	go func() {
    89  		_, err := WaitForContainerReady(ctx, f.client, pod, nt)
    90  		result <- err
    91  	}()
    92  
    93  	newPod := fakePod(expectedPod, blorgDevImgStr)
    94  	newPod.Status = v1.PodStatus{
    95  		ContainerStatuses: []v1.ContainerStatus{
    96  			{
    97  				ContainerID: "docker://container-id",
    98  				Image:       nt.String(),
    99  				Ready:       true,
   100  			},
   101  		},
   102  	}
   103  
   104  	<-f.watchNotify
   105  	f.updatePod(newPod)
   106  	err = <-result
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  }
   111  
   112  func TestWaitForContainerFailure(t *testing.T) {
   113  	f := newClientTestFixture(t)
   114  	f.addObject(&fakePodList)
   115  
   116  	nt := container.MustParseTaggedSelector(blorgDevImgStr)
   117  	pod, err := f.client.core.Pods("").Get(expectedPod.String(), metav1.GetOptions{})
   118  	if err != nil {
   119  		f.t.Fatal(err)
   120  	}
   121  
   122  	ctx, cancel := context.WithTimeout(f.ctx, time.Second)
   123  	defer cancel()
   124  
   125  	result := make(chan error)
   126  	go func() {
   127  		_, err := WaitForContainerReady(ctx, f.client, pod, nt)
   128  		result <- err
   129  	}()
   130  
   131  	newPod := fakePod(expectedPod, blorgDevImgStr)
   132  	newPod.Status = v1.PodStatus{
   133  		ContainerStatuses: []v1.ContainerStatus{
   134  			{
   135  				Image: nt.String(),
   136  				State: v1.ContainerState{
   137  					Terminated: &v1.ContainerStateTerminated{},
   138  				},
   139  			},
   140  		},
   141  	}
   142  
   143  	<-f.watchNotify
   144  	f.updatePod(newPod)
   145  	err = <-result
   146  
   147  	expected := "Container will never be ready"
   148  	if err == nil || !strings.Contains(err.Error(), expected) {
   149  		t.Fatalf("Expected error %q, actual: %v", expected, err)
   150  	}
   151  }
   152  
   153  func TestWaitForContainerUnschedulable(t *testing.T) {
   154  	f := newClientTestFixture(t)
   155  	f.addObject(&fakePodList)
   156  
   157  	nt := container.MustParseTaggedSelector(blorgDevImgStr)
   158  	pod, err := f.client.core.Pods("").Get(expectedPod.String(), metav1.GetOptions{})
   159  	if err != nil {
   160  		f.t.Fatal(err)
   161  	}
   162  
   163  	ctx, cancel := context.WithTimeout(f.ctx, time.Second)
   164  	defer cancel()
   165  
   166  	result := make(chan error)
   167  	go func() {
   168  		_, err := WaitForContainerReady(ctx, f.client, pod, nt)
   169  		result <- err
   170  	}()
   171  
   172  	newPod := fakePod(expectedPod, blorgDevImgStr)
   173  	newPod.Status = v1.PodStatus{
   174  		Conditions: []v1.PodCondition{
   175  			{
   176  				Reason:  v1.PodReasonUnschedulable,
   177  				Message: "0/4 nodes are available: 4 Insufficient cpu.",
   178  				Status:  "False",
   179  				Type:    v1.PodScheduled,
   180  			},
   181  		},
   182  	}
   183  
   184  	<-f.watchNotify
   185  	f.updatePod(newPod)
   186  	err = <-result
   187  
   188  	expected := "Container will never be ready: 0/4 nodes are available: 4 Insufficient cpu."
   189  	if err == nil || !strings.Contains(err.Error(), expected) {
   190  		t.Fatalf("Expected error %q, actual: %v", expected, err)
   191  	}
   192  }