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

Add unit test and rm conn.close #97

Merged
merged 4 commits into from
Nov 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,19 @@ before_script:
- ceph status
- sudo apt-get install -y libcunit1 libcunit1-doc libcunit1-dev
- sudo apt-get install -y open-iscsi
- go get -u github.com/golang/dep/cmd/dep

script:
- cd ${TRAVIS_BUILD_DIR}
- make deps
# Try a build without cgo first
- make build-nocgo
- make clean
# Now build with cgo and cephstore.
- make
- hack/verify-gofmt.sh
- go test -v ./pkg/...
- go test -v ./mock/...
- dd if=/dev/zero of=/var/tmp/disk.img bs=1024 count=102400
- mkdir ${HOME}/.gotgt
- echo ${TGT_CFG} > ${HOME}/.gotgt/config.json
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ BIN_DIR=_output/cmd/bin

all: init build

deps:
dep ensure

build: init
go build -o ${BIN_DIR}/gotgt gotgt.go

Expand Down
201 changes: 201 additions & 0 deletions mock/remote.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
package mock

import (
"encoding/binary"
"fmt"
"net"
"os"
"time"

uuid "github.com/satori/go.uuid"
"github.com/sirupsen/logrus"

"github.com/gostor/gotgt/pkg/api"
"github.com/gostor/gotgt/pkg/config" /* init lib */
"github.com/gostor/gotgt/pkg/port/iscsit"
"github.com/gostor/gotgt/pkg/scsi"
_ "github.com/gostor/gotgt/pkg/scsi/backingstore" /* init lib */
"github.com/gostor/gotgt/pkg/scsi/backingstore/remote"
)

type remoteBs struct {
Volume string
Size int64
SectorSize int

isUp bool
rw api.RemoteBackingStore

tgtName string
lhbsName string
clusterIP string
cfg *config.Config
targetDriver scsi.SCSITargetDriver
stats scsi.Stats
}

func (r *remoteBs) ReadAt(data []byte, size int64) (int, error) {
return 0, nil
}

func (r *remoteBs) WriteAt(data []byte, size int64) (int, error) {
return 0, nil
}

func (r *remoteBs) Sync() (int, error) {
return 0, nil
}

func (r *remoteBs) Unmap(bs int64, size int64) (int, error) {
return 0, nil
}

func initializeSCSITarget(size int64) {
iscsit.EnableStats = true
scsi.EnableORWrite16 = false
scsi.EnablePersistentReservation = false
scsi.EnableMultipath = false
remote.Size = uint64(size)
}

// Startup starts iscsi target server
func (r *remoteBs) Startup(name string, frontendIP string, clusterIP string, size, sectorSize int64) error {
initializeSCSITarget(size)

if frontendIP == "" {
host, _ := os.Hostname()
addrs, _ := net.LookupIP(host)
for _, addr := range addrs {
if ipv4 := addr.To4(); ipv4 != nil {
frontendIP = ipv4.String()
if frontendIP == "127.0.0.1" {
continue
}
break
}
}
}

r.tgtName = "iqn.2016-09.com.gotgt.gostor:" + name
r.lhbsName = "RemBs:" + name
r.cfg = &config.Config{
Storages: []config.BackendStorage{
{
DeviceID: 1000,
Path: r.lhbsName,
Online: true,
},
},
ISCSIPortals: []config.ISCSIPortalInfo{
{
ID: 0,
Portal: frontendIP + ":3260",
},
},
ISCSITargets: map[string]config.ISCSITarget{
r.tgtName: {
TPGTs: map[string][]uint64{
"1": {0},
},
LUNs: map[string]uint64{
"1": uint64(1000),
},
},
},
}

r.Volume = name
r.Size = size
r.SectorSize = int(sectorSize)
r.rw = r
r.clusterIP = clusterIP
logrus.Info("Start SCSI target")
if err := r.startScsiTarget(r.cfg); err != nil {
return err
}

r.isUp = true

return nil
}

// Shutdown stop scsi target
func (r *remoteBs) Shutdown() error {
if r.Volume != "" {
r.Volume = ""
}

if err := r.stopScsiTarget(); err != nil {
return fmt.Errorf("Failed to stop scsi target, err: %v", err)
}
r.isUp = false

return nil
}

// State provides info whether scsi target is up or down
func (r *remoteBs) State() string {
if r.isUp {
return "Up"
}
return "Down"
}

// Stats get target stats from the scsi target
func (r *remoteBs) Stats() scsi.Stats {
if !r.isUp {
return scsi.Stats{}
}
return r.targetDriver.Stats()
}

// Resize is called to resize the volume
func (r *remoteBs) Resize(size uint64) error {
if !r.isUp {
return fmt.Errorf("Volume is not up")
}
return r.targetDriver.Resize(size)
}

func (r *remoteBs) startScsiTarget(cfg *config.Config) error {
var err error
id := uuid.NewV4()
uid := binary.BigEndian.Uint64(id[:8])
err = scsi.InitSCSILUMapEx(&config.BackendStorage{
DeviceID: uid,
Path: "RemBs:" + r.tgtName,
Online: true,
BlockShift: 9,
ThinProvisioning: true,
},
r.tgtName, uint64(0), r.rw)
if err != nil {
return err
}
scsiTarget := scsi.NewSCSITargetService()
r.targetDriver, err = scsi.NewTargetDriver("iscsi", scsiTarget)
if err != nil {
logrus.Errorf("iscsi target driver error")
return err
}
r.targetDriver.NewTarget(r.tgtName, cfg)
//r.targetDriver.SetClusterIP(r.clusterIP)
go r.targetDriver.Run()
// Wait here so that listener get started
time.Sleep(1 * time.Second)

logrus.Infof("SCSI device created")
return nil
}

func (r *remoteBs) stopScsiTarget() error {
if r.targetDriver == nil {
return nil
}
logrus.Infof("Stopping target %v ...", r.tgtName)
if err := r.targetDriver.Close(); err != nil {
return err
}
logrus.Infof("Target %v stopped", r.tgtName)
return nil
}
53 changes: 53 additions & 0 deletions mock/remote_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package mock

import (
"log"
"testing"
)

func TestStartStop(t *testing.T) {
cases := map[string]struct {
count int
shutdownAgain bool
expectErr bool
}{
"TargetStartStop": {
count: 3,
expectErr: false,
},
"TargetStop": {
count: 1,
expectErr: true,
shutdownAgain: true,
},
}

for name, tt := range cases {
t.Run(name, func(t *testing.T) {
for i := 0; i < tt.count; i++ {
bs := &remoteBs{}
err := bs.Startup("store1", "", "127.0.0.1", 2147483648, 512)
if err != nil {
log.Fatal("Failed to initialize tgt, err: ", err)
}

expectErr := false
err = bs.Shutdown()
if err != nil {
expectErr = true
}

if tt.shutdownAgain {
err = bs.Shutdown()
if err != nil {
expectErr = true
}
}

if tt.expectErr != expectErr {
t.Fatalf("Startup test failed, err: %v", err)
}
}
})
}
}
1 change: 0 additions & 1 deletion pkg/port/iscsit/iscsid.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ func (s *ISCSITargetDriver) Run() error {
if err, ok := err.(net.Error); ok {
if !err.Temporary() {
log.Warning("Closing connection with initiator...")
conn.Close()
break
}
}
Expand Down