func (t crashTest) Test() { Context(t.Name, func() { var ( crashErr error shouldRestart bool actualLRPKey *models.ActualLRPKey instanceKey *models.ActualLRPInstanceKey initialTimestamp int64 initialModificationIndex uint32 beforeActualGroup, afterActualGroup *models.ActualLRPGroup ) 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) beforeActualGroup, afterActualGroup, shouldRestart, 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)) }) It("returns the existing and new actual lrp", func() { actualLRP := t.LRP() actualLRP.Since = 0 beforeActualGroup.Instance.Since = 0 Expect(beforeActualGroup).To(Equal(&models.ActualLRPGroup{Instance: &actualLRP})) newLRP, err := etcdHelper.GetInstanceActualLRP(actualLRPKey) Expect(err).NotTo(HaveOccurred()) Expect(afterActualGroup.Instance).To(Equal(newLRP)) }) } 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(shouldRestart).To(BeTrue()) }) } else { It("does not start an auction", func() { Expect(shouldRestart).To(BeFalse()) }) } 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)) }) }) }) }
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"}, ))