Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mock Unit Tests #6

Merged
merged 29 commits into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0fea8e9
Mock And Unit Tests
harshitap26 Feb 11, 2022
eeabf88
Mock and Unit Test
harshitap26 Feb 11, 2022
7721e8f
NVMe list
harshitap26 Feb 11, 2022
13501b1
nvme-connect changes
harshitap26 Feb 13, 2022
b9a49d5
Unit tests
harshitap26 Feb 13, 2022
5bfc922
NVME list Changes
harshitap26 Feb 14, 2022
2e8943a
NVME list Changes
harshitap26 Feb 14, 2022
23e93eb
Mock Unit Tests
harshitap26 Feb 14, 2022
ccaf502
Mock Unit Tests
harshitap26 Feb 14, 2022
70079ac
Mock Unit Tests
harshitap26 Feb 14, 2022
5eaf85c
Mock and Unit tests
harshitap26 Feb 14, 2022
d2ae94f
NVMe list changes
harshitap26 Feb 14, 2022
3428e1f
Unit and Mock tests
harshitap26 Feb 15, 2022
897ef11
Merging NVMe list changes
harshitap26 Feb 15, 2022
5361d62
Mock and Unit tests
harshitap26 Feb 15, 2022
16bf97f
Mock and Unit test
harshitap26 Feb 15, 2022
1feb72b
Mock And Unit Tests
harshitap26 Feb 11, 2022
b7fbb4a
Mock and Unit Test
harshitap26 Feb 11, 2022
23c5509
nvme-connect changes
harshitap26 Feb 13, 2022
60fe043
Unit tests
harshitap26 Feb 13, 2022
88b313e
Mock Unit Tests
harshitap26 Feb 14, 2022
22038e3
Mock Unit Tests
harshitap26 Feb 14, 2022
8729ead
Mock Unit Tests
harshitap26 Feb 14, 2022
5c25d68
Mock and Unit tests
harshitap26 Feb 14, 2022
51b3d01
Unit and Mock tests
harshitap26 Feb 15, 2022
dfc0c20
Mock and Unit tests
harshitap26 Feb 15, 2022
b07ee16
Mock and Unit test
harshitap26 Feb 15, 2022
d5a4581
Merge branch 'Mock-Unit-Tests' of github.com:dell/gonvme into Mock-Un…
harshitap26 Feb 15, 2022
7163e00
Merge branch 'feature/nvme-list' of github.com:dell/gonvme into Mock-…
harshitap26 Feb 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

# These values should be set for running the entire test suite
# all must be valid
Portal="1.1.1.1"
Target="nqn.1988-11.com.mock:00:e6e2d5b871f1403E169D"


all:check int-test

mock-test:
go clean -cache
go test -v -coverprofile=c.out --run=TestMock

int-test:
GONVME_PORTAL=$(Portal) GONVME_TARGET=$(Target) \
go test -v -timeout 20m -coverprofile=c.out -coverpkg ./...

gocover:
go tool cover -html=c.out

check:
gofmt -d .
golint -set_exit_status
go vet
25 changes: 25 additions & 0 deletions gonvme.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,31 @@ type Logger = logger.Logger
// Tracer - Placeholder for tracer
type Tracer = tracer.Tracer

// NVMEinterface is the interface that provides the iSCSI client functionality
type NVMEinterface interface {

// DiscoverNVMeTCPTargets discovers the targets exposed via a given portal
// returns an array of ISCSITarget instances
DiscoverNVMeTCPTargets(address string, login bool) ([]NVMeTarget, error)

// GetInitiators get a list of iSCSI initiators defined in a specified file
// To use the system default file of "/etc/nvme/hostnqn", provide a filename of ""
GetInitiators(filename string) ([]string, error)

//NVMeConnect connects into a specified NVMe target
NVMeConnect(target NVMeTarget) error

// NVMeDisconnect disconnect from the specified NVMe target
NVMeDisconnect(target NVMeTarget) error

// GetSessions queries information about sessions
GetSessions() ([]NVMESession, error)

// generic implementations
isMock() bool
getOptions() map[string]string
}

