Skip to content

Commit f36d8b3

Browse files
alloydsaakalenyu
andauthored
Add fractional sizes handling in gcnv
Co-authored-by: Alex Kalenyuk <akalenyu@redhat.com>
1 parent 62222bd commit f36d8b3

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

storage_drivers/gcp/gcp_gcnv.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,11 @@ func (d *NASStorageDriver) Create(
777777
sizeBytes = minimumGCNVVolumeSizeBytes
778778
}
779779

780+
// Ensure sizeBytes is a multiple of 1 GiB
781+
if remainder := sizeBytes % capacity.OneGiB; remainder != 0 {
782+
sizeBytes = ((sizeBytes / capacity.OneGiB) + 1) * capacity.OneGiB
783+
}
784+
780785
// Get the volume size based on the snapshot reserve
781786
sizeWithReserveBytes := drivers.CalculateVolumeSizeBytes(ctx, name, sizeBytes, snapshotReserveInt)
782787

@@ -2071,6 +2076,12 @@ func (d *NASStorageDriver) Resize(ctx context.Context, volConfig *storage.Volume
20712076
if volume.SnapshotReserve > math.MaxInt {
20722077
return fmt.Errorf("snapshot reserve too large")
20732078
}
2079+
2080+
// Ensure sizeBytes is a multiple of 1 GiB
2081+
if remainder := sizeBytes % capacity.OneGiB; remainder != 0 {
2082+
sizeBytes = ((sizeBytes / capacity.OneGiB) + 1) * capacity.OneGiB
2083+
}
2084+
20742085
sizeWithReserveBytes := drivers.CalculateVolumeSizeBytes(ctx, name, sizeBytes, int(volume.SnapshotReserve))
20752086

20762087
// If the volume is already the requested size, there's nothing to do

storage_drivers/gcp/gcp_gcnv_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717

1818
tridentconfig "github.com/netapp/trident/config"
1919
mockapi "github.com/netapp/trident/mocks/mock_storage_drivers/mock_gcp"
20+
"github.com/netapp/trident/pkg/capacity"
2021
"github.com/netapp/trident/pkg/convert"
2122
"github.com/netapp/trident/storage"
2223
storagefake "github.com/netapp/trident/storage/fake"
@@ -1938,6 +1939,47 @@ func TestCreate_ZeroSize(t *testing.T) {
19381939
assert.Equal(t, volume.FullName, volConfig.InternalID, "internal ID not set on volConfig")
19391940
}
19401941

1942+
func TestCreate_SizeNotGibMultiple(t *testing.T) {
1943+
mockAPI, driver := newMockGCNVDriver(t)
1944+
1945+
driver.Config.BackendName = "gcnv"
1946+
driver.Config.ServiceLevel = api.ServiceLevelPremium
1947+
driver.Config.NASType = "nfs"
1948+
1949+
err := driver.populateConfigurationDefaults(ctx, &driver.Config)
1950+
assert.NoError(t, err, "error occurred")
1951+
1952+
driver.initializeStoragePools(ctx)
1953+
driver.initializeTelemetry(ctx, api.BackendUUID)
1954+
1955+
storagePool := driver.pools["gcnv_pool"]
1956+
1957+
volConfig, capacityPool, volume, createRequest := getStructsForCreateNFSVolume(ctx, driver, storagePool)
1958+
volConfig.Size = "107374182401" // 100 GiB + 1 byte
1959+
createRequest.SizeBytes = int64(capacity.OneGiB * 101) // 101 GiB (rounded up)
1960+
volume.SizeBytes = int64(capacity.OneGiB * 101) // 101 GiB
1961+
createRequest.UnixPermissions = "0777"
1962+
volume.UnixPermissions = "0777"
1963+
1964+
mockAPI.EXPECT().RefreshGCNVResources(ctx).Return(nil).Times(1)
1965+
mockAPI.EXPECT().VolumeExists(ctx, volConfig).Return(false, nil, nil).Times(1)
1966+
1967+
mockAPI.EXPECT().CapacityPoolsForStoragePool(ctx, storagePool,
1968+
api.ServiceLevelPremium, gomock.Any()).Return([]*api.CapacityPool{capacityPool}).Times(1)
1969+
mockAPI.EXPECT().FilterCapacityPoolsOnTopology(ctx, []*api.CapacityPool{capacityPool}, volConfig.RequisiteTopologies, volConfig.PreferredTopologies).Return([]*api.CapacityPool{capacityPool}).Times(1)
1970+
mockAPI.EXPECT().CreateVolume(ctx, createRequest).Return(volume, nil).Times(1)
1971+
1972+
mockAPI.EXPECT().WaitForVolumeState(ctx, volume, api.VolumeStateReady, []string{api.VolumeStateError},
1973+
driver.volumeCreateTimeout).Return(api.VolumeStateReady, nil).Times(1)
1974+
1975+
result := driver.Create(ctx, volConfig, storagePool, nil)
1976+
1977+
assert.NoError(t, result, "create failed")
1978+
assert.Equal(t, createRequest.SizeBytes, int64(capacity.OneGiB*101), "request size mismatch")
1979+
assert.Equal(t, volConfig.Size, strconv.FormatInt(int64(capacity.OneGiB*101), 10), "config size mismatch") // 101 GiB
1980+
assert.Equal(t, volume.FullName, volConfig.InternalID, "internal ID not set on volConfig")
1981+
}
1982+
19411983
func TestCreate_ServiceLevelFlex(t *testing.T) {
19421984
mockAPI, driver := newMockGCNVDriver(t)
19431985

@@ -6490,6 +6532,25 @@ func TestResize(t *testing.T) {
64906532
assert.Equal(t, strconv.FormatUint(newSize, 10), volConfig.Size, "size mismatch")
64916533
}
64926534

6535+
func TestResize_SizeNotGibMultiple(t *testing.T) {
6536+
mockAPI, driver := newMockGCNVDriver(t)
6537+
6538+
driver.initializeTelemetry(ctx, api.BackendUUID)
6539+
6540+
volConfig, volume := getStructsForDestroyNFSVolume(ctx, driver)
6541+
newSize := (capacity.OneGiB * 100) + 1 // 100 GiB + 1 byte
6542+
expectedSize := capacity.OneGiB * 101 // 101 GiB (rounded up)
6543+
6544+
mockAPI.EXPECT().RefreshGCNVResources(ctx).Return(nil).Times(1)
6545+
mockAPI.EXPECT().Volume(ctx, volConfig).Return(volume, nil).Times(1)
6546+
mockAPI.EXPECT().ResizeVolume(ctx, volume, int64(expectedSize)).Return(nil).Times(1)
6547+
6548+
result := driver.Resize(ctx, volConfig, newSize)
6549+
6550+
assert.Nil(t, result, "not nil")
6551+
assert.Equal(t, strconv.FormatUint(expectedSize, 10), volConfig.Size, "size mismatch")
6552+
}
6553+
64936554
func TestResize_DiscoveryFailed(t *testing.T) {
64946555
mockAPI, driver := newMockGCNVDriver(t)
64956556

0 commit comments

Comments
 (0)