func testUbuntuSetupDhcp( t *testing.T, fakeStats *fakestats.FakeStatsCollector, fakeFs *fakesys.FakeFileSystem, fakeCmdRunner *fakesys.FakeCmdRunner, fakeDiskManager fakedisk.FakeDiskManager, fakeCompressor *fakedisk.FakeCompressor, ) { 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"}, }, } ubuntu := newUbuntuPlatform(fakeStats, fakeFs, fakeCmdRunner, fakeDiskManager, fakeCompressor) ubuntu.SetupDhcp(networks) dhcpConfig := fakeFs.GetFileTestStat("/etc/dhcp3/dhclient.conf") assert.NotNil(t, dhcpConfig) assert.Equal(t, dhcpConfig.Content, EXPECTED_DHCP_CONFIG) }
func init() { Describe("concreteV1Service", func() { var ( fs *fakesys.FakeFileSystem specPath = "/spec.json" service V1Service ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() service = NewConcreteV1Service(fs, specPath) }) Describe("Get", func() { Context("when filesystem has a spec file", func() { BeforeEach(func() { fs.WriteFileString(specPath, `{"deployment":"fake-deployment-name"}`) }) It("reads spec from filesystem", func() { spec, err := service.Get() Expect(err).ToNot(HaveOccurred()) Expect(spec).To(Equal(V1ApplySpec{Deployment: "fake-deployment-name"})) }) It("returns error if reading spec from filesystem errs", func() { fs.ReadFileError = errors.New("fake-read-error") spec, err := service.Get() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-read-error")) Expect(spec).To(Equal(V1ApplySpec{})) }) }) Context("when filesystem does not have a spec file", func() { It("reads spec from filesystem", func() { spec, err := service.Get() Expect(err).ToNot(HaveOccurred()) Expect(spec).To(Equal(V1ApplySpec{})) }) }) }) Describe("Set", func() { newSpec := V1ApplySpec{Deployment: "fake-deployment-name"} It("writes spec to filesystem", func() { err := service.Set(newSpec) Expect(err).ToNot(HaveOccurred()) specPathStats := fs.GetFileTestStat(specPath) Expect(specPathStats).ToNot(BeNil()) boshassert.MatchesJSONBytes(GinkgoT(), newSpec, specPathStats.Content) }) It("returns error if writing spec to filesystem errs", func() { fs.WriteToFileError = errors.New("fake-write-error") err := service.Set(newSpec) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-write-error")) }) }) Describe("PopulateDynamicNetworks", func() { Context("when there are no dynamic networks", func() { unresolvedSpec := V1ApplySpec{ Deployment: "fake-deployment", NetworkSpecs: map[string]NetworkSpec{ "fake-net": NetworkSpec{ Fields: map[string]interface{}{"ip": "fake-net-ip"}, }, }, } It("returns spec without modifying any networks", func() { spec, err := service.PopulateDynamicNetworks(unresolvedSpec, boshsettings.Settings{}) Expect(err).ToNot(HaveOccurred()) Expect(spec).To(Equal(V1ApplySpec{ Deployment: "fake-deployment", NetworkSpecs: map[string]NetworkSpec{ "fake-net": NetworkSpec{ Fields: map[string]interface{}{"ip": "fake-net-ip"}, }, }, })) }) }) Context("when there are dynamic networks", func() { unresolvedSpec := V1ApplySpec{ Deployment: "fake-deployment", NetworkSpecs: map[string]NetworkSpec{ "fake-net1": NetworkSpec{ Fields: map[string]interface{}{ "ip": "fake-net1-ip", "netmask": "fake-net1-netmask", "gateway": "fake-net1-gateway", }, }, "fake-net2": NetworkSpec{ Fields: map[string]interface{}{ "type": NetworkSpecTypeDynamic, "ip": "fake-net2-ip", "netmask": "fake-net2-netmask", "gateway": "fake-net2-gateway", }, }, "fake-net3": NetworkSpec{ Fields: map[string]interface{}{ "type": NetworkSpecTypeDynamic, "ip": "fake-net3-ip", "netmask": "fake-net3-netmask", "gateway": "fake-net3-gateway", }, }, }, } Context("when associated network is in settings", func() { settings := boshsettings.Settings{ Networks: boshsettings.Networks{ "fake-net1": boshsettings.Network{ IP: "fake-resolved1-ip", Netmask: "fake-resolved1-netmask", Gateway: "fake-resolved1-gateway", }, "fake-net2": boshsettings.Network{ IP: "fake-resolved2-ip", Netmask: "fake-resolved2-netmask", Gateway: "fake-resolved2-gateway", }, "fake-net3": boshsettings.Network{ IP: "fake-resolved3-ip", Netmask: "fake-resolved3-netmask", Gateway: "fake-resolved3-gateway", }, }, } It("returns spec with modified dynamic networks and keeping everything else the same", func() { spec, err := service.PopulateDynamicNetworks(unresolvedSpec, settings) Expect(err).ToNot(HaveOccurred()) Expect(spec).To(Equal(V1ApplySpec{ Deployment: "fake-deployment", NetworkSpecs: map[string]NetworkSpec{ "fake-net1": NetworkSpec{ Fields: map[string]interface{}{ // ip info not replaced "ip": "fake-net1-ip", "netmask": "fake-net1-netmask", "gateway": "fake-net1-gateway", }, }, "fake-net2": NetworkSpec{ Fields: map[string]interface{}{ "type": NetworkSpecTypeDynamic, "ip": "fake-resolved2-ip", "netmask": "fake-resolved2-netmask", "gateway": "fake-resolved2-gateway", }, }, "fake-net3": NetworkSpec{ Fields: map[string]interface{}{ "type": NetworkSpecTypeDynamic, "ip": "fake-resolved3-ip", "netmask": "fake-resolved3-netmask", "gateway": "fake-resolved3-gateway", }, }, }, })) }) }) Context("when associated network cannot be found in settings", func() { It("returns error", func() { spec, err := service.PopulateDynamicNetworks(unresolvedSpec, boshsettings.Settings{}) Expect(err).To(Equal(errors.New("Network fake-net2 is not found in settings"))) Expect(spec).To(Equal(V1ApplySpec{})) }) }) }) }) }) }
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 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, yy.yy.yy.yy, xx.xx.xx.xx; ` Describe("ubuntuNetManager", func() { var ( fs *fakesys.FakeFileSystem cmdRunner *fakesys.FakeCmdRunner defaultNetworkResolver *fakenet.FakeDefaultNetworkResolver netManager NetManager ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() cmdRunner = fakesys.NewFakeCmdRunner() defaultNetworkResolver = &fakenet.FakeDefaultNetworkResolver{} logger := boshlog.NewLogger(boshlog.LevelNone) netManager = NewUbuntuNetManager(fs, cmdRunner, defaultNetworkResolver, 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"}, }, } ItRestartsDhcp := func() { Context("when ifconfig version is 0.7", func() { BeforeEach(func() { cmdRunner.AddCmdResult("ifup --version", fakesys.FakeCmdResult{ Stdout: "ifup version 0.7.47", }) }) It("restarts dhclient", func() { err := netManager.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) Expect(len(cmdRunner.RunCommands)).To(Equal(3)) Expect(cmdRunner.RunCommands[1]).To(Equal([]string{"ifdown", "-a", "--no-loopback"})) Expect(cmdRunner.RunCommands[2]).To(Equal([]string{"ifup", "-a", "--no-loopback"})) }) }) Context("when ifconfig version is 0.6", func() { BeforeEach(func() { cmdRunner.AddCmdResult("ifup --version", fakesys.FakeCmdResult{ Stdout: "ifup version 0.6.0", }) }) It("restarts dhclient", func() { err := netManager.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) Expect(len(cmdRunner.RunCommands)).To(Equal(3)) Expect(cmdRunner.RunCommands[1]).To(Equal([]string{"ifdown", "-a", "--exclude=lo"})) Expect(cmdRunner.RunCommands[2]).To(Equal([]string{"ifup", "-a", "--exclude=lo"})) }) }) } ItUpdatesDhcp3Config := func() { It("updates /etc/dhcp3/dhclient.conf", func() { err := netManager.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) dhcpConfig := fs.GetFileTestStat("/etc/dhcp3/dhclient.conf") Expect(dhcpConfig).ToNot(BeNil()) Expect(dhcpConfig.StringContents()).To(Equal(expectedUbuntuDHCPConfig)) }) } ItUpdatesDhcpConfig := func() { It("updates /etc/dhcp/dhclient.conf", func() { err := netManager.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) dhcpConfig := fs.GetFileTestStat("/etc/dhcp/dhclient.conf") Expect(dhcpConfig).ToNot(BeNil()) Expect(dhcpConfig.StringContents()).To(Equal(expectedUbuntuDHCPConfig)) }) } ItDoesNotRestartDhcp := func() { It("does not restart dhclient", func() { err := netManager.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) Expect(len(cmdRunner.RunCommands)).To(Equal(0)) }) } Context("when dhclient3 is installed on the system", func() { BeforeEach(func() { cmdRunner.CommandExistsValue = true }) Context("when dhcp was not previously configured", func() { ItUpdatesDhcp3Config() ItRestartsDhcp() }) Context("when dhcp was previously configured with different configuration", func() { BeforeEach(func() { fs.WriteFileString("/etc/dhcp3/dhclient.conf", "fake-other-configuration") }) ItUpdatesDhcp3Config() ItRestartsDhcp() }) Context("when dhcp was previously configured with the same configuration", func() { BeforeEach(func() { fs.WriteFileString("/etc/dhcp3/dhclient.conf", expectedUbuntuDHCPConfig) }) ItUpdatesDhcp3Config() ItDoesNotRestartDhcp() }) }) Context("when dhclient3 is not installed on the system", func() { BeforeEach(func() { cmdRunner.CommandExistsValue = false }) Context("when dhcp was not previously configured", func() { ItUpdatesDhcpConfig() ItRestartsDhcp() }) Context("when dhcp was previously configured with different configuration", func() { BeforeEach(func() { fs.WriteFileString("/etc/dhcp/dhclient.conf", "fake-other-configuration") }) ItUpdatesDhcpConfig() ItRestartsDhcp() }) Context("when dhcp was previously configured with the same configuration", func() { BeforeEach(func() { fs.WriteFileString("/etc/dhcp/dhclient.conf", expectedUbuntuDHCPConfig) }) ItUpdatesDhcpConfig() ItDoesNotRestartDhcp() }) }) }) Describe("SetupManualNetworking", func() { var errCh chan error BeforeEach(func() { errCh = make(chan error) }) 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 := netManager.SetupManualNetworking(networks, nil) 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 := netManager.SetupManualNetworking(networks, errCh) Expect(err).ToNot(HaveOccurred()) <-errCh // wait for all arpings 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 := netManager.SetupManualNetworking(networks, nil) 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 := netManager.SetupManualNetworking(networks, errCh) Expect(err).ToNot(HaveOccurred()) <-errCh // wait for all arpings 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 := netManager.SetupManualNetworking(networks, nil) 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 := netManager.SetupManualNetworking(networks, errCh) Expect(err).ToNot(HaveOccurred()) <-errCh // wait for all arpings 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 := netManager.SetupManualNetworking(networks, nil) 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 pings", func() { err := netManager.SetupManualNetworking(networks, errCh) Expect(err).ToNot(HaveOccurred()) <-errCh // wait for all arpings 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 := netManager.SetupManualNetworking(networks, nil) 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 := netManager.SetupManualNetworking(networks, errCh) Expect(err).ToNot(HaveOccurred()) <-errCh // wait for all arpings for _, cmd := range cmdRunner.RunCommands { Expect(cmd[0]).ToNot(Equal("service")) } }) It("updates /etc/resolv.conf for DNS", func() { err := netManager.SetupManualNetworking(networks, nil) 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 := netManager.SetupManualNetworking(networks, errCh) Expect(err).ToNot(HaveOccurred()) <-errCh // wait for all arpings 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"})) }) }) }) }) }
"errors" "os" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "bosh/agent/applier/bundlecollection" boshlog "bosh/logger" fakesys "bosh/system/fakes" ) var _ = Describe("FileBundle", func() { var ( fs *fakesys.FakeFileSystem logger boshlog.Logger sourcePath string installPath string enablePath string fileBundle FileBundle ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() installPath = "/install-path" enablePath = "/enable-path" logger = boshlog.NewLogger(boshlog.LevelNone) fileBundle = NewFileBundle(installPath, enablePath, fs, logger) }) createSourcePath := func() string { path := "/source-path" err := fs.MkdirAll(path, os.ModePerm)
package main_test import ( fakesys "bosh/system/fakes" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "boshprovisioner/main" bpvm "boshprovisioner/vm" ) var _ = Describe("NewConfigFromPath", func() { var ( fs *fakesys.FakeFileSystem ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() }) It("defautls null values to agent provisioner config defaults", func() { configJSON := `{ "manifest_path": "fake-manifest-path", "assets_dir": "fake-assets-dir", "repos_dir": "fake-repos-dir", "blobstore": { "provider": "local", "options": { "blobstore_path": "fake-blobstore-path" } },
fakestats "bosh/platform/stats/fakes" boshvitals "bosh/platform/vitals" boshsettings "bosh/settings" boshdirs "bosh/settings/directories" fakesys "bosh/system/fakes" ) var _ = Describe("LinuxPlatform", func() { var ( collector *fakestats.FakeStatsCollector fs *fakesys.FakeFileSystem cmdRunner *fakesys.FakeCmdRunner diskManager *fakedisk.FakeDiskManager dirProvider boshdirs.DirectoriesProvider diskWaitTimeout time.Duration devicePathResolver *fakedpresolv.FakeDevicePathResolver platform Platform cdutil *fakecd.FakeCdUtil compressor boshcmd.Compressor copier boshcmd.Copier vitalsService boshvitals.Service netManager *fakenet.FakeNetManager options LinuxOptions ) BeforeEach(func() { logger := boshlog.NewLogger(boshlog.LevelNone) collector = &fakestats.FakeStatsCollector{} fs = fakesys.NewFakeFileSystem() cmdRunner = fakesys.NewFakeCmdRunner() diskManager = fakedisk.NewFakeDiskManager()
func init() { const expectedCentosDHCPConfig = `# 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; ` const expectedCentosIfcfg = `DEVICE=eth0 BOOTPROTO=static IPADDR=192.168.195.6 NETMASK=255.255.255.0 BROADCAST=192.168.195.255 GATEWAY=192.168.195.1 ONBOOT=yes` Describe("centos", 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.NewCentosNetManager(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("writes dhcp configuration", func() { err := platform.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) dhcpConfig := fs.GetFileTestStat("/etc/dhcp/dhclient.conf") Expect(dhcpConfig).ToNot(BeNil()) Expect(dhcpConfig.StringContents()).To(Equal(expectedCentosDHCPConfig)) }) It("restarts network", func() { err := platform.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) Expect(len(cmdRunner.RunCommands)).To(Equal(1)) Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"service", "network", "restart"})) }) }) Context("when dhcp was previously configured with different configuration", func() { BeforeEach(func() { fs.WriteFileString("/etc/dhcp/dhclient.conf", "fake-other-configuration") }) It("updates dhcp configuration", func() { err := platform.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) dhcpConfig := fs.GetFileTestStat("/etc/dhcp/dhclient.conf") Expect(dhcpConfig).ToNot(BeNil()) Expect(dhcpConfig.StringContents()).To(Equal(expectedCentosDHCPConfig)) }) It("restarts network", func() { err := platform.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) Expect(len(cmdRunner.RunCommands)).To(Equal(1)) Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"service", "network", "restart"})) }) }) Context("when dhcp was previously configured with same configuration", func() { BeforeEach(func() { fs.WriteFileString("/etc/dhcp/dhclient.conf", expectedCentosDHCPConfig) }) It("keeps dhcp configuration", func() { err := platform.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) dhcpConfig := fs.GetFileTestStat("/etc/dhcp/dhclient.conf") Expect(dhcpConfig).ToNot(BeNil()) Expect(dhcpConfig.StringContents()).To(Equal(expectedCentosDHCPConfig)) }) It("does not restart network", func() { err := platform.SetupDhcp(networks) Expect(err).ToNot(HaveOccurred()) Expect(len(cmdRunner.RunCommands)).To(Equal(0)) }) }) }) Describe("SetupManualNetworking", func() { 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"}, }, } BeforeEach(func() { 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"}) }) It("sets up centos expected ifconfig", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) networkConfig := fs.GetFileTestStat("/etc/sysconfig/network-scripts/ifcfg-eth0") Expect(networkConfig).ToNot(BeNil()) Expect(networkConfig.StringContents()).To(Equal(expectedCentosIfcfg)) }) It("sets up centos /etc/resolv.conf", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) resolvConf := fs.GetFileTestStat("/etc/resolv.conf") Expect(resolvConf).ToNot(BeNil()) Expect(resolvConf.StringContents()).To(Equal(expectedCentosResolvConf)) }) It("restarts networking", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) fs.GetFileTestStat("/etc/sysconfig/network-scripts/ifcfg-eth0") fs.GetFileTestStat("/etc/resolv.conf") time.Sleep(100 * time.Millisecond) Expect(len(cmdRunner.RunCommands)).To(Equal(7)) Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"service", "network", "restart"})) }) It("runs arping commands", func() { err := platform.SetupManualNetworking(networks) Expect(err).ToNot(HaveOccurred()) fs.GetFileTestStat("/etc/sysconfig/network-scripts/ifcfg-eth0") fs.GetFileTestStat("/etc/resolv.conf") time.Sleep(100 * time.Millisecond) Expect(cmdRunner.RunCommands[1]).To(Equal([]string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"})) Expect(cmdRunner.RunCommands[6]).To(Equal([]string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"})) }) }) }) }
package bundlecollection_test import ( . "bosh/agent/applier/bundlecollection" fakesys "bosh/system/fakes" "errors" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "os" ) var _ = Describe("FileBundle", func() { var ( fs *fakesys.FakeFileSystem installPath string enablePath string fileBundle FileBundle ) BeforeEach(func() { fs = &fakesys.FakeFileSystem{} installPath = "/install-path" enablePath = "/enable-path" }) JustBeforeEach(func() { fileBundle = NewFileBundle(installPath, enablePath, fs) }) Describe("#Install", func() { It("Installs the bundle at the given path with the correct permissions", func() {
. "github.com/onsi/gomega" "github.com/stretchr/testify/assert" . "bosh/infrastructure" fakedpresolv "bosh/infrastructure/devicepathresolver/fakes" fakeplatform "bosh/platform/fakes" boshsettings "bosh/settings" boshdir "bosh/settings/directories" fakefs "bosh/system/fakes" ) var _ = Describe("dummyInfrastructure", func() { Describe("GetSettings", func() { var ( fs *fakefs.FakeFileSystem dirProvider boshdir.DirectoriesProvider inf Infrastructure ) BeforeEach(func() { fs = fakefs.NewFakeFileSystem() dirProvider = boshdir.NewDirectoriesProvider("/var/vcap") platform := fakeplatform.NewFakePlatform() fakeDevicePathResolver := fakedpresolv.NewFakeDevicePathResolver() inf = NewDummyInfrastructure(fs, dirProvider, platform, fakeDevicePathResolver) }) Context("when infrastructure settings file is found", func() { BeforeEach(func() { settingsPath := filepath.Join(dirProvider.BoshDir(), "dummy-cpi-agent-env.json")
import ( "errors" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "bosh/blobstore" fakesys "bosh/system/fakes" fakeuuid "bosh/uuid/fakes" ) var _ = Describe("localBlobstore", func() { var ( fs *fakesys.FakeFileSystem uuidGen *fakeuuid.FakeGenerator fakeBlobstorePath = "/some/local/path" blobstore Blobstore ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() uuidGen = &fakeuuid.FakeGenerator{} options := map[string]interface{}{"blobstore_path": fakeBlobstorePath} blobstore = NewLocalBlobstore(fs, uuidGen, options) }) Describe("Validate", func() { It("returns no error when blobstore_path is present", func() { err := blobstore.Validate() Expect(err).ToNot(HaveOccurred()) })
. "github.com/onsi/ginkgo" . "github.com/onsi/gomega" boshlog "bosh/logger" . "bosh/platform" fakestats "bosh/platform/stats/fakes" boshsettings "bosh/settings" boshdirs "bosh/settings/directories" fakesys "bosh/system/fakes" ) var _ = Describe("dummyPlatform", func() { var ( collector *fakestats.FakeStatsCollector fs *fakesys.FakeFileSystem cmdRunner *fakesys.FakeCmdRunner dirProvider boshdirs.DirectoriesProvider platform Platform ) BeforeEach(func() { collector = &fakestats.FakeStatsCollector{} fs = fakesys.NewFakeFileSystem() cmdRunner = fakesys.NewFakeCmdRunner() dirProvider = boshdirs.NewDirectoriesProvider("/fake-dir") logger := boshlog.NewLogger(boshlog.LevelNone) platform = NewDummyPlatform(collector, fs, cmdRunner, dirProvider, logger) }) Describe("GetDefaultNetwork", func() { Context("when default networks settings file is found", func() {
. "github.com/onsi/ginkgo" . "github.com/onsi/gomega" boshassert "bosh/assert" . "bosh/blobstore" boshdir "bosh/settings/directories" fakesys "bosh/system/fakes" fakeuuid "bosh/uuid/fakes" ) var _ = Describe("external", func() { var ( fs *fakesys.FakeFileSystem runner *fakesys.FakeCmdRunner uuidGen *fakeuuid.FakeGenerator configPath string blobstore Blobstore ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() runner = fakesys.NewFakeCmdRunner() uuidGen = &fakeuuid.FakeGenerator{} dirProvider := boshdir.NewDirectoriesProvider("/var/vcap") configPath = filepath.Join(dirProvider.EtcDir(), "blobstore-fake-provider.json") blobstore = NewExternalBlobstore("fake-provider", map[string]interface{}{}, fs, runner, uuidGen, configPath) }) Describe("Validate", func() { It("external validate writes config file", func() {
func init() { Describe("Testing with Ginkgo", func() { var ( collector *fakestats.FakeStatsCollector fs *fakesys.FakeFileSystem cmdRunner *fakesys.FakeCmdRunner diskManager fakedisk.FakeDiskManager dirProvider boshdirs.DirectoriesProvider diskWaitTimeout time.Duration platform Platform cdutil *fakecd.FakeCdUtil compressor boshcmd.Compressor copier boshcmd.Copier vitalsService boshvitals.Service ) BeforeEach(func() { collector = &fakestats.FakeStatsCollector{} fs = &fakesys.FakeFileSystem{} cmdRunner = &fakesys.FakeCmdRunner{} diskManager = fakedisk.NewFakeDiskManager(cmdRunner) dirProvider = boshdirs.NewDirectoriesProvider("/fake-dir") diskWaitTimeout = 1 * time.Millisecond cdutil = fakecd.NewFakeCdUtil() compressor = boshcmd.NewTarballCompressor(cmdRunner, fs) copier = boshcmd.NewCpCopier(cmdRunner, fs) vitalsService = boshvitals.NewService(collector, dirProvider) }) JustBeforeEach(func() { netManager := boshnet.NewUbuntuNetManager(fs, cmdRunner, 1*time.Millisecond) platform = NewLinuxPlatform( fs, cmdRunner, collector, compressor, copier, dirProvider, vitalsService, cdutil, diskManager, diskWaitTimeout, netManager, ) }) It("ubuntu setup runtime configuration", func() { err := platform.SetupRuntimeConfiguration() assert.NoError(GinkgoT(), err) assert.Equal(GinkgoT(), 1, len(cmdRunner.RunCommands)) assert.Equal(GinkgoT(), []string{"bosh-agent-rc"}, cmdRunner.RunCommands[0]) }) It("ubuntu create user", func() { expectedUseradd := []string{ "useradd", "-m", "-b", "/some/path/to/home", "-s", "/bin/bash", "-p", "bar-pwd", "foo-user", } password := "******" err := platform.CreateUser("foo-user", password, "/some/path/to/home") assert.NoError(GinkgoT(), err) basePathStat := fs.GetFileTestStat("/some/path/to/home") assert.Equal(GinkgoT(), fakesys.FakeFileTypeDir, basePathStat.FileType) assert.Equal(GinkgoT(), os.FileMode(0755), basePathStat.FileMode) assert.Equal(GinkgoT(), 1, len(cmdRunner.RunCommands)) assert.Equal(GinkgoT(), expectedUseradd, cmdRunner.RunCommands[0]) }) It("ubuntu create user with an empty password", func() { expectedUseradd := []string{ "useradd", "-m", "-b", "/some/path/to/home", "-s", "/bin/bash", "foo-user", } password := "" err := platform.CreateUser("foo-user", password, "/some/path/to/home") assert.NoError(GinkgoT(), err) basePathStat := fs.GetFileTestStat("/some/path/to/home") assert.Equal(GinkgoT(), fakesys.FakeFileTypeDir, basePathStat.FileType) assert.Equal(GinkgoT(), os.FileMode(0755), basePathStat.FileMode) assert.Equal(GinkgoT(), 1, len(cmdRunner.RunCommands)) assert.Equal(GinkgoT(), expectedUseradd, cmdRunner.RunCommands[0]) }) It("ubuntu add user to groups", func() { err := platform.AddUserToGroups("foo-user", []string{"group1", "group2", "group3"}) assert.NoError(GinkgoT(), err) assert.Equal(GinkgoT(), 1, len(cmdRunner.RunCommands)) usermod := []string{"usermod", "-G", "group1,group2,group3", "foo-user"} assert.Equal(GinkgoT(), usermod, cmdRunner.RunCommands[0]) }) It("ubuntu delete users with prefix and regex", func() { passwdFile := fmt.Sprintf(`%sfoo:... %sbar:... foo:... bar:... foobar:... %sfoobar:...`, boshsettings.EPHEMERAL_USER_PREFIX, boshsettings.EPHEMERAL_USER_PREFIX, boshsettings.EPHEMERAL_USER_PREFIX, ) fs.WriteToFile("/etc/passwd", passwdFile) err := platform.DeleteEphemeralUsersMatching("bar$") assert.NoError(GinkgoT(), err) assert.Equal(GinkgoT(), 2, len(cmdRunner.RunCommands)) assert.Equal(GinkgoT(), []string{"userdel", "-r", "bosh_bar"}, cmdRunner.RunCommands[0]) assert.Equal(GinkgoT(), []string{"userdel", "-r", "bosh_foobar"}, cmdRunner.RunCommands[1]) }) It("ubuntu setup ssh", func() { fs.HomeDirHomePath = "/some/home/dir" platform.SetupSsh("some public key", "vcap") sshDirPath := "/some/home/dir/.ssh" sshDirStat := fs.GetFileTestStat(sshDirPath) assert.Equal(GinkgoT(), fs.HomeDirUsername, "vcap") assert.NotNil(GinkgoT(), sshDirStat) assert.Equal(GinkgoT(), fakesys.FakeFileTypeDir, sshDirStat.FileType) assert.Equal(GinkgoT(), sshDirStat.FileMode, os.FileMode(0700)) assert.Equal(GinkgoT(), sshDirStat.Username, "vcap") authKeysStat := fs.GetFileTestStat(filepath.Join(sshDirPath, "authorized_keys")) assert.NotNil(GinkgoT(), authKeysStat) assert.Equal(GinkgoT(), authKeysStat.FileType, fakesys.FakeFileTypeFile) assert.Equal(GinkgoT(), authKeysStat.FileMode, os.FileMode(0600)) assert.Equal(GinkgoT(), authKeysStat.Username, "vcap") assert.Equal(GinkgoT(), authKeysStat.Content, "some public key") }) It("ubuntu set user password", func() { platform.SetUserPassword("my-user", "my-encrypted-password") assert.Equal(GinkgoT(), 1, len(cmdRunner.RunCommands)) assert.Equal(GinkgoT(), []string{"usermod", "-p", "my-encrypted-password", "my-user"}, cmdRunner.RunCommands[0]) }) It("ubuntu setup hostname", func() { platform.SetupHostname("foobar.local") assert.Equal(GinkgoT(), 1, len(cmdRunner.RunCommands)) assert.Equal(GinkgoT(), []string{"hostname", "foobar.local"}, cmdRunner.RunCommands[0]) hostnameFileContent, err := fs.ReadFile("/etc/hostname") assert.NoError(GinkgoT(), err) assert.Equal(GinkgoT(), "foobar.local", hostnameFileContent) hostsFileContent, err := fs.ReadFile("/etc/hosts") assert.NoError(GinkgoT(), err) assert.Equal(GinkgoT(), UBUNTU_EXPECTED_ETC_HOSTS, hostsFileContent) }) It("ubuntu setup dhcp", 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"}, }, } platform.SetupDhcp(networks) dhcpConfig := fs.GetFileTestStat("/etc/dhcp3/dhclient.conf") assert.NotNil(GinkgoT(), dhcpConfig) assert.Equal(GinkgoT(), dhcpConfig.Content, UBUNTU_EXPECTED_DHCP_CONFIG) assert.Equal(GinkgoT(), len(cmdRunner.RunCommands), 2) assert.Equal(GinkgoT(), cmdRunner.RunCommands[0], []string{"pkill", "dhclient3"}) assert.Equal(GinkgoT(), cmdRunner.RunCommands[1], []string{"/etc/init.d/networking", "restart"}) }) It("ubuntu setup dhcp with pre existing configuration", func() { fs.WriteToFile("/etc/dhcp3/dhclient.conf", UBUNTU_EXPECTED_DHCP_CONFIG) 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"}, }, } platform.SetupDhcp(networks) dhcpConfig := fs.GetFileTestStat("/etc/dhcp3/dhclient.conf") assert.NotNil(GinkgoT(), dhcpConfig) assert.Equal(GinkgoT(), dhcpConfig.Content, UBUNTU_EXPECTED_DHCP_CONFIG) assert.Equal(GinkgoT(), len(cmdRunner.RunCommands), 0) }) It("ubuntu setup manual networking", func() { 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"}, }, } fs.WriteToFile("/sys/class/net/eth0", "") fs.WriteToFile("/sys/class/net/eth0/address", "22:00:0a:1f:ac:2a\n") fs.GlobPaths = []string{"/sys/class/net/eth0"} platform.SetupManualNetworking(networks) networkConfig := fs.GetFileTestStat("/etc/network/interfaces") assert.NotNil(GinkgoT(), networkConfig) assert.Equal(GinkgoT(), networkConfig.Content, UBUNTU_EXPECTED_NETWORK_INTERFACES) resolvConf := fs.GetFileTestStat("/etc/resolv.conf") assert.NotNil(GinkgoT(), resolvConf) assert.Equal(GinkgoT(), resolvConf.Content, UBUNTU_EXPECTED_RESOLV_CONF) time.Sleep(100 * time.Millisecond) assert.Equal(GinkgoT(), len(cmdRunner.RunCommands), 8) assert.Equal(GinkgoT(), cmdRunner.RunCommands[0], []string{"service", "network-interface", "stop", "INTERFACE=eth0"}) assert.Equal(GinkgoT(), cmdRunner.RunCommands[1], []string{"service", "network-interface", "start", "INTERFACE=eth0"}) assert.Equal(GinkgoT(), cmdRunner.RunCommands[2], []string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"}) assert.Equal(GinkgoT(), cmdRunner.RunCommands[7], []string{"arping", "-c", "1", "-U", "-I", "eth0", "192.168.195.6"}) }) It("ubuntu setup logrotate", func() { platform.SetupLogrotate("fake-group-name", "fake-base-path", "fake-size") logrotateFileContent, err := fs.ReadFile("/etc/logrotate.d/fake-group-name") assert.NoError(GinkgoT(), err) assert.Equal(GinkgoT(), UBUNTU_EXPECTED_ETC_LOGROTATE, logrotateFileContent) }) It("ubuntu set time with ntp servers", func() { platform.SetTimeWithNtpServers([]string{"0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"}) ntpConfig := fs.GetFileTestStat("/fake-dir/bosh/etc/ntpserver") assert.Equal(GinkgoT(), "0.north-america.pool.ntp.org 1.north-america.pool.ntp.org", ntpConfig.Content) assert.Equal(GinkgoT(), fakesys.FakeFileTypeFile, ntpConfig.FileType) assert.Equal(GinkgoT(), 1, len(cmdRunner.RunCommands)) assert.Equal(GinkgoT(), []string{"ntpdate"}, cmdRunner.RunCommands[0]) }) It("ubuntu set time with ntp servers is noop when no ntp server provided", func() { platform.SetTimeWithNtpServers([]string{}) assert.Equal(GinkgoT(), 0, len(cmdRunner.RunCommands)) ntpConfig := fs.GetFileTestStat("/fake-dir/bosh/etc/ntpserver") assert.Nil(GinkgoT(), ntpConfig) }) It("ubuntu setup ephemeral disk with path", func() { fakeFormatter := diskManager.FakeFormatter fakePartitioner := diskManager.FakePartitioner fakeMounter := diskManager.FakeMounter fakePartitioner.GetDeviceSizeInMbSizes = map[string]uint64{"/dev/xvda": uint64(1024 * 1024 * 1024)} fs.WriteToFile("/dev/xvda", "") err := platform.SetupEphemeralDiskWithPath("/dev/xvda") assert.NoError(GinkgoT(), err) dataDir := fs.GetFileTestStat("/fake-dir/data") assert.Equal(GinkgoT(), fakesys.FakeFileTypeDir, dataDir.FileType) assert.Equal(GinkgoT(), os.FileMode(0750), dataDir.FileMode) assert.Equal(GinkgoT(), "/dev/xvda", fakePartitioner.PartitionDevicePath) assert.Equal(GinkgoT(), 2, len(fakePartitioner.PartitionPartitions)) swapPartition := fakePartitioner.PartitionPartitions[0] ext4Partition := fakePartitioner.PartitionPartitions[1] assert.Equal(GinkgoT(), "swap", swapPartition.Type) assert.Equal(GinkgoT(), "linux", ext4Partition.Type) assert.Equal(GinkgoT(), 2, len(fakeFormatter.FormatPartitionPaths)) assert.Equal(GinkgoT(), "/dev/xvda1", fakeFormatter.FormatPartitionPaths[0]) assert.Equal(GinkgoT(), "/dev/xvda2", fakeFormatter.FormatPartitionPaths[1]) assert.Equal(GinkgoT(), 2, len(fakeFormatter.FormatFsTypes)) assert.Equal(GinkgoT(), boshdisk.FileSystemSwap, fakeFormatter.FormatFsTypes[0]) assert.Equal(GinkgoT(), boshdisk.FileSystemExt4, fakeFormatter.FormatFsTypes[1]) assert.Equal(GinkgoT(), 1, len(fakeMounter.MountMountPoints)) assert.Equal(GinkgoT(), "/fake-dir/data", fakeMounter.MountMountPoints[0]) assert.Equal(GinkgoT(), 1, len(fakeMounter.MountPartitionPaths)) assert.Equal(GinkgoT(), "/dev/xvda2", fakeMounter.MountPartitionPaths[0]) assert.Equal(GinkgoT(), 1, len(fakeMounter.SwapOnPartitionPaths)) assert.Equal(GinkgoT(), "/dev/xvda1", fakeMounter.SwapOnPartitionPaths[0]) sysLogStats := fs.GetFileTestStat("/fake-dir/data/sys/log") assert.NotNil(GinkgoT(), sysLogStats) assert.Equal(GinkgoT(), fakesys.FakeFileTypeDir, sysLogStats.FileType) assert.Equal(GinkgoT(), os.FileMode(0750), sysLogStats.FileMode) assert.Equal(GinkgoT(), []string{"chown", "root:vcap", "/fake-dir/data/sys"}, cmdRunner.RunCommands[0]) assert.Equal(GinkgoT(), []string{"chown", "root:vcap", "/fake-dir/data/sys/log"}, cmdRunner.RunCommands[1]) sysRunStats := fs.GetFileTestStat("/fake-dir/data/sys/run") assert.NotNil(GinkgoT(), sysRunStats) assert.Equal(GinkgoT(), fakesys.FakeFileTypeDir, sysRunStats.FileType) assert.Equal(GinkgoT(), os.FileMode(0750), sysRunStats.FileMode) assert.Equal(GinkgoT(), []string{"chown", "root:vcap", "/fake-dir/data/sys/run"}, cmdRunner.RunCommands[2]) }) It("setup tmp dir", func() { err := platform.SetupTmpDir() assert.NoError(GinkgoT(), err) assert.Equal(GinkgoT(), 2, len(cmdRunner.RunCommands)) assert.Equal(GinkgoT(), []string{"chown", "root:vcap", "/tmp"}, cmdRunner.RunCommands[0]) assert.Equal(GinkgoT(), []string{"chmod", "0770", "/tmp"}, cmdRunner.RunCommands[1]) }) It("ubuntu mount persistent disk", func() { fakeFormatter := diskManager.FakeFormatter fakePartitioner := diskManager.FakePartitioner fakeMounter := diskManager.FakeMounter fs.WriteToFile("/dev/vdf", "") err := platform.MountPersistentDisk("/dev/sdf", "/mnt/point") assert.NoError(GinkgoT(), err) mountPoint := fs.GetFileTestStat("/mnt/point") assert.Equal(GinkgoT(), fakesys.FakeFileTypeDir, mountPoint.FileType) assert.Equal(GinkgoT(), os.FileMode(0700), mountPoint.FileMode) partition := fakePartitioner.PartitionPartitions[0] assert.Equal(GinkgoT(), "/dev/vdf", fakePartitioner.PartitionDevicePath) assert.Equal(GinkgoT(), 1, len(fakePartitioner.PartitionPartitions)) assert.Equal(GinkgoT(), "linux", partition.Type) assert.Equal(GinkgoT(), 1, len(fakeFormatter.FormatPartitionPaths)) assert.Equal(GinkgoT(), "/dev/vdf1", fakeFormatter.FormatPartitionPaths[0]) assert.Equal(GinkgoT(), 1, len(fakeFormatter.FormatFsTypes)) assert.Equal(GinkgoT(), boshdisk.FileSystemExt4, fakeFormatter.FormatFsTypes[0]) assert.Equal(GinkgoT(), 1, len(fakeMounter.MountMountPoints)) assert.Equal(GinkgoT(), "/mnt/point", fakeMounter.MountMountPoints[0]) assert.Equal(GinkgoT(), 1, len(fakeMounter.MountPartitionPaths)) assert.Equal(GinkgoT(), "/dev/vdf1", fakeMounter.MountPartitionPaths[0]) }) Context("when not mounted", func() { It("does not unmount persistent disk", func() { fakeMounter := diskManager.FakeMounter fakeMounter.UnmountDidUnmount = false fs.WriteToFile("/dev/vdx", "") didUnmount, err := platform.UnmountPersistentDisk("/dev/sdx") assert.NoError(GinkgoT(), err) assert.Equal(GinkgoT(), didUnmount, false) assert.Equal(GinkgoT(), "/dev/vdx1", fakeMounter.UnmountPartitionPath) }) }) Context("when already mounted", func() { It("unmounts persistent disk", func() { fakeMounter := diskManager.FakeMounter fakeMounter.UnmountDidUnmount = true fs.WriteToFile("/dev/vdx", "") didUnmount, err := platform.UnmountPersistentDisk("/dev/sdx") assert.NoError(GinkgoT(), err) assert.Equal(GinkgoT(), didUnmount, true) assert.Equal(GinkgoT(), "/dev/vdx1", fakeMounter.UnmountPartitionPath) }) }) It("ubuntu normalize disk path", func() { fs.WriteToFile("/dev/xvda", "") path, found := platform.NormalizeDiskPath("/dev/sda") assert.Equal(GinkgoT(), path, "/dev/xvda") assert.True(GinkgoT(), found) fs.RemoveAll("/dev/xvda") fs.WriteToFile("/dev/vda", "") path, found = platform.NormalizeDiskPath("/dev/sda") assert.Equal(GinkgoT(), path, "/dev/vda") assert.True(GinkgoT(), found) fs.RemoveAll("/dev/vda") fs.WriteToFile("/dev/sda", "") path, found = platform.NormalizeDiskPath("/dev/sda") assert.Equal(GinkgoT(), path, "/dev/sda") assert.True(GinkgoT(), found) }) Describe("GetFileContentsFromCDROM", func() { It("delegates to cdutil", func() { cdutil.GetFileContentsContents = []byte("fake-contents") filename := "fake-env" contents, err := platform.GetFileContentsFromCDROM(filename) Expect(err).NotTo(HaveOccurred()) Expect(cdutil.GetFileContentsFilename).To(Equal(filename)) Expect(contents).To(Equal(cdutil.GetFileContentsContents)) }) }) It("ubuntu get real device path with multiple possible devices", func() { fs.WriteToFile("/dev/xvda", "") fs.WriteToFile("/dev/vda", "") realPath, found := platform.NormalizeDiskPath("/dev/sda") assert.True(GinkgoT(), found) assert.Equal(GinkgoT(), "/dev/xvda", realPath) }) Context("within timeout", func() { BeforeEach(func() { diskWaitTimeout = 1 * time.Second }) It("ubuntu get real device path with delay", func() { time.AfterFunc(time.Second, func() { fs.WriteToFile("/dev/xvda", "") }) realPath, found := platform.NormalizeDiskPath("/dev/sda") assert.True(GinkgoT(), found) assert.Equal(GinkgoT(), "/dev/xvda", realPath) }) }) It("ubuntu get real device path with delay beyond timeout", func() { time.AfterFunc(2*time.Second, func() { fs.WriteToFile("/dev/xvda", "") }) _, found := platform.NormalizeDiskPath("/dev/sda") assert.False(GinkgoT(), found) }) It("ubuntu calculate ephemeral disk partition sizes when disk is bigger than twice the memory", func() { totalMemInMb := uint64(1024) diskSizeInMb := totalMemInMb*2 + 64 expectedSwap := totalMemInMb collector.MemStats.Total = totalMemInMb * uint64(1024*1024) fakePartitioner := diskManager.FakePartitioner fakePartitioner.GetDeviceSizeInMbSizes = map[string]uint64{ "/dev/hda": diskSizeInMb, } err := platform.SetupEphemeralDiskWithPath("/dev/hda") assert.NoError(GinkgoT(), err) expectedPartitions := []boshdisk.Partition{ {SizeInMb: expectedSwap, Type: boshdisk.PartitionTypeSwap}, {SizeInMb: diskSizeInMb - expectedSwap, Type: boshdisk.PartitionTypeLinux}, } assert.Equal(GinkgoT(), fakePartitioner.PartitionPartitions, expectedPartitions) }) It("ubuntu calculate ephemeral disk partition sizes when disk twice the memory or smaller", func() { totalMemInMb := uint64(1024) diskSizeInMb := totalMemInMb*2 - 64 expectedSwap := diskSizeInMb / 2 collector.MemStats.Total = totalMemInMb * uint64(1024*1024) fakePartitioner := diskManager.FakePartitioner fakePartitioner.GetDeviceSizeInMbSizes = map[string]uint64{ "/dev/hda": diskSizeInMb, } err := platform.SetupEphemeralDiskWithPath("/dev/hda") assert.NoError(GinkgoT(), err) expectedPartitions := []boshdisk.Partition{ {SizeInMb: expectedSwap, Type: boshdisk.PartitionTypeSwap}, {SizeInMb: diskSizeInMb - expectedSwap, Type: boshdisk.PartitionTypeLinux}, } assert.Equal(GinkgoT(), fakePartitioner.PartitionPartitions, expectedPartitions) }) It("ubuntu migrate persistent disk", func() { fakeMounter := diskManager.FakeMounter platform.MigratePersistentDisk("/from/path", "/to/path") assert.Equal(GinkgoT(), fakeMounter.RemountAsReadonlyPath, "/from/path") assert.Equal(GinkgoT(), 1, len(cmdRunner.RunCommands)) assert.Equal(GinkgoT(), []string{"sh", "-c", "(tar -C /from/path -cf - .) | (tar -C /to/path -xpf -)"}, cmdRunner.RunCommands[0]) assert.Equal(GinkgoT(), fakeMounter.UnmountPartitionPath, "/from/path") assert.Equal(GinkgoT(), fakeMounter.RemountFromMountPoint, "/to/path") assert.Equal(GinkgoT(), fakeMounter.RemountToMountPoint, "/from/path") }) It("ubuntu is device path mounted", func() { fs.WriteToFile("/dev/xvda", "") fakeMounter := diskManager.FakeMounter fakeMounter.IsMountedResult = true result, err := platform.IsDevicePathMounted("/dev/sda") assert.NoError(GinkgoT(), err) assert.True(GinkgoT(), result) assert.Equal(GinkgoT(), fakeMounter.IsMountedDevicePathOrMountPoint, "/dev/xvda1") }) It("ubuntu start monit", func() { err := platform.StartMonit() assert.NoError(GinkgoT(), err) assert.Equal(GinkgoT(), 1, len(cmdRunner.RunCommands)) assert.Equal(GinkgoT(), []string{"sv", "up", "monit"}, cmdRunner.RunCommands[0]) }) It("ubuntu setup monit user if file does not exist", func() { err := platform.SetupMonitUser() assert.NoError(GinkgoT(), err) monitUserFileStats := fs.GetFileTestStat("/fake-dir/monit/monit.user") assert.NotNil(GinkgoT(), monitUserFileStats) assert.Equal(GinkgoT(), "vcap:random-password", monitUserFileStats.Content) }) It("ubuntu setup monit user if file does exist", func() { fs.WriteToFile("/fake-dir/monit/monit.user", "vcap:other-random-password") err := platform.SetupMonitUser() assert.NoError(GinkgoT(), err) monitUserFileStats := fs.GetFileTestStat("/fake-dir/monit/monit.user") assert.NotNil(GinkgoT(), monitUserFileStats) assert.Equal(GinkgoT(), "vcap:other-random-password", monitUserFileStats.Content) }) It("ubuntu get monit credentials reads monit file from disk", func() { fs.WriteToFile("/fake-dir/monit/monit.user", "fake-user:fake-random-password") username, password, err := platform.GetMonitCredentials() assert.NoError(GinkgoT(), err) assert.Equal(GinkgoT(), "fake-user", username) assert.Equal(GinkgoT(), "fake-random-password", password) }) It("ubuntu get monit credentials errs when invalid file format", func() { fs.WriteToFile("/fake-dir/monit/monit.user", "fake-user") _, _, err := platform.GetMonitCredentials() assert.Error(GinkgoT(), err) }) It("ubuntu get monit credentials leaves colons in password intact", func() { fs.WriteToFile("/fake-dir/monit/monit.user", "fake-user:fake:random:password") username, password, err := platform.GetMonitCredentials() assert.NoError(GinkgoT(), err) assert.Equal(GinkgoT(), "fake-user", username) assert.Equal(GinkgoT(), "fake:random:password", password) }) }) }
func init() { Describe("concretePackageApplier", func() { var ( packagesBc *fakebc.FakeBundleCollection blobstore *fakeblob.FakeBlobstore compressor *fakecmd.FakeCompressor fs *fakesys.FakeFileSystem logger boshlog.Logger applier PackageApplier ) BeforeEach(func() { packagesBc = fakebc.NewFakeBundleCollection() blobstore = fakeblob.NewFakeBlobstore() compressor = fakecmd.NewFakeCompressor() fs = fakesys.NewFakeFileSystem() logger = boshlog.NewLogger(boshlog.LevelNone) applier = NewConcretePackageApplier(packagesBc, true, blobstore, compressor, fs, logger) }) Describe("Prepare & Apply", func() { var ( pkg models.Package bundle *fakebc.FakeBundle ) BeforeEach(func() { pkg, bundle = buildPkg(packagesBc) }) ItInstallsPkg := func(act func() error) { It("returns error when installing package 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 package 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 package 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 package 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 package blob fails", func() { compressor.DecompressFileToDirErr = errors.New("fake-decompress-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-decompress-error")) }) It("installs bundle from decompressed tmp path of a package blob", 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")) }) } Describe("Prepare", func() { act := func() error { return applier.Prepare(pkg) } It("return an error if getting file bundle fails", func() { packagesBc.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 package installation 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 package 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 package", func() { err := act() Expect(err).ToNot(HaveOccurred()) Expect(blobstore.GetBlobIDs).To(BeNil()) }) }) Context("when package is not installed", func() { BeforeEach(func() { bundle.Installed = false }) It("installs package (but does not enable it)", func() { err := act() Expect(err).ToNot(HaveOccurred()) Expect(bundle.ActionsCalled).To(Equal([]string{"Install"})) }) ItInstallsPkg(act) }) }) Describe("Apply", func() { act := func() error { return applier.Apply(pkg) } It("return an error if getting file bundle fails", func() { packagesBc.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 package installation 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 package is already installed", func() { BeforeEach(func() { bundle.Installed = true }) It("does not install but only enables package", func() { err := act() Expect(err).ToNot(HaveOccurred()) Expect(bundle.ActionsCalled).To(Equal([]string{"Enable"})) // no Install }) It("returns error when package 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 package", func() { err := act() Expect(err).ToNot(HaveOccurred()) Expect(blobstore.GetBlobIDs).To(BeNil()) }) }) Context("when package is not installed", func() { BeforeEach(func() { bundle.Installed = false }) It("installs and enables package", func() { err := act() Expect(err).ToNot(HaveOccurred()) Expect(bundle.ActionsCalled).To(Equal([]string{"Install", "Enable"})) }) It("returns error when package enable fails", func() { bundle.EnableError = errors.New("fake-enable-error") err := act() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-enable-error")) }) ItInstallsPkg(act) }) }) }) Describe("KeepOnly", func() { ItReturnsErrors := func() { It("returns error when bundle collection fails to return list of installed bundles", func() { packagesBc.ListErr = errors.New("fake-bc-list-error") err := applier.KeepOnly([]models.Package{}) 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 package", func() { pkg1, bundle1 := buildPkg(packagesBc) packagesBc.ListBundles = []boshbc.Bundle{bundle1} packagesBc.GetErr = errors.New("fake-bc-get-error") err := applier.KeepOnly([]models.Package{pkg1}) 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 := buildPkg(packagesBc) packagesBc.ListBundles = []boshbc.Bundle{bundle1} bundle1.DisableErr = errors.New("fake-bc-disable-error") err := applier.KeepOnly([]models.Package{}) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-bc-disable-error")) }) } Context("when operating on packages as a package owner", func() { BeforeEach(func() { applier = NewConcretePackageApplier(packagesBc, true, blobstore, compressor, fs, logger) }) It("first disables and then uninstalls packages that are not in keeponly list", func() { _, bundle1 := buildPkg(packagesBc) pkg2, bundle2 := buildPkg(packagesBc) _, bundle3 := buildPkg(packagesBc) pkg4, bundle4 := buildPkg(packagesBc) packagesBc.ListBundles = []boshbc.Bundle{bundle1, bundle2, bundle3, bundle4} err := applier.KeepOnly([]models.Package{pkg4, pkg2}) 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{})) }) ItReturnsErrors() It("returns error when at least one bundle cannot be uninstalled", func() { _, bundle1 := buildPkg(packagesBc) packagesBc.ListBundles = []boshbc.Bundle{bundle1} bundle1.UninstallErr = errors.New("fake-bc-uninstall-error") err := applier.KeepOnly([]models.Package{}) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-bc-uninstall-error")) }) }) Context("when operating on packages not as a package owner", func() { BeforeEach(func() { applier = NewConcretePackageApplier(packagesBc, false, blobstore, compressor, fs, logger) }) It("disables and but does not uninstall packages that are not in keeponly list", func() { _, bundle1 := buildPkg(packagesBc) pkg2, bundle2 := buildPkg(packagesBc) _, bundle3 := buildPkg(packagesBc) pkg4, bundle4 := buildPkg(packagesBc) packagesBc.ListBundles = []boshbc.Bundle{bundle1, bundle2, bundle3, bundle4} err := applier.KeepOnly([]models.Package{pkg4, pkg2}) Expect(err).ToNot(HaveOccurred()) Expect(bundle1.ActionsCalled).To(Equal([]string{"Disable"})) // no Uninstall Expect(bundle2.ActionsCalled).To(Equal([]string{})) Expect(bundle3.ActionsCalled).To(Equal([]string{"Disable"})) // no Uninstall Expect(bundle4.ActionsCalled).To(Equal([]string{})) }) ItReturnsErrors() }) }) }) }
func init() { Describe("concreteCompiler", func() { var ( compiler Compiler compressor *fakecmd.FakeCompressor blobstore *fakeblobstore.FakeBlobstore fs *fakesys.FakeFileSystem runner *fakesys.FakeCmdRunner packageApplier *fakepa.FakePackageApplier packagesBc *fakebc.FakeBundleCollection ) BeforeEach(func() { compressor = fakecmd.NewFakeCompressor() blobstore = &fakeblobstore.FakeBlobstore{} fs = fakesys.NewFakeFileSystem() runner = fakesys.NewFakeCmdRunner() packageApplier = fakepa.NewFakePackageApplier() packagesBc = fakebc.NewFakeBundleCollection() compiler = NewConcreteCompiler( compressor, blobstore, fs, runner, FakeCompileDirProvider{Dir: "/fake-compile-dir"}, packageApplier, packagesBc, ) }) BeforeEach(func() { fs.MkdirAll("/fake-compile-dir", os.ModePerm) }) Describe("Compile", func() { var ( bundle *fakebc.FakeBundle pkg Package pkgDeps []boshmodels.Package ) BeforeEach(func() { bundle = packagesBc.FakeGet(boshmodels.Package{ Name: "pkg_name", Version: "pkg_version", }) bundle.InstallPath = "/fake-dir/data/packages/pkg_name/pkg_version" bundle.EnablePath = "/fake-dir/packages/pkg_name" compressor.CompressFilesInDirTarballPath = "/tmp/compressed-compiled-package" pkg, pkgDeps = getCompileArgs() }) It("returns blob id and sha1 of created compiled package", func() { blobstore.CreateBlobID = "fake-blob-id" blobstore.CreateFingerprint = "fake-blob-sha1" blobID, sha1, err := compiler.Compile(pkg, pkgDeps) Expect(err).ToNot(HaveOccurred()) Expect(blobID).To(Equal("fake-blob-id")) Expect(sha1).To(Equal("fake-blob-sha1")) }) It("cleans up all packages before applying dependent packages", func() { _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).ToNot(HaveOccurred()) Expect(packageApplier.ActionsCalled).To(Equal([]string{"KeepOnly", "Apply", "Apply"})) Expect(packageApplier.KeptOnlyPackages).To(BeEmpty()) }) It("returns an error if cleaning up packages fails", func() { packageApplier.KeepOnlyErr = errors.New("fake-keep-only-error") _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-keep-only-error")) }) It("fetches source package from blobstore", func() { _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).ToNot(HaveOccurred()) Expect(blobstore.GetBlobIDs[0]).To(Equal("blobstore_id")) Expect(blobstore.GetFingerprints[0]).To(Equal("sha1")) }) It("returns an error if removing compile target directory during uncompression fails", func() { fs.RegisterRemoveAllError("/fake-compile-dir/pkg_name", errors.New("fake-remove-error")) _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-remove-error")) }) It("returns an error if creating compile target directory during uncompression fails", func() { fs.RegisterMkdirAllError("/fake-compile-dir/pkg_name", errors.New("fake-mkdir-error")) _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-mkdir-error")) }) It("returns an error if removing temporary compile target directory during uncompression fails", func() { fs.RegisterRemoveAllError("/fake-compile-dir/pkg_name-bosh-agent-unpack", errors.New("fake-remove-error")) _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-remove-error")) }) It("returns an error if creating temporary compile target directory during uncompression fails", func() { fs.RegisterMkdirAllError("/fake-compile-dir/pkg_name-bosh-agent-unpack", errors.New("fake-mkdir-error")) _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-mkdir-error")) }) It("installs dependent packages", func() { _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).ToNot(HaveOccurred()) Expect(packageApplier.AppliedPackages).To(Equal(pkgDeps)) }) It("extracts source package to compile dir", func() { _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).ToNot(HaveOccurred()) Expect(fs.FileExists("/fake-compile-dir/pkg_name")).To(BeTrue()) Expect(compressor.DecompressFileToDirDirs[0]).To(Equal("/fake-compile-dir/pkg_name-bosh-agent-unpack")) Expect(compressor.DecompressFileToDirTarballPaths[0]).To(Equal(blobstore.GetFileName)) Expect(fs.RenameOldPaths[0]).To(Equal("/fake-compile-dir/pkg_name-bosh-agent-unpack")) Expect(fs.RenameNewPaths[0]).To(Equal("/fake-compile-dir/pkg_name")) }) It("installs, enables and later cleans up bundle", func() { _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).ToNot(HaveOccurred()) Expect(bundle.ActionsCalled).To(Equal([]string{ "InstallWithoutContents", "Enable", "Disable", "Uninstall", })) }) It("runs packaging script when packaging script exists", func() { compressor.DecompressFileToDirCallBack = func() { fs.WriteFileString("/fake-compile-dir/pkg_name/packaging", "hi") } _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).ToNot(HaveOccurred()) expectedCmd := boshsys.Command{ Name: "bash", Args: []string{"-x", "packaging"}, Env: map[string]string{ "BOSH_COMPILE_TARGET": "/fake-compile-dir/pkg_name", "BOSH_INSTALL_TARGET": "/fake-dir/packages/pkg_name", "BOSH_PACKAGE_NAME": "pkg_name", "BOSH_PACKAGE_VERSION": "pkg_version", }, WorkingDir: "/fake-compile-dir/pkg_name", } Expect(len(runner.RunComplexCommands)).To(Equal(1)) Expect(runner.RunComplexCommands[0]).To(Equal(expectedCmd)) }) It("does not run packaging script when script does not exist", func() { _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).ToNot(HaveOccurred()) Expect(runner.RunCommands).To(BeEmpty()) }) It("compresses compiled package", func() { _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).ToNot(HaveOccurred()) Expect(compressor.CompressFilesInDirDir).To(Equal("/fake-dir/data/packages/pkg_name/pkg_version")) }) It("uploads compressed package to blobstore", func() { compressor.CompressFilesInDirTarballPath = "/tmp/compressed-compiled-package" _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).ToNot(HaveOccurred()) Expect(blobstore.CreateFileName).To(Equal("/tmp/compressed-compiled-package")) }) It("returs error if uploading compressed package fails", func() { blobstore.CreateErr = errors.New("fake-create-err") _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-create-err")) }) It("cleans up compressed package after uploading it to blobstore", func() { var beforeCleanUpTarballPath, afterCleanUpTarballPath string blobstore.CreateCallBack = func() { beforeCleanUpTarballPath = compressor.CleanUpTarballPath } _, _, err := compiler.Compile(pkg, pkgDeps) Expect(err).ToNot(HaveOccurred()) // Compressed package is not cleaned up before blobstore upload Expect(beforeCleanUpTarballPath).To(Equal("")) // Deleted after it was uploaded afterCleanUpTarballPath = compressor.CleanUpTarballPath Expect(afterCleanUpTarballPath).To(Equal("/tmp/compressed-compiled-package")) }) }) }) }
package devicepathresolver_test import ( "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "bosh/infrastructure/devicepathresolver" fakesys "bosh/system/fakes" ) var _ = Describe("VSphere Path Resolver", func() { var ( fs *fakesys.FakeFileSystem resolver DevicePathResolver ) const sleepInterval = time.Millisecond * 1 BeforeEach(func() { fs = fakesys.NewFakeFileSystem() resolver = NewVsphereDevicePathResolver(sleepInterval, fs) fs.SetGlob("/sys/bus/scsi/devices/*:0:0:0/block/*", []string{ "/sys/bus/scsi/devices/0:0:0:0/block/sr0", "/sys/bus/scsi/devices/6:0:0:0/block/sdd", "/sys/bus/scsi/devices/fake-host-id:0:0:0/block/sda", }) fs.SetGlob("/sys/bus/scsi/devices/fake-host-id:0:fake-disk-id:0/block/*", []string{
package app_test import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "bosh/app" boshplatform "bosh/platform" fakesys "bosh/system/fakes" ) var _ = Describe("LoadConfigFromPath", func() { var ( fs *fakesys.FakeFileSystem ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() }) It("returns populates config", func() { fs.WriteFileString("/fake-config.conf", `{ "Platform": { "Linux": { "UseDefaultTmpDir": true, "UsePreformattedPersistentDisk": true, "BindMountPersistentDisk": true } } }`)
func init() { Describe("concreteV1Service", func() { var ( fs *fakesys.FakeFileSystem platform *fakeplatform.FakePlatform specPath = "/spec.json" service V1Service ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() platform = fakeplatform.NewFakePlatform() service = NewConcreteV1Service(fs, platform, specPath) }) Describe("Get", func() { Context("when filesystem has a spec file", func() { BeforeEach(func() { fs.WriteFileString(specPath, `{"deployment":"fake-deployment-name"}`) }) It("reads spec from filesystem", func() { spec, err := service.Get() Expect(err).ToNot(HaveOccurred()) Expect(spec).To(Equal(V1ApplySpec{Deployment: "fake-deployment-name"})) }) It("returns error if reading spec from filesystem errs", func() { fs.ReadFileError = errors.New("fake-read-error") spec, err := service.Get() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-read-error")) Expect(spec).To(Equal(V1ApplySpec{})) }) }) Context("when filesystem does not have a spec file", func() { It("reads spec from filesystem", func() { spec, err := service.Get() Expect(err).ToNot(HaveOccurred()) Expect(spec).To(Equal(V1ApplySpec{})) }) }) }) Describe("Set", func() { newSpec := V1ApplySpec{Deployment: "fake-deployment-name"} It("writes spec to filesystem", func() { err := service.Set(newSpec) Expect(err).ToNot(HaveOccurred()) specPathStats := fs.GetFileTestStat(specPath) Expect(specPathStats).ToNot(BeNil()) boshassert.MatchesJSONBytes(GinkgoT(), newSpec, specPathStats.Content) }) It("returns error if writing spec to filesystem errs", func() { fs.WriteToFileError = errors.New("fake-write-error") err := service.Set(newSpec) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-write-error")) }) }) Describe("ResolveDynamicNetworks", func() { Context("when there is are no dynamic networks", func() { unresolvedSpec := V1ApplySpec{ Deployment: "fake-deployment", NetworkSpecs: map[string]NetworkSpec{ "fake-net": NetworkSpec{ Fields: map[string]interface{}{"ip": "fake-net-ip"}, }, }, } It("returns spec without modifying any networks", func() { spec, err := service.ResolveDynamicNetworks(unresolvedSpec) Expect(err).ToNot(HaveOccurred()) Expect(spec).To(Equal(V1ApplySpec{ Deployment: "fake-deployment", NetworkSpecs: map[string]NetworkSpec{ "fake-net": NetworkSpec{ Fields: map[string]interface{}{"ip": "fake-net-ip"}, }, }, })) }) }) Context("when there is one dynamic network", func() { unresolvedSpec := V1ApplySpec{ Deployment: "fake-deployment", NetworkSpecs: map[string]NetworkSpec{ "fake-net1": NetworkSpec{ Fields: map[string]interface{}{ "ip": "fake-net1-ip", "netmask": "fake-net1-netmask", "gateway": "fake-net1-gateway", }, }, "fake-net2": NetworkSpec{ Fields: map[string]interface{}{ "type": NetworkSpecTypeDynamic, "ip": "fake-net2-ip", "netmask": "fake-net2-netmask", "gateway": "fake-net2-gateway", }, }, }, } Context("when default network can be retrieved", func() { BeforeEach(func() { platform.GetDefaultNetworkNetwork = boshsettings.Network{ IP: "fake-resolved-ip", Netmask: "fake-resolved-netmask", Gateway: "fake-resolved-gateway", } }) It("returns spec with modified dynamic network and keeping everything else the same", func() { spec, err := service.ResolveDynamicNetworks(unresolvedSpec) Expect(err).ToNot(HaveOccurred()) Expect(spec).To(Equal(V1ApplySpec{ Deployment: "fake-deployment", NetworkSpecs: map[string]NetworkSpec{ "fake-net1": NetworkSpec{ Fields: map[string]interface{}{ "ip": "fake-net1-ip", "netmask": "fake-net1-netmask", "gateway": "fake-net1-gateway", }, }, "fake-net2": NetworkSpec{ Fields: map[string]interface{}{ "type": NetworkSpecTypeDynamic, "ip": "fake-resolved-ip", "netmask": "fake-resolved-netmask", "gateway": "fake-resolved-gateway", }, }, }, })) }) }) Context("when default network fails to be retrieved", func() { BeforeEach(func() { platform.GetDefaultNetworkErr = errors.New("fake-get-default-network-err") }) It("returns error", func() { spec, err := service.ResolveDynamicNetworks(unresolvedSpec) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-get-default-network-err")) Expect(spec).To(Equal(V1ApplySpec{})) }) }) }) Context("when there is are multiple dynamic networks", func() { unresolvedSpec := V1ApplySpec{ NetworkSpecs: map[string]NetworkSpec{ "fake-net1": NetworkSpec{ Fields: map[string]interface{}{"type": NetworkSpecTypeDynamic}, }, "fake-net2": NetworkSpec{ Fields: map[string]interface{}{"type": NetworkSpecTypeDynamic}, }, }, } It("returns error because multiple dynamic networks are not supported", func() { spec, err := service.ResolveDynamicNetworks(unresolvedSpec) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("Multiple dynamic networks are not supported")) Expect(spec).To(Equal(V1ApplySpec{})) }) }) }) }) }
func init() { Describe("monitJobSupervisor", func() { var ( fs *fakesys.FakeFileSystem runner *fakesys.FakeCmdRunner client *fakemonit.FakeMonitClient logger boshlog.Logger dirProvider boshdir.DirectoriesProvider jobFailuresServerPort int monit JobSupervisor ) BeforeEach(func() { fs = &fakesys.FakeFileSystem{} runner = &fakesys.FakeCmdRunner{} client = fakemonit.NewFakeMonitClient() logger = boshlog.NewLogger(boshlog.LevelNone) dirProvider = boshdir.NewDirectoriesProvider("/var/vcap") jobFailuresServerPort = getJobFailureServerPort() monit = NewMonitJobSupervisor( fs, runner, client, logger, dirProvider, jobFailuresServerPort, 0*time.Millisecond, ) }) It("waits until the job is reloaded", func() { client.Incarnations = []int{1, 1, 1, 2, 3} client.StatusStatus = fakemonit.FakeMonitStatus{ Services: []boshmonit.Service{ boshmonit.Service{Monitored: true, Status: "failing"}, boshmonit.Service{Monitored: true, Status: "running"}, }, Incarnation: 1, } err := monit.Reload() Expect(err).ToNot(HaveOccurred()) Expect(1).To(Equal(len(runner.RunCommands))) Expect(runner.RunCommands[0]).To(Equal([]string{"monit", "reload"})) Expect(client.StatusCalledTimes).To(Equal(4)) }) It("stops trying to reload after 60 attempts", func() { for i := 0; i < 61; i++ { client.Incarnations = append(client.Incarnations, 1) } client.StatusStatus = fakemonit.FakeMonitStatus{ Services: []boshmonit.Service{ boshmonit.Service{Monitored: true, Status: "failing"}, boshmonit.Service{Monitored: true, Status: "running"}, }, Incarnation: 1, } err := monit.Reload() Expect(err).To(HaveOccurred()) Expect(1).To(Equal(len(runner.RunCommands))) Expect(runner.RunCommands[0]).To(Equal([]string{"monit", "reload"})) Expect(client.StatusCalledTimes).To(Equal(60)) }) It("start starts each monit service in group vcap", func() { client.ServicesInGroupServices = []string{"fake-service"} err := monit.Start() Expect(err).ToNot(HaveOccurred()) Expect("vcap").To(Equal(client.ServicesInGroupName)) Expect(1).To(Equal(len(client.StartServiceNames))) Expect("fake-service").To(Equal(client.StartServiceNames[0])) }) It("stop stops each monit service in group vcap", func() { client.ServicesInGroupServices = []string{"fake-service"} err := monit.Stop() Expect(err).ToNot(HaveOccurred()) Expect("vcap").To(Equal(client.ServicesInGroupName)) Expect(1).To(Equal(len(client.StopServiceNames))) Expect("fake-service").To(Equal(client.StopServiceNames[0])) }) It("status returns running when all services are monitored and running", func() { client.StatusStatus = fakemonit.FakeMonitStatus{ Services: []boshmonit.Service{ boshmonit.Service{Monitored: true, Status: "running"}, boshmonit.Service{Monitored: true, Status: "running"}, }, } status := monit.Status() Expect("running").To(Equal(status)) }) It("status returns failing when all services are monitored and at least one service is failing", func() { client.StatusStatus = fakemonit.FakeMonitStatus{ Services: []boshmonit.Service{ boshmonit.Service{Monitored: true, Status: "failing"}, boshmonit.Service{Monitored: true, Status: "running"}, }, } status := monit.Status() Expect("failing").To(Equal(status)) }) It("status returns failing when at least one service is not monitored", func() { client.StatusStatus = fakemonit.FakeMonitStatus{ Services: []boshmonit.Service{ boshmonit.Service{Monitored: false, Status: "running"}, boshmonit.Service{Monitored: true, Status: "running"}, }, } status := monit.Status() Expect("failing").To(Equal(status)) }) It("status returns start when at least one service is starting", func() { client.StatusStatus = fakemonit.FakeMonitStatus{ Services: []boshmonit.Service{ boshmonit.Service{Monitored: true, Status: "failing"}, boshmonit.Service{Monitored: true, Status: "starting"}, boshmonit.Service{Monitored: true, Status: "running"}, }, } status := monit.Status() Expect("starting").To(Equal(status)) }) It("status returns unknown when error", func() { client.StatusErr = errors.New("fake-monit-client-error") status := monit.Status() Expect("unknown").To(Equal(status)) }) It("monitor job failures", func() { var handledAlert boshalert.MonitAlert failureHandler := func(alert boshalert.MonitAlert) (err error) { handledAlert = alert return } go monit.MonitorJobFailures(failureHandler) msg := `Message-id: <1304319946.0@localhost> Service: nats Event: does not exist Action: restart Date: Sun, 22 May 2011 20:07:41 +0500 Description: process is not running` err := doJobFailureEmail(msg, jobFailuresServerPort) Expect(err).ToNot(HaveOccurred()) assert.Equal(GinkgoT(), handledAlert, boshalert.MonitAlert{ ID: "1304319946.0@localhost", Service: "nats", Event: "does not exist", Action: "restart", Date: "Sun, 22 May 2011 20:07:41 +0500", Description: "process is not running", }) }) It("monitor job failures ignores other emails", func() { var didHandleAlert bool failureHandler := func(alert boshalert.MonitAlert) (err error) { didHandleAlert = true return } go monit.MonitorJobFailures(failureHandler) msg := `Hi! How'sit goin` err := doJobFailureEmail(msg, jobFailuresServerPort) Expect(err).ToNot(HaveOccurred()) Expect(didHandleAlert).To(BeFalse()) }) Describe("AddJob", func() { BeforeEach(func() { fs.WriteFileString("/some/config/path", "fake-config") }) Context("when reading configuration from config path succeeds", func() { Context("when writing job configuration succeeds", func() { It("returns no error because monit can track added job in jobs directory", func() { err := monit.AddJob("router", 0, "/some/config/path") Expect(err).ToNot(HaveOccurred()) writtenConfig, err := fs.ReadFileString( dirProvider.MonitJobsDir() + "/0000_router.monitrc") Expect(err).ToNot(HaveOccurred()) Expect(writtenConfig).To(Equal("fake-config")) }) }) Context("when writing job configuration fails", func() { It("returns error", func() { fs.WriteToFileError = errors.New("fake-write-error") err := monit.AddJob("router", 0, "/some/config/path") Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-write-error")) }) }) }) Context("when reading configuration from config path fails", func() { It("returns error", func() { fs.ReadFileError = errors.New("fake-read-error") err := monit.AddJob("router", 0, "/some/config/path") Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-read-error")) }) }) }) Describe("RemoveAllJobs", func() { Context("when jobs directory removal succeeds", func() { It("does not return error because all jobs are removed from monit", func() { jobsDir := dirProvider.MonitJobsDir() jobBasename := "/0000_router.monitrc" fs.WriteFileString(jobsDir+jobBasename, "fake-added-job") err := monit.RemoveAllJobs() Expect(err).ToNot(HaveOccurred()) Expect(fs.FileExists(jobsDir)).To(BeFalse()) Expect(fs.FileExists(jobsDir + jobBasename)).To(BeFalse()) }) }) Context("when jobs directory removal fails", func() { It("returns error if removing jobs directory fails", func() { fs.RemoveAllError = errors.New("fake-remove-all-error") err := monit.RemoveAllJobs() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-remove-all-error")) }) }) }) Describe("Unmonitor", func() { BeforeEach(func() { client.ServicesInGroupServices = []string{"fake-srv-1", "fake-srv-2", "fake-srv-3"} client.UnmonitorServiceErrs = []error{nil, nil, nil} }) Context("when all services succeed to be unmonitored", func() { It("returns no error because all services got unmonitored", func() { err := monit.Unmonitor() Expect(err).ToNot(HaveOccurred()) Expect(client.ServicesInGroupName).To(Equal("vcap")) Expect(client.UnmonitorServiceNames).To(Equal( []string{"fake-srv-1", "fake-srv-2", "fake-srv-3"})) }) }) Context("when at least one service fails to be unmonitored", func() { BeforeEach(func() { client.UnmonitorServiceErrs = []error{ nil, errors.New("fake-unmonitor-error"), nil, } }) It("returns first unmonitor error", func() { err := monit.Unmonitor() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-unmonitor-error")) }) It("only tries to unmonitor services before the first unmonitor error", func() { err := monit.Unmonitor() Expect(err).To(HaveOccurred()) Expect(client.ServicesInGroupName).To(Equal("vcap")) Expect(client.UnmonitorServiceNames).To(Equal([]string{"fake-srv-1", "fake-srv-2"})) }) }) Context("when failed retrieving list of services", func() { It("returns error", func() { client.ServicesInGroupErr = errors.New("fake-services-error") err := monit.Unmonitor() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-services-error")) }) }) }) }) }
func init() { Describe("concreteManagerProvider", func() { Describe("NewManager", func() { It("returns manager with tasks.json as its tasks path", func() { logger := boshlog.NewLogger(boshlog.LEVEL_NONE) fs := fakesys.NewFakeFileSystem() taskInfo := boshtask.TaskInfo{ TaskId: "fake-task-id", Method: "fake-method", Payload: []byte("fake-payload"), } manager := boshtask.NewManagerProvider().NewManager(logger, fs, "/dir/path") err := manager.AddTaskInfo(taskInfo) Expect(err).ToNot(HaveOccurred()) // Check expected file location with another manager otherManager := boshtask.NewManager(logger, fs, "/dir/path/tasks.json") taskInfos, err := otherManager.GetTaskInfos() Expect(err).ToNot(HaveOccurred()) Expect(taskInfos).To(Equal([]boshtask.TaskInfo{taskInfo})) }) }) }) Describe("concreteManager", func() { var ( logger boshlog.Logger fs *fakesys.FakeFileSystem manager boshtask.Manager ) BeforeEach(func() { logger = boshlog.NewLogger(boshlog.LEVEL_NONE) fs = fakesys.NewFakeFileSystem() manager = boshtask.NewManager(logger, fs, "/dir/path") }) Describe("GetTaskInfos", func() { It("can load multiple tasks", func() { err := manager.AddTaskInfo(boshtask.TaskInfo{ TaskId: "fake-task-id-1", Method: "fake-method-1", Payload: []byte("fake-payload-1"), }) Expect(err).ToNot(HaveOccurred()) err = manager.AddTaskInfo(boshtask.TaskInfo{ TaskId: "fake-task-id-2", Method: "fake-method-2", Payload: []byte("fake-payload-2"), }) Expect(err).ToNot(HaveOccurred()) // Make sure we are not getting cached copy of taskInfos reloadedManager := boshtask.NewManager(logger, fs, "/dir/path") taskInfos, err := reloadedManager.GetTaskInfos() Expect(err).ToNot(HaveOccurred()) Expect(taskInfos).To(Equal([]boshtask.TaskInfo{ boshtask.TaskInfo{ TaskId: "fake-task-id-1", Method: "fake-method-1", Payload: []byte("fake-payload-1"), }, boshtask.TaskInfo{ TaskId: "fake-task-id-2", Method: "fake-method-2", Payload: []byte("fake-payload-2"), }, })) }) It("succeeds when there is no tasks (file is not present)", func() { taskInfos, err := manager.GetTaskInfos() Expect(err).ToNot(HaveOccurred()) Expect(len(taskInfos)).To(Equal(0)) }) It("returns an error when failing to load tasks from the file that exists", func() { err := manager.AddTaskInfo(boshtask.TaskInfo{ TaskId: "fake-task-id-2", Method: "fake-method-2", Payload: []byte("fake-payload-2"), }) Expect(err).ToNot(HaveOccurred()) fs.ReadFileError = errors.New("fake-read-error") _, err = manager.GetTaskInfos() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-read-error")) }) }) Describe("AddTaskInfo", func() { It("can add multiple tasks", func() { err := manager.AddTaskInfo(boshtask.TaskInfo{ TaskId: "fake-task-id-1", Method: "fake-method-1", Payload: []byte("fake-payload-1"), }) Expect(err).ToNot(HaveOccurred()) err = manager.AddTaskInfo(boshtask.TaskInfo{ TaskId: "fake-task-id-2", Method: "fake-method-2", Payload: []byte("fake-payload-2"), }) Expect(err).ToNot(HaveOccurred()) content, err := fs.ReadFile("/dir/path") Expect(err).ToNot(HaveOccurred()) var decodedMap map[string]boshtask.TaskInfo err = json.Unmarshal(content, &decodedMap) Expect(err).ToNot(HaveOccurred()) Expect(decodedMap).To(Equal(map[string]boshtask.TaskInfo{ "fake-task-id-1": boshtask.TaskInfo{ TaskId: "fake-task-id-1", Method: "fake-method-1", Payload: []byte("fake-payload-1"), }, "fake-task-id-2": boshtask.TaskInfo{ TaskId: "fake-task-id-2", Method: "fake-method-2", Payload: []byte("fake-payload-2"), }, })) }) It("returns an error when failing to save task", func() { fs.WriteToFileError = errors.New("fake-write-error") err := manager.AddTaskInfo(boshtask.TaskInfo{ TaskId: "fake-task-id", Method: "fake-method", Payload: []byte("fake-payload"), }) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-write-error")) }) }) Describe("RemoveTaskInfo", func() { BeforeEach(func() { err := manager.AddTaskInfo(boshtask.TaskInfo{ TaskId: "fake-task-id-1", Method: "fake-method-1", Payload: []byte("fake-payload-1"), }) Expect(err).ToNot(HaveOccurred()) err = manager.AddTaskInfo(boshtask.TaskInfo{ TaskId: "fake-task-id-2", Method: "fake-method-2", Payload: []byte("fake-payload-2"), }) Expect(err).ToNot(HaveOccurred()) }) It("removes the task", func() { err := manager.RemoveTaskInfo("fake-task-id-1") Expect(err).ToNot(HaveOccurred()) content, err := fs.ReadFile("/dir/path") Expect(err).ToNot(HaveOccurred()) var decodedMap map[string]boshtask.TaskInfo err = json.Unmarshal(content, &decodedMap) Expect(err).ToNot(HaveOccurred()) Expect(decodedMap).To(Equal(map[string]boshtask.TaskInfo{ "fake-task-id-2": boshtask.TaskInfo{ TaskId: "fake-task-id-2", Method: "fake-method-2", Payload: []byte("fake-payload-2"), }, })) }) It("does not return error when removing task that does not exist", func() { err := manager.RemoveTaskInfo("fake-unknown-task-id") Expect(err).ToNot(HaveOccurred()) }) It("returns an error when failing to remove task", func() { fs.WriteToFileError = errors.New("fake-write-error") err := manager.RemoveTaskInfo("fake-task-id") Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-write-error")) }) }) }) }
boshlog "bosh/logger" fakesys "bosh/system/fakes" ) type testBundle struct { Name string Version string } func (s testBundle) BundleName() string { return s.Name } func (s testBundle) BundleVersion() string { return s.Version } var _ = Describe("FileBundleCollection", func() { var ( fs *fakesys.FakeFileSystem logger boshlog.Logger fileBundleCollection FileBundleCollection ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() logger = boshlog.NewLogger(boshlog.LevelNone) fileBundleCollection = NewFileBundleCollection( "/fake-collection-path/data", "/fake-collection-path", "fake-collection-name", fs, logger, ) })
"crypto/tls" "errors" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "io/ioutil" "net/http" "net/url" "strings" "time" ) var _ = Describe("HTTPSHandler", func() { var ( serverURL string handler HTTPSHandler fs *fakesys.FakeFileSystem receivedRequest boshhandler.Request httpClient http.Client ) BeforeEach(func() { serverURL = "https://*****:*****@127.0.0.1:6900" mbusURL, _ := url.Parse(serverURL) logger := boshlog.NewLogger(boshlog.LevelNone) 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")
func init() { Describe("concreteServiceProvider", func() { var ( platform *fakeplatform.FakePlatform ) Describe("NewService", func() { It("returns service with settings.json as its settings path", func() { // Cannot compare fetcher functions since function comparison is problematic fs := fakesys.NewFakeFileSystem() logger := boshlog.NewLogger(boshlog.LevelNone) service := NewServiceProvider().NewService(fs, "/setting/path", nil, platform, logger) Expect(service).To(Equal(NewService(fs, "/setting/path/settings.json", nil, platform, logger))) }) }) }) Describe("concreteService", func() { var ( fs *fakesys.FakeFileSystem platform *fakeplatform.FakePlatform ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() platform = fakeplatform.NewFakePlatform() }) buildService := func(fetcher SettingsFetcher) (Service, *fakesys.FakeFileSystem) { logger := boshlog.NewLogger(boshlog.LevelNone) service := NewService(fs, "/setting/path", fetcher, platform, logger) return service, fs } Describe("LoadSettings", func() { var ( fetchedSettings Settings fetcherFuncErr error service Service ) BeforeEach(func() { fetchedSettings = Settings{} fetcherFuncErr = nil }) JustBeforeEach(func() { fetcherFunc := func() (Settings, error) { return fetchedSettings, fetcherFuncErr } service, fs = buildService(fetcherFunc) }) Context("when settings fetcher succeeds fetching settings", func() { BeforeEach(func() { fetchedSettings = Settings{AgentID: "some-new-agent-id"} }) Context("when settings contain at most one dynamic network", func() { BeforeEach(func() { fetchedSettings.Networks = Networks{ "fake-net-1": Network{Type: NetworkTypeDynamic}, } }) It("updates the service with settings from the fetcher", func() { err := service.LoadSettings() Expect(err).NotTo(HaveOccurred()) Expect(service.GetSettings().AgentID).To(Equal("some-new-agent-id")) }) It("persists settings to the settings file", func() { err := service.LoadSettings() Expect(err).NotTo(HaveOccurred()) json, err := json.Marshal(fetchedSettings) Expect(err).NotTo(HaveOccurred()) fileContent, err := fs.ReadFile("/setting/path") Expect(err).NotTo(HaveOccurred()) Expect(fileContent).To(Equal(json)) }) It("returns any error from writing to the setting file", func() { fs.WriteToFileError = errors.New("fs-write-file-error") err := service.LoadSettings() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fs-write-file-error")) }) }) Context("when settings contain multiple dynamic networks", func() { BeforeEach(func() { fetchedSettings.Networks = Networks{ "fake-net-1": Network{Type: NetworkTypeDynamic}, "fake-net-2": Network{Type: NetworkTypeDynamic}, } }) It("returns error because multiple dynamic networks are not supported", func() { err := service.LoadSettings() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("Multiple dynamic networks are not supported")) }) }) }) Context("when settings fetcher fails fetching settings", func() { BeforeEach(func() { fetcherFuncErr = errors.New("fake-fetch-error") }) Context("when a settings file exists", func() { Context("when settings contain at most one dynamic network", func() { BeforeEach(func() { fs.WriteFile("/setting/path", []byte(`{ "agent_id":"some-agent-id", "networks": {"fake-net-1": {"type": "dynamic"}} }`)) }) It("returns settings from the settings file", func() { err := service.LoadSettings() Expect(err).ToNot(HaveOccurred()) Expect(service.GetSettings()).To(Equal(Settings{ AgentID: "some-agent-id", Networks: Networks{ "fake-net-1": Network{Type: NetworkTypeDynamic}, }, })) }) }) Context("when settings contain multiple dynamic networks", func() { BeforeEach(func() { fs.WriteFile("/setting/path", []byte(`{ "agent_id":"some-agent-id", "networks": { "fake-net-1": {"type": "dynamic"}, "fake-net-2": {"type": "dynamic"} } }`)) }) It("returns error because multiple dynamic networks are not supported", func() { err := service.LoadSettings() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("Multiple dynamic networks are not supported")) }) }) }) Context("when non-unmarshallable settings file exists", func() { It("returns any error from the fetcher", func() { fs.WriteFile("/setting/path", []byte(`$%^&*(`)) err := service.LoadSettings() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-fetch-error")) Expect(service.GetSettings()).To(Equal(Settings{})) }) }) Context("when no settings file exists", func() { It("returns any error from the fetcher", func() { err := service.LoadSettings() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-fetch-error")) Expect(service.GetSettings()).To(Equal(Settings{})) }) }) }) }) Describe("InvalidateSettings", func() { It("removes the settings file", func() { service, fs := buildService(nil) fs.WriteFile("/setting/path", []byte(`{}`)) err := service.InvalidateSettings() Expect(err).ToNot(HaveOccurred()) Expect(fs.FileExists("/setting/path")).To(BeFalse()) }) It("returns err if removing settings file errored", func() { service, fs := buildService(nil) fs.RemoveAllError = errors.New("fs-remove-all-error") err := service.InvalidateSettings() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fs-remove-all-error")) }) }) Describe("GetSettings", func() { var ( loadedSettings Settings service Service ) BeforeEach(func() { loadedSettings = Settings{AgentID: "some-agent-id"} }) JustBeforeEach(func() { service, _ = buildService(func() (Settings, error) { return loadedSettings, nil }) err := service.LoadSettings() Expect(err).NotTo(HaveOccurred()) }) Context("when there is are no dynamic networks", func() { It("returns settings without modifying any networks", func() { Expect(service.GetSettings()).To(Equal(loadedSettings)) }) It("does not try to determine default network", func() { _ = service.GetSettings() Expect(platform.GetDefaultNetworkCalled).To(BeFalse()) }) }) Context("when there is one dynamic network", func() { BeforeEach(func() { loadedSettings = Settings{ Networks: map[string]Network{ "fake-net1": Network{ IP: "fake-net1-ip", Netmask: "fake-net1-netmask", Gateway: "fake-net1-gateway", }, "fake-net2": Network{ Type: "dynamic", IP: "fake-net2-ip", Netmask: "fake-net2-netmask", Gateway: "fake-net2-gateway", DNS: []string{"fake-net2-dns"}, }, }, } }) Context("when default network can be retrieved", func() { BeforeEach(func() { platform.GetDefaultNetworkNetwork = Network{ IP: "fake-resolved-ip", Netmask: "fake-resolved-netmask", Gateway: "fake-resolved-gateway", } }) It("returns settings with resolved dynamic network ip, netmask, gateway and keeping everything else the same", func() { settings := service.GetSettings() Expect(settings).To(Equal(Settings{ Networks: map[string]Network{ "fake-net1": Network{ IP: "fake-net1-ip", Netmask: "fake-net1-netmask", Gateway: "fake-net1-gateway", }, "fake-net2": Network{ Type: "dynamic", IP: "fake-resolved-ip", Netmask: "fake-resolved-netmask", Gateway: "fake-resolved-gateway", DNS: []string{"fake-net2-dns"}, }, }, })) }) }) Context("when default network fails to be retrieved", func() { BeforeEach(func() { platform.GetDefaultNetworkErr = errors.New("fake-get-default-network-err") }) It("returns error", func() { settings := service.GetSettings() Expect(settings).To(Equal(loadedSettings)) }) }) }) }) }) }
func init() { Describe("prepareNetworkChange", func() { var ( action PrepareNetworkChangeAction fs *fakesys.FakeFileSystem settingsService *fakesettings.FakeSettingsService ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() settingsService = &fakesettings.FakeSettingsService{} action = NewPrepareNetworkChange(fs, settingsService) }) It("is synchronous", func() { Expect(action.IsAsynchronous()).To(BeFalse()) }) It("is not persistent", func() { Expect(action.IsPersistent()).To(BeFalse()) }) It("invalidates settings so that load settings cannot fall back on old settings", func() { resp, err := action.Run() Expect(err).NotTo(HaveOccurred()) Expect(resp).To(Equal("ok")) Expect(settingsService.SettingsWereInvalidated).To(BeTrue()) }) Context("when settings invalidation succeeds", func() { Context("when the network rules file can be removed", func() { It("removes the network rules file", func() { fs.WriteFile("/etc/udev/rules.d/70-persistent-net.rules", []byte{}) resp, err := action.Run() Expect(err).NotTo(HaveOccurred()) Expect(resp).To(Equal("ok")) Expect(fs.FileExists("/etc/udev/rules.d/70-persistent-net.rules")).To(BeFalse()) }) }) Context("when the network rules file cannot be removed", func() { BeforeEach(func() { fs.RemoveAllError = errors.New("fake-remove-all-error") }) It("returns error from removing the network rules file", func() { resp, err := action.Run() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-remove-all-error")) Expect(resp).To(BeNil()) }) }) }) Context("when settings invalidation fails", func() { BeforeEach(func() { settingsService.InvalidateSettingsError = errors.New("fake-invalidate-error") }) It("returns error early if settings err invalidating", func() { resp, err := action.Run() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-invalidate-error")) Expect(resp).To(BeNil()) }) It("does not remove the network rules file", func() { fs.WriteFile("/etc/udev/rules.d/70-persistent-net.rules", []byte{}) action.Run() Expect(fs.FileExists("/etc/udev/rules.d/70-persistent-net.rules")).To(BeTrue()) }) }) }) }
import ( "errors" "os" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "bosh/agent/cmdrunner" boshsys "bosh/system" fakesys "bosh/system/fakes" ) var _ = Describe("FileLoggingCmdRunner", func() { var ( fs *fakesys.FakeFileSystem cmdRunner *fakesys.FakeCmdRunner cmd boshsys.Command runner CmdRunner ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() cmdRunner = fakesys.NewFakeCmdRunner() runner = NewFileLoggingCmdRunner(fs, cmdRunner, "/fake-base-dir", 15) cmd = boshsys.Command{ Name: "fake-cmd", Args: []string{"fake-args"}, Env: map[string]string{"fake-env-key": "fake-env-var"}, WorkingDir: "/fake-working-dir", } })
) type failingInterfaceAddress struct{} func (ia failingInterfaceAddress) GetInterfaceName() string { return "eth0" } func (ia failingInterfaceAddress) GetIP() (string, error) { return "", errors.New("fake-get-ip-err") } var _ = Describe("arping", func() { const arpingIterations = 6 var ( fs *fakesys.FakeFileSystem cmdRunner *fakesys.FakeCmdRunner arping AddressBroadcaster ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() cmdRunner = fakesys.NewFakeCmdRunner() logger := boshlog.NewLogger(boshlog.LevelNone) arping = NewArping(cmdRunner, fs, logger, arpingIterations, 0, 0) }) Describe("BroadcastMACAddresses", func() { BeforeEach(func() { fs.WriteFile("/sys/class/net/eth0", []byte{}) fs.WriteFile("/sys/class/net/eth1", []byte{}) })
package disk_test import ( "errors" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "bosh/platform/disk" fakesys "bosh/system/fakes" ) var _ = Describe("procMountsSearcher", func() { var ( fs *fakesys.FakeFileSystem searcher MountsSearcher ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() searcher = NewProcMountsSearcher(fs) }) Describe("SearchMounts", func() { Context("when reading /proc/mounts succeeds", func() { It("returns parsed mount information", func() { fs.WriteFileString( "/proc/mounts", `none /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k 0 0 none /run/shm tmpfs rw,nosuid,nodev,relatime 0 0 /dev/sda1 /boot ext2 rw,relatime,errors=continue 0 0
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() { Describe("concreteV1Service", func() { var ( fs *fakesys.FakeFileSystem specPath string service V1Service ) BeforeEach(func() { fs = fakesys.NewFakeFileSystem() specPath = "/spec.json" service = NewConcreteV1Service(fs, specPath) }) Describe("Get", func() { Context("when filesystem has a spec file", func() { BeforeEach(func() { fs.WriteFileString(specPath, `{"deployment":"fake-deployment-name"}`) }) It("reads spec from filesystem", func() { spec, err := service.Get() Expect(err).ToNot(HaveOccurred()) Expect(spec).To(Equal(V1ApplySpec{Deployment: "fake-deployment-name"})) }) It("returns error if reading spec from filesystem errs", func() { fs.ReadFileError = errors.New("fake-read-error") spec, err := service.Get() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-read-error")) Expect(spec).To(Equal(V1ApplySpec{})) }) }) Context("when filesystem does not have a spec file", func() { It("reads spec from filesystem", func() { spec, err := service.Get() Expect(err).ToNot(HaveOccurred()) Expect(spec).To(Equal(V1ApplySpec{})) }) }) }) Describe("Set", func() { newSpec := V1ApplySpec{Deployment: "fake-deployment-name"} It("writes spec to filesystem", func() { err := service.Set(newSpec) Expect(err).ToNot(HaveOccurred()) specPathStats := fs.GetFileTestStat(specPath) Expect(specPathStats).ToNot(BeNil()) boshassert.MatchesJSONBytes(GinkgoT(), newSpec, specPathStats.Content) }) It("returns error if writing spec to filesystem errs", func() { fs.WriteToFileError = errors.New("fake-write-error") err := service.Set(newSpec) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-write-error")) }) }) }) }