Skip to content

Commit

Permalink
Merge e37e268 into ed7d484
Browse files Browse the repository at this point in the history
  • Loading branch information
ZeroMagic committed Feb 11, 2020
2 parents ed7d484 + e37e268 commit 1e38509
Show file tree
Hide file tree
Showing 8 changed files with 301 additions and 26 deletions.
2 changes: 1 addition & 1 deletion pkg/azuredisk/controllerserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
requestGiB = defaultDiskSize
}

maxVolSize := int(req.GetCapacityRange().GetLimitBytes())
maxVolSize := int(volumehelper.RoundUpGiB(req.GetCapacityRange().GetLimitBytes()))
if (maxVolSize > 0) && (maxVolSize < requestGiB) {
return nil, status.Error(codes.InvalidArgument, "After round-up, volume size exceeds the limit specified")
}
Expand Down
149 changes: 149 additions & 0 deletions pkg/azuredisk/controllerserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,39 @@ limitations under the License.
package azuredisk

import (
"context"
"fmt"
"reflect"
"testing"

"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute"
"github.com/container-storage-interface/spec/lib/go/csi"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

volumehelper "sigs.k8s.io/azuredisk-csi-driver/pkg/util"
)

var (
testVolumeName = "unit-test-volume"

stdCapacityRange = &csi.CapacityRange{
RequiredBytes: volumehelper.GiBToBytes(10),
LimitBytes: volumehelper.GiBToBytes(15),
}
)

func checkTestError(t *testing.T, expectedErrCode codes.Code, err error) {
s, ok := status.FromError(err)
if !ok {
t.Errorf("could not get error status from err: %v", s)
}
if s.Code() != expectedErrCode {
t.Errorf("expected error code: %v, actual: %v, err: %v", expectedErrCode, s.Code(), err)
}
}

func TestGetCachingMode(t *testing.T) {
tests := []struct {
options map[string]string
Expand Down Expand Up @@ -129,3 +153,128 @@ func TestGetEntriesAndNextToken(t *testing.T) {
}
}
}

func TestCreateVolume(t *testing.T) {
d := NewFakeDriver()

tests := []struct {
desc string
req *csi.CreateVolumeRequest
expectedResp *csi.CreateVolumeResponse
expectedErrCode codes.Code
}{
{
desc: "fail with no name",
req: &csi.CreateVolumeRequest{
Name: "",
},
expectedResp: nil,
expectedErrCode: codes.InvalidArgument,
},
{
desc: "fail with no volume capabilities",
req: &csi.CreateVolumeRequest{
Name: testVolumeName,
},
expectedResp: nil,
expectedErrCode: codes.InvalidArgument,
},
{
desc: "fail with the invalid capabilities",
req: &csi.CreateVolumeRequest{
Name: testVolumeName,
VolumeCapabilities: createVolumeCapabilities(csi.VolumeCapability_AccessMode_UNKNOWN),
},
expectedResp: nil,
expectedErrCode: codes.InvalidArgument,
},
{
desc: "fail with the invalid requested size",
req: &csi.CreateVolumeRequest{
Name: testVolumeName,
VolumeCapabilities: stdVolumeCapabilities,
CapacityRange: &csi.CapacityRange{
RequiredBytes: volumehelper.GiBToBytes(20),
LimitBytes: volumehelper.GiBToBytes(15),
},
},
expectedResp: nil,
expectedErrCode: codes.InvalidArgument,
},
{
desc: "success standard",
req: &csi.CreateVolumeRequest{
Name: testVolumeName,
VolumeCapabilities: stdVolumeCapabilities,
CapacityRange: stdCapacityRange,
},
expectedResp: &csi.CreateVolumeResponse{
Volume: &csi.Volume{
VolumeId: fmt.Sprintf(managedDiskPath, d.cloud.SubscriptionID, d.cloud.ResourceGroup, testVolumeName),
CapacityBytes: stdCapacityRange.RequiredBytes,
VolumeContext: nil,
ContentSource: &csi.VolumeContentSource{},
AccessibleTopology: []*csi.Topology{
{
Segments: map[string]string{topologyKey: ""},
},
},
},
},
},
}

for _, test := range tests {
result, err := d.CreateVolume(context.Background(), test.req)
if err != nil {
checkTestError(t, test.expectedErrCode, err)
}
if !reflect.DeepEqual(result, test.expectedResp) {
t.Errorf("input request: %v, CreateVolume result: %v, expected: %v", test.req, result, test.expectedResp)
}
}
}

