-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #97 from utkarshmani1997/rmclose
Add unit test and rm conn.close
- Loading branch information
Showing
5 changed files
with
260 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters