var _ = Describe("Local", func() { var ( fetcher *repository_fetcher.Local fakeCake *fake_cake.FakeCake defaultRootFSPath string idProvider UnderscoreIDer ) BeforeEach(func() { fakeCake = new(fake_cake.FakeCake) defaultRootFSPath = "" idProvider = UnderscoreIDer{} // default to not containing an image fakeCake.GetReturns(nil, errors.New("no image")) }) JustBeforeEach(func() { fetcher = &repository_fetcher.Local{ Cake: fakeCake, IDProvider: idProvider, DefaultRootFSPath: defaultRootFSPath, } }) Describe("FetchID", func() { It("delegates to the IDProvider", func() { Expect(fetcher.FetchID(&url.URL{Path: "/something/something"})).To(Equal(layercake.DockerImageID("_something_something"))) }) })
}) Context("when the threshold is exceeded", func() { BeforeEach(func() { fakeThreshold.ExceededReturns(true) }) Describe("GC", func() { Context("when there is a single leaf", func() { BeforeEach(func() { fakeCake.GetAllLeavesReturns([]layercake.ID{layercake.DockerImageID("child")}, nil) size[layercake.DockerImageID("child2")] = 2048 }) It("should not remove it when it is used by a container", func() { fakeCake.GetReturns(&image.Image{Container: "used-by-me"}, nil) Expect(gc.GC(logger, fakeCake)).To(Succeed()) Expect(fakeCake.RemoveCallCount()).To(Equal(0)) }) Context("when the layer has no parents", func() { BeforeEach(func() { fakeCake.GetReturns(&image.Image{}, nil) }) It("removes the layer", func() { Expect(gc.GC(logger, fakeCake)).To(Succeed()) Expect(fakeCake.RemoveCallCount()).To(Equal(1)) Expect(fakeCake.RemoveArgsForCall(0)).To(Equal(layercake.DockerImageID("child"))) })
_, err := cakeOrdinator.Metrics(logger, "something", "") Expect(err).To(MatchError("rotten banana")) }) }) }) Describe("Destroy", func() { It("delegates removal", func() { Expect(cakeOrdinator.Destroy(logger, "something", "rootfs")).To(Succeed()) Expect(fakeCake.RemoveCallCount()).To(Equal(1)) Expect(fakeCake.RemoveArgsForCall(0)).To(Equal(layercake.ContainerID("something"))) }) Context("when the layer is already destroyed", func() { It("does not destroy again", func() { fakeCake.GetReturns(nil, errors.New("cannae find it")) Expect(cakeOrdinator.Destroy(logger, "something", "rootfs")).To(Succeed()) Expect(fakeCake.RemoveCallCount()).To(Equal(0)) }) }) Context("when the graph can't retrieve information about the layer", func() { BeforeEach(func() { fakeCake.GetReturns(nil, errors.New("failed tae find it")) }) It("skips destroy and logs the error instead", func() { Expect(cakeOrdinator.Destroy(logger, "something", "rootfs")).To(Succeed()) Expect(logger.LogMessages()).To(ContainElement("test.layer-already-deleted-skipping")) })
. "github.com/onsi/gomega" ) var _ = Describe("AUFSBaseSizer", func() { Describe("BaseSize", func() { var ( baseSizer *quota_manager.AUFSBaseSizer fakeCake *fake_cake.FakeCake logger lager.Logger ) BeforeEach(func() { logger = lagertest.NewTestLogger("test") fakeCake = new(fake_cake.FakeCake) fakeCake.GetReturns(nil, errors.New("no such image")) baseSizer = quota_manager.NewAUFSBaseSizer(fakeCake) }) It("asks for the size of the layer based on the base name of the rootfs path", func() { baseSizer.BaseSize(logger, "/some/path/to/54321") Expect(fakeCake.GetCallCount()).To(Equal(1)) Expect(fakeCake.GetArgsForCall(0)).To(Equal(layercake.DockerImageID("54321"))) }) Context("when the layer doesn't exist", func() { It("returns an error", func() { _, err := baseSizer.BaseSize(logger, "/i/dont/exist") Expect(err).To(HaveOccurred()) })
Expect(err).To(HaveOccurred()) Expect(fakeVolumeCreator.Created).To(BeEmpty()) }) }) }) Context("when the namespace parameter is true", func() { Context("and the image has not been translated yet", func() { var ( mountpoint string envvars []string ) JustBeforeEach(func() { fakeCake.GetReturns(nil, errors.New("no image here")) fakeCake.PathStub = func(id layercake.ID) (string, error) { return "/mount/point/" + id.GraphID(), nil } fakeNamespacer.CacheKeyReturns("jam") var err error mountpoint, envvars, err = provider.Create( lagertest.NewTestLogger("test"), "some-id", &repository_fetcher.Image{ ImageID: "some-image-id", Env: []string{"env1=env1value", "env2=env2value"}, },
}) }) Context("when the image ID is namespaced", func() { It("should delegate to the cake but with an empty parent", func() { cake.CreateReturns(testError) Expect(aufsCake.Create(namespacedChildID, parentID, "")).To(Equal(testError)) Expect(cake.CreateCallCount()).To(Equal(1)) cid, iid, _ := cake.CreateArgsForCall(0) Expect(cid).To(Equal(namespacedChildID)) Expect(iid.GraphID()).To(BeEmpty()) }) Context("when mounting child fails", func() { It("should return the error", func() { cake.GetReturns(nil, testError) Expect(aufsCake.Create(namespacedChildID, parentID, "")).To(Equal(testError)) }) }) Context("when getting parent's path fails", func() { BeforeEach(func() { cake.PathReturns("", testError) }) It("should return the error", func() { Expect(aufsCake.Create(namespacedChildID, parentID, "")).To(Equal(testError)) }) It("should not unmount the parent", func() { Expect(aufsCake.Create(namespacedChildID, parentID, "")).To(Equal(testError))