<commit_before>package auctionrunner_test

import (
	"errors"

	"code.cloudfoundry.org/auction/auctionrunner"
	"code.cloudfoundry.org/bbs/models"
	"code.cloudfoundry.org/rep"
	"code.cloudfoundry.org/rep/repfakes"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Cell", func() {
	var (
		client          *repfakes.FakeSimClient
		emptyCell, cell *auctionrunner.Cell
	)

	BeforeEach(func() {
		client = &repfakes.FakeSimClient{}
		emptyState := BuildCellState("cellID", 0, "the-zone", 100, 200, 50, false, 0, linuxOnlyRootFSProviders, nil, []string{}, []string{}, []string{}, 0)
		emptyCell = auctionrunner.NewCell(logger, "empty-cell", client, emptyState)

		state := BuildCellState("cellID", 0, "the-zone", 100, 200, 50, false, 10, linuxOnlyRootFSProviders, []rep.LRP{
			*BuildLRP("pg-1", "domain", 0, linuxRootFSURL, 10, 20, 10, []string{}),
			*BuildLRP("pg-1", "domain", 1, linuxRootFSURL, 10, 20, 10, []string{}),
			*BuildLRP("pg-2", "domain", 0, linuxRootFSURL, 10, 20, 10, []string{}),
			*BuildLRP("pg-3", "domain", 0, linuxRootFSURL, 10, 20, 10, []string{}),
			*BuildLRP("pg-4", "domain", 0, linuxRootFSURL, 10, 20, 10, []string{}),
		},
			[]string{},
			[]string{},
			[]string{},
			0,
		)
		cell = auctionrunner.NewCell(logger, "the-cell", client, state)
	})

	Describe("ScoreForLRP", func() {
		It("factors in memory usage", func() {
			bigInstance := BuildLRP("pg-big", "domain", 0, linuxRootFSURL, 20, 10, 10, []string{})
			smallInstance := BuildLRP("pg-small", "domain", 0, linuxRootFSURL, 10, 10, 10, []string{})

			By("factoring in the amount of memory taken up by the instance")
			bigScore, err := emptyCell.ScoreForLRP(bigInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			smallScore, err := emptyCell.ScoreForLRP(smallInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())

			Expect(smallScore).To(BeNumerically("<", bigScore))

			By("factoring in the relative emptiness of Cells")
			emptyScore, err := emptyCell.ScoreForLRP(smallInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			score, err := cell.ScoreForLRP(smallInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			Expect(emptyScore).To(BeNumerically("<", score))
		})

		Context("when the cell has proxies enabled", func() {
			var (
				proxiedCellMemory   int32
				lrpDesiredMemory    int32
				proxyMemoryOverhead int
				proxiedCell         *auctionrunner.Cell
				lrp                 *rep.LRP
			)

			JustBeforeEach(func() {
				proxiedCellState := BuildCellState("cellID", 0, "the-zone", proxiedCellMemory, 200, 50, false, 0, linuxOnlyRootFSProviders, nil, []string{}, []string{}, []string{}, proxyMemoryOverhead)
				proxiedCell = auctionrunner.NewCell(logger, "proxied-cell", client, proxiedCellState)
				lrp = BuildLRP("pg-big", "domain", 0, linuxRootFSURL, lrpDesiredMemory, 10, 10, []string{})
			})

			Context("when there is enough memory for the cell and the proxy", func() {
				BeforeEach(func() {
					proxiedCellMemory = 260
					lrpDesiredMemory = 256
					proxyMemoryOverhead = 4
				})

				It("succeeds placing the lrp", func() {
					score, err := proxiedCell.ScoreForLRP(lrp, 0.0, 0.0)
					Expect(err).NotTo(HaveOccurred())
					Expect(score).To(BeNumerically(">", 0))
				})
			})

			Context("when there is not enough memory for the cell and the proxy", func() {
				BeforeEach(func() {
					proxiedCellMemory = 259
					lrpDesiredMemory = 256
					proxyMemoryOverhead = 4
				})

				It("errors with memory placement error", func() {
					score, err := proxiedCell.ScoreForLRP(lrp, 0.0, 0.0)
					Expect(err).To(HaveOccurred())
					Expect(err.Error()).To(Equal("insufficient resources: memory"))
					Expect(score).To(BeZero())
				})
			})
		})

		It("factors in disk usage", func() {
			bigInstance := BuildLRP("pg-big", "domain", 0, linuxRootFSURL, 10, 20, 10, []string{})
			smallInstance := BuildLRP("pg-small", "domain", 0, linuxRootFSURL, 10, 10, 10, []string{})

			By("factoring in the amount of memory taken up by the instance")
			bigScore, err := emptyCell.ScoreForLRP(bigInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			smallScore, err := emptyCell.ScoreForLRP(smallInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())

			Expect(smallScore).To(BeNumerically("<", bigScore))

			By("factoring in the relative emptiness of Cells")
			emptyScore, err := emptyCell.ScoreForLRP(smallInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			score, err := cell.ScoreForLRP(smallInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			Expect(emptyScore).To(BeNumerically("<", score))
		})

		It("factors in container usage", func() {
			instance := BuildLRP("pg-big", "domain", 0, linuxRootFSURL, 20, 20, 10, []string{})

			bigState := BuildCellState("cellID", 0, "the-zone", 100, 200, 50, false, 0, linuxOnlyRootFSProviders, nil, []string{}, []string{}, []string{}, 0)
			bigCell := auctionrunner.NewCell(logger, "big-cell", client, bigState)

			smallState := BuildCellState("cellID", 0, "the-zone", 100, 200, 20, false, 0, linuxOnlyRootFSProviders, nil, []string{}, []string{}, []string{}, 0)
			smallCell := auctionrunner.NewCell(logger, "small-cell", client, smallState)

			bigScore, err := bigCell.ScoreForLRP(instance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			smallScore, err := smallCell.ScoreForLRP(instance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			Expect(bigScore).To(BeNumerically("<", smallScore), "prefer Cells with more resources")
		})

		Context("Starting Containers", func() {
			var instance *rep.LRP
			var busyState, boredState rep.CellState
			var busyCell, boredCell *auctionrunner.Cell

			BeforeEach(func() {
				instance = BuildLRP("pg-busy", "domain", 0, linuxRootFSURL, 20, 20, 10, []string{})

				busyState = BuildCellState(
					"cellID",
					0,
					"the-zone",
					100,
					200,
					50,
					false,
					10,
					linuxOnlyRootFSProviders,
					[]rep.LRP{{ActualLRPKey: models.ActualLRPKey{ProcessGuid: "not-HA"}}},
					[]string{},
					[]string{},<commit_msg>auctionrunner: add cell test for Bin Pack First Fit algoritm<commit_after>package auctionrunner_test

import (
	"errors"

	"code.cloudfoundry.org/auction/auctionrunner"
	"code.cloudfoundry.org/bbs/models"
	"code.cloudfoundry.org/rep"
	"code.cloudfoundry.org/rep/repfakes"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Cell", func() {
	var (
		client          *repfakes.FakeSimClient
		emptyCell, cell *auctionrunner.Cell
	)

	BeforeEach(func() {
		client = &repfakes.FakeSimClient{}
		emptyState := BuildCellState("cellID", 0, "the-zone", 100, 200, 50, false, 0, linuxOnlyRootFSProviders, nil, []string{}, []string{}, []string{}, 0)
		emptyCell = auctionrunner.NewCell(logger, "empty-cell", client, emptyState)

		state := BuildCellState("cellID", 0, "the-zone", 100, 200, 50, false, 10, linuxOnlyRootFSProviders, []rep.LRP{
			*BuildLRP("pg-1", "domain", 0, linuxRootFSURL, 10, 20, 10, []string{}),
			*BuildLRP("pg-1", "domain", 1, linuxRootFSURL, 10, 20, 10, []string{}),
			*BuildLRP("pg-2", "domain", 0, linuxRootFSURL, 10, 20, 10, []string{}),
			*BuildLRP("pg-3", "domain", 0, linuxRootFSURL, 10, 20, 10, []string{}),
			*BuildLRP("pg-4", "domain", 0, linuxRootFSURL, 10, 20, 10, []string{}),
		},
			[]string{},
			[]string{},
			[]string{},
			0,
		)
		cell = auctionrunner.NewCell(logger, "the-cell", client, state)
	})

	Describe("ScoreForLRP", func() {
		It("factors in memory usage", func() {
			bigInstance := BuildLRP("pg-big", "domain", 0, linuxRootFSURL, 20, 10, 10, []string{})
			smallInstance := BuildLRP("pg-small", "domain", 0, linuxRootFSURL, 10, 10, 10, []string{})

			By("factoring in the amount of memory taken up by the instance")
			bigScore, err := emptyCell.ScoreForLRP(bigInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			smallScore, err := emptyCell.ScoreForLRP(smallInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())

			Expect(smallScore).To(BeNumerically("<", bigScore))

			By("factoring in the relative emptiness of Cells")
			emptyScore, err := emptyCell.ScoreForLRP(smallInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			score, err := cell.ScoreForLRP(smallInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			Expect(emptyScore).To(BeNumerically("<", score))
		})

		Context("when the cell has proxies enabled", func() {
			var (
				proxiedCellMemory   int32
				lrpDesiredMemory    int32
				proxyMemoryOverhead int
				proxiedCell         *auctionrunner.Cell
				lrp                 *rep.LRP
			)

			JustBeforeEach(func() {
				proxiedCellState := BuildCellState("cellID", 0, "the-zone", proxiedCellMemory, 200, 50, false, 0, linuxOnlyRootFSProviders, nil, []string{}, []string{}, []string{}, proxyMemoryOverhead)
				proxiedCell = auctionrunner.NewCell(logger, "proxied-cell", client, proxiedCellState)
				lrp = BuildLRP("pg-big", "domain", 0, linuxRootFSURL, lrpDesiredMemory, 10, 10, []string{})
			})

			Context("when there is enough memory for the cell and the proxy", func() {
				BeforeEach(func() {
					proxiedCellMemory = 260
					lrpDesiredMemory = 256
					proxyMemoryOverhead = 4
				})

				It("succeeds placing the lrp", func() {
					score, err := proxiedCell.ScoreForLRP(lrp, 0.0, 0.0)
					Expect(err).NotTo(HaveOccurred())
					Expect(score).To(BeNumerically(">", 0))
				})
			})

			Context("when there is not enough memory for the cell and the proxy", func() {
				BeforeEach(func() {
					proxiedCellMemory = 259
					lrpDesiredMemory = 256
					proxyMemoryOverhead = 4
				})

				It("errors with memory placement error", func() {
					score, err := proxiedCell.ScoreForLRP(lrp, 0.0, 0.0)
					Expect(err).To(HaveOccurred())
					Expect(err.Error()).To(Equal("insufficient resources: memory"))
					Expect(score).To(BeZero())
				})
			})
		})

		It("factors in disk usage", func() {
			bigInstance := BuildLRP("pg-big", "domain", 0, linuxRootFSURL, 10, 20, 10, []string{})
			smallInstance := BuildLRP("pg-small", "domain", 0, linuxRootFSURL, 10, 10, 10, []string{})

			By("factoring in the amount of memory taken up by the instance")
			bigScore, err := emptyCell.ScoreForLRP(bigInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			smallScore, err := emptyCell.ScoreForLRP(smallInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())

			Expect(smallScore).To(BeNumerically("<", bigScore))

			By("factoring in the relative emptiness of Cells")
			emptyScore, err := emptyCell.ScoreForLRP(smallInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			score, err := cell.ScoreForLRP(smallInstance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			Expect(emptyScore).To(BeNumerically("<", score))
		})

		It("factors in container usage", func() {
			instance := BuildLRP("pg-big", "domain", 0, linuxRootFSURL, 20, 20, 10, []string{})

			bigState := BuildCellState("cellID", 0, "the-zone", 100, 200, 50, false, 0, linuxOnlyRootFSProviders, nil, []string{}, []string{}, []string{}, 0)
			bigCell := auctionrunner.NewCell(logger, "big-cell", client, bigState)

			smallState := BuildCellState("cellID", 0, "the-zone", 100, 200, 20, false, 0, linuxOnlyRootFSProviders, nil, []string{}, []string{}, []string{}, 0)
			smallCell := auctionrunner.NewCell(logger, "small-cell", client, smallState)

			bigScore, err := bigCell.ScoreForLRP(instance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			smallScore, err := smallCell.ScoreForLRP(instance, 0.0, 0.0)
			Expect(err).NotTo(HaveOccurred())
			Expect(bigScore).To(BeNumerically("<", smallScore), "prefer Cells with more resources")
		})

		Context("Weighted Bin Pack First Fit algorithm", func() {
			var instance *rep.LRP
			var cellStateZero, cellStateOne rep.CellState
			var cellZero, cellOne *auctionrunner.Cell

			BeforeEach(func() {
				instance = BuildLRP("pg-0", "domain", 0, linuxRootFSURL, 20, 20, 10, []string{})

				cellStateZero = BuildCellState(
					"cellID",
					0,
					"the-zone",
					100,
					200,
					50,
					false,
					0,
					linuxOnlyRootFSProviders,
					[]rep.LRP{
						*BuildLRP("pg-1", "domain", 0, linuxRootFSURL, 20, 20, 10, []string{}),
					},
					[]string{},
					[]string{},
					[]string{},
					0,
				)
				cellZero = auctionrunner.NewCell(logger, "cell-0", client, cellStateZero)

				cellStateOne = BuildCellState(
					"cellID",
					1,
					"the-zone",
					100,
					200,
					50,
					false,
					0,
					linuxOnlyRootFSProviders,
					[]rep.LRP{
						*BuildLRP("pg-2", "domain", 0, linuxRootFSURL, 20, 20, 10, []string{}),
					},
					[]string{},
					[]string{},
					[]string{},
					0,
				)
				cellOne = auctionrunner.NewCell(logger, "cell-1", client, cellStateOne)
			})

			It("factors in Bin Pack First Fit algorithm when a weight is provided", func() {
				binPackFirstFitWeight := 0.2

				cellZeroScore, err := cellZero.ScoreForLRP(instance, 0.0, binPackFirstFitWeight)
				Expect(err).NotTo(HaveOccurred())
				cellOneScore, err := cellOne.ScoreForLRP(instance, 0.0, binPackFirstFitWeight)
				Expect(err).NotTo(HaveOccurred())

				Expect(cellZeroScore).To(BeNumerically("<", cellOneScore), "prefer Cells that have a lower index number")
			})

			It("privileges spreading LRPs across cells over Bin Pack First Fit algorithm", func() {
				instance = BuildLRP("pg-1", "domain", 1, linuxRootFSURL, 20, 20, 10, []string{})
				binPackFirstFitWeight := 0.2

				cellZeroScore, err := cellZero.ScoreForLRP(instance, 0.0, binPackFirstFitWeight)
				Expect(err).NotTo(HaveOccurred())
				cellOneScore, err := cellOne.ScoreForLRP(instance, 0.0, binPackFirstFitWeight)
				Expect(err).NotTo(HaveOccurred())

				Expect(cellZeroScore).To(BeNumerically(">", cellOneScore), "prefer Cells that do not have an instance of self already running")
			})

			It("ignores Bin Pack First Fit algorithm when a weight is not provided", func() {
				binPackFirstFitWeight := 0.0

				cellZeroScore, err := cellZero.ScoreForLRP(instance, 0.0, binPackFirstFitWeight)
				Expect(err).NotTo(HaveOccurred())
				cellOneScore, err := cellOne.ScoreForLRP(instance, 0.0, binPackFirstFitWeight)
				Expect(err).NotTo(HaveOccurred())

				Expect(cellZeroScore).To(BeNumerically("==", cellOneScore), "ignore Bin Pack First Fit algorithm")
			})
		})

		Context("Starting Containers", func() {
			var instance *rep.LRP
			var busyState, boredState rep.CellState
			var busyCell, boredCell *auctionrunner.Cell

			BeforeEach(func() {
				instance = BuildLRP("pg-busy", "domain", 0, linuxRootFSURL, 20, 20, 10, []string{})

				busyState = BuildCellState(
					"cellID",
					0,
					"the-zone",
					100,
					200,
					50,
					false,
					10,
					linuxOnlyRootFSProviders,
					[]rep.LRP{{ActualLRPKey: models.ActualLRPKey{ProcessGuid: "not-HA"}}},
					[]string{},
					[]string{},
{'fraction_non_alphanumeric': 0.1627528166146328, 'fraction_numerical': 0.03447807791502647, 'mean_word_length': 4.065314541079409, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '742573', 'n_tokens_mistral': 6411, 'n_tokens_neox': 5007, 'n_words': 1157}