func (f *feature) aDeleteSnapshotRequestWithID(snap_id string) error {
	f.deleteSnapshotRequest = nil
	req := new(csi.DeleteSnapshotRequest)
	req.SnapshotId = snap_id
	f.deleteSnapshotRequest = req
	return nil
}
aDeleteSnapshotRequestWithID method is used to build a Delete Snapshot request with ID
package unit_test
import (
	"context"
	"errors"
	"fmt"
	"os"
	"path"
	"strconv"
	"strings"
	"time"
	"github.com/container-storage-interface/spec/lib/go/csi"
	"github.com/cucumber/godog"
)
const (
	RetrySleepTime = 1 * time.Second
	SleepTime      = 100 * time.Millisecond
)
type feature struct {
	errs                              []error
	createVolumeRequest               *csi.CreateVolumeRequest
	createVolumeResponse              *csi.CreateVolumeResponse
	createSnapshotRequest             *csi.CreateSnapshotRequest
	createSnapshotResponse            *csi.CreateSnapshotResponse
	deleteSnapshotRequest             *csi.DeleteSnapshotRequest
	deleteSnapshotResponse            *csi.DeleteSnapshotResponse
	capability                        *csi.VolumeCapability
	capabilities                      []*csi.VolumeCapability
	validateVolumeCapabilitiesRequest *csi.ValidateVolumeCapabilitiesRequest
	controllerGetCapabilitiesRequest  *csi.ControllerGetCapabilitiesRequest
	controllerExpandVolumeRequest     *csi.ControllerExpandVolumeRequest
	nodePublishVolumeRequest          *csi.NodePublishVolumeRequest
	nodeUnpublishVolumeRequest        *csi.NodeUnpublishVolumeRequest
	nodeStageVolumeRequest            *csi.NodeStageVolumeRequest
	nodeUnstageVolumeRequest          *csi.NodeUnstageVolumeRequest
	volumeContext                     map[string]string
	volID                             string
	volIDList                         []string
	maxRetryCount                     int
	nodeId                            string
	ephemeral                         bool
}
func (f *feature) addError(err error) {
	f.errs = append(make([]error, 0), err)
}
func (f *feature) thereAreNoErrors() error {
	if len(f.errs) == 0 {
		return nil
	}
	return f.errs[0]
}
func (f *feature) aCSIService() error {
	f.errs = make([]error, 0)
	f.createVolumeRequest = nil
	f.createVolumeResponse = nil
	f.volIDList = f.volIDList[:0]
	f.ephemeral = false
	ctx := context.Background()
	fmt.Printf("testing Identity Probe\n")
	client := csi.NewIdentityClient(grpcClient)
	probeResp, err := client.Probe(ctx, &csi.ProbeRequest{})
	if err != nil {
		fmt.Printf("Probe failed with error: %s:\n", err.Error())
	} else {
		fmt.Printf("Probe passed: %s\n", probeResp.Ready)
	}
	return nil
}
func (f *feature) aCSIServiceWithNode() error {
	stop()
	time.Sleep(10 * time.Second)
	os.Setenv("X_CSI_MODE", "node")
	ctx := context.Background()
	grpcClient, stop = startServer(ctx)
	time.Sleep(5 * time.Second)
	ctx = context.Background()
	fmt.Printf("testing Identity Probe\n")
	client := csi.NewIdentityClient(grpcClient)
	probeResp, err := client.Probe(ctx, &csi.ProbeRequest{})
	time.Sleep(120 * time.Second)
	if err != nil {
		fmt.Printf("Probe failed with error: %s:\n", err.Error())
	} else {
		fmt.Printf("Probe passed: %s\n", probeResp.Ready)
	}
	stop()
	time.Sleep(10 * time.Second)
	os.Setenv("X_CSI_MODE", "")
	ctx = context.Background()
	grpcClient, stop = startServer(ctx)
	time.Sleep(5 * time.Second)
	return nil
}
func (f *feature) aCSIServiceWithNodeTopology() error {
	stop()
	time.Sleep(10 * time.Second)
	os.Setenv("X_CSI_MODE", "node")
	ctx := context.Background()
	grpcClient, stop = startServer(ctx)
	time.Sleep(5 * time.Second)
	ctx = context.Background()
	fmt.Printf("testing Identity Probe\n")
	client := csi.NewIdentityClient(grpcClient)
	probeResp, err := client.Probe(ctx, &csi.ProbeRequest{})
	time.Sleep(120 * time.Second)
	if err != nil {
		fmt.Printf("Probe failed with error: %s:\n", err.Error())
	} else {
		fmt.Printf("Probe passed: %s\n", probeResp.Ready)
	}
	nodeReq := new(csi.NodeGetInfoRequest)
	nodeClient := csi.NewNodeClient(grpcClient)
	nodeResp, e := nodeClient.NodeGetInfo(ctx, nodeReq)
	if nodeResp.AccessibleTopology.Segments == nil || e != nil {
		fmt.Printf("Erro getting topology segments")
	}
	stop()
	time.Sleep(10 * time.Second)
	os.Setenv("X_CSI_MODE", "")
	ctx = context.Background()
	grpcClient, stop = startServer(ctx)
	time.Sleep(5 * time.Second)
	return nil
}
func (f *feature) aBasicBlockVolumeRequest(volumeName, arrayId, protocol string, size int) error {
	f.createVolumeRequest = nil
	req := new(csi.CreateVolumeRequest)
	params := make(map[string]string)
	params["storagePool"] = os.Getenv("STORAGE_POOL")
	params["thinProvisioned"] = "true"
	params["isDataReductionEnabled"] = "false"
	params["tieringPolicy"] = "0"
	params["description"] = "CSI Volume Unit Test"
	params["arrayId"] = os.Getenv(arrayId)
	params["protocol"] = protocol
	params["nasServer"] = os.Getenv("NAS_SERVER")
	req.Parameters = params
	req.Name = volumeName
	capacityRange := new(csi.CapacityRange)
	capacityRange.RequiredBytes = int64(size * 1024 * 1024 * 1024)
	req.CapacityRange = capacityRange
	capability := new(csi.VolumeCapability)
	mount := new(csi.VolumeCapability_MountVolume)
	mountType := new(csi.VolumeCapability_Mount)
	mountType.Mount = mount
	capability.AccessType = mountType
	accessMode := new(csi.VolumeCapability_AccessMode)
	accessMode.Mode = csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER
	capability.AccessMode = accessMode
	f.capability = capability
	capabilities := make([]*csi.VolumeCapability, 0)
	capabilities = append(capabilities, capability)
	req.VolumeCapabilities = capabilities
	f.createVolumeRequest = req
	return nil
}
func (f *feature) aBasicRawBlockVolumeRequest(volumeName, arrayId, protocol string, size int) error {
	f.createVolumeRequest = nil
	req := new(csi.CreateVolumeRequest)
	params := make(map[string]string)
	params["storagePool"] = os.Getenv("STORAGE_POOL")
	params["thinProvisioned"] = "true"
	params["isDataReductionEnabled"] = "false"
	params["tieringPolicy"] = "0"
	params["description"] = "CSI Volume Unit Test"
	params["arrayId"] = os.Getenv(arrayId)
	params["protocol"] = protocol
	req.Parameters = params
	req.Name = volumeName
	capacityRange := new(csi.CapacityRange)
	capacityRange.RequiredBytes = int64(size * 1024 * 1024 * 1024)
	req.CapacityRange = capacityRange
	block := new(csi.VolumeCapability_BlockVolume)
	capability := new(csi.VolumeCapability)
	accessType := new(csi.VolumeCapability_Block)
	accessType.Block = block
	capability.AccessType = accessType
	accessMode := new(csi.VolumeCapability_AccessMode)
	accessMode.Mode = csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER
	capability.AccessMode = accessMode
	f.capability = capability
	capabilities := make([]*csi.VolumeCapability, 0)
	capabilities = append(capabilities, capability)
	req.VolumeCapabilities = capabilities
	f.createVolumeRequest = req
	return nil
}
func (f *feature) aBasicFilesystemRequest(volumeName, arrayId, protocol, am string, size int) error {
	f.createVolumeRequest = nil
	req := new(csi.CreateVolumeRequest)
	params := make(map[string]string)
	params["storagePool"] = os.Getenv("STORAGE_POOL")
	params["thinProvisioned"] = "true"
	params["isDataReductionEnabled"] = "false"
	params["tieringPolicy"] = "0"
	params["description"] = "CSI Volume Unit Test"
	params["arrayId"] = os.Getenv(arrayId)
	params["protocol"] = protocol
	params["nasServer"] = os.Getenv("NAS_SERVER")
	req.Parameters = params
	req.Name = volumeName
	capacityRange := new(csi.CapacityRange)
	capacityRange.RequiredBytes = int64(size * 1024 * 1024 * 1024)
	req.CapacityRange = capacityRange
	capability := new(csi.VolumeCapability)
	mount := new(csi.VolumeCapability_MountVolume)
	mountType := new(csi.VolumeCapability_Mount)
	mountType.Mount = mount
	capability.AccessType = mountType
	accessMode := new(csi.VolumeCapability_AccessMode)
	if am == "ROX" {
		accessMode.Mode = csi.VolumeCapability_AccessMode_MULTI_NODE_READER_ONLY
	} else if am == "RWX" {
		accessMode.Mode = csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER
	} else if am == "RWO" {
		accessMode.Mode = csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER
	} else {
		accessMode.Mode = csi.VolumeCapability_AccessMode_UNKNOWN
	}
	capability.AccessMode = accessMode
	f.capability = capability
	capabilities := make([]*csi.VolumeCapability, 0)
	capabilities = append(capabilities, capability)
	req.VolumeCapabilities = capabilities
	f.createVolumeRequest = req
	return nil
}
func (f *feature) aBasicBlockVolumeRequestWithParameters(volumeName, arrayId, protocol string, size int, storagepool, thinProvisioned, isDataReductionEnabled, tieringPolicy string) error {
	f.createVolumeRequest = nil
	req := new(csi.CreateVolumeRequest)
	params := make(map[string]string)
	if storagepool == "id" {
		params["storagePool"] = os.Getenv("STORAGE_POOL")
	} else {
		params["storagePool"] = storagepool
	}
	params["thinProvisioned"] = thinProvisioned
	params["isDataReductionEnabled"] = isDataReductionEnabled
	params["tieringPolicy"] = tieringPolicy
	params["description"] = "CSI Volume Unit Test"
	params["arrayId"] = os.Getenv(arrayId)
	params["protocol"] = protocol
	params["nasServer"] = os.Getenv("NAS_SERVER")
	req.Parameters = params
	req.Name = volumeName
	capacityRange := new(csi.CapacityRange)
	capacityRange.RequiredBytes = int64(size * 1024 * 1024 * 1024)
	req.CapacityRange = capacityRange
	capability := new(csi.VolumeCapability)
	mount := new(csi.VolumeCapability_MountVolume)
	mountType := new(csi.VolumeCapability_Mount)
	mountType.Mount = mount
	capability.AccessType = mountType
	accessMode := new(csi.VolumeCapability_AccessMode)
	accessMode.Mode = csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER
	capability.AccessMode = accessMode
	f.capability = capability
	capabilities := make([]*csi.VolumeCapability, 0)
	capabilities = append(capabilities, capability)
	req.VolumeCapabilities = capabilities
	f.createVolumeRequest = req
	return nil
}
func (f *feature) aBasicBlockVolumeRequestWithVolumeContentSource(volumeName, arrayId, protocol string, size int) error {
	f.createVolumeRequest = nil
	req := new(csi.CreateVolumeRequest)
	params := make(map[string]string)
	params["storagePool"] = os.Getenv("STORAGE_POOL")
	params["arrayId"] = os.Getenv(arrayId)
	params["protocol"] = protocol
	req.Parameters = params
	req.Name = volumeName
	capacityRange := new(csi.CapacityRange)
	capacityRange.RequiredBytes = int64(size * 1024 * 1024 * 1024)
	req.CapacityRange = capacityRange
	capability := new(csi.VolumeCapability)
	mount := new(csi.VolumeCapability_MountVolume)
	mountType := new(csi.VolumeCapability_Mount)
	mountType.Mount = mount
	capability.AccessType = mountType
	accessMode := new(csi.VolumeCapability_AccessMode)
	accessMode.Mode = csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER
	capability.AccessMode = accessMode
	f.capability = capability
	capabilities := make([]*csi.VolumeCapability, 0)
	capabilities = append(capabilities, capability)
	req.VolumeCapabilities = capabilities
	volumeContentSource_SnapshotSource := new(csi.VolumeContentSource_SnapshotSource)
	volumeContentSource_SnapshotSource.SnapshotId = f.createSnapshotResponse.GetSnapshot().GetSnapshotId()
	volumeContentSource_Snapshot := new(csi.VolumeContentSource_Snapshot)
	volumeContentSource_Snapshot.Snapshot = volumeContentSource_SnapshotSource
	volumeContentSource := new(csi.VolumeContentSource)
	volumeContentSource.Type = volumeContentSource_Snapshot
	req.VolumeContentSource = volumeContentSource
	f.createVolumeRequest = req
	return nil
}
func (f *feature) aBasicBlockVolumeRequestWithVolumeContentSourceAsVolume(volumeName, arrayId, protocol string, size int) error {
	f.createVolumeRequest = nil
	req := new(csi.CreateVolumeRequest)
	params := make(map[string]string)
	params["storagePool"] = os.Getenv("STORAGE_POOL")
	params["arrayId"] = os.Getenv(arrayId)
	params["protocol"] = protocol
	req.Parameters = params
	req.Name = volumeName
	capacityRange := new(csi.CapacityRange)
	capacityRange.RequiredBytes = int64(size * 1024 * 1024 * 1024)
	req.CapacityRange = capacityRange
	capability := new(csi.VolumeCapability)
	mount := new(csi.VolumeCapability_MountVolume)
	mountType := new(csi.VolumeCapability_Mount)
	mountType.Mount = mount
	capability.AccessType = mountType
	accessMode := new(csi.VolumeCapability_AccessMode)
	accessMode.Mode = csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER
	capability.AccessMode = accessMode
	f.capability = capability
	capabilities := make([]*csi.VolumeCapability, 0)
	capabilities = append(capabilities, capability)
	req.VolumeCapabilities = capabilities
	volumeContentSource_VolumeSource := new(csi.VolumeContentSource_VolumeSource)
	volumeContentSource_VolumeSource.VolumeId = f.createVolumeResponse.GetVolume().GetVolumeId()
	volumeContentSource_Volume := new(csi.VolumeContentSource_Volume)
	volumeContentSource_Volume.Volume = volumeContentSource_VolumeSource
	volumeContentSource := new(csi.VolumeContentSource)
	volumeContentSource.Type = volumeContentSource_Volume
	req.VolumeContentSource = volumeContentSource
	f.createVolumeRequest = req
	return nil
}
func (f *feature) iChangeVolumeCapabilityAccessmode() error {
	f.createVolumeRequest.VolumeCapabilities[0].AccessMode.Mode = 4
	return nil
}
func (f *feature) iCallCreateVolume() error {
	ctx := context.Background()
	client := csi.NewControllerClient(grpcClient)
	volResp, err := client.CreateVolume(ctx, f.createVolumeRequest)
	if err != nil {
		fmt.Printf("CreateVolume %s:\n", err.Error())
		f.volID = "NoID"
		f.addError(err)
	} else {
		fmt.Printf("CreateVolume %s (%s) %s\n", volResp.GetVolume().VolumeContext["Name"],
			volResp.GetVolume().VolumeId, volResp.GetVolume().VolumeContext["CreationTime"])
		f.volID = volResp.GetVolume().VolumeId
		f.volIDList = append(f.volIDList, volResp.GetVolume().VolumeId)
		f.volumeContext = f.createVolumeRequest.Parameters
	}
	f.createVolumeResponse = volResp
	return nil
}
func (f *feature) whenICallDeleteVolume() error {
	ctx := context.Background()
	client := csi.NewControllerClient(grpcClient)
	delVolReq := new(csi.DeleteVolumeRequest)
	delVolReq.VolumeId = f.volID
	var err error
	_, err = client.DeleteVolume(ctx, delVolReq)
	if err != nil {
		fmt.Printf("DeleteVolume %s:\n", err.Error())
		f.addError(err)
	} else {
		fmt.Printf("DeleteVolume %s completed successfully\n", f.volID)
	}
	return nil
}
func (f *feature) whenICallDeleteAllCreatedVolumes() error {
	ctx := context.Background()
	client := csi.NewControllerClient(grpcClient)
	delVolReq := new(csi.DeleteVolumeRequest)
	for i := 0; i < len(f.volIDList); i++ {
		delVolReq.VolumeId = f.volIDList[i]
		var err error
		_, err = client.DeleteVolume(ctx, delVolReq)
		if err != nil {
			fmt.Printf("DeleteVolume %s:\n", err.Error())
			f.addError(err)
		} else {
			fmt.Printf("DeleteVolume %s completed successfully\n", f.volID)
		}
	}
	return nil
}
func (f *feature) whenICallPublishVolume() error {
	req := new(csi.ControllerPublishVolumeRequest)
	req.VolumeId = f.volID
	req.NodeId = os.Getenv("X_CSI_UNITY_NODENAME") + "," + os.Getenv("X_CSI_UNITY_LONGNODENAME")
	f.nodeId = req.NodeId
	req.Readonly = false
	req.VolumeCapability = f.capability
	req.VolumeContext = f.volumeContext
	ctx := context.Background()
	client := csi.NewControllerClient(grpcClient)
	_, err := client.ControllerPublishVolume(ctx, req)
	if err != nil {
		fmt.Printf("ControllerPublishVolume %s:\n", err.Error())
		f.addError(err)
	} else {
		fmt.Printf("ControllerPublishVolume completed successfully\n")
	}
	time.Sleep(SleepTime)
	return nil
}
func (f *feature) whenICallPublishVolumeWithParam(hostName, readonly string) error {
	req := new(csi.ControllerPublishVolumeRequest)
	req.VolumeId = f.volID
	req.NodeId = os.Getenv("X_CSI_UNITY_NODENAME") + "," + os.Getenv("X_CSI_UNITY_LONGNODENAME")
	f.nodeId = req.NodeId
	read, _ := strconv.ParseBool(readonly)
	req.Readonly = read
	req.VolumeCapability = f.capability
	req.VolumeContext = f.volumeContext
	ctx := context.Background()
	client := csi.NewControllerClient(grpcClient)
	_, err := client.ControllerPublishVolume(ctx, req)
	if err != nil {
		fmt.Printf("ControllerPublishVolume %s:\n", err.Error())
		f.addError(err)
	} else {
		fmt.Printf("ControllerPublishVolume completed successfully\n")
	}
	time.Sleep(SleepTime)
	return nil
}
func (f *feature) whenICallPublishVolumeWithVolumeId(volId string) error {
	req := new(csi.ControllerPublishVolumeRequest)
	req.VolumeId = volId
	req.NodeId = os.Getenv("X_CSI_UNITY_NODENAME") + "," + os.Getenv("X_CSI_UNITY_LONGNODENAME")
	f.nodeId = req.NodeId
	req.Readonly = false
	req.VolumeCapability = f.capability
	req.VolumeContext = f.volumeContext
	ctx := context.Background()
	client := csi.NewControllerClient(grpcClient)
	_, err := client.ControllerPublishVolume(ctx, req)
	if err != nil {
		fmt.Printf("ControllerPublishVolume %s:\n", err.Error())
		f.addError(err)
	} else {
		fmt.Printf("ControllerPublishVolume completed successfully\n")
	}
	time.Sleep(SleepTime)
	return nil
}
func (f *feature) whenICallUnpublishVolume() error {
	req := new(csi.ControllerUnpublishVolumeRequest)
	req.VolumeId = f.volID
	req.NodeId = os.Getenv("X_CSI_UNITY_NODENAME") + "," + os.Getenv("X_CSI_UNITY_LONGNODENAME")
	ctx := context.Background()
	client := csi.NewControllerClient(grpcClient)
	_, err := client.ControllerUnpublishVolume(ctx, req)
	if err != nil {
		fmt.Printf("ControllerUnpublishVolume failed: %s\n", err.Error())
		f.addError(err)
	} else {
		fmt.Printf("ControllerUnpublishVolume completed successfully\n")
	}
	time.Sleep(SleepTime)
	return nil
}
func (f *feature) iCallUnpublishVolumeWithVolumeId(volId string) error {
	req := new(csi.ControllerUnpublishVolumeRequest)
	req.VolumeId = volId
	req.NodeId = os.Getenv("X_CSI_UNITY_NODENAME") + "," + os.Getenv("X_CSI_UNITY_LONGNODENAME")
	ctx := context.Background()
	client := csi.NewControllerClient(grpcClient)
	_, err := client.ControllerUnpublishVolume(ctx, req)
	if err != nil {
		fmt.Printf("ControllerUnpublishVolume failed: %s\n", err.Error())
		f.addError(err)
	} else {
		fmt.Printf("ControllerUnpublishVolume completed successfully\n")
	}
	time.Sleep(SleepTime)
	return nil
}
func (f *feature) theErrorMessageShouldContain(expected string) error {
	if expected == "none" {
		if len(f.errs) == 0 {
			return nil
		} else {
			err := f.errs[0]
			f.errs = make([]error, 0)
			return fmt.Errorf("Unexpected error(s): %s", err)
		}
	}
	if len(f.errs) == 0 {
		return errors.New("there were no errors but we expected: " + expected)
	}
	err0 := f.errs[0]
	f.errs = make([]error, 0)
	if !strings.Contains(err0.Error(), expected) {
		return errors.New(fmt.Sprintf("Error %s does not contain the expected message: %s", err0.Error(), expected))
	}
	return nil
}
func (f *feature) aCreateSnapshotRequest(name string) error {
	f.createSnapshotRequest = nil
	req := new(csi.CreateSnapshotRequest)
	params := make(map[string]string)
	params["description"] = ""
	params["retentionDuration"] = ""
	params["isReadOnly"] = ""
	req.Parameters = params
	if f.createVolumeResponse != nil {
		req.SourceVolumeId = f.createVolumeResponse.Volume.VolumeId
	} else {
		req.SourceVolumeId = ""
	}
	req.Name = name
	f.createSnapshotRequest = req
	return nil
}
func (f *feature) iCallCreateSnapshot() error {
	ctx := context.Background()
	client := csi.NewControllerClient(grpcClient)
	snapResp, err := client.CreateSnapshot(ctx, f.createSnapshotRequest)
	if err != nil {
		fmt.Printf("CreateSnapshot %s:\n", err.Error())
		f.addError(err)
	}
	if err == nil {
		fmt.Printf("Snapshot ID: %s \n", snapResp.Snapshot.SnapshotId)
	}
	f.createSnapshotResponse = snapResp
	return nil
}
func (f *feature) aDeleteSnapshotRequest() error {
	f.deleteSnapshotRequest = nil
	req := new(csi.DeleteSnapshotRequest)
	if f.createSnapshotResponse != nil {
		req.SnapshotId = f.createSnapshotResponse.Snapshot.SnapshotId
	} else {
		req.SnapshotId = ""
	}
	f.deleteSnapshotRequest = req
	return nil
}