summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKubeEdge Bot <48982446+kubeedge-bot@users.noreply.github.com>2024-08-14 11:45:25 +0800
committerGitHub <noreply@github.com>2024-08-14 11:45:25 +0800
commitc3ad021a2e9f659f2af6b2ea93998d7a50134540 (patch)
treeb9c72e05754f0d108949f7762f7fd7f38c173f4f
parentMerge pull request #5793 from fujitatomoya/typo-fixes-github-workflow (diff)
parentTest coverage for csidriver (diff)
downloadkubeedge-c3ad021a2e9f659f2af6b2ea93998d7a50134540.tar.gz
Merge pull request #5795 from 1Shubham7/listener
Added tests for `cloud/pkg/csidriver` pkg
-rw-r--r--cloud/pkg/csidriver/controllerserver_test.go173
-rw-r--r--cloud/pkg/csidriver/identityserver_test.go116
-rw-r--r--cloud/pkg/csidriver/uds_test.go39
-rw-r--r--cloud/pkg/csidriver/utils_test.go189
4 files changed, 517 insertions, 0 deletions
diff --git a/cloud/pkg/csidriver/controllerserver_test.go b/cloud/pkg/csidriver/controllerserver_test.go
new file mode 100644
index 000000000..618c24f7a
--- /dev/null
+++ b/cloud/pkg/csidriver/controllerserver_test.go
@@ -0,0 +1,173 @@
+/*
+Copyright 2024 The KubeEdge 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 csidriver
+
+import (
+ "testing"
+
+ "github.com/container-storage-interface/spec/lib/go/csi"
+ "github.com/stretchr/testify/assert"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+func TestNewControllerServer(t *testing.T) {
+ assert := assert.New(t)
+
+ nodeID := "test-node"
+ kubeEdgeEndpoint := "http://localhost:8080/test"
+
+ cs := newControllerServer(nodeID, kubeEdgeEndpoint)
+ assert.NotNil(cs)
+
+ assert.Equal(nodeID, cs.nodeID)
+ assert.Equal(kubeEdgeEndpoint, cs.kubeEdgeEndpoint)
+
+ expectedCaps := getControllerServiceCapabilities(
+ []csi.ControllerServiceCapability_RPC_Type{
+ csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME,
+ csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME,
+ })
+ assert.Equal(expectedCaps, cs.caps)
+
+ assert.Equal(csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME,
+ cs.caps[0].GetRpc().GetType())
+ assert.Equal(csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME,
+ cs.caps[1].GetRpc().GetType())
+}
+
+func TestValidateVolumeCapabilities(t *testing.T) {
+ assert := assert.New(t)
+
+ cs := &controllerServer{
+ nodeID: "test-node",
+ kubeEdgeEndpoint: "http://localhost:8080/test",
+ }
+
+ // Test case 1: Invalid request (missing volume ID)
+ invalidReq := &csi.ValidateVolumeCapabilitiesRequest{
+ VolumeCapabilities: []*csi.VolumeCapability{
+ {
+ AccessType: &csi.VolumeCapability_Mount{
+ Mount: &csi.VolumeCapability_MountVolume{},
+ },
+ AccessMode: &csi.VolumeCapability_AccessMode{
+ Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
+ },
+ },
+ },
+ }
+
+ result, err := cs.ValidateVolumeCapabilities(context.Background(), invalidReq)
+ assert.Error(err)
+ assert.Nil(result)
+ assert.Equal(codes.InvalidArgument, status.Code(err))
+ assert.Contains(err.Error(), "Volume ID cannot be empty")
+
+ // Test case 2: Invalid request (missing volume capabilities)
+ invalidReq2 := &csi.ValidateVolumeCapabilitiesRequest{
+ VolumeId: "test-volume-id",
+ }
+
+ result, err = cs.ValidateVolumeCapabilities(context.Background(), invalidReq2)
+ assert.Error(err)
+ assert.Nil(result)
+ assert.Equal(codes.InvalidArgument, status.Code(err))
+ assert.Contains(err.Error(), "test-volume-id")
+
+ // Test case 3: Valid request
+ validReq := &csi.ValidateVolumeCapabilitiesRequest{
+ VolumeId: "test-volume-id",
+ VolumeCapabilities: []*csi.VolumeCapability{
+ {
+ AccessType: &csi.VolumeCapability_Mount{
+ Mount: &csi.VolumeCapability_MountVolume{},
+ },
+ AccessMode: &csi.VolumeCapability_AccessMode{
+ Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
+ },
+ },
+ },
+ }
+
+ result, err = cs.ValidateVolumeCapabilities(context.Background(), validReq)
+ assert.NoError(err)
+ assert.NotNil(result)
+ assert.NotNil(result.Confirmed)
+ assert.NotEmpty(result.Confirmed.VolumeCapabilities)
+ assert.Equal(csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
+ result.Confirmed.VolumeCapabilities[0].AccessMode.Mode)
+}
+
+func TestControllerGetCapabilities(t *testing.T) {
+ assert := assert.New(t)
+
+ cs := &controllerServer{
+ nodeID: "test-node",
+ kubeEdgeEndpoint: "http://localhost:8080/test",
+ caps: getControllerServiceCapabilities(
+ []csi.ControllerServiceCapability_RPC_Type{
+ csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME,
+ csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME,
+ },
+ ),
+ }
+
+ req := &csi.ControllerGetCapabilitiesRequest{}
+ resp, err := cs.ControllerGetCapabilities(context.Background(), req)
+ assert.NoError(err)
+ assert.NotNil(resp)
+
+ expectedCaps := []csi.ControllerServiceCapability_RPC_Type{
+ csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME,
+ csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME,
+ }
+
+ for i, cap := range resp.Capabilities {
+ assert.Equal(expectedCaps[i], cap.GetRpc().Type,
+ "Capability %d should be %v", i, expectedCaps[i])
+ }
+}
+
+func TestGetControllerServiceCapabilities(t *testing.T) {
+ assert := assert.New(t)
+
+ // Test case 1: Empty capability list
+ emptyCaps := getControllerServiceCapabilities([]csi.ControllerServiceCapability_RPC_Type{})
+ assert.Empty(emptyCaps)
+
+ // Test case 2: One capability
+ singleCapType := csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME
+ singleCap := getControllerServiceCapabilities([]csi.ControllerServiceCapability_RPC_Type{singleCapType})
+
+ assert.Equal(singleCapType, singleCap[0].GetRpc().Type)
+
+ // Test case 3: Multiple capabilities
+ multiCapTypes := []csi.ControllerServiceCapability_RPC_Type{
+ csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME,
+ csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME,
+ csi.ControllerServiceCapability_RPC_LIST_VOLUMES,
+ }
+ multiCaps := getControllerServiceCapabilities(multiCapTypes)
+
+ assert.Len(multiCaps, 3)
+ for i, capType := range multiCapTypes {
+ assert.Equal(capType, multiCaps[i].GetRpc().Type,
+ "Capability %d should be %v", i, capType)
+ }
+}
diff --git a/cloud/pkg/csidriver/identityserver_test.go b/cloud/pkg/csidriver/identityserver_test.go
new file mode 100644
index 000000000..fd0bb6fa1
--- /dev/null
+++ b/cloud/pkg/csidriver/identityserver_test.go
@@ -0,0 +1,116 @@
+/*
+Copyright 2024 The KubeEdge 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 csidriver
+
+import (
+ "context"
+ "testing"
+
+ "github.com/container-storage-interface/spec/lib/go/csi"
+ "github.com/stretchr/testify/assert"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+func TestNewIdentityServer(t *testing.T) {
+ assert := assert.New(t)
+
+ name := "test-server"
+ version := "v1.0.0"
+
+ ids := newIdentityServer(name, version)
+
+ assert.NotNil(ids)
+ assert.Equal(name, ids.name)
+ assert.Equal(version, ids.version)
+}
+
+func TestGetPluginInfo(t *testing.T) {
+ assert := assert.New(t)
+
+ testCases := []struct {
+ name string
+ version string
+ expectError bool
+ errorCode codes.Code
+ }{
+ {
+ name: "test-driver",
+ version: "v1.0.0",
+ expectError: false,
+ errorCode: codes.OK,
+ },
+ {
+ name: "",
+ version: "v1.0.0",
+ expectError: true,
+ errorCode: codes.Unavailable,
+ },
+ {
+ name: "test-driver",
+ version: "",
+ expectError: true,
+ errorCode: codes.Unavailable,
+ },
+ {
+ name: "",
+ version: "",
+ expectError: true,
+ errorCode: codes.Unavailable,
+ },
+ }
+
+ for _, tc := range testCases {
+ ids := newIdentityServer(tc.name, tc.version)
+ result, err := ids.GetPluginInfo(context.Background(), &csi.GetPluginInfoRequest{})
+
+ if tc.expectError {
+ assert.Error(err)
+ assert.Equal(tc.errorCode, status.Code(err))
+ } else {
+ assert.NoError(err)
+ assert.NotNil(result)
+ assert.Equal(tc.name, result.Name)
+ assert.Equal(tc.version, result.VendorVersion)
+ }
+ }
+}
+
+func TestProbe(t *testing.T) {
+ assert := assert.New(t)
+
+ ids := newIdentityServer("test-driver", "v1.0.0")
+ resp, err := ids.Probe(context.Background(), &csi.ProbeRequest{})
+
+ assert.NoError(err)
+ assert.NotNil(resp)
+}
+
+func TestGetPluginCapabilities(t *testing.T) {
+ assert := assert.New(t)
+
+ ids := newIdentityServer("test-driver", "v1.0.0")
+ result, err := ids.GetPluginCapabilities(context.Background(), &csi.GetPluginCapabilitiesRequest{})
+
+ assert.NoError(err)
+ assert.NotNil(result)
+ assert.Len(result.Capabilities, 1)
+
+ capabilities := result.Capabilities[0]
+ assert.NotNil(capabilities.GetService())
+ assert.Equal(csi.PluginCapability_Service_CONTROLLER_SERVICE, capabilities.GetService().Type)
+}
diff --git a/cloud/pkg/csidriver/uds_test.go b/cloud/pkg/csidriver/uds_test.go
new file mode 100644
index 000000000..dafd118be
--- /dev/null
+++ b/cloud/pkg/csidriver/uds_test.go
@@ -0,0 +1,39 @@
+/*
+Copyright 2024 The KubeEdge 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 csidriver
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestNewUnixDomainSocket(t *testing.T) {
+ assert := assert.New(t)
+
+ // Using default buffer size
+ us := NewUnixDomainSocket("/tmp/test.sock")
+ assert.NotNil(us)
+ assert.Equal("/tmp/test.sock", us.filename)
+ assert.Equal(DefaultBufferSize, us.buffersize)
+
+ // Using custom buffer size
+ us = NewUnixDomainSocket("/tmp/test.sock", 2048)
+ assert.NotNil(us)
+ assert.Equal("/tmp/test.sock", us.filename)
+ assert.Equal(2048, us.buffersize)
+}
diff --git a/cloud/pkg/csidriver/utils_test.go b/cloud/pkg/csidriver/utils_test.go
new file mode 100644
index 000000000..3fe5189ed
--- /dev/null
+++ b/cloud/pkg/csidriver/utils_test.go
@@ -0,0 +1,189 @@
+/*
+Copyright 2024 The KubeEdge 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 csidriver
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+
+ "github.com/kubeedge/beehive/pkg/core/model"
+)
+
+func TestParseEndpoint(t *testing.T) {
+ assert := assert.New(t)
+
+ testCases := []struct {
+ input string
+ expectedStrOne string
+ expectedStrTwo string
+ expectError bool
+ }{
+ {
+ input: "unix:///tmp/test.sock",
+ expectedStrOne: "unix",
+ expectedStrTwo: "/tmp/test.sock",
+ expectError: false,
+ },
+ {
+ input: "unix://tmp/test.sock",
+ expectedStrOne: "unix",
+ expectedStrTwo: "tmp/test.sock",
+ expectError: false,
+ },
+ {
+ input: "tcp://127.0.0.1:8080",
+ expectedStrOne: "tcp",
+ expectedStrTwo: "127.0.0.1:8080",
+ expectError: false,
+ },
+ {
+ input: "/tmp/test.sock",
+ expectedStrOne: "",
+ expectedStrTwo: "",
+ expectError: true,
+ },
+ {
+ input: "unix://",
+ expectedStrOne: "",
+ expectedStrTwo: "",
+ expectError: true,
+ },
+ }
+
+ for _, tc := range testCases {
+ firstStr, secondStr, err := parseEndpoint(tc.input)
+ if tc.expectError {
+ assert.Error(err)
+ } else {
+ assert.NoError(err)
+ assert.Equal(tc.expectedStrOne, firstStr)
+ assert.Equal(tc.expectedStrTwo, secondStr)
+ }
+ }
+}
+
+func TestBuildResource(t *testing.T) {
+ assert := assert.New(t)
+
+ tests := []struct {
+ name string
+ nodeID string
+ namespace string
+ resourceType string
+ resourceID string
+ want string
+ wantErr bool
+ }{
+ {
+ name: "Valid resource without resourceID",
+ nodeID: "node1",
+ namespace: "default",
+ resourceType: "volume",
+ resourceID: "",
+ want: "node/node1/default/volume",
+ wantErr: false,
+ },
+ {
+ name: "Valid resource with resourceID",
+ nodeID: "node1",
+ namespace: "default",
+ resourceType: "volume",
+ resourceID: "vol1",
+ want: "node/node1/default/volume/vol1",
+ wantErr: false,
+ },
+ {
+ name: "Resource without nodeID",
+ nodeID: "",
+ namespace: "default",
+ resourceType: "volume",
+ resourceID: "",
+ want: "",
+ wantErr: true,
+ },
+ {
+ name: "Resource missing namespace",
+ nodeID: "node1",
+ namespace: "",
+ resourceType: "volume",
+ resourceID: "",
+ want: "",
+ wantErr: true,
+ },
+ {
+ name: "Resource without resourceType",
+ nodeID: "node1",
+ namespace: "default",
+ resourceType: "",
+ resourceID: "",
+ want: "",
+ wantErr: true,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ got, err := buildResource(test.nodeID, test.namespace, test.resourceType, test.resourceID)
+ if test.wantErr {
+ assert.Error(err)
+ } else {
+ assert.NoError(err)
+ assert.Equal(test.want, got)
+ }
+ })
+ }
+}
+
+func TestExtractMessage(t *testing.T) {
+ assert := assert.New(t)
+
+ tests := []struct {
+ name string
+ context string
+ wantErr bool
+ }{
+ {
+ name: "Valid JSON",
+ context: `{"header":{"namespace":"default"},"router":{"resource":"test"},"content":"test"}`,
+ wantErr: false,
+ },
+ {
+ name: "Invalid JSON",
+ context: `{invalid json}`,
+ wantErr: true,
+ },
+ {
+ name: "Empty context",
+ context: "",
+ wantErr: true,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ msg, err := extractMessage(test.context)
+ if test.wantErr {
+ assert.Error(err)
+ } else {
+ assert.NoError(err)
+ assert.NotNil(msg)
+ assert.IsType(&model.Message{}, msg)
+ }
+ })
+ }
+}