for i := 0; i < 19; i++ { testError := fmt.Errorf("test error") runner.AddCmdResult(",,L\n sfdisk -uM /dev/sda", fakesys.FakeCmdResult{ExitStatus: 1, Error: testError}) } runner.AddCmdResult("sfdisk -d /dev/sda", fakesys.FakeCmdResult{Stdout: devSdaSfdiskDumpOnePartition}) runner.AddCmdResult("sfdisk -s /dev/sda", fakesys.FakeCmdResult{Stdout: "1048576"}) runner.AddCmdResult(",,L\n sfdisk -uM /dev/sda", fakesys.FakeCmdResult{Stdout: devSdaSfdiskDumpOnePartition}) partitions := []Partition{ {Type: PartitionTypeLinux}, } err := partitioner.Partition("/dev/sda", partitions) Expect(err).To(BeNil()) Expect(fakeclock.SleepCallCount()).To(Equal(19)) Expect(len(runner.RunCommandsWithInput)).To(Equal(20)) }) It("dmsetup command is retried 20 times", func() { runner.AddCmdResult("sfdisk -d /dev/mapper/xxxxxx", fakesys.FakeCmdResult{Stdout: devSdaSfdiskDumpOnePartition}) for i := 0; i < 19; i++ { testError := fmt.Errorf("test error") runner.AddCmdResult("dmsetup ls", fakesys.FakeCmdResult{ExitStatus: 1, Error: testError}) } runner.AddCmdResult("dmsetup ls", fakesys.FakeCmdResult{Stdout: expectedDmSetupLs}) runner.AddCmdResult("sfdisk -s /dev/mapper/xxxxxx", fakesys.FakeCmdResult{Stdout: "1048576"}) partitions := []Partition{ {Type: PartitionTypeLinux}, }
"BOSH_JOB_STATE": "{\"persistent_disk\":42}", "BOSH_JOB_NEXT_STATE": "{\"persistent_disk\":42}", }, } Expect(len(runner.RunComplexCommands)).To(Equal(1)) Expect(runner.RunComplexCommands[0]).To(Equal(expectedCmd)) }) It("sleeps when script returns a positive integer", func() { runner.AddProcess("/fake/script job_unchanged hash_unchanged bar foo", &fakesys.FakeProcess{WaitResult: boshsys.Result{Stdout: "12"}}) err := script.Run() Expect(err).ToNot(HaveOccurred()) Expect(fakeClock.SleepCallCount()).To(Equal(1)) Expect(fakeClock.SleepArgsForCall(0)).To(Equal(12 * time.Second)) }) It("sleeps then calls the script again as long as script returns a negative integer", func() { runner.AddProcess("/fake/script job_unchanged hash_unchanged bar foo", &fakesys.FakeProcess{WaitResult: boshsys.Result{Stdout: "-5"}}) runner.AddProcess("/fake/script job_check_status hash_unchanged", &fakesys.FakeProcess{WaitResult: boshsys.Result{Stdout: "-5"}}) runner.AddProcess("/fake/script job_check_status hash_unchanged", &fakesys.FakeProcess{WaitResult: boshsys.Result{Stdout: "-5"}}) runner.AddProcess("/fake/script job_check_status hash_unchanged", &fakesys.FakeProcess{WaitResult: boshsys.Result{Stdout: "0"}}) err := script.Run() Expect(err).ToNot(HaveOccurred())
Eventually(errChan).Should(Receive(Equal(lastError))) Expect(retryable.Response().Body.(ClosedChecker).Closed()).To(BeTrue()) }) }) }) It("waits for retry delay between retries", func() { for i := 0; i < maxUnavailableAttempts+maxOtherAttempts; i++ { retryable.AddAttemptBehavior(unavailable, true, lastError) } errChan := tryInBackground(monitRetryStrategy) Eventually(errChan).Should(Receive(Equal(lastError))) Expect(timeService.SleepCallCount()).To(Equal(maxUnavailableAttempts + maxOtherAttempts)) }) Context("when error is not due to failed response", func() { It("retries until maxOtherAttempts are exhausted", func() { for i := 0; i < maxOtherAttempts-1; i++ { retryable.AddAttemptBehavior(nil, true, errors.New("request error")) } retryable.AddAttemptBehavior(nil, true, lastError) errChan := tryInBackground(monitRetryStrategy) Eventually(errChan).Should(Receive(Equal(lastError))) Expect(retryable.Attempts()).To(Equal(maxOtherAttempts)) }) })