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

     1  package topgun_test
     2  
     3  import (
     4  	"strings"
     5  	"time"
     6  
     7  	. "github.com/pf-qiu/concourse/v6/topgun/common"
     8  	_ "github.com/lib/pq"
     9  	. "github.com/onsi/ginkgo"
    10  	. "github.com/onsi/gomega"
    11  	"github.com/onsi/gomega/gbytes"
    12  )
    13  
    14  var _ = Describe("Garbage collecting resource cache volumes", func() {
    15  	Describe("A resource that was removed from pipeline", func() {
    16  		BeforeEach(func() {
    17  			Deploy("deployments/concourse.yml")
    18  		})
    19  
    20  		It("has its resource cache, resource cache uses and resource cache volumes cleared out", func() {
    21  			By("setting pipeline that creates resource cache")
    22  			Fly.Run("set-pipeline", "-n", "-c", "pipelines/get-task-changing-resource.yml", "-p", "volume-gc-test")
    23  
    24  			By("unpausing the pipeline")
    25  			Fly.Run("unpause-pipeline", "-p", "volume-gc-test")
    26  
    27  			By("triggering the job")
    28  			Fly.Run("trigger-job", "-w", "-j", "volume-gc-test/simple-job")
    29  
    30  			By("getting the resource cache volumes")
    31  			Expect(VolumesByResourceType("time")).To(HaveLen(1))
    32  
    33  			By("updating pipeline and removing resource")
    34  			Fly.Run("set-pipeline", "-n", "-c", "pipelines/task-waiting.yml", "-p", "volume-gc-test")
    35  
    36  			By("eventually expiring the resource cache volumes")
    37  			Eventually(func() int {
    38  				return len(VolumesByResourceType("time"))
    39  			}, 5*time.Minute, 10*time.Second).Should(BeZero())
    40  		})
    41  	})
    42  
    43  	Describe("A resource that was updated", func() {
    44  		BeforeEach(func() {
    45  			Deploy("deployments/concourse.yml")
    46  		})
    47  
    48  		It("has its resource cache, resource cache uses and resource cache volumes cleared out", func() {
    49  			By("setting pipeline that creates resource cache")
    50  			Fly.Run("set-pipeline", "-n", "-c", "pipelines/get-task.yml", "-p", "volume-gc-test")
    51  
    52  			By("unpausing the pipeline")
    53  			Fly.Run("unpause-pipeline", "-p", "volume-gc-test")
    54  
    55  			By("triggering the job")
    56  			Fly.Run("trigger-job", "-w", "-j", "volume-gc-test/simple-job")
    57  
    58  			By("getting the resource cache volumes")
    59  			volumes := FlyTable("volumes")
    60  			originalResourceVolumeHandles := []string{}
    61  			for _, volume := range volumes {
    62  				if volume["type"] == "resource" && strings.HasPrefix(volume["identifier"], "time:") {
    63  					originalResourceVolumeHandles = append(originalResourceVolumeHandles, volume["handle"])
    64  				}
    65  			}
    66  			Expect(originalResourceVolumeHandles).To(HaveLen(1))
    67  
    68  			By("updating pipeline and removing resource")
    69  			Fly.Run("set-pipeline", "-n", "-c", "pipelines/get-task-changing-resource.yml", "-p", "volume-gc-test")
    70  
    71  			By("eventually expiring the resource cache volumes")
    72  			Eventually(func() []string {
    73  				return VolumesByResourceType("time")
    74  			}, 5*time.Minute, 10*time.Second).ShouldNot(ContainElement(originalResourceVolumeHandles[0]))
    75  		})
    76  	})
    77  
    78  	Describe("A resource in paused pipeline", func() {
    79  		BeforeEach(func() {
    80  			Deploy("deployments/concourse.yml")
    81  		})
    82  
    83  		It("has its resource cache, resource cache uses and resource cache volumes cleared out", func() {
    84  			By("setting pipeline that creates resource cache")
    85  			Fly.Run("set-pipeline", "-n", "-c", "pipelines/get-task-changing-resource.yml", "-p", "volume-gc-test")
    86  
    87  			By("unpausing the pipeline")
    88  			Fly.Run("unpause-pipeline", "-p", "volume-gc-test")
    89  
    90  			By("triggering the job")
    91  			Fly.Run("trigger-job", "-w", "-j", "volume-gc-test/simple-job")
    92  
    93  			By("getting the resource cache volumes")
    94  			volumes := FlyTable("volumes")
    95  			resourceVolumeHandles := []string{}
    96  			for _, volume := range volumes {
    97  				if volume["type"] == "resource" && strings.HasPrefix(volume["identifier"], "time:") {
    98  					resourceVolumeHandles = append(resourceVolumeHandles, volume["handle"])
    99  				}
   100  			}
   101  			Expect(resourceVolumeHandles).To(HaveLen(1))
   102  
   103  			By("pausing the pipeline")
   104  			Fly.Run("pause-pipeline", "-p", "volume-gc-test")
   105  
   106  			By("eventually expiring the resource cache volumes")
   107  			Eventually(func() int {
   108  				return len(VolumesByResourceType("time"))
   109  			}, 5*time.Minute, 10*time.Second).Should(BeZero())
   110  		})
   111  	})
   112  
   113  	Describe("a resource that has new versions", func() {
   114  		BeforeEach(func() {
   115  			Deploy("deployments/concourse.yml")
   116  		})
   117  
   118  		It("has its old resource cache, old resource cache uses and old resource cache volumes cleared out", func() {
   119  			By("setting pipeline that creates resource cache")
   120  			Fly.Run("set-pipeline", "-n", "-c", "pipelines/get-resource.yml", "-p", "volume-gc-test")
   121  
   122  			By("unpausing the pipeline")
   123  			Fly.Run("unpause-pipeline", "-p", "volume-gc-test")
   124  
   125  			By("triggering the job")
   126  			Fly.Run("trigger-job", "-w", "-j", "volume-gc-test/simple-job")
   127  
   128  			By("locating the cache")
   129  			volumes := FlyTable("volumes")
   130  			var firstCacheHandle string
   131  			for _, volume := range volumes {
   132  				if volume["type"] == "resource" && volume["identifier"] == "version:first-version" {
   133  					firstCacheHandle = volume["handle"]
   134  				}
   135  			}
   136  			Expect(firstCacheHandle).ToNot(BeEmpty(), "should have found a resource cache volume")
   137  
   138  			By("creating a new resource version")
   139  			Fly.Run("check-resource", "-r", "volume-gc-test/some-resource", "-f", "version:second-version")
   140  
   141  			By("triggering the job")
   142  			Fly.Run("trigger-job", "-w", "-j", "volume-gc-test/simple-job")
   143  
   144  			By("eventually expiring the resource cache volume")
   145  			Eventually(func() []string {
   146  				volumes := FlyTable("volumes")
   147  				resourceVolumeHandles := []string{}
   148  				for _, volume := range volumes {
   149  					if volume["type"] == "resource" && strings.HasPrefix(volume["identifier"], "version:") {
   150  						resourceVolumeHandles = append(resourceVolumeHandles, volume["handle"])
   151  					}
   152  				}
   153  				return resourceVolumeHandles
   154  			}, 10*time.Minute, 10*time.Second).ShouldNot(ContainElement(firstCacheHandle))
   155  		})
   156  	})
   157  
   158  	Describe("resource cache is not reaped when being used by a build", func() {
   159  		BeforeEach(func() {
   160  			Deploy("deployments/concourse.yml", "-o", "operations/fast-gc.yml")
   161  		})
   162  
   163  		It("finds the resource cache volumes throughout duration of build", func() {
   164  			By("setting pipeline that creates resource cache")
   165  			Fly.Run("set-pipeline", "-n", "-c", "pipelines/get-resource-and-wait.yml", "-p", "volume-gc-test")
   166  
   167  			By("unpausing the pipeline")
   168  			Fly.Run("unpause-pipeline", "-p", "volume-gc-test")
   169  
   170  			By("triggering the job")
   171  			watchSession := Fly.Start("trigger-job", "-w", "-j", "volume-gc-test/simple-job")
   172  			Eventually(watchSession).Should(gbytes.Say("waiting for /tmp/stop-waiting"))
   173  
   174  			By("locating the cache")
   175  			volumes := FlyTable("volumes")
   176  			var firstCacheHandle string
   177  			for _, volume := range volumes {
   178  				if volume["type"] == "resource" && volume["identifier"] == "version:first-version" {
   179  					firstCacheHandle = volume["handle"]
   180  				}
   181  			}
   182  			Expect(firstCacheHandle).ToNot(BeEmpty(), "should have found a resource cache volume")
   183  
   184  			By("creating a new resource version")
   185  			Fly.Run("check-resource", "-r", "volume-gc-test/some-resource", "-f", "version:second-version")
   186  
   187  			By("not expiring the resource cache volume for the ongoing build")
   188  			Consistently(func() []string {
   189  				volumes := FlyTable("volumes")
   190  				resourceVolumeHandles := []string{}
   191  				for _, volume := range volumes {
   192  					if volume["type"] == "resource" && volume["identifier"] == "version:first-version" {
   193  						resourceVolumeHandles = append(resourceVolumeHandles, volume["handle"])
   194  					}
   195  				}
   196  				return resourceVolumeHandles
   197  			}).Should(ConsistOf([]string{firstCacheHandle}))
   198  
   199  			By("hijacking the build to tell it to finish")
   200  			Fly.Run(
   201  				"hijack",
   202  				"-j", "volume-gc-test/simple-job",
   203  				"-s", "wait",
   204  				"touch", "/tmp/stop-waiting",
   205  			)
   206  
   207  			By("waiting for the build to exit")
   208  			Eventually(watchSession, 1*time.Minute).Should(gbytes.Say("done"))
   209  			<-watchSession.Exited
   210  			Expect(watchSession.ExitCode()).To(Equal(0))
   211  
   212  			By("eventually expiring the resource cache volume")
   213  			Eventually(func() []string {
   214  				volumes := FlyTable("volumes")
   215  				resourceVolumeHandles := []string{}
   216  				for _, volume := range volumes {
   217  					if volume["type"] == "resource" && volume["identifier"] == "version:first-version" {
   218  						resourceVolumeHandles = append(resourceVolumeHandles, volume["handle"])
   219  					}
   220  				}
   221  				return resourceVolumeHandles
   222  			}).ShouldNot(ContainElement(firstCacheHandle))
   223  		})
   224  	})
   225  })