github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/topgun/both/hijack_container_gc_test.go (about)

     1  package topgun_test
     2  
     3  import (
     4  	"time"
     5  
     6  	. "github.com/pf-qiu/concourse/v6/topgun/common"
     7  	_ "github.com/lib/pq"
     8  	. "github.com/onsi/ginkgo"
     9  	. "github.com/onsi/gomega"
    10  	"github.com/onsi/gomega/gbytes"
    11  )
    12  
    13  var _ = Describe("Hijacked containers", func() {
    14  	BeforeEach(func() {
    15  		Deploy("deployments/concourse.yml")
    16  	})
    17  
    18  	getContainer := func(match func(map[string]string) bool) func() hijackedContainerResult {
    19  		return func() (h hijackedContainerResult) {
    20  			containers := FlyTable("containers")
    21  
    22  			var containerHandle string
    23  			for _, c := range containers {
    24  				if match(c) {
    25  					containerHandle = c["handle"]
    26  					h.flyContainerExists = true
    27  
    28  					break
    29  				}
    30  			}
    31  
    32  			_, err := WorkerGardenClient.Lookup(containerHandle)
    33  			if err == nil {
    34  				h.gardenContainerExists = true
    35  			}
    36  
    37  			return
    38  		}
    39  	}
    40  
    41  	It("does not delete hijacked build containers from the database, and sets a 5 minute TTL on the container in garden", func() {
    42  		By("setting the pipeline that has a build")
    43  		Fly.Run("set-pipeline", "-n", "-c", "pipelines/task-waiting.yml", "-p", "hijacked-containers-test")
    44  
    45  		By("triggering the build")
    46  		Fly.Run("unpause-pipeline", "-p", "hijacked-containers-test")
    47  		buildSession := Fly.Start("trigger-job", "-w", "-j", "hijacked-containers-test/simple-job")
    48  		//For the initializing block
    49  		Eventually(buildSession).Should(gbytes.Say("echo 'waiting for /tmp/stop-waiting to exist'"))
    50  		//For the output from the running step
    51  		Eventually(buildSession).Should(gbytes.Say("waiting for /tmp/stop-waiting to exist"))
    52  
    53  		By("hijacking into the build container")
    54  		hijackSession := Fly.Start(
    55  			"hijack",
    56  			"-j", "hijacked-containers-test/simple-job",
    57  			"-b", "1",
    58  			"-s", "simple-task",
    59  			"sleep", "120",
    60  		)
    61  
    62  		By("finishing the build")
    63  		Eventually(func() int {
    64  			hS := Fly.Start(
    65  				"hijack",
    66  				"-j", "hijacked-containers-test/simple-job",
    67  				"-s", "simple-task",
    68  				"touch", "/tmp/stop-waiting",
    69  			)
    70  			<-hS.Exited
    71  			return hS.ExitCode()
    72  		}).Should(Equal(0))
    73  
    74  		<-buildSession.Exited
    75  
    76  		By("triggering a new build")
    77  		buildSession = Fly.Start("trigger-job", "-w", "-j", "hijacked-containers-test/simple-job")
    78  		//For the initializing block
    79  		Eventually(buildSession).Should(gbytes.Say("echo 'waiting for /tmp/stop-waiting to exist'"))
    80  		//For the output from the running step
    81  		Eventually(buildSession).Should(gbytes.Say("waiting for /tmp/stop-waiting to exist"))
    82  
    83  		Eventually(func() int {
    84  			hS := Fly.Start(
    85  				"hijack",
    86  				"-j", "hijacked-containers-test/simple-job",
    87  				"-b", "2",
    88  				"-s", "simple-task",
    89  				"touch", "/tmp/stop-waiting",
    90  			)
    91  			<-hS.Exited
    92  			return hS.ExitCode()
    93  		}).Should(Equal(0))
    94  		<-buildSession.Exited
    95  
    96  		By("verifying the hijacked container exists via fly and Garden")
    97  		Consistently(getContainer(func(c map[string]string) bool {
    98  			return c["build #"] == "1" && c["name"] == "simple-task"
    99  		}), 2*time.Minute, 30*time.Second).Should(Equal(hijackedContainerResult{true, true}))
   100  
   101  		By("unhijacking and seeing the container removed via fly/Garden after 5 minutes")
   102  		hijackSession.Interrupt()
   103  		<-hijackSession.Exited
   104  
   105  		Eventually(getContainer(func(c map[string]string) bool {
   106  			return c["build #"] == "1" && c["name"] == "simple-task"
   107  		}), 10*time.Minute, 30*time.Second).Should(Equal(hijackedContainerResult{false, false}))
   108  	})
   109  
   110  	It("does not delete hijacked one-off build containers from the database, and sets a 5 minute TTL on the container in garden", func() {
   111  		By("triggering a one-off build")
   112  		buildSession := Fly.Start("execute", "-c", "tasks/wait.yml")
   113  		//For the initializing block
   114  		Eventually(buildSession).Should(gbytes.Say("echo 'waiting for /tmp/stop-waiting to exist'"))
   115  		//For the output from the running step
   116  		Eventually(buildSession).Should(gbytes.Say("waiting for /tmp/stop-waiting to exist"))
   117  
   118  		By("hijacking into the build container")
   119  		hijackSession := Fly.Start(
   120  			"hijack",
   121  			"-b", "1",
   122  			"-s", "one-off",
   123  			"--",
   124  			"while true; do sleep 1; done",
   125  		)
   126  
   127  		By("waiting for build to finish")
   128  		Eventually(func() int {
   129  			hS := Fly.Start(
   130  				"hijack",
   131  				"-b", "1",
   132  				"-s", "one-off",
   133  				"touch", "/tmp/stop-waiting",
   134  			)
   135  			<-hS.Exited
   136  			return hS.ExitCode()
   137  		}).Should(Equal(0))
   138  		<-buildSession.Exited
   139  
   140  		By("verifying the hijacked container exists via fly and Garden")
   141  		Consistently(getContainer(func(c map[string]string) bool {
   142  			return c["build #"] == "1" && c["name"] == "one-off"
   143  		}), 2*time.Minute, 30*time.Second).Should(Equal(hijackedContainerResult{true, true}))
   144  
   145  		By("unhijacking and seeing the container removed via fly/Garden after 5 minutes")
   146  		hijackSession.Interrupt()
   147  		<-hijackSession.Exited
   148  
   149  		Eventually(getContainer(func(c map[string]string) bool {
   150  			return c["build #"] == "1" && c["name"] == "one-off"
   151  		}), 10*time.Minute, 30*time.Second).Should(Equal(hijackedContainerResult{false, false}))
   152  	})
   153  
   154  	It("does not delete hijacked resource containers from the database, and sets a 5 minute TTL on the container in garden", func() {
   155  		By("setting the pipeline that has a build")
   156  		Fly.Run("set-pipeline", "-n", "-c", "pipelines/get-task.yml", "-p", "hijacked-resource-test")
   157  		Fly.Run("unpause-pipeline", "-p", "hijacked-resource-test")
   158  
   159  		By("checking resource")
   160  		Fly.Run("check-resource", "-r", "hijacked-resource-test/tick-tock")
   161  
   162  		containers := FlyTable("containers")
   163  		var checkContainerHandle string
   164  		for _, c := range containers {
   165  			if c["type"] == "check" {
   166  				checkContainerHandle = c["handle"]
   167  				break
   168  			}
   169  		}
   170  		Expect(checkContainerHandle).ToNot(BeEmpty())
   171  
   172  		By("hijacking into the resource container")
   173  		hijackSession := Fly.Start(
   174  			"hijack",
   175  			"-c", "hijacked-resource-test/tick-tock",
   176  			"sleep", "120",
   177  		)
   178  
   179  		By("reconfiguring pipeline without resource")
   180  		Fly.Run("set-pipeline", "-n", "-c", "pipelines/task-waiting.yml", "-p", "hijacked-resource-test")
   181  
   182  		By("verifying the hijacked container exists via Garden")
   183  		_, err := WorkerGardenClient.Lookup(checkContainerHandle)
   184  		Expect(err).NotTo(HaveOccurred())
   185  
   186  		By("unhijacking and seeing the container removed via fly/Garden after 5 minutes")
   187  		hijackSession.Interrupt()
   188  		<-hijackSession.Exited
   189  
   190  		Eventually(getContainer(func(c map[string]string) bool {
   191  			return c["type"] == "check"
   192  		}), 10*time.Minute, 30*time.Second).Should(Equal(hijackedContainerResult{false, false}))
   193  	})
   194  })
   195  
   196  type hijackedContainerResult struct {
   197  	flyContainerExists    bool
   198  	gardenContainerExists bool
   199  }