Example #1
0
	var child2parent map[layercake.ID]layercake.ID // child -> parent

	BeforeEach(func() {
		fakeCake = new(fake_cake.FakeCake)
		fakeRetainer = new(fake_retainer.FakeRetainer)
		gc = &layercake.OvenCleaner{
			Cake:     fakeCake,
			Retainer: fakeRetainer,
			Logger:   lagertest.NewTestLogger("test"),
		}

		child2parent = make(map[layercake.ID]layercake.ID)
		fakeCake.GetStub = func(id layercake.ID) (*image.Image, error) {
			if parent, ok := child2parent[id]; ok {
				return &image.Image{ID: id.GraphID(), Parent: parent.GraphID()}, nil
			}

			return &image.Image{}, nil
		}

		fakeCake.IsLeafStub = func(id layercake.ID) (bool, error) {
			for _, p := range child2parent {
				if p == id {
					return false, nil
				}
			}

			return true, nil
		}

		fakeCake.RemoveStub = func(id layercake.ID) error {
		retainer = new(fake_retainer.FakeRetainer)
		fetcher = &RemoteV2Fetcher{
			Cake:      cake,
			Retainer:  retainer,
			GraphLock: lock,
		}

		cake.GetReturns(nil, errors.New("no image"))
	})

	It("retains the layers before getting them, to ensure they are not deleted after we decide to use cache", func() {
		setupSuccessfulV2Fetch(server, false)

		retained := make(map[layercake.ID]bool)
		cake.GetStub = func(id layercake.ID) (*image.Image, error) {
			Expect(retained).To(HaveKey(id))
			return nil, errors.New("no layer")
		}

		retainer.RetainStub = func(id layercake.ID) {
			retained[id] = true
		}

		fetcher.Fetch(fetchRequest)
	})

	It("releases all the layers after fetching", func() {
		setupSuccessfulV2Fetch(server, false)

		released := make(map[layercake.ID]bool)
		retainer.ReleaseStub = func(id layercake.ID) {
			released[id] = true
				})
			})

			Context("and the image has already been translated", func() {
				BeforeEach(func() {
					fakeRepositoryFetcher.FetchResult = "some-image-id"
					fakeCake.PathStub = func(id layercake.ID) (string, error) {
						return "/mount/point/" + id.GraphID(), nil
					}

					fakeNamespacer.CacheKeyReturns("sandwich")

					fakeCake.GetStub = func(id layercake.ID) (*image.Image, error) {
						if id == (layercake.NamespacedLayerID{"some-image-id", "sandwich"}) {
							return &image.Image{}, nil
						}

						return nil, errors.New("hello")
					}

				})

				It("reuses the translated layer", func() {
					mountpoint, envvars, err := provider.ProvideRootFS(
						logger,
						"some-id",
						parseURL("docker:///some-repository-name"),
						true,
						0,
					)
					Expect(err).ToNot(HaveOccurred())
		fetcher = &RemoteV1Fetcher{
			Cake:      cake,
			Retainer:  retainer,
			GraphLock: lock,
		}

		cake.GetReturns(&image.Image{}, nil)
	})

	It("retains all the layers before starting", func() {
		setupSuccessfulFetch(endpoint1Server)

		retained := make(map[layercake.ID]bool)
		cake.GetStub = func(id layercake.ID) (*image.Image, error) {
			Expect(retained).To(HaveKey(layercake.DockerImageID("layer-1")))
			Expect(retained).To(HaveKey(layercake.DockerImageID("layer-2")))
			Expect(retained).To(HaveKey(layercake.DockerImageID("layer-3")))
			return nil, errors.New("no layer")
		}

		retainer.RetainStub = func(id layercake.ID) {
			retained[id] = true
		}

		fetcher.Fetch(fetchRequest)
	})

	It("releases all the layers after fetching", func() {
		setupSuccessfulFetch(endpoint1Server)

		released := make(map[layercake.ID]bool)
		retainer.ReleaseStub = func(id layercake.ID) {