github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/controllers/core/dockercomposelogstream/reconciler_test.go (about) 1 package dockercomposelogstream 2 3 import ( 4 "strings" 5 "testing" 6 "time" 7 8 dtypes "github.com/docker/docker/api/types" 9 "github.com/stretchr/testify/assert" 10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 12 "github.com/tilt-dev/tilt/internal/container" 13 "github.com/tilt-dev/tilt/internal/controllers/fake" 14 "github.com/tilt-dev/tilt/internal/docker" 15 "github.com/tilt-dev/tilt/internal/dockercompose" 16 "github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1" 17 ) 18 19 // Make sure we stream logs correctly when 20 // we're triggered by a project event. 21 func TestBasicLogsFromEvents(t *testing.T) { 22 f := newFixture(t) 23 24 output := make(chan string, 1) 25 defer close(output) 26 27 containerID := "my-container-id" 28 f.dc.ContainerLogChans[containerID] = output 29 f.dcc.ContainerIDDefault = container.ID(containerID) 30 31 obj := v1alpha1.DockerComposeLogStream{ 32 ObjectMeta: metav1.ObjectMeta{ 33 Name: "fe", 34 }, 35 Spec: v1alpha1.DockerComposeLogStreamSpec{ 36 Service: "fe", 37 Project: v1alpha1.DockerComposeProject{ 38 YAML: "fake-yaml", 39 }, 40 }, 41 } 42 f.Create(&obj) 43 44 container := dtypes.ContainerState{ 45 Status: "running", 46 Running: true, 47 StartedAt: "2021-09-08T19:58:01.483005100Z", 48 } 49 f.dc.Containers[containerID] = container 50 51 event := dockercompose.Event{Type: dockercompose.TypeContainer, ID: containerID, Service: "fe"} 52 f.dcc.SendEvent(event) 53 54 expected := "hello world" 55 output <- expected 56 57 assert.Eventually(t, func() bool { 58 return strings.Contains(f.Stdout(), expected) 59 }, time.Second, 10*time.Millisecond) 60 } 61 62 // Make sure we stream logs correctly when 63 // we're connecting to an existing project. 64 func TestBasicLogsFromExisting(t *testing.T) { 65 f := newFixture(t) 66 67 output := make(chan string, 1) 68 defer close(output) 69 70 containerID := "my-container-id" 71 f.dc.ContainerLogChans[containerID] = output 72 c := dtypes.ContainerState{ 73 Status: "running", 74 Running: true, 75 StartedAt: "2021-09-08T19:58:01.483005100Z", 76 } 77 f.dc.Containers[containerID] = c 78 f.dcc.ContainerIDDefault = container.ID(containerID) 79 80 obj := v1alpha1.DockerComposeLogStream{ 81 ObjectMeta: metav1.ObjectMeta{ 82 Name: "fe", 83 }, 84 Spec: v1alpha1.DockerComposeLogStreamSpec{ 85 Service: "fe", 86 Project: v1alpha1.DockerComposeProject{ 87 YAML: "fake-yaml", 88 }, 89 }, 90 } 91 f.Create(&obj) 92 93 expected := "hello world" 94 output <- expected 95 96 assert.Eventually(t, func() bool { 97 return strings.Contains(f.Stdout(), expected) 98 }, time.Second, 10*time.Millisecond) 99 } 100 101 func TestTwoServices(t *testing.T) { 102 f := newFixture(t) 103 104 feContainerID := "fe-id" 105 beContainerID := "be-id" 106 107 feOutput := make(chan string, 1) 108 defer close(feOutput) 109 f.dc.ContainerLogChans[feContainerID] = feOutput 110 f.dcc.ContainerIDByService["fe"] = container.ID(feContainerID) 111 112 beOutput := make(chan string, 1) 113 defer close(beOutput) 114 f.dc.ContainerLogChans[beContainerID] = beOutput 115 f.dcc.ContainerIDByService["be"] = container.ID(beContainerID) 116 117 project := v1alpha1.DockerComposeProject{ 118 YAML: "fake-yaml", 119 } 120 121 fe := v1alpha1.DockerComposeLogStream{ 122 ObjectMeta: metav1.ObjectMeta{ 123 Name: "fe", 124 }, 125 Spec: v1alpha1.DockerComposeLogStreamSpec{ 126 Service: "fe", 127 Project: project, 128 }, 129 } 130 f.Create(&fe) 131 132 be := v1alpha1.DockerComposeLogStream{ 133 ObjectMeta: metav1.ObjectMeta{ 134 Name: "be", 135 }, 136 Spec: v1alpha1.DockerComposeLogStreamSpec{ 137 Service: "be", 138 Project: project, 139 }, 140 } 141 142 container := dtypes.ContainerState{ 143 Status: "running", 144 Running: true, 145 StartedAt: "2021-09-08T19:58:01.483005100Z", 146 } 147 f.dc.Containers[feContainerID] = container 148 f.dc.Containers[beContainerID] = container 149 150 f.dcc.SendEvent(dockercompose.Event{Type: dockercompose.TypeContainer, ID: feContainerID, Service: "fe"}) 151 f.dcc.SendEvent(dockercompose.Event{Type: dockercompose.TypeContainer, ID: beContainerID, Service: "be"}) 152 153 // Create the BE log stream later, and make sure everything's OK. 154 f.Create(&be) 155 expected := "hello backend" 156 beOutput <- expected 157 158 assert.Eventually(t, func() bool { 159 return strings.Contains(f.Stdout(), expected) 160 }, time.Second, 10*time.Millisecond) 161 } 162 163 type fixture struct { 164 *fake.ControllerFixture 165 r *Reconciler 166 dc *docker.FakeClient 167 dcc *dockercompose.FakeDCClient 168 } 169 170 func newFixture(t *testing.T) *fixture { 171 cfb := fake.NewControllerFixtureBuilder(t) 172 dcCli := dockercompose.NewFakeDockerComposeClient(t, cfb.Context()) 173 dCli := docker.NewFakeClient() 174 r := NewReconciler(cfb.Client, cfb.Store, dcCli, dCli) 175 176 return &fixture{ 177 ControllerFixture: cfb.WithRequeuer(r.requeuer).Build(r), 178 r: r, 179 dc: dCli, 180 dcc: dcCli, 181 } 182 }