<commit_before>package devicepathresolver_test

import (
	"errors"
	"fmt"
	"path/filepath"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	. "github.com/cloudfoundry/bosh-agent/infrastructure/devicepathresolver"
	"github.com/cloudfoundry/bosh-agent/platform/openiscsi/openiscsifakes"
	boshsettings "github.com/cloudfoundry/bosh-agent/settings"
	boshdirs "github.com/cloudfoundry/bosh-agent/settings/directories"
	boshlog "github.com/cloudfoundry/bosh-utils/logger"
	fakesys "github.com/cloudfoundry/bosh-utils/system/fakes"
)

type dmsetupDevice struct {
	Name      string
	MajMinNum string
}

func buildDmsetupOutput(devices []dmsetupDevice) (output string) {
	for _, device := range devices {
		output += fmt.Sprintf("%s\t%s\n", device.Name, device.MajMinNum)
	}
	return
}

var _ = Describe("iscsiDevicePathResolver", func() {
	var (
		initiatorName string
		username      string
		target        string
		password      string

		runner                  *fakesys.FakeCmdRunner
		openiscsi               *openiscsifakes.FakeOpenIscsi
		fs                      *fakesys.FakeFileSystem
		dirProvider             boshdirs.Provider
		diskSettings            boshsettings.DiskSettings
		pathResolver            DevicePathResolver
		managedDiskSettingsPath string

		dmsetupOutputForNoDeviceFound = fakesys.FakeCmdResult{
			Stdout: "No devices found"}
		dmsetupOutputForNonPartitionedDisk = fakesys.FakeCmdResult{
			Stdout: buildDmsetupOutput(
				[]dmsetupDevice{
					{Name: "fake_device_path", MajMinNum: "(252:0)"},
				}),
		}
		dmsetupOutputForPartitionedDisk = fakesys.FakeCmdResult{Stdout: buildDmsetupOutput(
			[]dmsetupDevice{
				{Name: "fake_device_path-part1", MajMinNum: "(252:1)"},
				{Name: "fake_device_path", MajMinNum: "(252:0)"},
			}),
		}
	)

	BeforeEach(func() {
		initiatorName = "iqn.2007-05.com.fake-domain:fake-username"
		username = "fake-username"
		target = "11.11.22.22"
		password = "<PASSWORD>"

		runner = fakesys.NewFakeCmdRunner()
		openiscsi = &openiscsifakes.FakeOpenIscsi{}
		fs = fakesys.NewFakeFileSystem()
		dirProvider = boshdirs.NewProvider("/fake-base-dir")

		pathResolver = NewIscsiDevicePathResolver(
			500*time.Millisecond,
			runner,
			openiscsi,
			fs,
			dirProvider,
			boshlog.NewLogger(boshlog.LevelNone),
		)
		diskSettings = boshsettings.DiskSettings{
			ISCSISettings: boshsettings.ISCSISettings{
				InitiatorName: initiatorName,
				Username:      username,
				Target:        target,
				Password:      password,
			},
		}

		// Setup the managed_disk_settings.json
		managedDiskSettingsPath = filepath.Join(dirProvider.BoshDir(), "managed_disk_settings.json")
		err := fs.WriteFileString(managedDiskSettingsPath, "12345678")
		Expect(err).NotTo(HaveOccurred())
	})

	Describe("GetRealDevicePath", func() {
		Context("when no devices are found", func() {
			BeforeEach(func() {
				// for the pathResolver call to find devices
				runner.AddCmdResult(
					"dmsetup ls",
					dmsetupOutputForNoDeviceFound)

				openiscsi.SetupReturns(nil)

				openiscsi.DiscoveryReturns(nil)

				openiscsi.LoginReturns(nil)
			})

			It("returns the real path after iSCSI restart", func() {
				// for the pathResolver call to find devices after openiscsi restart
				runner.AddCmdResult(
					"dmsetup ls",
					dmsetupOutputForNonPartitionedDisk)

				path, timeout, err := pathResolver.GetRealDevicePath(diskSettings)
				Expect(err).ToNot(HaveOccurred())

				Expect(path).To(Equal("/dev/mapper/fake_device_path"))
				Expect(timeout).To(BeFalse())

				Expect(openiscsi.SetupCallCount()).To(Equal(1))
				Expect(openiscsi.DiscoveryCallCount()).To(Equal(1))
				Expect(openiscsi.LoginCallCount()).To(Equal(1))
			})

			It("returns timeout after iSCSI restart", func() {
				// for the pathResolver call to find devices after openiscsi restart
				runner.AddCmdResult(
					"dmsetup ls",
					dmsetupOutputForNoDeviceFound)

				path, timeout, err := pathResolver.GetRealDevicePath(diskSettings)
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(ContainSubstring("Timed out to get real iSCSI device path"))

				Expect(path).To(Equal(""))
				Expect(timeout).To(BeTrue())
			})
		})

		Context("when one device is to be found", func() {
			BeforeEach(func() {
				diskSettings.ID = "12345678"
			})

			Context("when the device has never been mounted previously", func() {
				BeforeEach(func() {
					// ...that has never been mounted previously...
					fs.RemoveAll(managedDiskSettingsPath)
				})

				Context("when the device is not yet partitioned", func() {
					BeforeEach(func() {
						runner.AddCmdResult("dmsetup ls",
							dmsetupOutputForNoDeviceFound)
						runner.AddCmdResult("dmsetup ls",
							dmsetupOutputForNonPartitionedDisk)
					})

					It("returns the real path after iSCSI discovery", func() {
						path, timeout, err := pathResolver.GetRealDevicePath(diskSettings)
						Expect(err).ToNot(HaveOccurred())

						Expect(path).To(Equal("/dev/mapper/fake_device_path"))
						Expect(timeout).To(BeFalse())
<commit_msg>Fix blocking lint error<commit_after>package devicepathresolver_test

import (
	"errors"
	"fmt"
	"path/filepath"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	. "github.com/cloudfoundry/bosh-agent/infrastructure/devicepathresolver"
	"github.com/cloudfoundry/bosh-agent/platform/openiscsi/openiscsifakes"
	boshsettings "github.com/cloudfoundry/bosh-agent/settings"
	boshdirs "github.com/cloudfoundry/bosh-agent/settings/directories"
	boshlog "github.com/cloudfoundry/bosh-utils/logger"
	fakesys "github.com/cloudfoundry/bosh-utils/system/fakes"
)

type dmsetupDevice struct {
	Name      string
	MajMinNum string
}

func buildDmsetupOutput(devices []dmsetupDevice) (output string) {
	for _, device := range devices {
		output += fmt.Sprintf("%s\t%s\n", device.Name, device.MajMinNum)
	}
	return
}

var _ = Describe("iscsiDevicePathResolver", func() {
	var (
		initiatorName string
		username      string
		target        string
		password      string

		runner                  *fakesys.FakeCmdRunner
		openiscsi               *openiscsifakes.FakeOpenIscsi
		fs                      *fakesys.FakeFileSystem
		dirProvider             boshdirs.Provider
		diskSettings            boshsettings.DiskSettings
		pathResolver            DevicePathResolver
		managedDiskSettingsPath string

		dmsetupOutputForNoDeviceFound = fakesys.FakeCmdResult{
			Stdout: "No devices found"}
		dmsetupOutputForNonPartitionedDisk = fakesys.FakeCmdResult{
			Stdout: buildDmsetupOutput(
				[]dmsetupDevice{
					{Name: "fake_device_path", MajMinNum: "(252:0)"},
				}),
		}
		dmsetupOutputForPartitionedDisk = fakesys.FakeCmdResult{Stdout: buildDmsetupOutput(
			[]dmsetupDevice{
				{Name: "fake_device_path-part1", MajMinNum: "(252:1)"},
				{Name: "fake_device_path", MajMinNum: "(252:0)"},
			}),
		}
	)

	BeforeEach(func() {
		initiatorName = "iqn.2007-05.com.fake-domain:fake-username"
		username = "fake-username"
		target = "11.11.22.22"
		password = "<PASSWORD>"

		runner = fakesys.NewFakeCmdRunner()
		openiscsi = &openiscsifakes.FakeOpenIscsi{}
		fs = fakesys.NewFakeFileSystem()
		dirProvider = boshdirs.NewProvider("/fake-base-dir")

		pathResolver = NewIscsiDevicePathResolver(
			500*time.Millisecond,
			runner,
			openiscsi,
			fs,
			dirProvider,
			boshlog.NewLogger(boshlog.LevelNone),
		)
		diskSettings = boshsettings.DiskSettings{
			ISCSISettings: boshsettings.ISCSISettings{
				InitiatorName: initiatorName,
				Username:      username,
				Target:        target,
				Password:      password,
			},
		}

		// Setup the managed_disk_settings.json
		managedDiskSettingsPath = filepath.Join(dirProvider.BoshDir(), "managed_disk_settings.json")
		err := fs.WriteFileString(managedDiskSettingsPath, "12345678")
		Expect(err).NotTo(HaveOccurred())
	})

	Describe("GetRealDevicePath", func() {
		Context("when no devices are found", func() {
			BeforeEach(func() {
				// for the pathResolver call to find devices
				runner.AddCmdResult(
					"dmsetup ls",
					dmsetupOutputForNoDeviceFound)

				openiscsi.SetupReturns(nil)

				openiscsi.DiscoveryReturns(nil)

				openiscsi.LoginReturns(nil)
			})

			It("returns the real path after iSCSI restart", func() {
				// for the pathResolver call to find devices after openiscsi restart
				runner.AddCmdResult(
					"dmsetup ls",
					dmsetupOutputForNonPartitionedDisk)

				path, timeout, err := pathResolver.GetRealDevicePath(diskSettings)
				Expect(err).ToNot(HaveOccurred())

				Expect(path).To(Equal("/dev/mapper/fake_device_path"))
				Expect(timeout).To(BeFalse())

				Expect(openiscsi.SetupCallCount()).To(Equal(1))
				Expect(openiscsi.DiscoveryCallCount()).To(Equal(1))
				Expect(openiscsi.LoginCallCount()).To(Equal(1))
			})

			It("returns timeout after iSCSI restart", func() {
				// for the pathResolver call to find devices after openiscsi restart
				runner.AddCmdResult(
					"dmsetup ls",
					dmsetupOutputForNoDeviceFound)

				path, timeout, err := pathResolver.GetRealDevicePath(diskSettings)
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(ContainSubstring("Timed out to get real iSCSI device path"))

				Expect(path).To(Equal(""))
				Expect(timeout).To(BeTrue())
			})
		})

		Context("when one device is to be found", func() {
			BeforeEach(func() {
				diskSettings.ID = "12345678"
			})

			Context("when the device has never been mounted previously", func() {
				BeforeEach(func() {
					// ...that has never been mounted previously...
					err := fs.RemoveAll(managedDiskSettingsPath)
					Expect(err).ToNot(HaveOccurred())
				})

				Context("when the device is not yet partitioned", func() {
					BeforeEach(func() {
						runner.AddCmdResult("dmsetup ls",
							dmsetupOutputForNoDeviceFound)
						runner.AddCmdResult("dmsetup ls",
							dmsetupOutputForNonPartitionedDisk)
					})

					It("returns the real path after iSCSI discovery", func() {
						path, timeout, err := pathResolver.GetRealDevicePath(diskSettings)
						Expect(err).ToNot(HaveOccurred())

						Expect(path).To(Equal("/dev/mapper/fake_device_path"))
						Expect(timeout).To(BeFalse())

{'fraction_non_alphanumeric': 0.11778085443037975, 'fraction_numerical': 0.009691455696202531, 'mean_word_length': 3.7860861334595364, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2405132', 'n_tokens_mistral': 3923, 'n_tokens_neox': 3303, 'n_words': 581}