Пример #1
0
			Context("when the Index is negative", func() {
				BeforeEach(func() {
					actualLRPKey.Index = -1
				})

				It("returns a validation error", func() {
					Expect(actualLRPKey.Validate()).To(ConsistOf(models.ErrInvalidField{"index"}))
				})
			})
		})
	})

	Describe("ActualLRPInstanceKey", func() {
		Describe("Validate", func() {
			var actualLRPInstanceKey models.ActualLRPInstanceKey

			Context("when both instance guid and cell id are specified", func() {
				It("returns nil", func() {
					actualLRPInstanceKey = models.NewActualLRPInstanceKey("instance-guid", "cell-id")
					Expect(actualLRPInstanceKey.Validate()).To(BeNil())
				})
			})

			Context("when both instance guid and cell id are empty", func() {
				It("returns a validation error", func() {
					actualLRPInstanceKey = models.NewActualLRPInstanceKey("", "")
					Expect(actualLRPInstanceKey.Validate()).To(ConsistOf(
						models.ErrInvalidField{"cell_id"},
						models.ErrInvalidField{"instance_guid"},
					))
func (t crashTest) Test() {
	Context(t.Name, func() {
		var (
			crashErr                 error
			actualLRPKey             *models.ActualLRPKey
			instanceKey              *models.ActualLRPInstanceKey
			initialTimestamp         int64
			initialModificationIndex uint32
		)

		BeforeEach(func() {
			actualLRP := t.LRP()
			actualLRPKey = &actualLRP.ActualLRPKey
			instanceKey = &actualLRP.ActualLRPInstanceKey

			initialTimestamp = actualLRP.Since
			initialModificationIndex = actualLRP.ModificationTag.Index

			desiredLRP := models.DesiredLRP{
				ProcessGuid: actualLRPKey.ProcessGuid,
				Domain:      actualLRPKey.Domain,
				Instances:   actualLRPKey.Index + 1,
				RootFs:      "foo:bar",
				Action:      models.WrapAction(&models.RunAction{Path: "true", User: "******"}),
			}

			etcdHelper.SetRawDesiredLRP(&desiredLRP)
			etcdHelper.SetRawActualLRP(&actualLRP)
		})

		JustBeforeEach(func() {
			clock.Increment(600)
			crashErr = etcdDB.CrashActualLRP(logger, actualLRPKey, instanceKey, "crashed")
		})

		if t.Result.ReturnedErr == nil {
			It("does not return an error", func() {
				Expect(crashErr).NotTo(HaveOccurred())
			})
		} else {
			It(fmt.Sprintf("returned error should be '%s'", t.Result.ReturnedErr.Error()), func() {
				Expect(crashErr).To(Equal(t.Result.ReturnedErr))
			})
		}

		It(fmt.Sprintf("has crash count %d", t.Result.CrashCount), func() {
			actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
			Expect(err).NotTo(HaveOccurred())
			Expect(actualLRP.CrashCount).To(Equal(t.Result.CrashCount))
		})

		It(fmt.Sprintf("has crash reason %s", t.Result.CrashReason), func() {
			actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
			Expect(err).NotTo(HaveOccurred())
			Expect(actualLRP.CrashReason).To(Equal(t.Result.CrashReason))
		})

		if t.Result.ShouldUpdate {
			It("updates the Since", func() {
				actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
				Expect(err).NotTo(HaveOccurred())
				Expect(actualLRP.Since).To(Equal(clock.Now().UnixNano()))
			})

			It("updates the ModificationIndex", func() {
				actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
				Expect(err).NotTo(HaveOccurred())
				Expect(actualLRP.ModificationTag.Index).To(Equal(initialModificationIndex + 1))
			})
		} else {
			It("does not update the Since", func() {
				actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
				Expect(err).NotTo(HaveOccurred())
				Expect(actualLRP.Since).To(Equal(initialTimestamp))
			})

			It("does not update the ModificationIndex", func() {
				actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
				Expect(err).NotTo(HaveOccurred())
				Expect(actualLRP.ModificationTag.Index).To(Equal(initialModificationIndex))
			})
		}

		It(fmt.Sprintf("CAS to %s", t.Result.State), func() {
			actualLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey)
			Expect(err).NotTo(HaveOccurred())
			Expect(actualLRP.State).To(Equal(t.Result.State))
		})

		if t.Result.Auction {
			It("starts an auction", func() {
				Expect(fakeAuctioneerClient.RequestLRPAuctionsCallCount()).To(Equal(1))

				requestedAuctions := fakeAuctioneerClient.RequestLRPAuctionsArgsForCall(0)
				Expect(requestedAuctions).To(HaveLen(1))

				desiredLRP, err := etcdDB.DesiredLRPByProcessGuid(logger, actualLRPKey.ProcessGuid)
				Expect(err).NotTo(HaveOccurred())
				expectedStartRequest := auctioneer.NewLRPStartRequestFromModel(desiredLRP, int(actualLRPKey.Index))
				Expect(*requestedAuctions[0]).To(Equal(expectedStartRequest))
			})

			Context("when the desired LRP no longer exists", func() {
				BeforeEach(func() {
					etcdHelper.DeleteDesiredLRP(actualLRPKey.ProcessGuid)
				})

				It("the actual LRP is also deleted", func() {
					Expect(crashErr).NotTo(HaveOccurred())

					_, err := etcdDB.ActualLRPGroupByProcessGuidAndIndex(logger, actualLRPKey.ProcessGuid, actualLRPKey.Index)
					Expect(err).To(Equal(models.ErrResourceNotFound))
				})
			})
		} else {
			It("does not start an auction", func() {
				Expect(fakeAuctioneerClient.RequestLRPAuctionsCallCount()).To(Equal(0))
			})
		}

		Context("when crashing a different instance key", func() {
			var beforeActualGroup *models.ActualLRPGroup

			BeforeEach(func() {
				var err error
				beforeActualGroup, err = etcdDB.ActualLRPGroupByProcessGuidAndIndex(logger, actualLRPKey.ProcessGuid, actualLRPKey.Index)
				Expect(err).NotTo(HaveOccurred())
				instanceKey.InstanceGuid = "another-guid"
			})

			It("does not crash", func() {
				Expect(crashErr).To(Equal(models.ErrActualLRPCannotBeCrashed))

				afterActualGroup, err := etcdDB.ActualLRPGroupByProcessGuidAndIndex(logger, actualLRPKey.ProcessGuid, actualLRPKey.Index)
				Expect(err).NotTo(HaveOccurred())
				Expect(afterActualGroup).To(Equal(beforeActualGroup))
			})
		})
	})
}
Пример #3
0
	"github.com/cloudfoundry-incubator/executor"
	"github.com/cloudfoundry-incubator/rep"
	"github.com/cloudfoundry-incubator/rep/generator"
	"github.com/cloudfoundry-incubator/rep/generator/internal"
	"github.com/cloudfoundry-incubator/rep/generator/internal/fake_internal"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
)

var _ = Describe("Operation", func() {
	Describe("ResidualInstanceLRPOperation", func() {
		var (
			containerDelegate    *fake_internal.FakeContainerDelegate
			residualLRPOperation *generator.ResidualInstanceLRPOperation
			lrpKey               models.ActualLRPKey
			instanceKey          models.ActualLRPInstanceKey

			expectedContainerGuid string
		)

		BeforeEach(func() {
			lrpKey = models.NewActualLRPKey("the-process-guid", 0, "the-domain")
			instanceKey = models.NewActualLRPInstanceKey("the-instance-guid", "the-cell-id")
			containerDelegate = new(fake_internal.FakeContainerDelegate)
			residualLRPOperation = generator.NewResidualInstanceLRPOperation(logger, fakeBBS, containerDelegate, lrpKey, instanceKey)

			expectedContainerGuid = rep.LRPContainerGuid(lrpKey.GetProcessGuid(), instanceKey.GetInstanceGuid())
		})

		Describe("Key", func() {
			It("returns the InstanceGuid", func() {