|
@ -1,86 +1,37 @@ |
|
|
package storage |
|
|
package storage |
|
|
|
|
|
|
|
|
import ( |
|
|
import ( |
|
|
"os" |
|
|
|
|
|
"testing" |
|
|
"testing" |
|
|
|
|
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/storage/needle" |
|
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/storage/super_block" |
|
|
|
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
func TestCompactVolumeSpaceCheck(t *testing.T) { |
|
|
|
|
|
// Create a temporary directory for testing
|
|
|
|
|
|
dir, err := os.MkdirTemp("", "seaweedfs_test") |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
t.Fatalf("Failed to create temp dir: %v", err) |
|
|
|
|
|
} |
|
|
|
|
|
defer os.RemoveAll(dir) |
|
|
|
|
|
|
|
|
|
|
|
// Create a disk location
|
|
|
|
|
|
location := &DiskLocation{ |
|
|
|
|
|
Directory: dir, |
|
|
|
|
|
IdxDirectory: dir, |
|
|
|
|
|
volumes: make(map[needle.VolumeId]*Volume), |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Create a store
|
|
|
|
|
|
store := &Store{ |
|
|
|
|
|
Locations: []*DiskLocation{location}, |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Create a volume with some data
|
|
|
|
|
|
vid := needle.VolumeId(1) |
|
|
|
|
|
replication, _ := super_block.NewReplicaPlacementFromString("000") |
|
|
|
|
|
volume, err := NewVolume(dir, dir, "", vid, NeedleMapInMemory, replication, nil, 0, needle.GetCurrentVersion(), 0, 0) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
t.Fatalf("Failed to create volume: %v", err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
location.SetVolume(vid, volume) |
|
|
|
|
|
|
|
|
|
|
|
// Test space checking logic
|
|
|
|
|
|
t.Run("InsufficientSpace", func(t *testing.T) { |
|
|
|
|
|
// This should fail because we're testing the improved space checking
|
|
|
|
|
|
err := store.CompactVolume(vid, 0, 0, nil) |
|
|
|
|
|
if err == nil { |
|
|
|
|
|
t.Error("Expected compaction to fail due to insufficient space") |
|
|
|
|
|
} |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
t.Logf("Expected error: %v", err) |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
// Clean up
|
|
|
|
|
|
volume.Close() |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestSpaceCalculation(t *testing.T) { |
|
|
func TestSpaceCalculation(t *testing.T) { |
|
|
// Test the space calculation logic
|
|
|
// Test the space calculation logic
|
|
|
testCases := []struct { |
|
|
testCases := []struct { |
|
|
name string |
|
|
|
|
|
volumeSize uint64 |
|
|
|
|
|
indexSize uint64 |
|
|
|
|
|
preallocate int64 |
|
|
|
|
|
expectedMinimum int64 |
|
|
|
|
|
|
|
|
name string |
|
|
|
|
|
volumeSize uint64 |
|
|
|
|
|
indexSize uint64 |
|
|
|
|
|
preallocate int64 |
|
|
|
|
|
expectedMin int64 |
|
|
}{ |
|
|
}{ |
|
|
{ |
|
|
{ |
|
|
name: "SmallVolume", |
|
|
|
|
|
volumeSize: 1024 * 1024, // 1MB
|
|
|
|
|
|
indexSize: 1024, // 1KB
|
|
|
|
|
|
preallocate: 0, |
|
|
|
|
|
expectedMinimum: int64((1024*1024 + 1024) * 110 / 100), // 110% of volume+index size
|
|
|
|
|
|
|
|
|
name: "Large volume, small preallocate", |
|
|
|
|
|
volumeSize: 244 * 1024 * 1024 * 1024, // 244GB
|
|
|
|
|
|
indexSize: 1024 * 1024, // 1MB
|
|
|
|
|
|
preallocate: 1024, // 1KB
|
|
|
|
|
|
expectedMin: int64((244*1024*1024*1024 + 1024*1024) * 11 / 10), // +10% buffer
|
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
name: "LargePreallocate", |
|
|
|
|
|
volumeSize: 1024 * 1024, // 1MB
|
|
|
|
|
|
indexSize: 1024, // 1KB
|
|
|
|
|
|
preallocate: 10 * 1024 * 1024, // 10MB
|
|
|
|
|
|
expectedMinimum: int64(10 * 1024 * 1024 * 110 / 100), // 110% of preallocate
|
|
|
|
|
|
|
|
|
name: "Small volume, large preallocate", |
|
|
|
|
|
volumeSize: 100 * 1024 * 1024, // 100MB
|
|
|
|
|
|
indexSize: 1024, // 1KB
|
|
|
|
|
|
preallocate: 1024 * 1024 * 1024, // 1GB
|
|
|
|
|
|
expectedMin: int64(1024 * 1024 * 1024 * 11 / 10), // preallocate + 10%
|
|
|
}, |
|
|
}, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
for _, tc := range testCases { |
|
|
for _, tc := range testCases { |
|
|
t.Run(tc.name, func(t *testing.T) { |
|
|
t.Run(tc.name, func(t *testing.T) { |
|
|
|
|
|
// Calculate space needed using the same logic as our fix
|
|
|
estimatedCompactSize := int64(tc.volumeSize + tc.indexSize) |
|
|
estimatedCompactSize := int64(tc.volumeSize + tc.indexSize) |
|
|
spaceNeeded := tc.preallocate |
|
|
spaceNeeded := tc.preallocate |
|
|
if estimatedCompactSize > tc.preallocate { |
|
|
if estimatedCompactSize > tc.preallocate { |
|
@ -89,11 +40,12 @@ func TestSpaceCalculation(t *testing.T) { |
|
|
// Add 10% safety buffer
|
|
|
// Add 10% safety buffer
|
|
|
spaceNeeded = spaceNeeded + (spaceNeeded / 10) |
|
|
spaceNeeded = spaceNeeded + (spaceNeeded / 10) |
|
|
|
|
|
|
|
|
if spaceNeeded < tc.expectedMinimum { |
|
|
|
|
|
t.Errorf("Space calculation incorrect: got %d, expected at least %d", spaceNeeded, tc.expectedMinimum) |
|
|
|
|
|
|
|
|
if spaceNeeded < tc.expectedMin { |
|
|
|
|
|
t.Errorf("Space calculation too low: got %d, expected at least %d", spaceNeeded, tc.expectedMin) |
|
|
} |
|
|
} |
|
|
t.Logf("Volume: %d, Index: %d, Preallocate: %d -> SpaceNeeded: %d", |
|
|
|
|
|
tc.volumeSize, tc.indexSize, tc.preallocate, spaceNeeded) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t.Logf("Volume size: %d bytes, Space needed: %d bytes (%.2f%% of volume size)", |
|
|
|
|
|
tc.volumeSize, spaceNeeded, float64(spaceNeeded)/float64(tc.volumeSize)*100) |
|
|
}) |
|
|
}) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |