func buildFactory() (
	deps concreteFactoryDependencies,
	factory Factory) {

	deps.settings = &fakesettings.FakeSettingsService{}
	deps.platform = fakeplatform.NewFakePlatform()
	deps.blobstore = &fakeblobstore.FakeBlobstore{}
	deps.taskService = &faketask.FakeService{}
	deps.notifier = fakenotif.NewFakeNotifier()
	deps.applier = fakeappl.NewFakeApplier()
	deps.compiler = fakecomp.NewFakeCompiler()
	deps.monitor = fakemon.NewFakeMonitor()
	deps.specService = fakeas.NewFakeV1Service()
	deps.dirProvider = boshdirs.NewDirectoriesProvider("/foo")
	deps.drainScriptProvider = boshdrain.NewDrainScriptProvider(nil, nil, deps.dirProvider)

	factory = NewFactory(
		deps.settings,
		deps.platform,
		deps.blobstore,
		deps.taskService,
		deps.notifier,
		deps.applier,
		deps.compiler,
		deps.monitor,
		deps.specService,
		deps.dirProvider,
		deps.drainScriptProvider,
	)
	return
}
func buildFactory() (
	deps concreteFactoryDependencies,
	factory Factory) {

	deps.settings = &fakesettings.FakeSettingsService{}
	deps.platform = fakeplatform.NewFakePlatform()
	deps.blobstore = &fakeblobstore.FakeBlobstore{}
	deps.taskService = &faketask.FakeService{}
	deps.notifier = fakenotif.NewFakeNotifier()
	deps.applier = fakeappl.NewFakeApplier()
	deps.compiler = fakecomp.NewFakeCompiler()
	deps.jobSupervisor = fakejobsuper.NewFakeJobSupervisor()
	deps.specService = fakeas.NewFakeV1Service()
	deps.drainScriptProvider = boshdrain.NewConcreteDrainScriptProvider(nil, nil, deps.platform.GetDirProvider())

	factory = NewFactory(
		deps.settings,
		deps.platform,
		deps.blobstore,
		deps.taskService,
		deps.notifier,
		deps.applier,
		deps.compiler,
		deps.jobSupervisor,
		deps.specService,
		deps.drainScriptProvider,
	)
	return
}
Example #3
0
func buildDrain() (
	cmdRunner *fakesys.FakeCmdRunner,
	fs *fakesys.FakeFileSystem,
	notifier *fakenotif.FakeNotifier,
	specService *fakeas.FakeV1Service,
	action drainAction,
) {
	cmdRunner = fakesys.NewFakeCmdRunner()
	fs = fakesys.NewFakeFileSystem()
	notifier = fakenotif.NewFakeNotifier()
	specService = fakeas.NewFakeV1Service()
	dirProvider := boshdirs.NewDirectoriesProvider("/fake-dir")
	drainScriptProvider := boshdrain.NewDrainScriptProvider(cmdRunner, fs, dirProvider)
	action = newDrain(notifier, specService, drainScriptProvider)
	return
}
Example #4
0
func buildDrain() (
	notifier *fakenotif.FakeNotifier,
	fakeDrainProvider *fakedrain.FakeDrainScriptProvider,
	action drainAction,
) {
	notifier = fakenotif.NewFakeNotifier()

	specService := fakeas.NewFakeV1Service()
	currentSpec := boshas.V1ApplySpec{}
	currentSpec.JobSpec.Template = "foo"
	specService.Spec = currentSpec

	fakeDrainProvider = fakedrain.NewFakeDrainScriptProvider()
	fakeDrainProvider.NewDrainScriptDrainScript.ExistsBool = true

	action = newDrain(notifier, specService, fakeDrainProvider)

	return
}
func init() {
	Describe("concreteFactory", func() {
		var (
			settings            *fakesettings.FakeSettingsService
			platform            *fakeplatform.FakePlatform
			infrastructure      *fakeinfrastructure.FakeInfrastructure
			blobstore           *fakeblobstore.FakeBlobstore
			taskService         *faketask.FakeService
			notifier            *fakenotif.FakeNotifier
			applier             *fakeappl.FakeApplier
			compiler            *fakecomp.FakeCompiler
			jobSupervisor       *fakejobsuper.FakeJobSupervisor
			specService         *fakeas.FakeV1Service
			drainScriptProvider boshdrain.DrainScriptProvider
			factory             Factory
			logger              boshlog.Logger
		)

		BeforeEach(func() {
			settings = &fakesettings.FakeSettingsService{}
			platform = fakeplatform.NewFakePlatform()
			infrastructure = fakeinfrastructure.NewFakeInfrastructure()
			blobstore = &fakeblobstore.FakeBlobstore{}
			taskService = &faketask.FakeService{}
			notifier = fakenotif.NewFakeNotifier()
			applier = fakeappl.NewFakeApplier()
			compiler = fakecomp.NewFakeCompiler()
			jobSupervisor = fakejobsuper.NewFakeJobSupervisor()
			specService = fakeas.NewFakeV1Service()
			drainScriptProvider = boshdrain.NewConcreteDrainScriptProvider(nil, nil, platform.GetDirProvider())
			logger = boshlog.NewLogger(boshlog.LEVEL_NONE)
		})

		JustBeforeEach(func() {
			factory = NewFactory(
				settings,
				platform,
				infrastructure,
				blobstore,
				taskService,
				notifier,
				applier,
				compiler,
				jobSupervisor,
				specService,
				drainScriptProvider,
				logger,
			)
		})

		It("new factory", func() {
			actions := []string{
				"apply",
				"drain",
				"fetch_logs",
				"get_task",
				"get_state",
				"list_disk",
				"migrate_disk",
				"mount_disk",
				"ping",
				"prepare_network_change",
				"ssh",
				"start",
				"stop",
				"unmount_disk",
				"compile_package",
				"release_apply_spec",
			}

			for _, actionName := range actions {
				action, err := factory.Create(actionName)
				Expect(err).NotTo(HaveOccurred())
				Expect(action).ToNot(BeNil())
			}

			action, err := factory.Create("gobberish")
			Expect(err).To(HaveOccurred())
			Expect(action).To(BeNil())
		})

		It("apply", func() {
			action, err := factory.Create("apply")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewApply(applier, specService)).To(Equal(action))
		})

		It("drain", func() {
			action, err := factory.Create("drain")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewDrain(notifier, specService, drainScriptProvider, jobSupervisor)).To(Equal(action))
		})

		It("fetch_logs", func() {
			action, err := factory.Create("fetch_logs")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewLogs(platform.GetCompressor(), platform.GetCopier(), blobstore, platform.GetDirProvider())).To(Equal(action))
		})

		It("get_task", func() {
			action, err := factory.Create("get_task")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewGetTask(taskService)).To(Equal(action))
		})

		It("get_state", func() {
			ntpService := boshntp.NewConcreteService(platform.GetFs(), platform.GetDirProvider())
			action, err := factory.Create("get_state")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewGetState(settings, specService, jobSupervisor, platform.GetVitalsService(), ntpService)).To(Equal(action))
		})

		It("list_disk", func() {
			action, err := factory.Create("list_disk")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewListDisk(settings, platform, logger)).To(Equal(action))
		})

		It("migrate_disk", func() {
			action, err := factory.Create("migrate_disk")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewMigrateDisk(platform, platform.GetDirProvider())).To(Equal(action))
		})

		It("mount_disk", func() {
			action, err := factory.Create("mount_disk")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewMountDisk(settings, infrastructure, platform, platform.GetDirProvider())).To(Equal(action))
		})

		It("prepare_network_change", func() {
			action, err := factory.Create("prepare_network_change")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewPrepareNetworkChange(platform.GetFs(), settings)).To(Equal(action))
		})

		It("prepare_configure_networks", func() {
			action, err := factory.Create("prepare_configure_networks")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewPrepareConfigureNetworks(platform.GetFs(), settings)).To(Equal(action))
		})

		It("configure_networks", func() {
			action, err := factory.Create("configure_networks")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewConfigureNetworks()).To(Equal(action))
		})

		It("ssh", func() {
			action, err := factory.Create("ssh")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewSsh(settings, platform, platform.GetDirProvider())).To(Equal(action))
		})

		It("start", func() {
			action, err := factory.Create("start")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewStart(jobSupervisor)).To(Equal(action))
		})

		It("unmount_disk", func() {
			action, err := factory.Create("unmount_disk")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewUnmountDisk(settings, platform)).To(Equal(action))
		})

		It("compile_package", func() {
			action, err := factory.Create("compile_package")
			Expect(err).NotTo(HaveOccurred())
			Expect(action).ToNot(BeNil())
			Expect(NewCompilePackage(compiler)).To(Equal(action))
		})
	})
}
		notifier            *fakenotif.FakeNotifier
		applier             *fakeappl.FakeApplier
		compiler            *fakecomp.FakeCompiler
		jobSupervisor       *fakejobsuper.FakeJobSupervisor
		specService         *fakeas.FakeV1Service
		drainScriptProvider boshdrain.DrainScriptProvider
		factory             Factory
		logger              boshlog.Logger
	)

	BeforeEach(func() {
		settingsService = &fakesettings.FakeSettingsService{}
		platform = fakeplatform.NewFakePlatform()
		blobstore = &fakeblobstore.FakeBlobstore{}
		taskService = &faketask.FakeService{}
		notifier = fakenotif.NewFakeNotifier()
		applier = fakeappl.NewFakeApplier()
		compiler = fakecomp.NewFakeCompiler()
		jobSupervisor = fakejobsuper.NewFakeJobSupervisor()
		specService = fakeas.NewFakeV1Service()
		drainScriptProvider = boshdrain.NewConcreteDrainScriptProvider(nil, nil, platform.GetDirProvider())
		logger = boshlog.NewLogger(boshlog.LevelNone)

		factory = NewFactory(
			settingsService,
			platform,
			blobstore,
			taskService,
			notifier,
			applier,
			compiler,
Example #7
0
func init() {
	Describe("DrainAction", func() {
		var (
			notifier            *fakenotif.FakeNotifier
			specService         *fakeas.FakeV1Service
			drainScriptProvider *fakedrain.FakeDrainScriptProvider
			jobSupervisor       *fakejobsuper.FakeJobSupervisor
			action              DrainAction
		)

		BeforeEach(func() {
			notifier = fakenotif.NewFakeNotifier()
			specService = fakeas.NewFakeV1Service()
			drainScriptProvider = fakedrain.NewFakeDrainScriptProvider()
			jobSupervisor = fakejobsuper.NewFakeJobSupervisor()
			action = NewDrain(notifier, specService, drainScriptProvider, jobSupervisor)
		})

		BeforeEach(func() {
			drainScriptProvider.NewDrainScriptDrainScript.ExistsBool = true
		})

		It("is asynchronous", func() {
			Expect(action.IsAsynchronous()).To(BeTrue())
		})

		It("is not persistent", func() {
			Expect(action.IsPersistent()).To(BeFalse())
		})

		Context("when drain update is requested", func() {
			act := func() (int, error) { return action.Run(DrainTypeUpdate, boshas.V1ApplySpec{}) }

			Context("when current agent has a job spec template", func() {
				var currentSpec boshas.V1ApplySpec

				BeforeEach(func() {
					currentSpec = boshas.V1ApplySpec{}
					currentSpec.JobSpec.Template = "foo"
					specService.Spec = currentSpec
				})

				It("unmonitors services so that drain scripts can kill processes on their own", func() {
					value, err := act()
					Expect(err).ToNot(HaveOccurred())
					Expect(value).To(Equal(1))

					Expect(jobSupervisor.Unmonitored).To(BeTrue())
				})

				Context("when unmonitoring services succeeds", func() {
					It("does not notify of job shutdown", func() {
						value, err := act()
						Expect(err).ToNot(HaveOccurred())
						Expect(value).To(Equal(1))

						Expect(notifier.NotifiedShutdown).To(BeFalse())
					})

					Context("when new apply spec is provided", func() {
						newSpec := boshas.V1ApplySpec{
							PackageSpecs: map[string]boshas.PackageSpec{
								"foo": boshas.PackageSpec{
									Name: "foo",
									Sha1: "foo-sha1-new",
								},
							},
						}

						Context("when drain script exists", func() {
							It("runs drain script with job_shutdown param", func() {
								value, err := action.Run(DrainTypeUpdate, newSpec)
								Expect(err).ToNot(HaveOccurred())
								Expect(value).To(Equal(1))

								Expect(drainScriptProvider.NewDrainScriptTemplateName).To(Equal("foo"))
								Expect(drainScriptProvider.NewDrainScriptDrainScript.DidRun).To(BeTrue())

								params := drainScriptProvider.NewDrainScriptDrainScript.RunParams
								Expect(params).To(Equal(boshdrain.NewUpdateDrainParams(currentSpec, newSpec)))
							})

							Context("when drain script runs and errs", func() {
								It("returns error", func() {
									drainScriptProvider.NewDrainScriptDrainScript.RunError = errors.New("fake-drain-run-error")

									value, err := act()
									Expect(err).To(HaveOccurred())
									Expect(err.Error()).To(ContainSubstring("fake-drain-run-error"))
									Expect(value).To(Equal(0))
								})
							})
						})

						Context("when drain script does not exist", func() {
							It("returns 0", func() {
								drainScriptProvider.NewDrainScriptDrainScript.ExistsBool = false

								value, err := act()
								Expect(err).ToNot(HaveOccurred())
								Expect(value).To(Equal(0))

								Expect(drainScriptProvider.NewDrainScriptDrainScript.DidRun).To(BeFalse())
							})
						})
					})

					Context("when apply spec is not provided", func() {
						It("returns error", func() {
							value, err := action.Run(DrainTypeUpdate)
							Expect(err).To(HaveOccurred())
							Expect(err.Error()).To(ContainSubstring("Drain update requires new spec"))
							Expect(value).To(Equal(0))
						})
					})
				})

				Context("when unmonitoring services fails", func() {
					It("returns error", func() {
						jobSupervisor.UnmonitorErr = errors.New("fake-unmonitor-error")

						value, err := act()
						Expect(err).To(HaveOccurred())
						Expect(err.Error()).To(ContainSubstring("fake-unmonitor-error"))
						Expect(value).To(Equal(0))
					})
				})
			})

			Context("when current agent spec does not have a job spec template", func() {
				It("returns 0 and does not run drain script", func() {
					specService.Spec = boshas.V1ApplySpec{}

					value, err := act()
					Expect(err).ToNot(HaveOccurred())
					Expect(value).To(Equal(0))

					Expect(drainScriptProvider.NewDrainScriptDrainScript.DidRun).To(BeFalse())
				})
			})
		})

		Context("when drain shutdown is requested", func() {
			act := func() (int, error) { return action.Run(DrainTypeShutdown) }

			Context("when current agent has a job spec template", func() {
				var currentSpec boshas.V1ApplySpec

				BeforeEach(func() {
					currentSpec = boshas.V1ApplySpec{}
					currentSpec.JobSpec.Template = "foo"
					specService.Spec = currentSpec
				})

				It("unmonitors services so that drain scripts can kill processes on their own", func() {
					value, err := act()
					Expect(err).ToNot(HaveOccurred())
					Expect(value).To(Equal(1))

					Expect(jobSupervisor.Unmonitored).To(BeTrue())
				})

				Context("when unmonitoring services succeeds", func() {
					It("notifies that job is about to shutdown", func() {
						value, err := act()
						Expect(err).ToNot(HaveOccurred())
						Expect(value).To(Equal(1))

						Expect(notifier.NotifiedShutdown).To(BeTrue())
					})

					Context("when job shutdown notification succeeds", func() {
						Context("when drain script exists", func() {
							It("runs drain script with job_shutdown param passing no apply spec", func() {
								value, err := action.Run(DrainTypeShutdown)
								Expect(err).ToNot(HaveOccurred())
								Expect(value).To(Equal(1))

								Expect(drainScriptProvider.NewDrainScriptTemplateName).To(Equal("foo"))
								Expect(drainScriptProvider.NewDrainScriptDrainScript.DidRun).To(BeTrue())

								params := drainScriptProvider.NewDrainScriptDrainScript.RunParams
								Expect(params).To(Equal(boshdrain.NewShutdownDrainParams(currentSpec, nil)))
							})

							It("runs drain script with job_shutdown param passing in first apply spec", func() {
								newSpec := boshas.V1ApplySpec{}
								newSpec.JobSpec.Template = "fake-updated-template"

								value, err := action.Run(DrainTypeShutdown, newSpec)
								Expect(err).ToNot(HaveOccurred())
								Expect(value).To(Equal(1))

								Expect(drainScriptProvider.NewDrainScriptTemplateName).To(Equal("foo"))
								Expect(drainScriptProvider.NewDrainScriptDrainScript.DidRun).To(BeTrue())

								params := drainScriptProvider.NewDrainScriptDrainScript.RunParams
								Expect(params).To(Equal(boshdrain.NewShutdownDrainParams(currentSpec, &newSpec)))
							})

							Context("when drain script runs and errs", func() {
								It("returns error", func() {
									drainScriptProvider.NewDrainScriptDrainScript.RunError = errors.New("fake-drain-run-error")

									value, err := act()
									Expect(err).To(HaveOccurred())
									Expect(err.Error()).To(ContainSubstring("fake-drain-run-error"))
									Expect(value).To(Equal(0))
								})
							})
						})

						Context("when drain script does not exist", func() {
							It("returns 0", func() {
								drainScriptProvider.NewDrainScriptDrainScript.ExistsBool = false

								value, err := act()
								Expect(err).ToNot(HaveOccurred())
								Expect(value).To(Equal(0))

								Expect(drainScriptProvider.NewDrainScriptDrainScript.DidRun).To(BeFalse())
							})
						})
					})

					Context("when job shutdown notification fails", func() {
						It("returns error if job shutdown notifications errs", func() {
							notifier.NotifyShutdownErr = errors.New("fake-shutdown-error")

							value, err := act()
							Expect(err).To(HaveOccurred())
							Expect(err.Error()).To(ContainSubstring("fake-shutdown-error"))
							Expect(value).To(Equal(0))
						})
					})
				})

				Context("when unmonitoring services fails", func() {
					It("returns error", func() {
						jobSupervisor.UnmonitorErr = errors.New("fake-unmonitor-error")

						value, err := act()
						Expect(err).To(HaveOccurred())
						Expect(err.Error()).To(ContainSubstring("fake-unmonitor-error"))
						Expect(value).To(Equal(0))
					})
				})
			})

			Context("when current agent spec does not have a job spec template", func() {
				It("returns 0 and does not run drain script", func() {
					specService.Spec = boshas.V1ApplySpec{}

					value, err := act()
					Expect(err).ToNot(HaveOccurred())
					Expect(value).To(Equal(0))

					Expect(drainScriptProvider.NewDrainScriptDrainScript.DidRun).To(BeFalse())
				})
			})
		})

		Context("when drain status is requested", func() {
			act := func() (int, error) { return action.Run(DrainTypeStatus) }

			Context("when current agent has a job spec template", func() {
				var currentSpec boshas.V1ApplySpec

				BeforeEach(func() {
					currentSpec = boshas.V1ApplySpec{}
					currentSpec.JobSpec.Template = "foo"
					specService.Spec = currentSpec
				})

				It("unmonitors services so that drain scripts can kill processes on their own", func() {
					value, err := act()
					Expect(err).ToNot(HaveOccurred())
					Expect(value).To(Equal(1))

					Expect(jobSupervisor.Unmonitored).To(BeTrue())
				})

				It("does not notify of job shutdown", func() {
					value, err := act()
					Expect(err).ToNot(HaveOccurred())
					Expect(value).To(Equal(1))

					Expect(notifier.NotifiedShutdown).To(BeFalse())
				})

				Context("when unmonitoring services succeeds", func() {
					Context("when drain script exists", func() {
						It("runs drain script with job_check_status param passing no apply spec", func() {
							value, err := action.Run(DrainTypeStatus)
							Expect(err).ToNot(HaveOccurred())
							Expect(value).To(Equal(1))

							Expect(drainScriptProvider.NewDrainScriptTemplateName).To(Equal("foo"))
							Expect(drainScriptProvider.NewDrainScriptDrainScript.DidRun).To(BeTrue())

							params := drainScriptProvider.NewDrainScriptDrainScript.RunParams
							Expect(params).To(Equal(boshdrain.NewStatusDrainParams(currentSpec, nil)))
						})

						It("runs drain script with job_check_status param passing in first apply spec", func() {
							newSpec := boshas.V1ApplySpec{}
							newSpec.JobSpec.Template = "fake-updated-template"

							value, err := action.Run(DrainTypeStatus, newSpec)
							Expect(err).ToNot(HaveOccurred())
							Expect(value).To(Equal(1))

							Expect(drainScriptProvider.NewDrainScriptTemplateName).To(Equal("foo"))
							Expect(drainScriptProvider.NewDrainScriptDrainScript.DidRun).To(BeTrue())

							params := drainScriptProvider.NewDrainScriptDrainScript.RunParams
							Expect(params).To(Equal(boshdrain.NewStatusDrainParams(currentSpec, &newSpec)))
						})

						Context("when drain script runs and errs", func() {
							It("returns error if drain script errs", func() {
								drainScriptProvider.NewDrainScriptDrainScript.RunError = errors.New("fake-drain-run-error")

								value, err := act()
								Expect(err).To(HaveOccurred())
								Expect(err.Error()).To(ContainSubstring("fake-drain-run-error"))
								Expect(value).To(Equal(0))
							})
						})
					})

					Context("when drain script does not exist", func() {
						It("returns error because drain status must be called after starting draining", func() {
							drainScriptProvider.NewDrainScriptDrainScript.ExistsBool = false

							value, err := act()
							Expect(err).To(HaveOccurred())
							Expect(err.Error()).To(ContainSubstring("Check Status on Drain action requires a valid drain script"))
							Expect(value).To(Equal(0))
						})
					})
				})

				Context("when unmonitoring services fails", func() {
					It("returns error if unmonitoring services errs", func() {
						jobSupervisor.UnmonitorErr = errors.New("fake-unmonitor-error")

						value, err := act()
						Expect(err).To(HaveOccurred())
						Expect(err.Error()).To(ContainSubstring("fake-unmonitor-error"))
						Expect(value).To(Equal(0))
					})
				})
			})

			Context("when current agent spec does not have a job spec template", func() {
				It("returns error because drain status should only be called after starting draining", func() {
					specService.Spec = boshas.V1ApplySpec{}

					value, err := action.Run(DrainTypeStatus)
					Expect(err).To(HaveOccurred())
					Expect(err.Error()).To(ContainSubstring("Check Status on Drain action requires job spec"))
					Expect(value).To(Equal(0))
				})
			})
		})
	})
}