func (b *LinuxBackend) ApplyLimits(container garden.Container, limits garden.Limits) error { if limits.CPU != (garden.CPULimits{}) { if err := container.LimitCPU(limits.CPU); err != nil { return err } } if limits.Disk != (garden.DiskLimits{}) { if err := container.LimitDisk(limits.Disk); err != nil { return err } } if limits.Bandwidth != (garden.BandwidthLimits{}) { if err := container.LimitBandwidth(limits.Bandwidth); err != nil { return err } } if limits.Memory != (garden.MemoryLimits{}) { if err := container.LimitMemory(limits.Memory); err != nil { return err } } return nil }
ghttp.CombineHandlers( ghttp.VerifyRequest("POST", "/api/containers/containerhandle/cpu_limit"), ghttp.RespondWith(200, `{}`), func(w http.ResponseWriter, req *http.Request) { body, err := ioutil.ReadAll(req.Body) req.Body.Close() Expect(err).ShouldNot(HaveOccurred()) requestBody = string(body) }, ), ) }) It("sets limits on the container", func() { limit := garden.CPULimits{LimitInShares: uint64(50)} err := container.LimitCPU(limit) Expect(err).NotTo(HaveOccurred()) Expect(server.ReceivedRequests()).Should(HaveLen(1)) Expect(requestBody).Should(Equal(`{"limit_in_shares":50}`)) }) }) Context("Containerizer returns non 200", func() { BeforeEach(func() { server.AppendHandlers( ghttp.CombineHandlers( ghttp.VerifyRequest("POST", "/api/containers/containerhandle/cpu_limit"), ghttp.RespondWith(500, "{}"), ), )
BeforeEach(func() { fakeConnection.LimitBandwidthReturns(garden.BandwidthLimits{}, disaster) }) It("returns the error", func() { err := container.LimitBandwidth(garden.BandwidthLimits{}) Ω(err).Should(Equal(disaster)) }) }) }) Describe("LimitCPU", func() { It("sends a limit cpu request", func() { err := container.LimitCPU(garden.CPULimits{ LimitInShares: 1, }) Ω(err).ShouldNot(HaveOccurred()) handle, limits := fakeConnection.LimitCPUArgsForCall(0) Ω(handle).Should(Equal("some-handle")) Ω(limits).Should(Equal(garden.CPULimits{LimitInShares: 1})) }) Context("when the request fails", func() { disaster := errors.New("oh no!") BeforeEach(func() { fakeConnection.LimitCPUReturns(garden.CPULimits{}, disaster) })
BeforeEach(func() { fakeContainer.CurrentDiskLimitsReturns(garden.DiskLimits{}, errors.New("oh no!")) }) It("fails", func() { _, err := container.CurrentDiskLimits() Ω(err).Should(HaveOccurred()) }) }) }) Describe("set the cpu limit", func() { setLimits := garden.CPULimits{123} It("sets the container's CPU shares", func() { err := container.LimitCPU(setLimits) Ω(err).ShouldNot(HaveOccurred()) Ω(fakeContainer.LimitCPUArgsForCall(0)).Should(Equal(setLimits)) }) itResetsGraceTimeWhenHandling(func() { err := container.LimitCPU(setLimits) Ω(err).ShouldNot(HaveOccurred()) }) itFailsWhenTheContainerIsNotFound(func() error { return container.LimitCPU(setLimits) }) Context("when limiting the CPU fails", func() {
BeforeEach(func() { fakeContainer.CurrentDiskLimitsReturns(garden.DiskLimits{}, errors.New("oh no!")) }) It("fails", func() { _, err := container.CurrentDiskLimits() Ω(err).Should(HaveOccurred()) }) }) }) Describe("set the cpu limit", func() { setLimits := garden.CPULimits{123} It("sets the container's CPU shares", func() { err := container.LimitCPU(setLimits) Ω(err).ShouldNot(HaveOccurred()) Ω(fakeContainer.LimitCPUArgsForCall(0)).Should(Equal(setLimits)) }) itResetsGraceTimeWhenHandling(func() { err := container.LimitCPU(setLimits) Ω(err).ShouldNot(HaveOccurred()) }) itFailsWhenTheContainerIsNotFound(func() { err := container.LimitCPU(setLimits) Ω(err).Should(HaveOccurred()) })