func TestDeleteVolume(t *testing.T) {
d := NewFakeDriver()

tests := []struct {
desc string
req *csi.DeleteVolumeRequest
expectedResp *csi.DeleteVolumeResponse
expectedErrCode codes.Code
}{
{
desc: "fail with no volume id",
req: &csi.DeleteVolumeRequest{
VolumeId: "",
},
expectedResp: nil,
expectedErrCode: codes.InvalidArgument,
},
{
desc: "fail with the invalid diskURI",
req: &csi.DeleteVolumeRequest{
VolumeId: "123",
},
expectedResp: &csi.DeleteVolumeResponse{},
},
{
desc: "success standard",
req: &csi.DeleteVolumeRequest{
VolumeId: fmt.Sprintf(managedDiskPath, d.cloud.SubscriptionID, d.cloud.ResourceGroup, testVolumeName),
},
expectedResp: &csi.DeleteVolumeResponse{},
},
}

for _, test := range tests {
result, err := d.DeleteVolume(context.Background(), test.req)
if err != nil {
checkTestError(t, test.expectedErrCode, err)
}
if !reflect.DeepEqual(result, test.expectedResp) {
t.Errorf("input request: %v, DeleteVolume result: %v, expected: %v", test.req, result, test.expectedResp)
}
}
}
109 changes: 109 additions & 0 deletions pkg/azuredisk/fake-azuredisk.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
Copyright 2020 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package azuredisk

import (
"os"

"github.com/container-storage-interface/spec/lib/go/csi"

"k8s.io/klog"

csicommon "sigs.k8s.io/azuredisk-csi-driver/pkg/csi-common"
"sigs.k8s.io/azuredisk-csi-driver/pkg/mounter"
"sigs.k8s.io/azuredisk-csi-driver/test/utils/credentials"
)

const (
fakeDriverName = "fake.disk.csi.azure.com"
fakeNodeID = "fakeNodeID"
fakeDriverVersion = "fakeDriverVersion"
)

var (
stdVolumeCapability = &csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
},
}
stdVolumeCapabilities = []*csi.VolumeCapability{
stdVolumeCapability,
}
)

func NewFakeDriver() *Driver {
_, err := credentials.CreateAzureCredentialFile(false)
defer func() {
err := credentials.DeleteAzureCredentialFile()
klog.Fatalln("NewFakeDriver: failed to delete auzre credential file: ", err)
}()
if err != nil {
klog.Fatalln("NewFakeDriver: failed to create auzre credential file: ", err)
}

os.Setenv("AZURE_CREDENTIAL_FILE", credentials.TempAzureCredentialFilePath)

driver := Driver{}
driver.Name = fakeDriverName
driver.Version = fakeDriverVersion
driver.NodeID = fakeNodeID
driver.CSIDriver = *csicommon.NewFakeCSIDriver()

cloud, err := GetCloudProvider()
if err != nil {
klog.Fatalln("NewFakeDriver: failed to get Azure Cloud Provider")
}
driver.cloud = cloud
driver.mounter = mounter.NewSafeMounter()

driver.AddControllerServiceCapabilities(
[]csi.ControllerServiceCapability_RPC_Type{
csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME,
csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME,
csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT,
csi.ControllerServiceCapability_RPC_LIST_SNAPSHOTS,
csi.ControllerServiceCapability_RPC_CLONE_VOLUME,
csi.ControllerServiceCapability_RPC_EXPAND_VOLUME,
})
driver.AddVolumeCapabilityAccessModes([]csi.VolumeCapability_AccessMode_Mode{csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER})
driver.AddNodeServiceCapabilities([]csi.NodeServiceCapability_RPC_Type{
csi.NodeServiceCapability_RPC_STAGE_UNSTAGE_VOLUME,
csi.NodeServiceCapability_RPC_EXPAND_VOLUME,
})

return &driver
}

