test(metanode): add unit tests for DelExtFile functionality . #1000348192

- Implemented unit tests for DelExtFile methods including GetIdx, Len,
  Swap, Less, and Sort.
- Created mockFileInfo type to simulate os.FileInfo for testing.
- Added test cases to validate behavior for valid and invalid file names.
- Ensured proper handling of sorting and filtering of file information.

This commit enhances test coverage for DelExtFile, ensuring the
correctness of its methods within the CubeFS system.

Signed-off-by: Victor1319 <zengxuewei@oppo.com>
This commit is contained in:
Victor1319 2025-09-17 20:09:28 +08:00 committed by 常亮
parent a48c593ecb
commit b58cfa92f4
2 changed files with 178 additions and 16 deletions

178
metanode/util_test.go Normal file
View File

@ -0,0 +1,178 @@
package metanode
import (
"os"
"testing"
"time"
)
// mockFileInfo implements os.FileInfo for testing
type mockFileInfo struct {
name string
isDir bool
}
func (m mockFileInfo) Name() string { return m.name }
func (m mockFileInfo) IsDir() bool { return m.isDir }
func (m mockFileInfo) Size() int64 { return 0 }
func (m mockFileInfo) Mode() os.FileMode { return 0 }
func (m mockFileInfo) ModTime() time.Time { return time.Time{} }
func (m mockFileInfo) Sys() interface{} { return nil }
func TestDelExtFile_GetIdx(t *testing.T) {
tests := []struct {
name string
input string
expected int64
expectPanic bool
}{
{
name: "valid file name",
input: "EXTENT_DEL_1",
expected: 1,
expectPanic: false,
},
{
name: "valid file name with multiple digits",
input: "EXTENT_DEL_12345",
expected: 12345,
expectPanic: false,
},
{
name: "file name without underscore - should panic",
input: "EXTENTDEL",
expected: 0,
expectPanic: true,
},
{
name: "file name with non-numeric index - should panic",
input: "EXTENT_DEL_abc",
expected: 0,
expectPanic: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
r := recover()
if tt.expectPanic && r == nil {
t.Errorf("getDelExtFileIdx(%q) expected panic, but didn't panic", tt.input)
}
if !tt.expectPanic && r != nil {
t.Errorf("getDelExtFileIdx(%q) unexpected panic: %v", tt.input, r)
}
}()
result := getDelExtFileIdx(tt.input)
if !tt.expectPanic && result != tt.expected {
t.Errorf("getDelExtFileIdx(%q) = %d, expected %d", tt.input, result, tt.expected)
}
})
}
}
func TestDelExtFile_Len(t *testing.T) {
files := DelExtFile{
mockFileInfo{name: "EXTENT_DEL_1", isDir: false},
mockFileInfo{name: "EXTENT_DEL_2", isDir: false},
}
if files.Len() != 2 {
t.Errorf("DelExtFile.Len() = %d, expected 2", files.Len())
}
}
func TestDelExtFile_Swap(t *testing.T) {
files := DelExtFile{
mockFileInfo{name: "EXTENT_DEL_1", isDir: false},
mockFileInfo{name: "EXTENT_DEL_2", isDir: false},
}
originalFirst := files[0]
originalSecond := files[1]
files.Swap(0, 1)
if files[0] != originalSecond {
t.Errorf("Swap(0, 1) failed: first element should be %v, got %v", originalSecond, files[0])
}
if files[1] != originalFirst {
t.Errorf("Swap(0, 1) failed: second element should be %v, got %v", originalFirst, files[1])
}
}
func TestDelExtFile_Less(t *testing.T) {
files := DelExtFile{
mockFileInfo{name: "EXTENT_DEL_1", isDir: false},
mockFileInfo{name: "EXTENT_DEL_2", isDir: false},
}
if !files.Less(0, 1) {
t.Errorf("DelExtFile.Less(0, 1) should return true")
}
if files.Less(1, 0) {
t.Errorf("DelExtFile.Less(1, 0) should return false")
}
}
func TestDelExtFile_Sort(t *testing.T) {
// Test with valid files
files := []os.FileInfo{
mockFileInfo{name: "EXTENT_DEL_3", isDir: false},
mockFileInfo{name: "EXTENT_DEL_1", isDir: false},
mockFileInfo{name: "EXTENT_DEL_2", isDir: false},
}
result := sortDelExtFileInfo(files)
if len(result) != 3 {
t.Errorf("sortDelExtFileInfo() returned %d files, expected 3", len(result))
return
}
expected := []string{"EXTENT_DEL_1", "EXTENT_DEL_2", "EXTENT_DEL_3"}
for i, file := range result {
if file.Name() != expected[i] {
t.Errorf("sortDelExtFileInfo() result[%d] = %s, expected %s", i, file.Name(), expected[i])
}
}
}
func TestDelExtFile_SortWithDirectories(t *testing.T) {
// Test filtering out directories
files := []os.FileInfo{
mockFileInfo{name: "EXTENT_DEL_2", isDir: false},
mockFileInfo{name: "some_directory", isDir: true},
mockFileInfo{name: "EXTENT_DEL_1", isDir: false},
}
result := sortDelExtFileInfo(files)
if len(result) != 2 {
t.Errorf("sortDelExtFileInfo() returned %d files, expected 2", len(result))
return
}
expected := []string{"EXTENT_DEL_1", "EXTENT_DEL_2"}
for i, file := range result {
if file.Name() != expected[i] {
t.Errorf("sortDelExtFileInfo() result[%d] = %s, expected %s", i, file.Name(), expected[i])
}
}
}
func TestDelExtFile_SortEmptyInput(t *testing.T) {
// Test with empty input
result := sortDelExtFileInfo([]os.FileInfo{})
if len(result) != 0 {
t.Errorf("sortDelExtFileInfo() with empty input returned %d files, expected 0", len(result))
}
// Test with nil input
result = sortDelExtFileInfo(nil)
if len(result) != 0 {
t.Errorf("sortDelExtFileInfo() with nil input returned %d files, expected 0", len(result))
}
}

View File

@ -79,12 +79,6 @@ type Partition interface {
// CloseAndBackup closes the partition and backs up the WAL.
CloseAndBackup() error
// GetID returns the partition ID
GetID() uint64
// GetWalPath returns the WAL path
GetWalPath() string
Closed() bool
}
@ -96,16 +90,6 @@ type partition struct {
config *PartitionConfig
}
// GetID returns the partition ID
func (p *partition) GetID() uint64 {
return p.id
}
// GetWalPath returns the WAL path
func (p *partition) GetWalPath() string {
return p.walPath
}
// ChangeMember submits member change event and information to raft log.
func (p *partition) ChangeMember(changeType proto.ConfChangeType, peer proto.Peer, context []byte) (
resp interface{}, err error,