func init() { Describe("Testing with Ginkgo", func() { It("running a successful task", func() { testRunningTask(GinkgoT(), TaskStateDone, 123, nil) }) It("running a failing task", func() { testRunningTask(GinkgoT(), TaskStateFailed, nil, errors.New("Oops")) }) It("start task generates task id", func() { var taskFunc = func() (value interface{}, err error) { return } service := NewAsyncTaskService(boshlog.NewLogger(boshlog.LEVEL_NONE)) for expectedTaskId := 1; expectedTaskId < 20; expectedTaskId++ { task := service.StartTask(taskFunc) assert.Equal(GinkgoT(), fmt.Sprintf("%d", expectedTaskId), task.Id) } }) It("processing many tasks simultaneously", func() { taskFunc := func() (value interface{}, err error) { time.Sleep(10 * time.Millisecond) return } service := NewAsyncTaskService(boshlog.NewLogger(boshlog.LEVEL_NONE)) ids := []string{} for id := 1; id < 200; id++ { ids = append(ids, fmt.Sprintf("%d", id)) go service.StartTask(taskFunc) } for { allDone := true for _, id := range ids { task, _ := service.FindTask(id) if task.State != TaskStateDone { allDone = false break } } if allDone { break } time.Sleep(200 * time.Millisecond) } }) }) }
func getActionDispatcherDependencies() (logger boshlog.Logger, taskService *faketask.FakeService, actionFactory *fakeaction.FakeFactory, actionRunner *fakeaction.FakeRunner) { logger = boshlog.NewLogger(boshlog.LEVEL_NONE) taskService = &faketask.FakeService{} actionFactory = &fakeaction.FakeFactory{} actionRunner = &fakeaction.FakeRunner{} return }
func getNewProvider() (provider provider) { dirProvider := boshsys.NewDirectoriesProvider("/var/vcap") fs := fakefs.NewFakeFileSystem() provider = NewProvider(boshlog.NewLogger(boshlog.LEVEL_NONE), fs, dirProvider) return }
func buildAlertBuilder() (settingsService *fakesettings.FakeSettingsService, builder Builder) { logger := boshlog.NewLogger(boshlog.LEVEL_NONE) settingsService = &fakesettings.FakeSettingsService{} builder = NewBuilder(settingsService, logger) return }
func TestGetReturnsAnAwsInfrastructure(t *testing.T) { provider := NewProvider(boshlog.NewLogger(boshlog.LEVEL_NONE)) inf, err := provider.Get("aws") assert.NoError(t, err) assert.IsType(t, awsInfrastructure{}, inf) }
func TestProcessingManyTasksSimultaneously(t *testing.T) { taskFunc := func() (value interface{}, err error) { time.Sleep(10 * time.Millisecond) return } service := NewAsyncTaskService(boshlog.NewLogger(boshlog.LEVEL_NONE)) ids := []string{} for id := 1; id < 200; id++ { ids = append(ids, fmt.Sprintf("%d", id)) go service.StartTask(taskFunc) } for { allDone := true for _, id := range ids { task, _ := service.FindTask(id) if task.State != TaskStateDone { allDone = false break } } if allDone { break } time.Sleep(200 * time.Millisecond) } }
func testRunningTask(t *testing.T, expectedState TaskState, withValue interface{}, withErr error) { service := NewAsyncTaskService(boshlog.NewLogger(boshlog.LEVEL_NONE)) taskIsFinished := false task := service.StartTask(func() (value interface{}, err error) { for !taskIsFinished { } value = withValue err = withErr return }) assert.Equal(t, "1", task.Id) assert.Equal(t, "running", task.State) taskIsFinished = true updatedTask, _ := service.FindTask(task.Id) for updatedTask.State != expectedState { time.Sleep(time.Nanosecond) updatedTask, _ = service.FindTask(task.Id) } assert.Equal(t, expectedState, updatedTask.State) assert.Equal(t, withValue, updatedTask.Value) if withErr != nil { assert.Equal(t, withErr.Error(), updatedTask.Error) } else { assert.Equal(t, "", updatedTask.Error) } }
func TestHandlerProviderGetReturnsAnErrorIfNotSupported(t *testing.T) { settings := &fakesettings.FakeSettingsService{MbusUrl: "foo://0.0.0.0"} logger := boshlog.NewLogger(boshlog.LEVEL_NONE) provider := NewHandlerProvider(settings, logger) _, err := provider.Get() assert.Error(t, err) }
func buildMonit() (fs *fakesys.FakeFileSystem, runner *fakesys.FakeCmdRunner, client *fakemonit.FakeMonitClient, monit monit) { fs = &fakesys.FakeFileSystem{} runner = &fakesys.FakeCmdRunner{} client = fakemonit.NewFakeMonitClient() logger := boshlog.NewLogger(boshlog.LEVEL_NONE) monit = NewMonit(fs, runner, client, logger) return }
func buildProvider(mbusUrl string) (provider mbusHandlerProvider, platform *fakeplatform.FakePlatform, dirProvider boshdir.DirectoriesProvider) { settings := &fakesettings.FakeSettingsService{MbusUrl: mbusUrl} logger := boshlog.NewLogger(boshlog.LEVEL_NONE) provider = NewHandlerProvider(settings, logger) platform = fakeplatform.NewFakePlatform() dirProvider = boshdir.NewDirectoriesProvider("/var/vcap") return }
func buildProvider(mbusUrl string) (deps providerDeps, provider MbusHandlerProvider) { deps.settings = &fakesettings.FakeSettingsService{MbusUrl: mbusUrl} deps.logger = boshlog.NewLogger(boshlog.LEVEL_NONE) provider = NewHandlerProvider(deps.settings, deps.logger) deps.platform = fakeplatform.NewFakePlatform() deps.dirProvider = boshdir.NewDirectoriesProvider("/var/vcap") return }
func TestHandlerProviderGetReturnsNatsHandler(t *testing.T) { settings := &fakesettings.FakeSettingsService{MbusUrl: "nats://0.0.0.0"} logger := boshlog.NewLogger(boshlog.LEVEL_NONE) provider := NewHandlerProvider(settings, logger) handler, err := provider.Get() assert.NoError(t, err) assert.IsType(t, natsHandler{}, handler) }
func TestStartTaskGeneratesTaskId(t *testing.T) { var taskFunc = func() (value interface{}, err error) { return } service := NewAsyncTaskService(boshlog.NewLogger(boshlog.LEVEL_NONE)) for expectedTaskId := 1; expectedTaskId < 20; expectedTaskId++ { task := service.StartTask(taskFunc) assert.Equal(t, fmt.Sprintf("%d", expectedTaskId), task.Id) } }
func init() { Describe("Testing with Ginkgo", func() { It("services in group returns slice of service", func() { expectedServices := []Service{ { Monitored: true, Status: "running", }, { Monitored: false, Status: "unknown", }, { Monitored: true, Status: "starting", }, { Monitored: true, Status: "failing", }, } monitStatusFilePath, _ := filepath.Abs("../../../../fixtures/monit_status_with_multiple_services.xml") Expect(monitStatusFilePath).ToNot(BeNil()) file, err := os.Open(monitStatusFilePath) Expect(err).ToNot(HaveOccurred()) defer file.Close() handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { io.Copy(w, file) Expect(r.Method).To(Equal("GET")) Expect(r.URL.Path).To(Equal("/_status2")) Expect(r.URL.Query().Get("format")).To(Equal("xml")) }) ts := httptest.NewServer(handler) defer ts.Close() logger := boshlog.NewLogger(boshlog.LEVEL_NONE) client := NewHttpClient(ts.Listener.Addr().String(), "fake-user", "fake-pass", http.DefaultClient, 1*time.Millisecond, logger) status, err := client.Status() Expect(err).ToNot(HaveOccurred()) services := status.ServicesInGroup("vcap") Expect(len(expectedServices)).To(Equal(len(services))) for i, expectedService := range expectedServices { Expect(expectedService).To(Equal(services[i])) } }) }) }
func buildMonitJobSupervisor() (deps monitJobSupDeps, monit monitJobSupervisor) { deps = monitJobSupDeps{ fs: &fakesys.FakeFileSystem{}, runner: &fakesys.FakeCmdRunner{}, client: fakemonit.NewFakeMonitClient(), logger: boshlog.NewLogger(boshlog.LEVEL_NONE), dirProvider: boshdir.NewDirectoriesProvider("/var/vcap"), } monit = NewMonitJobSupervisor(deps.fs, deps.runner, deps.client, deps.logger, deps.dirProvider) return }
func main() { logger := boshlog.NewLogger(boshlog.LEVEL_DEBUG) defer logger.HandlePanic("Main") app := boshapp.New(logger) err := app.Run(os.Args) if err != nil { logger.Error("Main", err.Error()) os.Exit(1) } }
func buildAgent() (deps agentDeps, agent Agent) { deps = agentDeps{ logger: boshlog.NewLogger(boshlog.LEVEL_NONE), handler: &fakembus.FakeHandler{}, platform: fakeplatform.NewFakePlatform(), actionDispatcher: &FakeActionDispatcher{}, alertBuilder: fakealert.NewFakeAlertBuilder(), jobSupervisor: fakejobsup.NewFakeJobSupervisor(), } agent = New(deps.logger, deps.handler, deps.platform, deps.actionDispatcher, deps.alertBuilder, deps.jobSupervisor, 5*time.Millisecond) return }
func main() { logger := boshlog.NewLogger(boshlog.LEVEL_DEBUG) defer logger.HandlePanic("Main") logger.Debug("main", "Starting agent") app := boshapp.New(logger) app.Setup(os.Args) err := app.Run() if err != nil { logger.Error("Main", err.Error()) os.Exit(1) } }
func startServer() (serverURL string, handler HttpsHandler, fs *fakesys.FakeFileSystem) { serverURL = "https://*****:*****@127.0.0.1:6900" mbusUrl, _ := url.Parse(serverURL) logger := boshlog.NewLogger(boshlog.LEVEL_NONE) fs = fakesys.NewFakeFileSystem() dirProvider := boshdir.NewDirectoriesProvider("/var/vcap") handler = NewHttpsHandler(mbusUrl, logger, fs, dirProvider) go handler.Start(func(req boshhandler.Request) (resp boshhandler.Response) { receivedRequest = req return boshhandler.NewValueResponse("expected value") }) return }
func startServer() (serverURL string) { port := getHttpsHandlerPort() serverURL = fmt.Sprintf("https://*****:*****@127.0.0.1:%d", port) mbusUrl, _ := url.Parse(serverURL) logger := boshlog.NewLogger(boshlog.LEVEL_NONE) handler := newHttpsHandler(mbusUrl, logger) go handler.Start(func(req Request) (resp Response) { receivedRequest = req return NewValueResponse("expected value") }) defer handler.Stop() return }
func getAgentDependencies() ( settings *fakesettings.FakeSettingsService, logger boshlog.Logger, handler *fakembus.FakeHandler, platform *fakeplatform.FakePlatform, actionDispatcher *FakeActionDispatcher) { settings = &fakesettings.FakeSettingsService{} logger = boshlog.NewLogger(boshlog.LEVEL_NONE) handler = &fakembus.FakeHandler{} platform = &fakeplatform.FakePlatform{ FakeStatsCollector: &fakestats.FakeStatsCollector{}, } actionDispatcher = &FakeActionDispatcher{} return }
func buildProvider() ( deps providerDependencies, provider provider, ) { deps.platform = fakeplatform.NewFakePlatform() deps.client = fakemonit.NewFakeMonitClient() deps.logger = boshlog.NewLogger(boshlog.LEVEL_NONE) deps.dirProvider = boshdir.NewDirectoriesProvider("/fake-base-dir") provider = NewProvider( deps.platform, deps.client, deps.logger, deps.dirProvider, ) return }
func getAgentDependencies() ( settings *fakesettings.FakeSettingsService, logger boshlog.Logger, handler *fakembus.FakeHandler, platform *fakeplatform.FakePlatform, taskService *faketask.FakeService, actionFactory *fakeaction.FakeFactory) { settings = &fakesettings.FakeSettingsService{} logger = boshlog.NewLogger(boshlog.LEVEL_NONE) handler = &fakembus.FakeHandler{} platform = &fakeplatform.FakePlatform{ FakeStatsCollector: &fakestats.FakeStatsCollector{}, } taskService = &faketask.FakeService{} actionFactory = &fakeaction.FakeFactory{} return }
func init() { Describe("Testing with Ginkgo", func() { It("get", func() { logger := boshlog.NewLogger(boshlog.LevelNone) platform := fakeplatform.NewFakePlatform() platform.GetMonitCredentialsUsername = "******" platform.GetMonitCredentialsPassword = "******" client, err := NewProvider(platform, logger).Get() Expect(err).ToNot(HaveOccurred()) expectedClient := NewHTTPClient("127.0.0.1:2822", "fake-user", "fake-pass", http.DefaultClient, 1*time.Second, logger) Expect(expectedClient).To(Equal(client)) }) }) }
func init() { Describe("Testing with Ginkgo", func() { var ( logger boshlog.Logger platform *fakeplatform.FakePlatform ) BeforeEach(func() { platform = fakeplatform.NewFakePlatform() logger = boshlog.NewLogger(boshlog.LEVEL_NONE) }) It("list disk should be synchronous", func() { settings := &fakesettings.FakeSettingsService{} action := NewListDisk(settings, platform, logger) Expect(action.IsAsynchronous()).To(BeFalse()) }) It("is not persistent", func() { settings := &fakesettings.FakeSettingsService{} action := NewListDisk(settings, platform, logger) Expect(action.IsPersistent()).To(BeFalse()) }) It("list disk run", func() { settings := &fakesettings.FakeSettingsService{ Disks: boshsettings.Disks{ Persistent: map[string]string{ "volume-1": "/dev/sda", "volume-2": "/dev/sdb", "volume-3": "/dev/sdc", }, }, } platform.MountedDevicePaths = []string{"/dev/sdb", "/dev/sdc"} action := NewListDisk(settings, platform, logger) value, err := action.Run() Expect(err).ToNot(HaveOccurred()) boshassert.MatchesJsonString(GinkgoT(), value, `["volume-2","volume-3"]`) }) }) }
func main() { logger := boshlog.NewLogger(boshlog.LevelDebug) defer logger.HandlePanic("Main") logger.Debug(mainLogTag, "Starting agent") app := boshapp.New(logger) err := app.Setup(os.Args) if err != nil { logger.Error(mainLogTag, "App setup %s", err.Error()) os.Exit(1) } err = app.Run() if err != nil { logger.Error(mainLogTag, "App run %s", err.Error()) os.Exit(1) } }
func init() { Describe("ListDisk", func() { var ( settingsService *fakesettings.FakeSettingsService platform *fakeplatform.FakePlatform logger boshlog.Logger action ListDiskAction ) BeforeEach(func() { settingsService = &fakesettings.FakeSettingsService{} platform = fakeplatform.NewFakePlatform() logger = boshlog.NewLogger(boshlog.LevelNone) action = NewListDisk(settingsService, platform, logger) }) It("list disk should be synchronous", func() { Expect(action.IsAsynchronous()).To(BeFalse()) }) It("is not persistent", func() { Expect(action.IsPersistent()).To(BeFalse()) }) It("list disk run", func() { platform.MountedDevicePaths = []string{"/dev/sdb", "/dev/sdc"} settingsService.Settings.Disks = boshsettings.Disks{ Persistent: map[string]string{ "volume-1": "/dev/sda", "volume-2": "/dev/sdb", "volume-3": "/dev/sdc", }, } value, err := action.Run() Expect(err).ToNot(HaveOccurred()) boshassert.MatchesJSONString(GinkgoT(), value, `["volume-2","volume-3"]`) }) }) }
func init() { Describe("renderedJobApplier", func() { var ( jobsBc *fakebc.FakeBundleCollection jobSupervisor *fakejobsuper.FakeJobSupervisor packageApplierProvider *fakepa.FakePackageApplierProvider blobstore *fakeblob.FakeBlobstore compressor *fakecmd.FakeCompressor fs *fakesys.FakeFileSystem applier JobApplier ) BeforeEach(func() { jobsBc = fakebc.NewFakeBundleCollection() jobSupervisor = fakejobsuper.NewFakeJobSupervisor() packageApplierProvider = fakepa.NewFakePackageApplierProvider() blobstore = fakeblob.NewFakeBlobstore() fs = fakesys.NewFakeFileSystem() compressor = fakecmd.NewFakeCompressor() logger := boshlog.NewLogger(boshlog.LevelNone) applier = NewRenderedJobApplier( jobsBc, jobSupervisor, packageApplierProvider, blobstore, compressor, fs, logger, ) }) Describe("Prepare & Apply", func() { var ( job models.Job bundle *fakebc.FakeBundle ) BeforeEach(func() { job, bundle = buildJob(jobsBc) }) ItInstallsJob := func(act func() error) { It("returns error when installing job fails", func() { bundle.InstallError = errors.New("fake-install-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-install-error")) }) It("downloads and later cleans up downloaded job template blob", func() { blobstore.GetFileName = "/fake-blobstore-file-name" err := act() Expect(err).ToNot(HaveOccurred()) Expect(blobstore.GetBlobIDs[0]).To(Equal("fake-blobstore-id")) Expect(blobstore.GetFingerprints[0]).To(Equal("fake-blob-sha1")) // downloaded file is cleaned up Expect(blobstore.CleanUpFileName).To(Equal("/fake-blobstore-file-name")) }) It("returns error when downloading job template blob fails", func() { blobstore.GetError = errors.New("fake-get-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-get-error")) }) It("decompresses job template blob to tmp path and later cleans it up", func() { fs.TempDirDir = "/fake-tmp-dir" blobstore.GetFileName = "/fake-blobstore-file-name" var tmpDirExistsBeforeInstall bool bundle.InstallCallBack = func() { tmpDirExistsBeforeInstall = true } err := act() Expect(err).ToNot(HaveOccurred()) Expect(compressor.DecompressFileToDirTarballPaths[0]).To(Equal("/fake-blobstore-file-name")) Expect(compressor.DecompressFileToDirDirs[0]).To(Equal("/fake-tmp-dir")) // tmp dir exists before bundle install Expect(tmpDirExistsBeforeInstall).To(BeTrue()) // tmp dir is cleaned up after install Expect(fs.FileExists(fs.TempDirDir)).To(BeFalse()) }) It("returns error when temporary directory creation fails", func() { fs.TempDirError = errors.New("fake-filesystem-tempdir-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-filesystem-tempdir-error")) }) It("returns error when decompressing job template fails", func() { compressor.DecompressFileToDirErr = errors.New("fake-decompress-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-decompress-error")) }) It("returns error when getting the list of bin files fails", func() { fs.GlobErr = errors.New("fake-glob-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-glob-error")) }) It("returns error when changing permissions on bin files fails", func() { fs.TempDirDir = "/fake-tmp-dir" fs.SetGlob("/fake-tmp-dir/fake-path-in-archive/bin/*", []string{ "/fake-tmp-dir/fake-path-in-archive/bin/test", }) fs.ChmodErr = errors.New("fake-chmod-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-chmod-error")) }) It("installs bundle from decompressed tmp path of a job template", func() { fs.TempDirDir = "/fake-tmp-dir" var installedBeforeDecompression bool compressor.DecompressFileToDirCallBack = func() { installedBeforeDecompression = bundle.Installed } err := act() Expect(err).ToNot(HaveOccurred()) // bundle installation did not happen before decompression Expect(installedBeforeDecompression).To(BeFalse()) // make sure that bundle install happened after decompression Expect(bundle.InstallSourcePath).To(Equal("/fake-tmp-dir/fake-path-in-archive")) }) It("sets executable bit for files in bin", func() { fs.TempDirDir = "/fake-tmp-dir" compressor.DecompressFileToDirCallBack = func() { fs.WriteFile("/fake-tmp-dir/fake-path-in-archive/bin/test1", []byte{}) fs.WriteFile("/fake-tmp-dir/fake-path-in-archive/bin/test2", []byte{}) fs.WriteFile("/fake-tmp-dir/fake-path-in-archive/config/test", []byte{}) } fs.SetGlob("/fake-tmp-dir/fake-path-in-archive/bin/*", []string{ "/fake-tmp-dir/fake-path-in-archive/bin/test1", "/fake-tmp-dir/fake-path-in-archive/bin/test2", }) var binTest1Stats, binTest2Stats, configTestStats *fakesys.FakeFileStats bundle.InstallCallBack = func() { binTest1Stats = fs.GetFileTestStat("/fake-tmp-dir/fake-path-in-archive/bin/test1") binTest2Stats = fs.GetFileTestStat("/fake-tmp-dir/fake-path-in-archive/bin/test2") configTestStats = fs.GetFileTestStat("/fake-tmp-dir/fake-path-in-archive/config/test") } err := act() Expect(err).ToNot(HaveOccurred()) // bin files are executable Expect(int(binTest1Stats.FileMode)).To(Equal(0755)) Expect(int(binTest2Stats.FileMode)).To(Equal(0755)) // non-bin files are not made executable Expect(int(configTestStats.FileMode)).ToNot(Equal(0755)) }) } ItUpdatesPackages := func(act func() error) { var packageApplier *fakepa.FakePackageApplier BeforeEach(func() { packageApplier = fakepa.NewFakePackageApplier() packageApplierProvider.JobSpecificPackageAppliers[job.Name] = packageApplier }) It("applies each package that job depends on and then cleans up packages", func() { err := act() Expect(err).ToNot(HaveOccurred()) Expect(packageApplier.ActionsCalled).To(Equal([]string{"Apply", "Apply", "KeepOnly"})) Expect(len(packageApplier.AppliedPackages)).To(Equal(2)) // present Expect(packageApplier.AppliedPackages).To(Equal(job.Packages)) }) It("returns error when applying package that job depends on fails", func() { packageApplier.ApplyError = errors.New("fake-apply-err") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-apply-err")) }) It("keeps only currently required packages but does not completely uninstall them", func() { err := act() Expect(err).ToNot(HaveOccurred()) Expect(len(packageApplier.KeptOnlyPackages)).To(Equal(2)) // present Expect(packageApplier.KeptOnlyPackages).To(Equal(job.Packages)) }) It("returns error when keeping only currently required packages fails", func() { packageApplier.KeepOnlyErr = errors.New("fake-keep-only-err") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-keep-only-err")) }) } Describe("Prepare", func() { act := func() error { return applier.Prepare(job) } It("return an error if getting file bundle fails", func() { jobsBc.GetErr = errors.New("fake-get-bundle-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-get-bundle-error")) }) It("returns an error if checking for installed path fails", func() { bundle.IsInstalledErr = errors.New("fake-is-installed-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-is-installed-error")) }) Context("when job is already installed", func() { BeforeEach(func() { bundle.Installed = true }) It("does not install", func() { err := act() Expect(err).ToNot(HaveOccurred()) Expect(bundle.ActionsCalled).To(Equal([]string{})) // no Install }) It("does not download the job template", func() { err := act() Expect(err).ToNot(HaveOccurred()) Expect(blobstore.GetBlobIDs).To(BeNil()) }) }) Context("when job is not installed", func() { BeforeEach(func() { bundle.Installed = false }) It("installs job (but does not enable)", func() { err := act() Expect(err).ToNot(HaveOccurred()) Expect(bundle.ActionsCalled).To(Equal([]string{"Install"})) }) ItInstallsJob(act) }) }) Describe("Apply", func() { act := func() error { return applier.Apply(job) } It("return an error if getting file bundle fails", func() { jobsBc.GetErr = errors.New("fake-get-bundle-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-get-bundle-error")) }) It("returns an error if checking for installed path fails", func() { bundle.IsInstalledErr = errors.New("fake-is-installed-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-is-installed-error")) }) Context("when job is already installed", func() { BeforeEach(func() { bundle.Installed = true }) It("does not install but only enables job", func() { err := act() Expect(err).ToNot(HaveOccurred()) Expect(bundle.ActionsCalled).To(Equal([]string{"Enable"})) // no Install }) It("returns error when job enable fails", func() { bundle.EnableError = errors.New("fake-enable-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-enable-error")) }) It("does not download the job template", func() { err := act() Expect(err).ToNot(HaveOccurred()) Expect(blobstore.GetBlobIDs).To(BeNil()) }) ItUpdatesPackages(act) }) Context("when job is not installed", func() { BeforeEach(func() { bundle.Installed = false }) It("installs and enables job", func() { err := act() Expect(err).ToNot(HaveOccurred()) Expect(bundle.ActionsCalled).To(Equal([]string{"Install", "Enable"})) }) It("returns error when job enable fails", func() { bundle.EnableError = errors.New("fake-enable-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-enable-error")) }) ItInstallsJob(act) ItUpdatesPackages(act) }) }) }) Describe("Configure", func() { It("adds job to the job supervisor", func() { job, bundle := buildJob(jobsBc) fs := fakesys.NewFakeFileSystem() fs.WriteFileString("/path/to/job/monit", "some conf") fs.SetGlob("/path/to/job/*.monit", []string{"/path/to/job/subjob.monit"}) bundle.GetDirPath = "/path/to/job" bundle.GetDirFs = fs err := applier.Configure(job, 0) Expect(err).ToNot(HaveOccurred()) Expect(2).To(Equal(len(jobSupervisor.AddJobArgs))) firstArgs := fakejobsuper.AddJobArgs{ Name: job.Name, Index: 0, ConfigPath: "/path/to/job/monit", } secondArgs := fakejobsuper.AddJobArgs{ Name: job.Name + "_subjob", Index: 0, ConfigPath: "/path/to/job/subjob.monit", } Expect(firstArgs).To(Equal(jobSupervisor.AddJobArgs[0])) Expect(secondArgs).To(Equal(jobSupervisor.AddJobArgs[1])) }) }) Describe("KeepOnly", func() { It("first disables and then uninstalls jobs that are not in keeponly list", func() { _, bundle1 := buildJob(jobsBc) job2, bundle2 := buildJob(jobsBc) _, bundle3 := buildJob(jobsBc) job4, bundle4 := buildJob(jobsBc) jobsBc.ListBundles = []boshbc.Bundle{bundle1, bundle2, bundle3, bundle4} err := applier.KeepOnly([]models.Job{job4, job2}) Expect(err).ToNot(HaveOccurred()) Expect(bundle1.ActionsCalled).To(Equal([]string{"Disable", "Uninstall"})) Expect(bundle2.ActionsCalled).To(Equal([]string{})) Expect(bundle3.ActionsCalled).To(Equal([]string{"Disable", "Uninstall"})) Expect(bundle4.ActionsCalled).To(Equal([]string{})) }) It("returns error when bundle collection fails to return list of installed bundles", func() { jobsBc.ListErr = errors.New("fake-bc-list-error") err := applier.KeepOnly([]models.Job{}) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-bc-list-error")) }) It("returns error when bundle collection cannot retrieve bundle for keep-only job", func() { job1, bundle1 := buildJob(jobsBc) jobsBc.ListBundles = []boshbc.Bundle{bundle1} jobsBc.GetErr = errors.New("fake-bc-get-error") err := applier.KeepOnly([]models.Job{job1}) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-bc-get-error")) }) It("returns error when at least one bundle cannot be disabled", func() { _, bundle1 := buildJob(jobsBc) jobsBc.ListBundles = []boshbc.Bundle{bundle1} bundle1.DisableErr = errors.New("fake-bc-disable-error") err := applier.KeepOnly([]models.Job{}) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-bc-disable-error")) }) It("returns error when at least one bundle cannot be uninstalled", func() { _, bundle1 := buildJob(jobsBc) jobsBc.ListBundles = []boshbc.Bundle{bundle1} bundle1.UninstallErr = errors.New("fake-bc-uninstall-error") err := applier.KeepOnly([]models.Job{}) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-bc-uninstall-error")) }) }) }) }
func init() { const expectedUbuntuDHCPConfig = `# Generated by bosh-agent option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; send host-name "<hostname>"; request subnet-mask, broadcast-address, time-offset, routers, domain-name, domain-name-servers, domain-search, host-name, netbios-name-servers, netbios-scope, interface-mtu, rfc3442-classless-static-routes, ntp-servers; prepend domain-name-servers zz.zz.zz.zz; prepend domain-name-servers yy.yy.yy.yy; prepend domain-name-servers xx.xx.xx.xx; ` Describe("ubuntu", func() { var ( collector *fakestats.FakeStatsCollector fs *fakesys.FakeFileSystem cmdRunner *fakesys.FakeCmdRunner diskManager *fakedisk.FakeDiskManager dirProvider boshdirs.DirectoriesProvider platform Platform cdutil *fakecd.FakeCdUtil compressor boshcmd.Compressor copier boshcmd.Copier vitalsService boshvitals.Service logger boshlog.Logger ) BeforeEach(func() { collector = &fakestats.FakeStatsCollector{} fs = fakesys.NewFakeFileSystem() cmdRunner = fakesys.NewFakeCmdRunner() diskManager = fakedisk.NewFakeDiskManager() dirProvider = boshdirs.NewDirectoriesProvider("/fake-dir") cdutil = fakecd.NewFakeCdUtil() compressor = boshcmd.NewTarballCompressor(cmdRunner, fs) copier = boshcmd.NewCpCopier(cmdRunner, fs) vitalsService = boshvitals.NewService(collector, dirProvider) logger = boshlog.NewLogger(boshlog.LevelNone) }) JustBeforeEach(func() { netManager := boshnet.NewUbuntuNetManager(fs, cmdRunner, 1*time.Millisecond) platform = NewLinuxPlatform( fs, cmdRunner, collector, compressor, copier, dirProvider, vitalsService, cdutil, diskManager, netManager, 1*time.Millisecond, logger, ) }) Describe("SetupDhcp", func() { networks := boshsettings.Networks{ "bosh": boshsettings.Network{ Default: []string{"dns"}, DNS: []string{"xx.xx.xx.xx", "yy.yy.yy.yy", "zz.zz.zz.zz"}, }, "vip": boshsettings.Network{ Default: []string{}, DNS: []string{"aa.aa.aa.aa"}, }, } Context("when dhcp was not previously configured", func() { It("updates dhclient.conf", func() { err := platform.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) dhcpConfig := fs.GetFileTestStat("/etc/dhcp3/dhclient.conf") Expect(dhcpConfig).ToNot(BeNil()) Expect(dhcpConfig.StringContents()).To(Equal(expectedUbuntuDHCPConfig)) }) It("restarts dhclient", func() { err := platform.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) Expect(len(cmdRunner.RunCommands)).To(Equal(2)) Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"pkill", "dhclient3"})) Expect(cmdRunner.RunCommands[1]).To(Equal([]string{"/etc/init.d/networking", "restart"})) }) }) Context("when dhcp was previously configured with different configuration", func() { BeforeEach(func() { fs.WriteFileString("/etc/dhcp3/dhclient.conf", "fake-other-configuration") }) It("sets up dhcp and restarts dhclient", func() { err := platform.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) dhcpConfig := fs.GetFileTestStat("/etc/dhcp3/dhclient.conf") Expect(dhcpConfig).ToNot(BeNil()) Expect(dhcpConfig.StringContents()).To(Equal(expectedUbuntuDHCPConfig)) }) It("sets up dhcp and restarts dhclient", func() { err := platform.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) Expect(len(cmdRunner.RunCommands)).To(Equal(2)) Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"pkill", "dhclient3"})) Expect(cmdRunner.RunCommands[1]).To(Equal([]string{"/etc/init.d/networking", "restart"})) }) }) Context("when dhcp was previously configured with the same configuration", func() { BeforeEach(func() { fs.WriteFileString("/etc/dhcp3/dhclient.conf", expectedUbuntuDHCPConfig) }) It("does not restart dhclient", func() { err := platform.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) dhcpConfig := fs.GetFileTestStat("/etc/dhcp3/dhclient.conf") Expect(dhcpConfig).ToNot(BeNil()) Expect(dhcpConfig.StringContents()).To(Equal(expectedUbuntuDHCPConfig)) }) It("does not restart dhclient", func() { err := platform.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) Expect(len(cmdRunner.RunCommands)).To(Equal(0)) }) }) }) Describe("SetupManualNetworking", func() { BeforeEach(func() { // For mac addr to interface resolution fs.WriteFile("/sys/class/net/eth0", []byte{}) fs.WriteFileString("/sys/class/net/eth0/address", "22:00:0a:1f:ac:2a\n") fs.SetGlob("/sys/class/net/*", []string{"/sys/class/net/eth0"}) }) networks := boshsettings.Networks{ "bosh": boshsettings.Network{ Default: []string{"dns", "gateway"}, IP: "192.168.195.6", Netmask: "255.255.255.0", Gateway: "192.168.195.1", Mac: "22:00:0a:1f:ac:2a", DNS: []string{"10.80.130.2", "10.80.130.1"}, }, } Context("when manual networking was not previously configured", func() { It("writes /etc/network/interfaces", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) networkConfig := fs.GetFileTestStat("/etc/network/interfaces") Expect(networkConfig).ToNot(BeNil()) Expect(networkConfig.StringContents()).To(Equal(expectedUbuntuNetworkInterfaces)) }) It("restarts networking", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) Expect(len(cmdRunner.RunCommands) >= 2).To(BeTrue()) Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"service", "network-interface", "stop", "INTERFACE=eth0"})) Expect(cmdRunner.RunCommands[1]).To(Equal([]string{"service", "network-interface", "start", "INTERFACE=eth0"})) }) It("updates dns", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) resolvConf := fs.GetFileTestStat("/etc/resolv.conf") Expect(resolvConf).ToNot(BeNil()) Expect(resolvConf.StringContents()).To(Equal(expectedUbuntuResolvConf)) }) It("starts sending arping", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) time.Sleep(100 * time.Millisecond) Expect(cmdRunner.RunCommands[2]).To(Equal([]string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"})) Expect(cmdRunner.RunCommands[7]).To(Equal([]string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"})) }) }) Context("when manual networking was previously configured with different configuration", func() { BeforeEach(func() { fs.WriteFileString("/etc/network/interfaces", "fake-manual-config") }) It("updates /etc/network/interfaces", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) networkConfig := fs.GetFileTestStat("/etc/network/interfaces") Expect(networkConfig).ToNot(BeNil()) Expect(networkConfig.StringContents()).To(Equal(expectedUbuntuNetworkInterfaces)) }) It("restarts networking", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) Expect(len(cmdRunner.RunCommands) >= 2).To(BeTrue()) Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"service", "network-interface", "stop", "INTERFACE=eth0"})) Expect(cmdRunner.RunCommands[1]).To(Equal([]string{"service", "network-interface", "start", "INTERFACE=eth0"})) }) It("updates dns", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) resolvConf := fs.GetFileTestStat("/etc/resolv.conf") Expect(resolvConf).ToNot(BeNil()) Expect(resolvConf.StringContents()).To(Equal(expectedUbuntuResolvConf)) }) It("starts sending arping", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) time.Sleep(100 * time.Millisecond) Expect(cmdRunner.RunCommands[2]).To(Equal([]string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"})) Expect(cmdRunner.RunCommands[7]).To(Equal([]string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"})) }) }) Context("when manual networking was previously configured with same configuration", func() { BeforeEach(func() { fs.WriteFileString("/etc/network/interfaces", expectedUbuntuNetworkInterfaces) }) It("keeps same /etc/network/interfaces", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) networkConfig := fs.GetFileTestStat("/etc/network/interfaces") Expect(networkConfig).ToNot(BeNil()) Expect(networkConfig.StringContents()).To(Equal(expectedUbuntuNetworkInterfaces)) }) It("does not restart networking because configuration did not change", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) for _, cmd := range cmdRunner.RunCommands { Expect(cmd[0]).ToNot(Equal("service")) } }) It("updates /etc/resolv.conf for DNS", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) resolvConf := fs.GetFileTestStat("/etc/resolv.conf") Expect(resolvConf).ToNot(BeNil()) Expect(resolvConf.StringContents()).To(Equal(expectedUbuntuResolvConf)) }) It("starts sending 6 arp ping", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) time.Sleep(100 * time.Millisecond) Expect(len(cmdRunner.RunCommands)).To(Equal(6)) Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"})) Expect(cmdRunner.RunCommands[5]).To(Equal([]string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"})) }) }) }) }) }
func createResolver() (r DigDnsResolver) { r = NewDigDnsResolver(boshlog.NewLogger(boshlog.LEVEL_NONE)) return }