github.com/grahambrereton-form3/tilt@v0.10.18/integration/live_update_two_images_one_manifest_test.go (about) 1 //+build integration 2 3 package integration 4 5 import ( 6 "context" 7 "fmt" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func TestLiveUpdateTwoImagesOneManifest(t *testing.T) { 15 // TODO(nick): Re-enable this after 16 // https://app.clubhouse.io/windmill/story/3818/after-a-crash-rebuild-can-t-live-update-because-pod-set-is-inaccurate 17 // is fixed, which i'm pretty sure is the same underlying issue 18 t.SkipNow() 19 20 f := newK8sFixture(t, "live_update_two_images_one_manifest") 21 defer f.TearDown() 22 23 f.TiltWatch() 24 25 sparkleURL := "http://localhost:8100" 26 tadaURL := "http://localhost:8101" 27 28 fmt.Println("> Initial build") 29 30 ctx, cancel := context.WithTimeout(f.ctx, time.Minute) 31 defer cancel() 32 33 initialPods := f.WaitForAllPodsReady(ctx, "app=twoimages") 34 f.CurlUntil(ctx, sparkleURL, "✨ One-Up! ✨\n") 35 f.CurlUntil(ctx, tadaURL, "🎉 One-Up! 🎉\n") 36 37 // Live Update only one 38 fmt.Println("> LiveUpdate 'sparkle'") 39 f.ReplaceContents("./sparkle/index.html", "One-Up", "Two-Up") 40 41 ctx, cancel = context.WithTimeout(f.ctx, time.Minute) 42 defer cancel() 43 f.CurlUntil(ctx, sparkleURL, "✨ Two-Up! ✨\n") 44 f.CurlUntil(ctx, tadaURL, "🎉 One-Up! 🎉\n") 45 46 podsAfterSparkleLiveUpd := f.WaitForAllPodsReady(ctx, "app=twoimages") 47 48 // Assert that the pod was changed in-place / that we did NOT create new pods. 49 assert.Equal(t, initialPods, podsAfterSparkleLiveUpd) 50 51 // Kill the container we didn't LiveUpdate; k8s should quietly replace it, WITHOUT us 52 // doing a crash rebuild (b/c that container didn't have state on it) 53 // We expect the `kill` command to die abnormally when the parent process dies. 54 fmt.Println("> kill 'tada' and wait for container to come back up") 55 _, _ = f.runCommand("kubectl", "exec", podsAfterSparkleLiveUpd[0], "-c=tada", namespaceFlag, 56 "--", "killall", "busybox") 57 58 ctx, cancel = context.WithTimeout(f.ctx, time.Minute) 59 defer cancel() 60 f.CurlUntil(ctx, sparkleURL, "✨ Two-Up! ✨\n") 61 f.CurlUntil(ctx, tadaURL, "🎉 One-Up! 🎉\n") 62 63 podsAfterKillTada := f.WaitForAllPodsReady(ctx, "app=twoimages") 64 assert.Equal(t, initialPods, podsAfterKillTada) 65 66 // Instead of sleeping here, a better way to do this would be to read the engine 67 // state, and make sure that Tilt had up-to-date pod info. But this would 68 // require better APIs for reading Tilt internal state from the outside. 69 fmt.Println("> Sleep for 2s to make sure Pod events reach the engine") 70 time.Sleep(2 * time.Second) 71 72 // Make sure that we can LiveUpdate both at once 73 fmt.Println("> LiveUpdate both services at once") 74 75 f.ReplaceContents("./sparkle/index.html", "Two-Up", "Three-Up") 76 f.ReplaceContents("./tada/index.html", "One-Up", "Three-Up") 77 78 ctx, cancel = context.WithTimeout(f.ctx, time.Minute) 79 defer cancel() 80 f.CurlUntil(ctx, sparkleURL, "✨ Three-Up! ✨\n") 81 f.CurlUntil(ctx, tadaURL, "🎉 Three-Up! 🎉\n") 82 83 ctx, cancel = context.WithTimeout(f.ctx, time.Minute) 84 defer cancel() 85 podsAfterBothLiveUpdate := f.WaitForAllPodsReady(ctx, "app=twoimages") 86 assert.Equal(t, podsAfterKillTada, podsAfterBothLiveUpdate) 87 88 // Kill a container we DID LiveUpdate; we should detect it and do a crash rebuild. 89 fmt.Println("> kill 'sparkle' and wait for crash rebuild") 90 _, _ = f.runCommand("kubectl", "exec", podsAfterBothLiveUpdate[0], "-c=sparkle", namespaceFlag, 91 "--", "killall", "busybox") 92 93 ctx, cancel = context.WithTimeout(f.ctx, time.Minute) 94 defer cancel() 95 f.CurlUntil(ctx, sparkleURL, "✨ Three-Up! ✨\n") 96 f.CurlUntil(ctx, tadaURL, "🎉 Three-Up! 🎉\n") 97 98 ctx, cancel = context.WithTimeout(f.ctx, time.Minute) 99 defer cancel() 100 allPodsAfterKillSparkle := f.WaitForAllPodsReady(f.ctx, "app=twoimages") 101 assert.NotEqual(t, podsAfterBothLiveUpdate, allPodsAfterKillSparkle) 102 }