Expect(2).To(Equal(len(fakeRunner.RunCommands))) Expect(fakeRunner.RunCommands[1]).To(Equal([]string{"mke2fs", "-t", "ext4", "-j", "-E", "lazy_itable_init=1", "/dev/xvda2"})) }) Context("when mke2fs errors", func() { var fakeRunner *fakesys.FakeCmdRunner var fakeFs *fakesys.FakeFileSystem var mkeCmd string BeforeEach(func() { fakeRunner = fakesys.NewFakeCmdRunner() fakeFs = fakesys.NewFakeFileSystem() fakeFs.WriteFile("/sys/fs/ext4/features/lazy_itable_init", []byte{}) fakeRunner.AddCmdResult("blkid -p /dev/xvda2", fakesys.FakeCmdResult{Stdout: `xxxxx TYPE="ext2" yyyy zzzz`}) mkeCmd = fmt.Sprintf("mke2fs -t %s -j -E lazy_itable_init=1 %s", FileSystemExt4, "/dev/xvda2") }) It("retries mke2fs if the erros is 'device is already in use'", func() { fakeRunner.AddCmdResult(mkeCmd, fakesys.FakeCmdResult{ Error: errors.New(`mke2fs 1.42.9 (4-Feb-2014) /dev/xvdf1 is apparently in use by the system; will not make a filesystem here`), }) fakeRunner.AddCmdResult(mkeCmd, fakesys.FakeCmdResult{ ExitStatus: 0, }) formatter := NewLinuxFormatter(fakeRunner, fakeFs) formatter.Format("/dev/xvda2", FileSystemExt4)
Expect(ip).To(Equal("74.125.239.101")) }) }) Context("when host is not an ip", func() { It("returns 127.0.0.1 for 'localhost'", func() { ip, err := resolver.LookupHost([]string{"8.8.8.8"}, "localhost") Expect(err).ToNot(HaveOccurred()) Expect(ip).To(Equal("127.0.0.1")) }) It("returns ip for resolved host", func() { digResult := fakesys.FakeCmdResult{ Stdout: "74.125.19.99", } runner.AddCmdResult("dig @8.8.8.8 google.com. +short +time=1", digResult) ip, err := resolver.LookupHost([]string{"8.8.8.8"}, "google.com.") Expect(err).ToNot(HaveOccurred()) Expect(ip).To(Equal("74.125.19.99")) }) It("returns ip for resolved host after failing and then succeeding", func() { digResult := fakesys.FakeCmdResult{ Stdout: "74.125.19.99", } runner.AddCmdResult("dig @8.8.8.8 google.com. +short +time=1", digResult) ip, err := resolver.LookupHost([]string{"127.0.0.127", "8.8.8.8"}, "google.com.") Expect(err).ToNot(HaveOccurred()) Expect(ip).To(Equal("74.125.19.99")) })
runner *fakesys.FakeCmdRunner searcher RoutesSearcher ) BeforeEach(func() { runner = fakesys.NewFakeCmdRunner() searcher = NewCmdRoutesSearcher(runner) }) Describe("SearchRoutes", func() { Context("when running command succeeds", func() { It("returns parsed routes information", func() { runner.AddCmdResult("route -n", fakesys.FakeCmdResult{ Stdout: `Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 172.16.79.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 0.0.0.0 172.16.79.1 0.0.0.0 UG 0 0 0 eth0 `, }) routes, err := searcher.SearchRoutes() Expect(err).ToNot(HaveOccurred()) Expect(routes).To(Equal([]Route{ Route{Destination: "172.16.79.0", Gateway: "0.0.0.0", InterfaceName: "eth0"}, Route{Destination: "169.254.0.0", Gateway: "0.0.0.0", InterfaceName: "eth0"}, Route{Destination: "0.0.0.0", Gateway: "172.16.79.1", InterfaceName: "eth0"}, })) }) It("ignores empty lines", func() { runner.AddCmdResult("route -n", fakesys.FakeCmdResult{
}) It("returns error", func() { _, _, err := compiler.Compile(pkg) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("Packaging script for package 'fake-package-1' not found")) }) }) Context("when the packaging script fails", func() { JustBeforeEach(func() { fakeResult := fakesys.FakeCmdResult{ ExitStatus: 1, Error: errors.New("fake-error"), } runner.AddCmdResult("bash -x packaging", fakeResult) }) It("returns error", func() { _, _, err := compiler.Compile(pkg) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("Compiling package")) Expect(err.Error()).To(ContainSubstring("fake-error")) }) }) Context("when compression fails", func() { JustBeforeEach(func() { compressor.CompressFilesInDirErr = errors.New("fake-compression-error") })
Expect(actualCmd.WorkingDir).To(Equal("/fake-working-dir")) }) It("returns an error if it fails to save output", func() { fs.OpenFileErr = errors.New("fake-open-file-error") _, err := runner.RunCommand("fake-log-dir-name", "fake-log-file-name", cmd) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-open-file-error")) }) Context("when command succeeds", func() { BeforeEach(func() { cmdRunner.AddCmdResult("fake-cmd fake-args", fakesys.FakeCmdResult{ Stdout: "fake-stdout", Stderr: "fake-stderr", ExitStatus: 0, }) }) It("returns correct result", func() { expectedResult := &CmdResult{ IsStdoutTruncated: false, Stdout: []byte("fake-stdout"), Stderr: []byte("fake-stderr"), ExitStatus: 0, } result, err := runner.RunCommand("fake-log-dir-name", "fake-log-file-name", cmd) Expect(err).ToNot(HaveOccurred()) Expect(result).To(Equal(expectedResult))
BeforeEach(func() { logger = boshlog.NewLogger(boshlog.LevelNone) fakeCmdRunner = fakesys.NewFakeCmdRunner() fakeclock = &fakeboshaction.FakeClock{} partitioner = NewPartedPartitioner(logger, fakeCmdRunner, fakeclock) }) Describe("Partition", func() { Context("when the desired partitions do not exist", func() { Context("when there is no partition table", func() { BeforeEach(func() { fakeCmdRunner.AddCmdResult( "parted -m /dev/sda unit B print", fakesys.FakeCmdResult{ Stdout: "Error: /dev/sda: unrecognised disk label", ExitStatus: 1, Error: errors.New("Error: /dev/sda: unrecognised disk label"), }, ) fakeCmdRunner.AddCmdResult( "parted -m /dev/sda unit B print", fakesys.FakeCmdResult{ Stdout: `BYT; /dev/xvdf:221190815744B:xvd:512:512:gpt:Xen Virtual Block Device; `}) fakeCmdRunner.AddCmdResult( "parted -s /dev/sda mklabel gpt", fakesys.FakeCmdResult{Stdout: "", ExitStatus: 0}) }) It("makes a gpt label and then creates partitions using parted", func() {
Expect(outBuf).To(MatchRegexp(expectedContent)) }) It("runs arp -d for the given IP", func() { expectedCommand := []string{"arp", "-d", address} cmd := cmdRunner.RunCommands[0] Expect(reflect.DeepEqual(cmd, expectedCommand)).To(BeTrue()) }) Context("When ARP deletion command returns an error", func() { BeforeEach(func() { cmd := fmt.Sprintf("arp -d %s", address) errorResult := fakesys.FakeCmdResult{ Stdout: "", Stderr: "", ExitStatus: 1, Error: errors.New("an error"), Sticky: false, } cmdRunner.AddCmdResult(cmd, errorResult) }) It("logs the error as INFO", func() { expectedContent := expectedLogFormat("INFO", fmt.Sprintf("Ignoring arp failure deleting %s from cache:.*", address)) Expect(outBuf).To(MatchRegexp(expectedContent)) }) }) }) })
func describeUbuntuNetManager() { var ( fs *fakesys.FakeFileSystem cmdRunner *fakesys.FakeCmdRunner ipResolver *fakeip.FakeResolver addressBroadcaster *fakearp.FakeAddressBroadcaster interfaceAddrsProvider *fakeip.FakeInterfaceAddressesProvider netManager UbuntuNetManager interfaceConfigurationCreator InterfaceConfigurationCreator ) writeNetworkDevice := func(iface string, macAddress string, isPhysical bool) string { interfacePath := fmt.Sprintf("/sys/class/net/%s", iface) fs.WriteFile(interfacePath, []byte{}) if isPhysical { fs.WriteFile(fmt.Sprintf("/sys/class/net/%s/device", iface), []byte{}) } fs.WriteFileString(fmt.Sprintf("/sys/class/net/%s/address", iface), fmt.Sprintf("%s\n", macAddress)) return interfacePath } stubInterfacesWithVirtual := func(physicalInterfaces map[string]boshsettings.Network, virtualInterfaces []string) { interfacePaths := []string{} for iface, networkSettings := range physicalInterfaces { interfacePaths = append(interfacePaths, writeNetworkDevice(iface, networkSettings.Mac, true)) } for _, iface := range virtualInterfaces { interfacePaths = append(interfacePaths, writeNetworkDevice(iface, "virtual", false)) } fs.SetGlob("/sys/class/net/*", interfacePaths) } stubInterfaces := func(physicalInterfaces map[string]boshsettings.Network) { stubInterfacesWithVirtual(physicalInterfaces, nil) } BeforeEach(func() { fs = fakesys.NewFakeFileSystem() cmdRunner = fakesys.NewFakeCmdRunner() ipResolver = &fakeip.FakeResolver{} logger := boshlog.NewLogger(boshlog.LevelNone) interfaceConfigurationCreator = NewInterfaceConfigurationCreator(logger) addressBroadcaster = &fakearp.FakeAddressBroadcaster{} interfaceAddrsProvider = &fakeip.FakeInterfaceAddressesProvider{} interfaceAddrsValidator := boship.NewInterfaceAddressesValidator(interfaceAddrsProvider) dnsValidator := NewDNSValidator(fs) netManager = NewUbuntuNetManager( fs, cmdRunner, ipResolver, interfaceConfigurationCreator, interfaceAddrsValidator, dnsValidator, addressBroadcaster, logger, ).(UbuntuNetManager) }) Describe("ComputeNetworkConfig", func() { Context("when there is one manual network and neither is marked as default for DNS", func() { It("should use the manual network for DNS", func() { networks := boshsettings.Networks{ "manual": factory.Network{DNS: &[]string{"8.8.8.8"}}.Build(), } stubInterfaces(networks) _, _, dnsServers, err := netManager.ComputeNetworkConfig(networks) Expect(err).ToNot(HaveOccurred()) Expect(dnsServers).To(Equal([]string{"8.8.8.8"})) }) }) Context("when there is a vip network and a manual network and neither is marked as default for DNS", func() { It("should use the manual network for DNS", func() { networks := boshsettings.Networks{ "vip": boshsettings.Network{Type: "vip"}, "manual": factory.Network{Type: "manual", DNS: &[]string{"8.8.8.8"}}.Build(), } stubInterfaces(networks) _, _, dnsServers, err := netManager.ComputeNetworkConfig(networks) Expect(err).ToNot(HaveOccurred()) Expect(dnsServers).To(Equal([]string{"8.8.8.8"})) }) }) Context("when there is a vip network and a manual network and the manual network is marked as default for DNS", func() { It("should use the manual network for DNS", func() { networks := boshsettings.Networks{ "vip": boshsettings.Network{Type: "vip"}, "manual": factory.Network{Type: "manual", DNS: &[]string{"8.8.8.8"}, Default: []string{"dns"}}.Build(), } stubInterfaces(networks) _, _, dnsServers, err := netManager.ComputeNetworkConfig(networks) Expect(err).ToNot(HaveOccurred()) Expect(dnsServers).To(Equal([]string{"8.8.8.8"})) }) }) Context("when specified more than one DNS", func() { It("extracts all DNS servers from the network configured as default DNS", func() { networks := boshsettings.Networks{ "default": factory.Network{ IP: "10.10.0.32", Netmask: "255.255.255.0", Mac: "aa::bb::cc", Default: []string{"dns", "gateway"}, DNS: &[]string{"54.209.78.6", "127.0.0.5"}, Gateway: "10.10.0.1", }.Build(), } stubInterfaces(networks) staticInterfaceConfigurations, dhcpInterfaceConfigurations, dnsServers, err := netManager.ComputeNetworkConfig(networks) Expect(err).ToNot(HaveOccurred()) Expect(staticInterfaceConfigurations).To(Equal([]StaticInterfaceConfiguration{ { Name: "default", Address: "10.10.0.32", Netmask: "255.255.255.0", Network: "10.10.0.0", IsDefaultForGateway: true, Broadcast: "10.10.0.255", Mac: "aa::bb::cc", Gateway: "10.10.0.1", }, })) Expect(dhcpInterfaceConfigurations).To(BeEmpty()) Expect(dnsServers).To(Equal([]string{"54.209.78.6", "127.0.0.5"})) }) }) }) Describe("SetupNetworking", func() { var ( dhcpNetwork boshsettings.Network staticNetwork boshsettings.Network expectedNetworkConfigurationForStaticAndDhcp string ) BeforeEach(func() { dhcpNetwork = boshsettings.Network{ Type: "dynamic", Default: []string{"dns"}, DNS: []string{"8.8.8.8", "9.9.9.9"}, Mac: "fake-dhcp-mac-address", } staticNetwork = boshsettings.Network{ Type: "manual", IP: "1.2.3.4", Default: []string{"gateway"}, Netmask: "255.255.255.0", Gateway: "3.4.5.6", Mac: "fake-static-mac-address", } interfaceAddrsProvider.GetInterfaceAddresses = []boship.InterfaceAddress{ boship.NewSimpleInterfaceAddress("ethstatic", "1.2.3.4"), } fs.WriteFileString("/etc/resolv.conf", ` nameserver 8.8.8.8 nameserver 9.9.9.9 `) expectedNetworkConfigurationForStaticAndDhcp = `# Generated by bosh-agent auto lo iface lo inet loopback auto ethdhcp iface ethdhcp inet dhcp auto ethstatic iface ethstatic inet static address 1.2.3.4 network 1.2.3.0 netmask 255.255.255.0 broadcast 1.2.3.255 gateway 3.4.5.6 dns-nameservers 8.8.8.8 9.9.9.9` }) It("writes interfaces in /etc/network/interfaces in alphabetic order", func() { anotherDHCPNetwork := boshsettings.Network{ Type: "dynamic", Default: []string{"dns"}, DNS: []string{"8.8.8.8", "9.9.9.9"}, Mac: "fake-another-mac-address", } stubInterfaces(map[string]boshsettings.Network{ "ethstatic": staticNetwork, "ethdhcp1": dhcpNetwork, "ethdhcp0": anotherDHCPNetwork, }) err := netManager.SetupNetworking(boshsettings.Networks{ "dhcp-network-1": dhcpNetwork, "dhcp-network-2": anotherDHCPNetwork, "static-network": staticNetwork, }, nil) Expect(err).ToNot(HaveOccurred()) networkConfig := fs.GetFileTestStat("/etc/network/interfaces") Expect(networkConfig).ToNot(BeNil()) expectedNetworkConfigurationForStaticAndDhcp = `# Generated by bosh-agent auto lo iface lo inet loopback auto ethdhcp0 iface ethdhcp0 inet dhcp auto ethdhcp1 iface ethdhcp1 inet dhcp auto ethstatic iface ethstatic inet static address 1.2.3.4 network 1.2.3.0 netmask 255.255.255.0 broadcast 1.2.3.255 gateway 3.4.5.6 dns-nameservers 8.8.8.8 9.9.9.9` Expect(networkConfig.StringContents()).To(Equal(expectedNetworkConfigurationForStaticAndDhcp)) }) It("configures gateway, broadcast and dns for default network only", func() { staticNetwork = boshsettings.Network{ Type: "manual", IP: "1.2.3.4", Netmask: "255.255.255.0", Gateway: "3.4.5.6", Mac: "fake-static-mac-address", } secondStaticNetwork := boshsettings.Network{ Type: "manual", IP: "5.6.7.8", Netmask: "255.255.255.0", Gateway: "6.7.8.9", Mac: "second-fake-static-mac-address", DNS: []string{"8.8.8.8"}, Default: []string{"gateway", "dns"}, } stubInterfaces(map[string]boshsettings.Network{ "eth0": staticNetwork, "eth1": secondStaticNetwork, }) interfaceAddrsProvider.GetInterfaceAddresses = []boship.InterfaceAddress{ boship.NewSimpleInterfaceAddress("eth0", "1.2.3.4"), boship.NewSimpleInterfaceAddress("eth1", "5.6.7.8"), } err := netManager.SetupNetworking(boshsettings.Networks{ "static-1": staticNetwork, "static-2": secondStaticNetwork, }, nil) Expect(err).ToNot(HaveOccurred()) networkConfig := fs.GetFileTestStat("/etc/network/interfaces") Expect(networkConfig).ToNot(BeNil()) Expect(networkConfig.StringContents()).To(Equal(`# Generated by bosh-agent auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 1.2.3.4 network 1.2.3.0 netmask 255.255.255.0 auto eth1 iface eth1 inet static address 5.6.7.8 network 5.6.7.0 netmask 255.255.255.0 broadcast 5.6.7.255 gateway 6.7.8.9 dns-nameservers 8.8.8.8`)) }) It("writes /etc/network/interfaces without dns-namservers if there are no dns servers", func() { staticNetworkWithoutDNS := boshsettings.Network{ Type: "manual", IP: "1.2.3.4", Default: []string{"gateway"}, Netmask: "255.255.255.0", Gateway: "3.4.5.6", Mac: "fake-static-mac-address", } stubInterfaces(map[string]boshsettings.Network{ "ethstatic": staticNetworkWithoutDNS, }) err := netManager.SetupNetworking(boshsettings.Networks{"static-network": staticNetworkWithoutDNS}, nil) Expect(err).ToNot(HaveOccurred()) networkConfig := fs.GetFileTestStat("/etc/network/interfaces") Expect(networkConfig).ToNot(BeNil()) Expect(networkConfig.StringContents()).To(Equal(`# Generated by bosh-agent auto lo iface lo inet loopback auto ethstatic iface ethstatic inet static address 1.2.3.4 network 1.2.3.0 netmask 255.255.255.0 broadcast 1.2.3.255 gateway 3.4.5.6 `)) }) It("returns errors from glob /sys/class/net/", func() { fs.GlobErr = errors.New("fs-glob-error") err := netManager.SetupNetworking(boshsettings.Networks{"dhcp-network": dhcpNetwork, "static-network": staticNetwork}, nil) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fs-glob-error")) }) It("returns errors from writing the network configuration", func() { stubInterfaces(map[string]boshsettings.Network{ "dhcp": dhcpNetwork, "static": staticNetwork, }) fs.WriteFileError = errors.New("fs-write-file-error") err := netManager.SetupNetworking(boshsettings.Networks{"dhcp-network": dhcpNetwork, "static-network": staticNetwork}, nil) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fs-write-file-error")) }) It("returns errors when it can't creating network interface configurations", func() { stubInterfaces(map[string]boshsettings.Network{ "ethdhcp": dhcpNetwork, "ethstatic": staticNetwork, }) staticNetwork.Netmask = "not an ip" //will cause InterfaceConfigurationCreator to fail err := netManager.SetupNetworking(boshsettings.Networks{"static-network": staticNetwork}, nil) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("Creating interface configurations")) }) It("writes a dhcp configuration if there are dhcp networks", func() { stubInterfaces(map[string]boshsettings.Network{ "ethdhcp": dhcpNetwork, "ethstatic": staticNetwork, }) err := netManager.SetupNetworking(boshsettings.Networks{"dhcp-network": dhcpNetwork, "static-network": staticNetwork}, nil) Expect(err).ToNot(HaveOccurred()) dhcpConfig := fs.GetFileTestStat("/etc/dhcp/dhclient.conf") Expect(dhcpConfig).ToNot(BeNil()) Expect(dhcpConfig.StringContents()).To(Equal(`# 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 8.8.8.8, 9.9.9.9; `)) }) It("writes a dhcp configuration without prepended dns servers if there are no dns servers specified", func() { dhcpNetworkWithoutDNS := boshsettings.Network{ Type: "dynamic", Mac: "fake-dhcp-mac-address", } stubInterfaces(map[string]boshsettings.Network{ "ethdhcp": dhcpNetwork, }) err := netManager.SetupNetworking(boshsettings.Networks{"dhcp-network": dhcpNetworkWithoutDNS}, nil) Expect(err).ToNot(HaveOccurred()) dhcpConfig := fs.GetFileTestStat("/etc/dhcp/dhclient.conf") Expect(dhcpConfig).ToNot(BeNil()) Expect(dhcpConfig.StringContents()).To(Equal(`# 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; `)) }) It("returns an error if it can't write a dhcp configuration", func() { stubInterfaces(map[string]boshsettings.Network{ "ethdhcp": dhcpNetwork, "ethstatic": staticNetwork, }) fs.WriteFileErrors["/etc/dhcp/dhclient.conf"] = errors.New("dhclient.conf-write-error") err := netManager.SetupNetworking(boshsettings.Networks{"dhcp-network": dhcpNetwork, "static-network": staticNetwork}, nil) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("dhclient.conf-write-error")) }) It("doesn't write a dhcp configuration if there are no dhcp networks", func() { stubInterfaces(map[string]boshsettings.Network{ "ethstatic": staticNetwork, }) err := netManager.SetupNetworking(boshsettings.Networks{"static-network": staticNetwork}, nil) Expect(err).ToNot(HaveOccurred()) dhcpConfig := fs.GetFileTestStat("/etc/dhcp/dhclient.conf") Expect(dhcpConfig).To(BeNil()) }) It("restarts the networks if /etc/network/interfaces changes", func() { initialDhcpConfig := `# 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 8.8.8.8, 9.9.9.9; ` stubInterfaces(map[string]boshsettings.Network{ "ethdhcp": dhcpNetwork, "ethstatic": staticNetwork, }) fs.WriteFileString("/etc/dhcp/dhclient.conf", initialDhcpConfig) err := netManager.SetupNetworking(boshsettings.Networks{"dhcp-network": dhcpNetwork, "static-network": staticNetwork}, nil) Expect(err).ToNot(HaveOccurred()) Expect(len(cmdRunner.RunCommands)).To(Equal(5)) Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"pkill", "dhclient"})) Expect(cmdRunner.RunCommands[1:3]).To(ContainElement([]string{"resolvconf", "-d", "ethdhcp.dhclient"})) Expect(cmdRunner.RunCommands[1:3]).To(ContainElement([]string{"resolvconf", "-d", "ethstatic.dhclient"})) Expect(cmdRunner.RunCommands[3]).To(Equal([]string{"ifdown", "--force", "ethdhcp", "ethstatic"})) Expect(cmdRunner.RunCommands[4]).To(Equal([]string{"ifup", "--force", "ethdhcp", "ethstatic"})) }) It("doesn't restart the networks if /etc/network/interfaces and /etc/dhcp/dhclient.conf don't change", func() { initialDhcpConfig := `# 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 8.8.8.8, 9.9.9.9; ` stubInterfaces(map[string]boshsettings.Network{ "ethdhcp": dhcpNetwork, "ethstatic": staticNetwork, }) fs.WriteFileString("/etc/network/interfaces", expectedNetworkConfigurationForStaticAndDhcp) fs.WriteFileString("/etc/dhcp/dhclient.conf", initialDhcpConfig) err := netManager.SetupNetworking(boshsettings.Networks{"dhcp-network": dhcpNetwork, "static-network": staticNetwork}, nil) Expect(err).ToNot(HaveOccurred()) networkConfig := fs.GetFileTestStat("/etc/network/interfaces") Expect(networkConfig.StringContents()).To(Equal(expectedNetworkConfigurationForStaticAndDhcp)) dhcpConfig := fs.GetFileTestStat("/etc/dhcp/dhclient.conf") Expect(dhcpConfig.StringContents()).To(Equal(initialDhcpConfig)) Expect(len(cmdRunner.RunCommands)).To(Equal(0)) }) It("restarts the networks if /etc/dhcp/dhclient.conf changes", func() { stubInterfaces(map[string]boshsettings.Network{ "ethdhcp": dhcpNetwork, "ethstatic": staticNetwork, }) fs.WriteFileString("/etc/network/interfaces", expectedNetworkConfigurationForStaticAndDhcp) err := netManager.SetupNetworking(boshsettings.Networks{"dhcp-network": dhcpNetwork, "static-network": staticNetwork}, nil) Expect(err).ToNot(HaveOccurred()) networkConfig := fs.GetFileTestStat("/etc/network/interfaces") Expect(networkConfig.StringContents()).To(Equal(expectedNetworkConfigurationForStaticAndDhcp)) Expect(len(cmdRunner.RunCommands)).To(Equal(5)) Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"pkill", "dhclient"})) Expect(cmdRunner.RunCommands[1:3]).To(ContainElement([]string{"resolvconf", "-d", "ethdhcp.dhclient"})) Expect(cmdRunner.RunCommands[1:3]).To(ContainElement([]string{"resolvconf", "-d", "ethstatic.dhclient"})) Expect(cmdRunner.RunCommands[3]).To(Equal([]string{"ifdown", "--force", "ethdhcp", "ethstatic"})) Expect(cmdRunner.RunCommands[4]).To(Equal([]string{"ifup", "--force", "ethdhcp", "ethstatic"})) }) It("broadcasts MAC addresses for all interfaces", func() { stubInterfaces(map[string]boshsettings.Network{ "ethdhcp": dhcpNetwork, "ethstatic": staticNetwork, }) errCh := make(chan error) err := netManager.SetupNetworking(boshsettings.Networks{"dhcp-network": dhcpNetwork, "static-network": staticNetwork}, errCh) Expect(err).ToNot(HaveOccurred()) broadcastErr := <-errCh // wait for all arpings Expect(broadcastErr).ToNot(HaveOccurred()) Expect(addressBroadcaster.BroadcastMACAddressesAddresses).To(Equal([]boship.InterfaceAddress{ boship.NewSimpleInterfaceAddress("ethstatic", "1.2.3.4"), boship.NewResolvingInterfaceAddress("ethdhcp", ipResolver), })) }) It("skips vip networks", func() { stubInterfaces(map[string]boshsettings.Network{ "ethdhcp": dhcpNetwork, "ethstatic": staticNetwork, }) vipNetwork := boshsettings.Network{ Type: "vip", Default: []string{"dns"}, DNS: []string{"8.8.8.8", "9.9.9.9"}, Mac: "fake-vip-mac-address", IP: "9.8.7.6", } err := netManager.SetupNetworking(boshsettings.Networks{ "dhcp-network": dhcpNetwork, "static-network": staticNetwork, "vip-network": vipNetwork, }, nil) Expect(err).ToNot(HaveOccurred()) networkConfig := fs.GetFileTestStat("/etc/network/interfaces") Expect(networkConfig).ToNot(BeNil()) Expect(networkConfig.StringContents()).To(Equal(expectedNetworkConfigurationForStaticAndDhcp)) }) Context("when manual networks were not configured with proper IP addresses", func() { BeforeEach(func() { interfaceAddrsProvider.GetInterfaceAddresses = []boship.InterfaceAddress{ boship.NewSimpleInterfaceAddress("ethstatic", "1.2.3.5"), } }) It("fails", func() { stubInterfaces(map[string]boshsettings.Network{ "ethstatic": staticNetwork, }) errCh := make(chan error) err := netManager.SetupNetworking(boshsettings.Networks{"static-network": staticNetwork}, errCh) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("Validating static network configuration")) }) }) Context("when dns is not properly configured", func() { BeforeEach(func() { fs.WriteFileString("/etc/resolv.conf", "") }) It("fails", func() { staticNetwork = boshsettings.Network{ Type: "manual", IP: "1.2.3.4", Default: []string{"dns"}, DNS: []string{"8.8.8.8"}, Netmask: "255.255.255.0", Gateway: "3.4.5.6", Mac: "fake-static-mac-address", } stubInterfaces(map[string]boshsettings.Network{ "ethstatic": staticNetwork, }) errCh := make(chan error) err := netManager.SetupNetworking(boshsettings.Networks{"static-network": staticNetwork}, errCh) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("Validating dns configuration")) }) }) Context("when no MAC address is provided in the settings", func() { It("configures network for single device", func() { staticNetworkWithoutMAC := boshsettings.Network{ Type: "manual", IP: "2.2.2.2", Default: []string{"gateway"}, Netmask: "255.255.255.0", Gateway: "3.4.5.6", } stubInterfaces( map[string]boshsettings.Network{ "ethstatic": staticNetwork, }, ) interfaceAddrsProvider.GetInterfaceAddresses = []boship.InterfaceAddress{ boship.NewSimpleInterfaceAddress("ethstatic", "2.2.2.2"), } err := netManager.SetupNetworking(boshsettings.Networks{ "static-network": staticNetworkWithoutMAC, }, nil) Expect(err).ToNot(HaveOccurred()) networkConfig := fs.GetFileTestStat("/etc/network/interfaces") Expect(networkConfig).ToNot(BeNil()) expectedNetworkConfiguration := `# Generated by bosh-agent auto lo iface lo inet loopback auto ethstatic iface ethstatic inet static address 2.2.2.2 network 2.2.2.0 netmask 255.255.255.0 broadcast 2.2.2.255 gateway 3.4.5.6 ` Expect(networkConfig.StringContents()).To(Equal(expectedNetworkConfiguration)) }) It("configures network for a single physical device, when a virtual device is also present", func() { staticNetworkWithoutMAC := boshsettings.Network{ Type: "manual", IP: "2.2.2.2", Default: []string{"gateway"}, Netmask: "255.255.255.0", Gateway: "3.4.5.6", } stubInterfacesWithVirtual( map[string]boshsettings.Network{ "ethstatic": staticNetwork, }, []string{"virtual"}, ) interfaceAddrsProvider.GetInterfaceAddresses = []boship.InterfaceAddress{ boship.NewSimpleInterfaceAddress("ethstatic", "2.2.2.2"), } err := netManager.SetupNetworking(boshsettings.Networks{ "static-network": staticNetworkWithoutMAC, }, nil) Expect(err).ToNot(HaveOccurred()) networkConfig := fs.GetFileTestStat("/etc/network/interfaces") Expect(networkConfig).ToNot(BeNil()) expectedNetworkConfiguration := `# Generated by bosh-agent auto lo iface lo inet loopback auto ethstatic iface ethstatic inet static address 2.2.2.2 network 2.2.2.0 netmask 255.255.255.0 broadcast 2.2.2.255 gateway 3.4.5.6 ` Expect(networkConfig.StringContents()).To(Equal(expectedNetworkConfiguration)) }) }) }) Describe("GetConfiguredNetworkInterfaces", func() { Context("when there are network devices", func() { BeforeEach(func() { interfacePaths := []string{} interfacePaths = append(interfacePaths, writeNetworkDevice("fake-eth0", "aa:bb", true)) interfacePaths = append(interfacePaths, writeNetworkDevice("fake-eth1", "cc:dd", true)) interfacePaths = append(interfacePaths, writeNetworkDevice("fake-eth2", "ee:ff", true)) fs.SetGlob("/sys/class/net/*", interfacePaths) }) It("returns networks that are defined in /etc/network/interfaces", func() { cmdRunner.AddCmdResult("ifup --no-act fake-eth0", fakesys.FakeCmdResult{ Stdout: "", Stderr: "ifup: interface fake-eth0 already configured", ExitStatus: 0, }) cmdRunner.AddCmdResult("ifup --no-act fake-eth1", fakesys.FakeCmdResult{ Stdout: "", Stderr: "Ignoring unknown interface fake-eth1=fake-eth1.", ExitStatus: 0, }) cmdRunner.AddCmdResult("ifup --no-act fake-eth2", fakesys.FakeCmdResult{ Stdout: "", Stderr: "ifup: interface fake-eth2 already configured", ExitStatus: 0, }) interfaces, err := netManager.GetConfiguredNetworkInterfaces() Expect(err).ToNot(HaveOccurred()) Expect(interfaces).To(ConsistOf("fake-eth0", "fake-eth2")) }) }) Context("when there are no network devices", func() { It("returns empty list", func() { interfaces, err := netManager.GetConfiguredNetworkInterfaces() Expect(err).ToNot(HaveOccurred()) Expect(interfaces).To(Equal([]string{})) }) }) }) }
var ( runner *fakesys.FakeCmdRunner searcher MountsSearcher ) BeforeEach(func() { runner = fakesys.NewFakeCmdRunner() searcher = NewCmdMountsSearcher(runner) }) Describe("SearchMounts", func() { Context("when running command succeeds", func() { It("returns parsed mount information", func() { runner.AddCmdResult("mount", fakesys.FakeCmdResult{ Stdout: `devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620) tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755) /dev/sda1 on /boot type ext2 (rw) none on /tmp/warden/cgroup type tmpfs (rw)`, }) mounts, err := searcher.SearchMounts() Expect(err).ToNot(HaveOccurred()) Expect(mounts).To(Equal([]Mount{ Mount{PartitionPath: "devpts", MountPoint: "/dev/pts"}, Mount{PartitionPath: "tmpfs", MountPoint: "/run"}, Mount{PartitionPath: "/dev/sda1", MountPoint: "/boot"}, Mount{PartitionPath: "none", MountPoint: "/tmp/warden/cgroup"}, })) }) It("ignores empty lines", func() { runner.AddCmdResult("mount", fakesys.FakeCmdResult{
var _ = Describe("MonitRetryable", func() { var ( cmdRunner *fakesys.FakeCmdRunner monitRetryable boshretry.Retryable ) BeforeEach(func() { cmdRunner = fakesys.NewFakeCmdRunner() monitRetryable = NewMonitRetryable(cmdRunner) }) Describe("Attempt", func() { Context("when starting monit fails", func() { BeforeEach(func() { cmdRunner.AddCmdResult("sv start monit", fakesys.FakeCmdResult{ ExitStatus: 255, Error: errors.New("fake-start-monit-error"), }) }) It("is retryable and returns err", func() { isRetryable, err := monitRetryable.Attempt() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-start-monit-error")) Expect(isRetryable).To(BeTrue()) Expect(len(cmdRunner.RunCommands)).To(Equal(1)) Expect(cmdRunner.RunCommands[0]).To(Equal([]string{"sv", "start", "monit"})) }) }) Context("when starting succeeds", func() { BeforeEach(func() {
Expect(runner.RunCommands).To( ContainElement([]string{"-Command", fmt.Sprintf(NicSettingsTemplate, network1.Mac, network1.IP, network1.Netmask, network1.Gateway)})) Expect(runner.RunCommands).To( ContainElement([]string{"-Command", fmt.Sprintf(NicSettingsTemplate, network2.Mac, network2.IP, network2.Netmask, "")})) }) It("ignores VIP networks", func() { err := setupNetworking(boshsettings.Networks{"vip": vip}) Expect(err).ToNot(HaveOccurred()) Expect(runner.RunCommands).To(ContainElement([]string{"-Command", ResetDNSTemplate})) }) It("returns an error when configuring fails", func() { setupMACs(network1) runner.AddCmdResult( "-Command "+fmt.Sprintf(NicSettingsTemplate, network1.Mac, network1.IP, network1.Netmask, network1.Gateway), fakesys.FakeCmdResult{Error: errors.New("fake-err")}, ) err := setupNetworking(boshsettings.Networks{"static-1": network1}) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(Equal("Configuring interface: fake-err")) }) }) Context("when there is a network marked default for DNS", func() { It("configures DNS with a single DNS server", func() { network := boshsettings.Network{ Type: "manual", DNS: []string{"8.8.8.8"}, Default: []string{"gateway", "dns"}, }
var _ = Describe("sfdiskPartitioner", func() { var ( runner *fakesys.FakeCmdRunner partitioner Partitioner ) BeforeEach(func() { runner = fakesys.NewFakeCmdRunner() logger := boshlog.NewLogger(boshlog.LevelNone) partitioner = NewSfdiskPartitioner(logger, runner) }) It("sfdisk partition", func() { runner.AddCmdResult("sfdisk -d /dev/sda", fakesys.FakeCmdResult{Stdout: devSdaSfdiskEmptyDump}) partitions := []Partition{ {Type: PartitionTypeSwap, SizeInBytes: 512 * 1024 * 1024}, {Type: PartitionTypeLinux, SizeInBytes: 1024 * 1024 * 1024}, {Type: PartitionTypeLinux, SizeInBytes: 512 * 1024 * 1024}, } partitioner.Partition("/dev/sda", partitions) Expect(1).To(Equal(len(runner.RunCommandsWithInput))) Expect(runner.RunCommandsWithInput[0]).To(Equal([]string{",512,S\n,1024,L\n,,L\n", "sfdisk", "-uM", "/dev/sda"})) }) It("sfdisk partition with no partition table", func() { runner.AddCmdResult("sfdisk -d /dev/sda", fakesys.FakeCmdResult{Stderr: devSdaSfdiskNotableDumpStderr})
}) }) }) Describe("StartJobSupervisor", func() { It("should start monit service", func() { err := monit.StartJobSupervisor() Expect(err).ToNot(HaveOccurred()) Expect(len(runner.RunCommands)).To(Equal(1)) Expect(runner.RunCommands[0]).To(Equal([]string{"sv", "start", "monit"})) }) It("should return error when starting monit service fails", func() { runner.AddCmdResult("sv start monit", fakesys.FakeCmdResult{Error: errors.New("fake-monit-error")}) err := monit.StartJobSupervisor() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-monit-error")) Expect(len(runner.RunCommands)).To(Equal(1)) Expect(runner.RunCommands[0]).To(Equal([]string{"sv", "start", "monit"})) }) }) Describe("StopJobSupervisor", func() { It("should stop monit service", func() { err := monit.StopJobSupervisor() Expect(err).ToNot(HaveOccurred())
fs = fakesys.NewFakeFileSystem() cmdRunner = fakesys.NewFakeCmdRunner() directorInfo := bltaction.DirectorInfo{ UUID: "fake-director-uuid", URL: "fake-director-url", } boshCmd := boshsys.Command{Name: "bosh"} fs.ReturnTempFile = fakesys.NewFakeFile("cli-config-path", fs) cliRunner := bltclirunner.NewRunner(boshCmd, cmdRunner, fs) cliRunner.Configure() renderer := NewRenderer(fs) cmdRunner.AddCmdResult("bosh -n -c cli-config-path deploy", fakesys.FakeCmdResult{ Stdout: "Task 15 done", }) cmdRunner.AddCmdResult("bosh -n -c cli-config-path deploy", fakesys.FakeCmdResult{ Stdout: "Task 20 done", }) parameters := bftconfig.Parameters{ NameLength: []int{5, 10}, Instances: []int{2, 4}, AvailabilityZones: [][]string{[]string{"z1"}, []string{"z1", "z2"}}, PersistentDiskDefinition: []string{"disk_type", "disk_pool"}, PersistentDiskSize: []int{0, 100}, NumberOfJobs: []int{1, 2}, MigratedFromCount: []int{0}, VmTypeDefinition: []string{"vm_type"},
Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-temp-dir-error")) }) }) Context("when writing renderer script fails", func() { It("returns an error", func() { fs.WriteFileError = errors.New("fake-write-error") err := erbRenderer.Render("src-path", "dst-path", context) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-write-error")) }) }) Context("when running ruby command fails", func() { BeforeEach(func() { runner.AddCmdResult( "ruby fake-temp-dir/erb-render.rb fake-temp-dir/erb-context.json fake-src-path fake-dst-path", fakesys.FakeCmdResult{ Error: errors.New("fake-cmd-error"), }) }) It("returns an error", func() { err := erbRenderer.Render("fake-src-path", "fake-dst-path", context) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-cmd-error")) }) }) })
Expect(err).NotTo(HaveOccurred()) logger = boshlog.NewLogger(boshlog.LevelNone) scriptRunner = NewConcreteScriptRunner(scriptCommandFactory, cmdRunner, fs, logger) }) Describe("RunCommand", func() { It("runs a successful script command and doesnt return an error", func() { script := ` Write-Output stdout [Console]::Error.WriteLine('stderr') ` cmdRunner.AddCmdResult("/fake-temp-file.fake-ext", fakesys.FakeCmdResult{ Stdout: "stdout", Stderr: "stderr", ExitStatus: 0, }) var scriptContent string cmdCallback := func() { var err error scriptContent, err = fs.ReadFileString("/fake-temp-file.fake-ext") Expect(err).NotTo(HaveOccurred()) } cmdRunner.SetCmdCallback("/fake-temp-file.fake-ext", cmdCallback) stdout, stderr, err := scriptRunner.Run(script) Expect(err).NotTo(HaveOccurred()) Expect(stdout).To(Equal("stdout")) Expect(stderr).To(Equal("stderr"))
Expect(err).To(HaveOccurred()) }) }) }) Describe("Mount", func() { var ( mountResults fakesys.FakeCmdResult ) BeforeEach(func() { mountResults = fakesys.FakeCmdResult{} }) JustBeforeEach(func() { runner.AddCmdResult("mount /dev/sr0 /fake/settings/path", mountResults) }) It("runs the mount command", func() { err := cd.Mount("/fake/settings/path") Expect(err).NotTo(HaveOccurred()) Expect(runner.RunCommands).To(Equal([][]string{{"mount", "/dev/sr0", "/fake/settings/path"}})) }) Context("when mount command errors", func() { BeforeEach(func() { mountResults = fakesys.FakeCmdResult{ Stderr: "failed to mount", Error: errors.New("exit 1"), } })
Expect(err.Error()).To(Equal("fake-mkdir-all-error")) }) It("returns an error if it fails to open stdout/stderr log file", func() { fs.OpenFileErr = errors.New("fake-open-file-error") err := genericScript.Run() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(Equal("fake-open-file-error")) }) Context("when command succeeds", func() { BeforeEach(func() { cmdRunner.AddCmdResult("/path-to-script", fakesys.FakeCmdResult{ Stdout: "fake-stdout", Stderr: "fake-stderr", ExitStatus: 0, Error: nil, }) }) It("saves stdout/stderr to log file", func() { err := genericScript.Run() Expect(err).ToNot(HaveOccurred()) Expect(fs.FileExists(stdoutLogPath)).To(BeTrue()) Expect(fs.FileExists(stderrLogPath)).To(BeTrue()) stdout, err := fs.ReadFileString(stdoutLogPath) Expect(err).ToNot(HaveOccurred()) Expect(stdout).To(Equal("fake-stdout"))
BeforeEach(func() { logger := boshlog.NewLogger(boshlog.LevelNone) fakeCmdRunner = fakesys.NewFakeCmdRunner() partitioner = NewRootDevicePartitioner(logger, fakeCmdRunner, 1) }) Describe("Partition", func() { Context("when the desired partitions do not exist", func() { BeforeEach(func() { // 20GiB device, ~3GiB partition 0, 18403868671B remaining fakeCmdRunner.AddCmdResult( "parted -m /dev/sda unit B print", fakesys.FakeCmdResult{ Stdout: `BYT; /dev/vda:21474836480B:virtblk:512:512:msdos:Virtio Block Device; 1:32256B:3071000063B:3070967808B:ext4::; `, }, ) }) It("creates partitions (aligned to 1MiB) using parted", func() { partitions := []Partition{ {SizeInBytes: 8589934592}, // swap (8GiB) {SizeInBytes: 8589934592}, // ephemeral (8GiB) } // Calculating "aligned" partition start/end/size // (3071000063 + 1) % 1048576 = 769536 // (3071000063 + 1) + 1048576 - 769536 = 3071279104 (aligned start)
) BeforeEach(func() { logger = boshlog.NewLogger(boshlog.LevelNone) fakeCmdRunner = fakesys.NewFakeCmdRunner() fakeclock = &fakeboshaction.FakeClock{} partitioner = NewPartedPartitioner(logger, fakeCmdRunner, fakeclock) }) Describe("Partition", func() { Context("when the desired partitions do not exist", func() { Context("when there is no partition table", func() { BeforeEach(func() { fakeCmdRunner.AddCmdResult( "parted -m /dev/sda unit B print", fakesys.FakeCmdResult{ Stdout: "Error: /dev/sda: unrecognised disk label", ExitStatus: 1, Error: errors.New("Error: /dev/sda: unrecognised disk label")}, ) fakeCmdRunner.AddCmdResult( "parted -m /dev/sda unit B print", fakesys.FakeCmdResult{ Stdout: `BYT; /dev/xvdf:221190815744B:xvd:512:512:gpt:Xen Virtual Block Device; `}) fakeCmdRunner.AddCmdResult( "parted -s /dev/sda mklabel gpt", fakesys.FakeCmdResult{Stdout: "", ExitStatus: 0}) }) It("makes a gpt label and then creates partitions using parted", func() { partitions := []Partition{
var ( runner *fakesys.FakeCmdRunner partitioner Partitioner fakeclock *fakeboshaction.FakeClock ) BeforeEach(func() { runner = fakesys.NewFakeCmdRunner() logger := boshlog.NewLogger(boshlog.LevelNone) fakeclock = &fakeboshaction.FakeClock{} partitioner = NewSfdiskPartitioner(logger, runner, fakeclock) }) It("sfdisk partition", func() { runner.AddCmdResult("sfdisk -d /dev/sda", fakesys.FakeCmdResult{Stdout: devSdaSfdiskEmptyDump}) partitions := []Partition{ {Type: PartitionTypeSwap, SizeInBytes: 512 * 1024 * 1024}, {Type: PartitionTypeLinux, SizeInBytes: 1024 * 1024 * 1024}, {Type: PartitionTypeLinux, SizeInBytes: 512 * 1024 * 1024}, } partitioner.Partition("/dev/sda", partitions) Expect(1).To(Equal(len(runner.RunCommandsWithInput))) Expect(runner.RunCommandsWithInput[0]).To(Equal([]string{",512,S\n,1024,L\n,,L\n", "sfdisk", "-uM", "/dev/sda"})) }) It("sfdisk partition with no partition table", func() { runner.AddCmdResult("sfdisk -d /dev/sda", fakesys.FakeCmdResult{Stderr: devSdaSfdiskNotableDumpStderr})
Eventually(func() string { err := <-errchan return err.Error() }).Should(Equal("Getting monit status: Error message")) Expect(len(runner.RunCommands)).To(Equal(1)) // called 'monit stop', the right loop is failing }) }) Context("when a stop service errors", func() { It("exits with an error message", func() { fakeErrorResult := fakesys.FakeCmdResult{ Error: errors.New("test error result"), } runner.AddCmdResult("monit stop -g vcap", fakeErrorResult) err := monit.StopAndWait() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(Equal(fmt.Sprintf("%s%s", "Stop all services: ", fakeErrorResult.Error))) }) }) Context("when a service is in error state", func() { It("exits with an error message", func() { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requestData := make(map[string]string) resBody := readFixture("monit/test_assets/monit_status_errored.xml") if r.URL.Path == "/_status2" { w.Write(resBody)
Expect(runner.RunCommands[1]).To(Equal([]string{"mount", "/dev/baz", "/mnt/bar"})) }) It("returns error and does not try to unmount/mount anything when searching mounts fails", func() { mountsSearcher.SearchMountsErr = errors.New("fake-search-mounts-err") err := mounter.Remount("/mnt/foo", "/mnt/bar") Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-search-mounts-err")) Expect(0).To(Equal(len(runner.RunCommands))) }) }) Describe("SwapOn", func() { It("linux swap on", func() { runner.AddCmdResult("swapon -s", fakesys.FakeCmdResult{Stdout: "Filename Type Size Used Priority\n"}) mounter.SwapOn("/dev/swap") Expect(2).To(Equal(len(runner.RunCommands))) Expect(runner.RunCommands[1]).To(Equal([]string{"swapon", "/dev/swap"})) }) It("linux swap on when already on", func() { runner.AddCmdResult("swapon -s", fakesys.FakeCmdResult{Stdout: swaponUsageOutput}) mounter.SwapOn("/dev/swap") Expect(1).To(Equal(len(runner.RunCommands))) Expect(runner.RunCommands[0]).To(Equal([]string{"swapon", "-s"})) }) It("linux swap on when already on other device", func() {
Expect(fileName).To(BeEmpty()) }) It("external get errs when external cli errs", func() { tempFile, err := fs.TempFile("bosh-blobstore-external-TestGetErrsWhenExternalCliErrs") Expect(err).ToNot(HaveOccurred()) fs.ReturnTempFile = tempFile defer fs.RemoveAll(tempFile.Name()) expectedCmd := []string{ "bosh-blobstore-fake-provider", "-c", configPath, "get", "fake-blob-id", tempFile.Name(), } runner.AddCmdResult(strings.Join(expectedCmd, " "), fakesys.FakeCmdResult{Error: errors.New("fake-error")}) fileName, err := blobstore.Get("fake-blob-id", "") Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-error")) Expect(fileName).To(BeEmpty()) Expect(fs.FileExists(tempFile.Name())).To(BeFalse()) }) }) Describe("CleanUp", func() { It("external clean up", func() { file, err := fs.TempFile("bosh-blobstore-external-TestCleanUp") Expect(err).ToNot(HaveOccurred()) fileName := file.Name()
var ( runner *fakesys.FakeCmdRunner partitioner Partitioner fakeclock *fakeboshaction.FakeClock ) BeforeEach(func() { runner = fakesys.NewFakeCmdRunner() logger := boshlog.NewLogger(boshlog.LevelNone) fakeclock = &fakeboshaction.FakeClock{} partitioner = NewSfdiskPartitioner(logger, runner, fakeclock) }) It("sfdisk partition", func() { runner.AddCmdResult("sfdisk -d /dev/sda", fakesys.FakeCmdResult{Stdout: devSdaSfdiskEmptyDump}) runner.AddCmdResult("sfdisk -s /dev/sda", fakesys.FakeCmdResult{Stdout: "1048576"}) partitions := []Partition{ {Type: PartitionTypeSwap, SizeInBytes: 512 * 1024 * 1024}, {Type: PartitionTypeLinux, SizeInBytes: 1024 * 1024 * 1024}, {Type: PartitionTypeLinux, SizeInBytes: 512 * 1024 * 1024}, } partitioner.Partition("/dev/sda", partitions) Expect(1).To(Equal(len(runner.RunCommandsWithInput))) Expect(runner.RunCommandsWithInput[0]).To(Equal([]string{",512,S\n,1024,L\n,,L\n", "sfdisk", "-uM", "/dev/sda"})) }) Context("when we get an error occurs", func() {
fakeFs.SetGlob(fmt.Sprintf("%s/bosh-trusted-cert-*", certBasePath), []string{ fmt.Sprintf("%s/bosh-trusted-cert-1.crt", certBasePath), }) err := certManager.UpdateCertificates("") Expect(err).To(HaveOccurred()) }) } Context("Ubuntu", func() { BeforeEach(func() { fakeFs = fakesys.NewFakeFileSystem() fakeCmd = fakesys.NewFakeCmdRunner() fakeCmd.AddCmdResult("/usr/sbin/update-ca-certificates", fakesys.FakeCmdResult{ Stdout: "", Stderr: "", ExitStatus: 0, Sticky: true, }) certManager = cert.NewUbuntuCertManager(fakeFs, fakeCmd, log) }) SharedLinuxCertManagerExamples("/usr/local/share/ca-certificates", "/usr/sbin/update-ca-certificates") // TODO this test can be shared if there is a way to update existing FakeCmdRunner command specs It("executes update cert command", func() { fakeCmd = fakesys.NewFakeCmdRunner() fakeCmd.AddCmdResult("/usr/sbin/update-ca-certificates -f", fakesys.FakeCmdResult{ Stdout: "", Stderr: "", ExitStatus: 2, Error: errors.New("command failed"),
cmdRunner = fakesys.NewFakeCmdRunner() logger := boshlog.NewLogger(boshlog.LevelNone) cpiCmdRunner = NewCPICmdRunner(cmdRunner, cpi, logger) }) Describe("Run", func() { It("creates correct command", func() { cmdOutput := CmdOutput{} outputBytes, err := json.Marshal(cmdOutput) Expect(err).NotTo(HaveOccurred()) result := fakesys.FakeCmdResult{ Stdout: string(outputBytes), ExitStatus: 0, } cmdRunner.AddCmdResult("/jobs/cpi/bin/cpi", result) _, err = cpiCmdRunner.Run(context, "fake-method", "fake-argument-1", "fake-argument-2") Expect(err).NotTo(HaveOccurred()) Expect(cmdRunner.RunComplexCommands).To(HaveLen(1)) actualCmd := cmdRunner.RunComplexCommands[0] Expect(actualCmd.Name).To(Equal("/jobs/cpi/bin/cpi")) Expect(actualCmd.Args).To(BeNil()) Expect(actualCmd.Env).To(Equal(map[string]string{ "BOSH_PACKAGES_DIR": cpi.PackagesDir, "BOSH_JOBS_DIR": cpi.JobsDir, "PATH": "/usr/local/bin:/usr/bin:/bin", })) Expect(actualCmd.UseIsolatedEnv).To(BeTrue()) bytes, err := ioutil.ReadAll(actualCmd.Stdin)