// NVMeType is the base structure for each platform implementation
type NVMeType struct {
mock bool
Expand Down
171 changes: 171 additions & 0 deletions gonvme_mock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package gonvme

import (
"errors"
"fmt"
"strconv"
)

const (
// MockNumberOfInitiators controls the number of initiators found in mock mode
MockNumberOfInitiators = "numberOfInitiators"
// MockNumberOfTargets controls the number of targets found in mock mode
MockNumberOfTargets = "numberOfTargets"
// MockNumberOfSessions controls the number of NVMe sessions found in mock mode
MockNumberOfSessions = "numberOfSession"
)

var (
// GONVMEMock is a struct controlling induced errors
GONVMEMock struct {
InduceDiscoveryError bool
InduceInitiatorError bool
InduceLoginError bool
InduceLogoutError bool
InduceGetSessionsError bool
}
)

// MockNVMeTCP provides a mock implementation of an NVMe client
type MockNVMeTCP struct {
NVMeType
}

// NewMockNVMeTCP - returns a mock NVMeTCP client
func NewMockNVMeTCP(opts map[string]string) *MockNVMeTCP {
nvme := MockNVMeTCP{
NVMeType: NVMeType{
mock: true,
options: opts,
},
}

return &nvme
}

func getOptionAsInt(opts map[string]string, key string) int64 {
v, _ := strconv.ParseInt(opts[key], 10, 64)
return v
}

func (nvme *MockNVMeTCP) discoverNVMeTCPTargets(address string, login bool) ([]NVMeTarget, error) {
if GONVMEMock.InduceDiscoveryError {
return []NVMeTarget{}, errors.New("discoverTargets induced error")
}
mockedTargets := make([]NVMeTarget, 0)
count := getOptionAsInt(nvme.options, MockNumberOfTargets)

if count == 0 {
count = 1
}

for idx := 0; idx < int(count); idx++ {
tgt := fmt.Sprintf("%05d", idx)
mockedTargets = append(mockedTargets,
NVMeTarget{
Portal: address,
TargetNqn: "nqn.1988-11.com.dell.mock:e6e2d5b871f1403E169D" + tgt,
TrType: "tcp",
AdrFam: "fibre-channel",
SubType: "nvme subsystem",
Treq: "not specified",
PortID: "0",
TrsvcID: "none",
SecType: "none",
TargetType: "tcp",
})
}

// send back a slice of targets
return mockedTargets, nil
}

func (nvme *MockNVMeTCP) getInitiators(filename string) ([]string, error) {

if GONVMEMock.InduceInitiatorError {
return []string{}, errors.New("getInitiators induced error")
}

mockedInitiators := make([]string, 0)
count := getOptionAsInt(nvme.options, MockNumberOfInitiators)
if count == 0 {
count = 1
}

for idx := 0; idx < int(count); idx++ {
init := fmt.Sprintf("%05d", idx)
mockedInitiators = append(mockedInitiators,
"nqn.1988-11.com.dell.mock:01:00000000"+init)
}
return mockedInitiators, nil
}

func (nvme *MockNVMeTCP) nvmeConnect(target NVMeTarget) error {

if GONVMEMock.InduceLoginError {
return errors.New("NVMe Login induced error")
}

return nil
harshitap26 marked this conversation as resolved.
Show resolved Hide resolved
}

func (nvme *MockNVMeTCP) nvmeDisconnect(target NVMeTarget) error {

if GONVMEMock.InduceLogoutError {
return errors.New("NVMe Logout induced error")
}

return nil
harshitap26 marked this conversation as resolved.
Show resolved Hide resolved
}

func (nvme *MockNVMeTCP) getSessions() ([]NVMESession, error) {

if GONVMEMock.InduceGetSessionsError {
return []NVMESession{}, errors.New("getSessions induced error")
}

var sessions []NVMESession
count := getOptionAsInt(nvme.options, MockNumberOfSessions)
if count == 0 {
count = 1
}
for idx := 0; idx < int(count); idx++ {
init := fmt.Sprintf("%0d", idx)
session := NVMESession{}
session.Target = fmt.Sprintf("nqn.1988-11.com.dell.mock:00:e6e2d5b871f1403E169D%d", idx)
session.Portal = fmt.Sprintf("192.168.1.%d", idx)
session.Name = "nvme" + init
session.NVMESessionState = NVMESessionStateLive
session.NVMETransportName = NVMETransportNameTCP
sessions = append(sessions, session)
}
return sessions, nil
}

// ====================================================================
// Architecture agnostic code for the mock implementation

// DiscoverNVMeTCPTargets runs an NVMe discovery and returns a list of targets.
func (nvme *MockNVMeTCP) DiscoverNVMeTCPTargets(address string, login bool) ([]NVMeTarget, error) {
return nvme.discoverNVMeTCPTargets(address, login)
}

// GetInitiators returns a list of NVMe initiators on the local system.
func (nvme *MockNVMeTCP) GetInitiators(filename string) ([]string, error) {
return nvme.getInitiators(filename)
}

// NVMeConnect will attempt to log into an NVMe target
func (nvme *MockNVMeTCP) NVMeConnect(target NVMeTarget) error {
return nvme.nvmeConnect(target)
}

// NVMeDisconnect will attempt to log out of an NVMe target
func (nvme *MockNVMeTCP) NVMeDisconnect(target NVMeTarget) error {
return nvme.nvmeDisconnect(target)
}

// GetSessions Queries NVMe session info
func (nvme *MockNVMeTCP) GetSessions() ([]NVMESession, error) {
return nvme.getSessions()
}
28 changes: 21 additions & 7 deletions gonvme_tcp.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gonvme

import (
"bufio"
"fmt"
"os"
"os/exec"
Expand Down Expand Up @@ -253,7 +254,15 @@ func (nvme *NVMeTCP) nvmeConnect(target NVMeTarget) error {
exe := nvme.buildNVMeCommand([]string{NVMeCommand, "connect", "-t", "tcp", "-n", target.TargetNqn, "-a", target.Portal, "-s", NVMePort})
cmd := exec.Command(exe[0], exe[1:]...)

_, err := cmd.Output()
var Output string
stderr, _ := cmd.StderrPipe()
err := cmd.Start()

scanner := bufio.NewScanner(stderr)
for scanner.Scan() {
Output = scanner.Text()
}
err = cmd.Wait()

if err != nil {
if exiterr, ok := err.(*exec.ExitError); ok {
Expand All @@ -265,8 +274,13 @@ func (nvme *NVMeTCP) nvmeConnect(target NVMeTarget) error {
if nvmeConnectResult == 114 || nvmeConnectResult == 70 {
// session already exists
// do not treat this as a failure
fmt.Printf("\nnvme connection already exists to: %s", target.TargetNqn)
err = nil
if Output == "Failed to write to /dev/nvme-fabrics: Operation already in progress" {
fmt.Printf("NVMe connection already exists\n")
err = nil
} else {
fmt.Printf("\nError during nvme connect %s at %s: %v", target.TargetNqn, target.Portal, err)
return err
}
} else {
fmt.Printf("\nnvme connect failure: %v", err)
}
Expand All @@ -285,12 +299,12 @@ func (nvme *NVMeTCP) nvmeConnect(target NVMeTarget) error {
return nil
}

// NVMeDisonnect will attempt to disconnect from a given nvme target
func (nvme *NVMeTCP) NVMeDisonnect(target NVMeTarget) error {
return nvme.nvmeDisonnect(target)
// NVMeDisconnect will attempt to disconnect from a given nvme target
func (nvme *NVMeTCP) NVMeDisconnect(target NVMeTarget) error {
return nvme.nvmeDisconnect(target)
}

func (nvme *NVMeTCP) nvmeDisonnect(target NVMeTarget) error {
func (nvme *NVMeTCP) nvmeDisconnect(target NVMeTarget) error {
// nvme disconnect is done via the nvme cli
// nvme disconnect -n <target NQN>
exe := nvme.buildNVMeCommand([]string{NVMeCommand, "disconnect", "-n", target.TargetNqn})
Expand Down
Loading