func createVolumeCapabilities(accessMode csi.VolumeCapability_AccessMode_Mode) []*csi.VolumeCapability {
return []*csi.VolumeCapability{
createVolumeCapability(accessMode),
}
}

func createVolumeCapability(accessMode csi.VolumeCapability_AccessMode_Mode) *csi.VolumeCapability {
return &csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: accessMode,
},
}
}
22 changes: 3 additions & 19 deletions pkg/csi-common/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,15 @@ import (
"google.golang.org/grpc/status"
)

const (
fakeDriverName = "fake"
fakeNodeID = "fakeNodeID"
)

var (
vendorVersion = "0.3.0"
)

func NewFakeDriver() *CSIDriver {

driver := NewCSIDriver(fakeDriverName, vendorVersion, fakeNodeID)

return driver
}

func TestNewFakeDriver(t *testing.T) {
func TestNewFakeCSIDriver(t *testing.T) {
// Test New fake driver with invalid arguments.
d := NewCSIDriver("", vendorVersion, fakeNodeID)
assert.Nil(t, d)
}

func TestGetVolumeCapabilityAccessModes(t *testing.T) {

d := NewFakeDriver()
d := NewFakeCSIDriver()

// Test no volume access modes.
// REVISIT: Do we need to support any default access modes.
Expand All @@ -64,7 +48,7 @@ func TestGetVolumeCapabilityAccessModes(t *testing.T) {
}

func TestValidateControllerServiceRequest(t *testing.T) {
d := NewFakeDriver()
d := NewFakeCSIDriver()

// Valid requests which require no capabilities
err := d.ValidateControllerServiceRequest(csi.ControllerServiceCapability_RPC_UNKNOWN)
Expand Down
33 changes: 33 additions & 0 deletions pkg/csi-common/fake-driver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
Copyright 2020 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package csicommon

const (
fakeCSIDriverName = "fake"
fakeNodeID = "fakeNodeID"
)

var (
vendorVersion = "0.3.0"
)

func NewFakeCSIDriver() *CSIDriver {

driver := NewCSIDriver(fakeCSIDriverName, vendorVersion, fakeNodeID)

return driver
}
4 changes: 2 additions & 2 deletions pkg/csi-common/identityserver-default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ import (
)

func TestGetPluginInfo(t *testing.T) {
d := NewFakeDriver()
d := NewFakeCSIDriver()

ids := NewDefaultIdentityServer(d)

req := csi.GetPluginInfoRequest{}
resp, err := ids.GetPluginInfo(context.Background(), &req)
assert.NoError(t, err)
assert.Equal(t, resp.GetName(), fakeDriverName)
assert.Equal(t, resp.GetName(), fakeCSIDriverName)
assert.Equal(t, resp.GetVendorVersion(), vendorVersion)
}
4 changes: 2 additions & 2 deletions pkg/csi-common/nodeserver-default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
)

func TestNodeGetInfo(t *testing.T) {
d := NewFakeDriver()
d := NewFakeCSIDriver()

ns := NewDefaultNodeServer(d)

Expand All @@ -37,7 +37,7 @@ func TestNodeGetInfo(t *testing.T) {
}

func TestNodeGetCapabilities(t *testing.T) {
d := NewFakeDriver()
d := NewFakeCSIDriver()

ns := NewDefaultNodeServer(d)

Expand Down

0 comments on commit 1e38509

Please sign in to comment.