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")) }) }) }) }
fs.WriteToFile("/var/vcap/micro_bosh/data/cache/123-456-789", "Some data") putBody := `Updated data` putPayload := strings.NewReader(putBody) waitForServerToStart(serverURL, "blobs", httpClient) request, err := http.NewRequest("PUT", serverURL+"/blobs/a5/123-456-789", putPayload) Expect(err).ToNot(HaveOccurred()) httpResponse, err := httpClient.Do(request) defer httpResponse.Body.Close() Expect(err).ToNot(HaveOccurred()) Expect(httpResponse.StatusCode).To(Equal(201)) contents, err := fs.ReadFile("/var/vcap/micro_bosh/data/cache/123-456-789") Expect(err).ToNot(HaveOccurred()) Expect(contents).To(Equal("Updated data")) }) Context("when manager errors", func() { It("returns a 500", func() { fs.WriteToFileError = errors.New("oops") putBody := `Updated data` putPayload := strings.NewReader(putBody) waitForServerToStart(serverURL, "blobs", httpClient) request, err := http.NewRequest("PUT", serverURL+"/blobs/a5/123-456-789", putPayload) Expect(err).ToNot(HaveOccurred())
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("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) }) }) }