// TestValidateVolumeCreate validates validateVolumeCreate() func TestValidateVolumeCreate(t *testing.T) { msg := new(volume.VolCreateRequest) msg.Name = "vol" msg.Bricks = []string{"127.0.0.1:/tmp/b1", "127.0.0.1:/tmp/b2"} c := transaction.NewMockCtx() c.Set("req", msg) defer heketitests.Patch(&volume.ValidateBrickEntriesFunc, func(bricks []brick.Brickinfo, volID uuid.UUID, force bool) (int, error) { return 0, nil }).Restore() defer heketitests.Patch(&peer.GetPeerIDByAddrF, peer.GetPeerIDByAddrMockGood).Restore() vol, e := createVolinfo(msg) tests.Assert(t, e == nil) c.Set("volinfo", vol) e = validateVolumeCreate(c) tests.Assert(t, e == nil) // Mock validateBrickEntries failure defer heketitests.Patch(&volume.ValidateBrickEntriesFunc, func(bricks []brick.Brickinfo, volID uuid.UUID, force bool) (int, error) { return 0, errBad }).Restore() e = validateVolumeCreate(c) tests.Assert(t, e == errBad) }
// TestValidateVolumeCreate validates validateVolumeCreate() func TestValidateVolumeCreate(t *testing.T) { msg := new(volume.VolCreateRequest) msg.Name = "vol" msg.Bricks = []string{"127.0.0.1:/tmp/b1", "127.0.0.1:/tmp/b2"} vol, e := createVolume(msg) defer heketitests.Patch(&volume.ExistsFunc, func(name string) bool { return false }).Restore() defer heketitests.Patch(&volume.ValidateBrickEntriesFunc, func(bricks []volume.Brickinfo, volID uuid.UUID, force bool) (int, error) { return 0, nil }).Restore() _, e = validateVolumeCreate(msg, vol) tests.Assert(t, e == nil) // Mock volume exists failure defer heketitests.Patch(&volume.ExistsFunc, func(name string) bool { return true }).Restore() _, e = validateVolumeCreate(msg, vol) tests.Assert(t, e == gderrors.ErrVolExists) // Mock validateBrickEntries failure defer heketitests.Patch(&volume.ExistsFunc, func(name string) bool { return false }).Restore() defer heketitests.Patch(&volume.ValidateBrickEntriesFunc, func(bricks []volume.Brickinfo, volID uuid.UUID, force bool) (int, error) { return 0, errBad }).Restore() _, e = validateVolumeCreate(msg, vol) tests.Assert(t, e == errBad) }
// TestGenerateVolfiles validates generateVolfiles func TestGenerateVolfiles(t *testing.T) { defer heketitests.Patch(&peer.GetPeerIDByAddrF, peer.GetPeerIDByAddrMockGood).Restore() msg := new(volume.VolCreateRequest) msg.Name = "vol" msg.Bricks = []string{"127.0.0.1:/tmp/b1", "127.0.0.1:/tmp/b2"} vol, e := createVolinfo(msg) c := transaction.NewMockCtx() c.Set("volinfo", vol) defer heketitests.Patch(&volgen.GenerateVolfileFunc, func(vinfo *volume.Volinfo) error { return nil }).Restore() defer heketitests.Patch(&volume.AddOrUpdateVolumeFunc, func(vinfo *volume.Volinfo) error { return nil }).Restore() e = generateVolfiles(c) tests.Assert(t, e == nil) // Mock volgen failure defer heketitests.Patch(&volgen.GenerateVolfileFunc, func(vinfo *volume.Volinfo) error { return errBad }).Restore() e = generateVolfiles(c) tests.Assert(t, e == errBad) defer heketitests.Patch(&volgen.GenerateVolfileFunc, func(vinfo *volume.Volinfo) error { return nil }).Restore() }
// TestNewBrickEntry validates NewBrickEntries () func TestNewBrickEntry(t *testing.T) { defer heketitests.Patch(&peer.GetPeerIDByAddrF, peer.GetPeerIDByAddrMockGood).Restore() bricks := getSampleBricks("/tmp/b1", "/tmp/b2") brickPaths := []string{"/tmp/b1", "/tmp/b2"} host, _ := os.Hostname() b, err := NewBrickEntriesFunc(bricks) tests.Assert(t, err == nil) tests.Assert(t, b != nil) for _, brick := range b { tests.Assert(t, find(brickPaths, brick.Path)) tests.Assert(t, host == brick.Hostname) } // Some negative tests mockBricks := []string{"/tmp/b1", "/tmp/b2"} //with out IPs _, err = NewBrickEntriesFunc(mockBricks) tests.Assert(t, err != nil) //Now mock filepath.Abs() defer heketitests.Patch(&absFilePath, func(path string) (string, error) { return "", errors.ErrBrickPathConvertFail }).Restore() _, err = NewBrickEntriesFunc(bricks) tests.Assert(t, err == errors.ErrBrickPathConvertFail) }
func TestLogDebug(t *testing.T) { var testbuffer bytes.Buffer defer tests.Patch(&stdout, &testbuffer).Restore() l := NewLogger("[testing]", LEVEL_DEBUG) l.Debug("Hello %v", "World") tests.Assert(t, strings.Contains(testbuffer.String(), "[testing] DEBUG "), testbuffer.String()) tests.Assert(t, strings.Contains(testbuffer.String(), "Hello World"), testbuffer.String()) tests.Assert(t, strings.Contains(testbuffer.String(), "log_test.go"), testbuffer.String()) // [testing] DEBUG 2016/04/28 15:25:08 /src/github.com/heketi/heketi/pkg/utils/log_test.go:66: Hello World fileinfo := strings.Split(testbuffer.String(), " ")[4] filename := strings.Split(fileinfo, ":")[0] // Need to check that it starts with /src/github.com tests.Assert(t, strings.HasPrefix(filename, "/src/github.com/")) tests.Assert(t, strings.HasSuffix(filename, "/pkg/utils/log_test.go")) testbuffer.Reset() l.SetLevel(LEVEL_INFO) l.Debug("TEXT") tests.Assert(t, testbuffer.Len() == 0) }
func TestLogError(t *testing.T) { var testbuffer bytes.Buffer defer tests.Patch(&stderr, &testbuffer).Restore() l := NewLogger("[testing]", LEVEL_DEBUG) l.LogError("Hello %v", "World") tests.Assert(t, strings.Contains(testbuffer.String(), "[testing] ERROR "), testbuffer.String()) tests.Assert(t, strings.Contains(testbuffer.String(), "Hello World"), testbuffer.String()) tests.Assert(t, strings.Contains(testbuffer.String(), "log_test.go"), testbuffer.String()) testbuffer.Reset() testbuffer.Reset() err := errors.New("BAD") l.Err(err) tests.Assert(t, strings.Contains(testbuffer.String(), "[testing] ERROR "), testbuffer.String()) tests.Assert(t, strings.Contains(testbuffer.String(), "BAD"), testbuffer.String()) tests.Assert(t, strings.Contains(testbuffer.String(), "log_test.go"), testbuffer.String()) testbuffer.Reset() l.SetLevel(LEVEL_CRITICAL) l.LogError("TEXT") tests.Assert(t, testbuffer.Len() == 0) }
// TestCreateVolinfo validates createVolinfo() func TestCreateVolinfo(t *testing.T) { defer heketitests.Patch(&peer.GetPeerIDByAddrF, peer.GetPeerIDByAddrMockGood).Restore() msg := new(volume.VolCreateRequest) msg.Name = "vol" msg.Bricks = []string{"127.0.0.1:/tmp/b1", "127.0.0.1:/tmp/b2"} vol, e := createVolinfo(msg) tests.Assert(t, e == nil && vol != nil) // Mock failure in NewBrickEntries(), createVolume() should fail defer heketitests.Patch(&volume.NewBrickEntriesFunc, func(bricks []string) ([]brick.Brickinfo, error) { return nil, errBad }).Restore() vol, e = createVolinfo(msg) tests.Assert(t, e == errBad) }
// TestNewVolumeEntryFromRequest tests whether the volume is created with a // valid request func TestNewVolumeEntryFromRequest(t *testing.T) { var err error defer heketitests.Patch(&utils.PathMax, 4096).Restore() defer heketitests.Patch(&utils.Setxattr, tests.MockSetxattr).Restore() defer heketitests.Patch(&utils.Getxattr, tests.MockGetxattr).Restore() defer heketitests.Patch(&utils.Removexattr, tests.MockRemovexattr).Restore() defer heketitests.Patch(&getVolumesFunc, mockGetVolumes).Restore() defer heketitests.Patch(&peer.GetPeerIDByAddrF, peer.GetPeerIDByAddrMockGood).Restore() //peer.GetPeerIDByAddrF = peer.GetPeerIDByAddrMockGood //defer func() { peer.GetPeerIDByAddrF = peer.GetPeerIDByAddr }() req := new(VolCreateRequest) req.Name = "vol1" req.Bricks = getSampleBricks("/tmp/b1", "/tmp/b2") req.Force = true v, e := NewVolumeEntry(req) tests.Assert(t, e == nil) tests.Assert(t, v.Name == "vol1") tests.Assert(t, v.Transport == "tcp") tests.Assert(t, v.ReplicaCount == 1) tests.Assert(t, len(v.ID) != 0) v.Bricks, err = NewBrickEntriesFunc(req.Bricks) tests.Assert(t, err == nil) tests.Assert(t, v.Bricks != nil) tests.Assert(t, len(v.Bricks) != 0) _, err = ValidateBrickEntriesFunc(v.Bricks, v.ID, true) tests.Assert(t, err == nil) defer heketitests.Patch(&validateBrickPathStatsFunc, tests.MockValidateBrickPathStats).Restore() _, err = ValidateBrickEntriesFunc(v.Bricks, v.ID, false) tests.Assert(t, err == nil) }
func TestRemoveBrickPaths(t *testing.T) { defer heketitests.Patch(&peer.GetPeerIDByAddrF, peer.GetPeerIDByAddrMockGood).Restore() req := new(VolCreateRequest) req.Name = "vol1" req.Bricks = getSampleBricks("/tmp/b1", "/tmp/b2") v, e := NewVolumeEntry(req) v.Bricks, e = NewBrickEntriesFunc(req.Bricks) e = RemoveBrickPaths(v.Bricks) tests.Assert(t, e == nil) }
func TestValidateXattrSupport(t *testing.T) { defer heketitests.Patch(&Setxattr, tests.MockSetxattr).Restore() defer heketitests.Patch(&Getxattr, tests.MockGetxattr).Restore() defer heketitests.Patch(&Removexattr, tests.MockRemovexattr).Restore() tests.Assert(t, ValidateXattrSupport("/tmp/b1", "localhost", uuid.NewRandom(), true) == nil) // Some negative tests var xattr_err error baderror := errors.New("Bad") xattr_err = baderror // Now check what happens when setxattr fails defer heketitests.Patch(&Setxattr, func(path string, attr string, data []byte, flags int) (err error) { return xattr_err }).Restore() tests.Assert(t, ValidateXattrSupport("/tmp/b1", "localhost", uuid.NewRandom(), true) == baderror) // Now check what happens when getxattr fails defer heketitests.Patch(&Getxattr, func(path string, attr string, dest []byte) (sz int, err error) { return 0, xattr_err }).Restore() tests.Assert(t, ValidateXattrSupport("/tmp/b1", "localhost", uuid.NewRandom(), true) == baderror) // Now check what happens when removexattr fails defer heketitests.Patch(&Removexattr, func(path string, attr string) (err error) { return xattr_err }).Restore() tests.Assert(t, ValidateXattrSupport("/tmp/b1", "localhost", uuid.NewRandom(), true) == baderror) }
// TestNewVolumeEntry tests whether the volinfo object is successfully created func TestNewVolumeObject(t *testing.T) { v := NewVolinfoFunc() tests.Assert(t, v.Options != nil) tests.Assert(t, len(v.ID) == 0) // Negative test defer heketitests.Patch(&NewVolinfoFunc, func() (vol *Volinfo) { return nil }).Restore() v1 := NewVolinfoFunc() tests.Assert(t, v1 == nil) }
// TestNewVolumeEntry validates NewVolumeEntry() func TestNewVolumeEntry(t *testing.T) { req := new(VolCreateRequest) v, e := NewVolumeEntry(req) tests.Assert(t, e == nil) tests.Assert(t, v != nil) // Negative test - mock out NewVolInfo() defer heketitests.Patch(&NewVolinfoFunc, func() (vol *Volinfo) { return nil }).Restore() _, e = NewVolumeEntry(req) tests.Assert(t, e == errors.ErrVolCreateFail) }
func TestLogLevel(t *testing.T) { var testbuffer bytes.Buffer defer tests.Patch(&stdout, &testbuffer).Restore() l := NewLogger("[testing]", LEVEL_INFO) tests.Assert(t, LEVEL_INFO == l.level) tests.Assert(t, LEVEL_INFO == l.Level()) l.SetLevel(LEVEL_CRITICAL) tests.Assert(t, LEVEL_CRITICAL == l.level) tests.Assert(t, LEVEL_CRITICAL == l.Level()) }
// TestCommitVolumeCreate validates commitVolumeCreate() func TestCommitVolumeCreate(t *testing.T) { msg := new(volume.VolCreateRequest) msg.Name = "vol" msg.Bricks = []string{"127.0.0.1:/tmp/b1", "127.0.0.1:/tmp/b2"} vol, e := createVolume(msg) defer heketitests.Patch(&volgen.GenerateVolfileFunc, func(vinfo *volume.Volinfo) error { return nil }).Restore() defer heketitests.Patch(&volume.AddOrUpdateVolumeFunc, func(vinfo *volume.Volinfo) error { return nil }).Restore() _, e = commitVolumeCreate(vol) tests.Assert(t, e == nil) // Mock volgen failure defer heketitests.Patch(&volgen.GenerateVolfileFunc, func(vinfo *volume.Volinfo) error { return errBad }).Restore() _, e = commitVolumeCreate(vol) tests.Assert(t, e == errBad) defer heketitests.Patch(&volgen.GenerateVolfileFunc, func(vinfo *volume.Volinfo) error { return nil }).Restore() // Mock store failure defer heketitests.Patch(&volume.AddOrUpdateVolumeFunc, func(vinfo *volume.Volinfo) error { return errBad }).Restore() _, e = commitVolumeCreate(vol) tests.Assert(t, e == errBad) }
func TestLogWarning(t *testing.T) { var testbuffer bytes.Buffer defer tests.Patch(&stdout, &testbuffer).Restore() l := NewLogger("[testing]", LEVEL_DEBUG) l.Warning("Hello %v", "World") tests.Assert(t, strings.Contains(testbuffer.String(), "[testing] WARNING "), testbuffer.String()) tests.Assert(t, strings.Contains(testbuffer.String(), "Hello World"), testbuffer.String()) testbuffer.Reset() l.SetLevel(LEVEL_ERROR) l.Warning("TEXT") tests.Assert(t, testbuffer.Len() == 0) }
func TestNewSshExecDefaults(t *testing.T) { f := NewFakeSsh() defer tests.Patch(&sshNew, func(logger *utils.Logger, user string, file string) (Ssher, error) { return f, nil }).Restore() config := &SshConfig{ PrivateKeyFile: "xkeyfile", } s, err := NewSshExecutor(config) tests.Assert(t, err == nil) tests.Assert(t, s != nil) tests.Assert(t, s.private_keyfile == "xkeyfile") tests.Assert(t, s.user == "heketi") tests.Assert(t, s.port == "22") tests.Assert(t, s.Fstab == "/etc/fstab") tests.Assert(t, s.exec != nil) }
func TestNewSshExec(t *testing.T) { f := NewFakeSsh() defer tests.Patch(&sshNew, func(logger *utils.Logger, user string, file string) (Ssher, error) { return f, nil }).Restore() config := &SshConfig{ PrivateKeyFile: "xkeyfile", User: "******", Port: "100", Fstab: "xfstab", } s, err := NewSshExecutor(config) tests.Assert(t, err == nil) tests.Assert(t, s != nil) tests.Assert(t, s.private_keyfile == config.PrivateKeyFile) tests.Assert(t, s.user == config.User) tests.Assert(t, s.port == config.Port) tests.Assert(t, s.Fstab == config.Fstab) tests.Assert(t, s.exec != nil) }
func TestStartETCDWithInvalidExecName(t *testing.T) { // Mock the executable name such that it fails defer heketitests.Patch(&ExecName, "abc").Restore() _, err := StartETCD() tests.Assert(t, err != nil) }
func TestSshExecBrickDestroy(t *testing.T) { f := NewFakeSsh() defer tests.Patch(&sshNew, func(logger *utils.Logger, user string, file string) (Ssher, error) { return f, nil }).Restore() config := &SshConfig{ PrivateKeyFile: "xkeyfile", User: "******", Port: "100", Fstab: "/my/fstab", } s, err := NewSshExecutor(config) tests.Assert(t, err == nil) tests.Assert(t, s != nil) // Create a Brick b := &executors.BrickRequest{ VgId: "xvgid", Name: "id", TpSize: 100, Size: 10, PoolMetadataSize: 5, } // Mock ssh function f.FakeConnectAndExec = func(host string, commands []string, timeoutMinutes int, useSudo bool) ([]string, error) { tests.Assert(t, host == "myhost:100", host) for _, cmd := range commands { cmd = strings.Trim(cmd, " ") switch { case strings.Contains(cmd, "umount"): tests.Assert(t, cmd == "sudo umount "+ "/var/lib/heketi/mounts/vg_xvgid/brick_id", cmd) case strings.Contains(cmd, "lvremove"): tests.Assert(t, cmd == "sudo lvremove -f vg_xvgid/tp_id", cmd) case strings.Contains(cmd, "rmdir"): tests.Assert(t, cmd == "sudo rmdir "+ "/var/lib/heketi/mounts/vg_xvgid/brick_id", cmd) case strings.Contains(cmd, "sed"): tests.Assert(t, cmd == "sudo sed -i.save "+ "'/brick_id/d' /my/fstab", cmd) } } return nil, nil } // Create Brick err = s.BrickDestroy("myhost", b) tests.Assert(t, err == nil, err) }
func TestSshExecBrickCreate(t *testing.T) { f := NewFakeSsh() defer tests.Patch(&sshNew, func(logger *utils.Logger, user string, file string) (Ssher, error) { return f, nil }).Restore() config := &SshConfig{ PrivateKeyFile: "xkeyfile", User: "******", Port: "100", Fstab: "/my/fstab", } s, err := NewSshExecutor(config) tests.Assert(t, err == nil) tests.Assert(t, s != nil) // Create a Brick b := &executors.BrickRequest{ VgId: "xvgid", Name: "id", TpSize: 100, Size: 10, PoolMetadataSize: 5, } // Mock ssh function f.FakeConnectAndExec = func(host string, commands []string, timeoutMinutes int, useSudo bool) ([]string, error) { tests.Assert(t, host == "myhost:100", host) tests.Assert(t, len(commands) == 6) for i, cmd := range commands { cmd = strings.Trim(cmd, " ") switch i { case 0: tests.Assert(t, cmd == "sudo mkdir -p /var/lib/heketi/mounts/vg_xvgid/brick_id", cmd) case 1: tests.Assert(t, cmd == "sudo lvcreate --poolmetadatasize 5K "+ "-c 256K -L 100K -T vg_xvgid/tp_id -V 10K -n brick_id", cmd) case 2: tests.Assert(t, cmd == "sudo mkfs.xfs -i size=512 "+ "-n size=8192 /dev/vg_xvgid/brick_id", cmd) case 3: tests.Assert(t, cmd == "echo \"/dev/vg_xvgid/brick_id "+ "/var/lib/heketi/mounts/vg_xvgid/brick_id "+ "xfs rw,inode64,noatime,nouuid 1 2\" | "+ "sudo tee -a /my/fstab > /dev/null", cmd) case 4: tests.Assert(t, cmd == "sudo mount -o rw,inode64,noatime,nouuid "+ "/dev/vg_xvgid/brick_id "+ "/var/lib/heketi/mounts/vg_xvgid/brick_id", cmd) case 5: tests.Assert(t, cmd == "sudo mkdir "+ "/var/lib/heketi/mounts/vg_xvgid/brick_id/brick", cmd) } } return nil, nil } // Create Brick _, err = s.BrickCreate("myhost", b) tests.Assert(t, err == nil, err) }