diff --git a/spectrocloud/resource_workspace_test.go b/spectrocloud/resource_workspace_test.go index c398fcb8..db3449a3 100644 --- a/spectrocloud/resource_workspace_test.go +++ b/spectrocloud/resource_workspace_test.go @@ -105,61 +105,190 @@ func TestToWorkspace(t *testing.T) { } } -func prepareResourceWorkspace() *schema.ResourceData { +func prepareBaseWorkspaceSchema() *schema.ResourceData { + // Get an initialized ResourceData from resourceWorkspace d := resourceWorkspace().TestResourceData() - d.SetId("test-ws-id") - _ = d.Set("name", "test-ws") - _ = d.Set("tags", []string{"dev:test"}) - _ = d.Set("description", "test description") - var c []interface{} - c = append(c, map[string]interface{}{ - "uid": "test-cluster-id", - }) - var bp []interface{} - bp = append(bp, map[string]interface{}{ - "prefix": "test-prefix", - "backup_location_id": "test-location-id", - "schedule": "0 1 * * *", - "expiry_in_hour": 1, - "include_disks": false, - "include_cluster_resources": true, - "namespaces": []string{"ns1", "ns2"}, - "cluster_uids": []string{"cluster1", "cluster2"}, - "include_all_clusters": false, - }) - _ = d.Set("backup_policy", bp) - var subjects []interface{} - subjects = append(subjects, map[string]interface{}{ - "type": "User", - "name": "test-name-user", - "namespace": "ns1", - }) - var rbacs []interface{} - rbacs = append(rbacs, map[string]interface{}{ - "type": "RoleBinding", - "namespace": "ns1", - "role": map[string]string{ - "test": "admin", - }, - "subjects": subjects, - }) - _ = d.Set("cluster_rbac_binding", rbacs) - var ns []interface{} - ns = append(ns, map[string]interface{}{ - "name": "test-ns-name", - "resource_allocation": map[string]string{ - "test": "test", - }, - "images_blacklist": []string{"test-list"}, - }) - _ = d.Set("namespaces", ns) + // Set values for the required and optional fields + if err := d.Set("name", "Default"); err != nil { + panic(err) // Handle the error as appropriate in your test setup + } + if err := d.Set("description", "A workspace for testing"); err != nil { + panic(err) + } + //Set the clusters field with ClusterRefs + clusters := []interface{}{ + map[string]interface{}{ + "uid": "Default", + }, + } + if err := d.Set("clusters", clusters); err != nil { + panic(err) + } return d } +func TestResourceWorkspaceCreate(t *testing.T) { + ctx := context.Background() + resourceData := prepareBaseWorkspaceSchema() + + // Call the function + diags := resourceWorkspaceCreate(ctx, resourceData, unitTestMockAPIClient) + + // Assertions + assert.Equal(t, 0, len(diags)) + +} + +func TestResourceWorkspaceRead(t *testing.T) { + ctx := context.Background() + resourceData := prepareBaseWorkspaceSchema() + + // Call the function + diags := resourceWorkspaceRead(ctx, resourceData, unitTestMockAPIClient) + + // Assertions + assert.Equal(t, 0, len(diags)) + +} + +func TestResourceWorkspaceUpdate(t *testing.T) { + ctx := context.Background() + resourceData := prepareBaseWorkspaceSchema() + + // Call the function + diags := resourceWorkspaceUpdate(ctx, resourceData, unitTestMockAPIClient) + + // Assertions + assert.Equal(t, 0, len(diags)) + +} + func TestResourceWorkspaceDelete(t *testing.T) { - d := prepareResourceWorkspace() - var ctx context.Context - diags := resourceWorkspaceDelete(ctx, d, unitTestMockAPIClient) - assert.Empty(t, diags) + ctx := context.Background() + resourceData := prepareBaseWorkspaceSchema() + resourceData.SetId("12763471256725") + + // Call the function + diags := resourceWorkspaceDelete(ctx, resourceData, unitTestMockAPIClient) + + // Assertions + assert.Equal(t, 0, len(diags)) + +} + +func TestResourceWorkspaceCreateNegative(t *testing.T) { + ctx := context.Background() + resourceData := prepareBaseWorkspaceSchema() + + // Call the function + diags := resourceWorkspaceCreate(ctx, resourceData, unitTestMockAPINegativeClient) + + // Assertions + if assert.NotEmpty(t, diags) { // Check that diags is not empty + assert.Contains(t, diags[0].Summary, "workspaces already exist") // Verify the error message + } + +} + +func TestResourceWorkspaceReadNegative(t *testing.T) { + ctx := context.Background() + resourceData := prepareBaseWorkspaceSchema() + resourceData.SetId("12763471256725") + + // Call the function + diags := resourceWorkspaceRead(ctx, resourceData, unitTestMockAPINegativeClient) + + // Assertions + if assert.NotEmpty(t, diags) { // Check that diags is not empty + assert.Contains(t, diags[0].Summary, "workspaces not found") // Verify the error message + } + +} + +func TestResourceWorkspaceUpdateNegative(t *testing.T) { + ctx := context.Background() + resourceData := prepareBaseWorkspaceSchema() + resourceData.SetId("12763471256725") + + // Call the function + diags := resourceWorkspaceUpdate(ctx, resourceData, unitTestMockAPINegativeClient) + + // Assertions + if assert.NotEmpty(t, diags) { // Check that diags is not empty + assert.Contains(t, diags[0].Summary, "workspaces not found") // Verify the error message + } } + +func TestResourceWorkspaceDeleteNegative(t *testing.T) { + ctx := context.Background() + resourceData := prepareBaseWorkspaceSchema() + resourceData.SetId("12763471256725") + + // Call the function + diags := resourceWorkspaceDelete(ctx, resourceData, unitTestMockAPINegativeClient) + + // Assertions + if assert.NotEmpty(t, diags) { // Check that diags is not empty + assert.Contains(t, diags[0].Summary, "workspaces not found") // Verify the error message + } +} + +//func prepareResourceWorkspace() *schema.ResourceData { +// d := resourceWorkspace().TestResourceData() +// d.SetId("test-ws-id") +// _ = d.Set("name", "test-ws") +// _ = d.Set("tags", []string{"dev:test"}) +// _ = d.Set("description", "test description") +// var c []interface{} +// c = append(c, map[string]interface{}{ +// "uid": "test-cluster-id", +// }) +// var bp []interface{} +// bp = append(bp, map[string]interface{}{ +// "prefix": "test-prefix", +// "backup_location_id": "test-location-id", +// "schedule": "0 1 * * *", +// "expiry_in_hour": 1, +// "include_disks": false, +// "include_cluster_resources": true, +// "namespaces": []string{"ns1", "ns2"}, +// "cluster_uids": []string{"cluster1", "cluster2"}, +// "include_all_clusters": false, +// }) +// _ = d.Set("backup_policy", bp) +// var subjects []interface{} +// subjects = append(subjects, map[string]interface{}{ +// "type": "User", +// "name": "test-name-user", +// "namespace": "ns1", +// }) +// var rbacs []interface{} +// rbacs = append(rbacs, map[string]interface{}{ +// "type": "RoleBinding", +// "namespace": "ns1", +// "role": map[string]string{ +// "test": "admin", +// }, +// "subjects": subjects, +// }) +// _ = d.Set("cluster_rbac_binding", rbacs) +// var ns []interface{} +// ns = append(ns, map[string]interface{}{ +// "name": "test-ns-name", +// "resource_allocation": map[string]string{ +// "test": "test", +// }, +// "images_blacklist": []string{"test-list"}, +// }) +// _ = d.Set("namespaces", ns) +// +// return d +//} +// +//func TestResourceWorkspaceDelete(t *testing.T) { +// d := prepareResourceWorkspace() +// var ctx context.Context +// diags := resourceWorkspaceDelete(ctx, d, unitTestMockAPIClient) +// assert.Empty(t, diags) +//} diff --git a/tests/mockApiServer/apiServerMock.go b/tests/mockApiServer/apiServerMock.go index 7456947d..754f2b2c 100644 --- a/tests/mockApiServer/apiServerMock.go +++ b/tests/mockApiServer/apiServerMock.go @@ -108,7 +108,7 @@ func init() { routes.IPPoolRoutes, routes.MacrosRoutes, routes.TenantRoutes, - routes.WorkSpaceRoutes, + routes.WorkspaceRoutes, routes.AlertRoutes, routes.ClusterGroupRoutes, ) @@ -127,5 +127,6 @@ func init() { routes.ClusterCommonNegativeRoutes, routes.MacrosNegativeRoutes, routes.TenantNegativeRoutes, + routes.WorkspaceNegativeRoutes, ) } diff --git a/tests/mockApiServer/routes/mockWorkSpace.go b/tests/mockApiServer/routes/mockWorkSpace.go index 91afb5c9..3eb3b546 100644 --- a/tests/mockApiServer/routes/mockWorkSpace.go +++ b/tests/mockApiServer/routes/mockWorkSpace.go @@ -2,124 +2,213 @@ package routes import ( "github.com/spectrocloud/palette-sdk-go/api/models" + "net/http" + "strconv" ) -func WorkSpaceRoutes() []Route { +func getMockWorkspacePayload() *models.V1Workspace { + return &models.V1Workspace{ + Metadata: &models.V1ObjectMeta{ + Name: "Default", + UID: generateRandomStringUID(), + Annotations: map[string]string{ + "description": "An example workspace for testing", + }, + Labels: map[string]string{ + "env": "test", + }, + }, + Spec: &models.V1WorkspaceSpec{ + ClusterNamespaces: []*models.V1WorkspaceClusterNamespace{ + { + Image: nil, + IsRegex: false, + Name: "Default", + NamespaceResourceAllocation: &models.V1WorkspaceNamespaceResourceAllocation{ + ClusterResourceAllocations: []*models.V1ClusterResourceAllocation{ + { + ClusterUID: generateRandomStringUID(), + ResourceAllocation: nil, + }, + }, + DefaultResourceAllocation: &models.V1WorkspaceResourceAllocation{ + CPUCores: 1000, + MemoryMiB: 4, + }, + }, + }, + }, + ClusterRbacs: []*models.V1ClusterRbac{ + { + Metadata: &models.V1ObjectMeta{ + Name: "Default", + UID: generateRandomStringUID(), + }, + Spec: &models.V1ClusterRbacSpec{ + Bindings: []*models.V1ClusterRbacBinding{ + { + Namespace: "Default", + Type: "DefaultType", + Role: &models.V1ClusterRoleRef{ + Name: "Default", + Kind: "DefaultKind", + }, + }, + }, + RelatedObject: &models.V1RelatedObject{ + Kind: "DefaultKind", + Name: "Default", + UID: generateRandomStringUID(), + }, + }, + Status: &models.V1ClusterRbacStatus{ + Errors: []*models.V1ClusterResourceError{}, + }, + }, + }, + ClusterRefs: []*models.V1WorkspaceClusterRef{ + { + ClusterUID: generateRandomStringUID(), + }, + }, + Policies: &models.V1WorkspacePolicies{ + BackupPolicy: &models.V1WorkspaceBackupConfigEntity{ + BackupConfig: &models.V1ClusterBackupConfig{ + // Add relevant fields with dummy data for BackupConfig here + Schedule: &models.V1ClusterFeatureSchedule{ + ScheduledRunTime: "daily", + }, + BackupLocationName: "Default", // Keep backups for 7 days + }, + ClusterUids: []string{generateRandomStringUID()}, // Dummy cluster UIDs + IncludeAllClusters: true, + }, + }, + Quota: &models.V1WorkspaceQuota{ + ResourceAllocation: &models.V1WorkspaceResourceAllocation{ + // Add relevant fields with dummy data here + CPUCores: 1000, + MemoryMiB: 4, + }, + }, + }, + Status: &models.V1WorkspaceStatus{ + Errors: []*models.V1WorkspaceError{}, + }, + } +} + +func getMockWorkspaceBackUpPayload() *models.V1WorkspaceBackup { + return &models.V1WorkspaceBackup{ + Metadata: &models.V1ObjectMeta{ + Name: "Deafult-backup", + UID: generateRandomStringUID(), + Labels: map[string]string{"environment": "dev"}, + Annotations: map[string]string{"createdBy": "testUser"}, + }, + Spec: &models.V1WorkspaceBackupSpec{ + // Populate with dummy data for the Spec + Config: &models.V1WorkspaceBackupConfig{ + BackupConfig: &models.V1ClusterBackupConfig{ + // Add relevant fields with dummy data for BackupConfig here + Schedule: &models.V1ClusterFeatureSchedule{ + ScheduledRunTime: "daily", + }, + BackupLocationName: "Default", // Keep backups for 7 days + }, + ClusterUids: []string{generateRandomStringUID()}, // Dummy cluster UIDs + }, + WorkspaceUID: generateRandomStringUID(), // Keep backups for 7 days + }, + Status: &models.V1WorkspaceBackupStatus{}, + } +} + +func WorkspaceRoutes() []Route { return []Route{ { Method: "POST", Path: "/v1/workspaces", Response: ResponseData{ - StatusCode: 201, - Payload: map[string]string{"UID": "test-ws-1"}, + StatusCode: http.StatusCreated, + Payload: map[string]interface{}{"UID": generateRandomStringUID()}, + }, + }, + { + Method: "GET", + Path: "/v1/workspaces/{uid}", + Response: ResponseData{ + StatusCode: http.StatusOK, + Payload: getMockWorkspacePayload(), + }, + }, + { + Method: "GET", + Path: "/v1/workspaces/{uid}/backup", + Response: ResponseData{ + StatusCode: http.StatusOK, + Payload: getMockWorkspaceBackUpPayload(), + }, + }, + { + Method: "PUT", + Path: "/v1/workspaces/{uid}/clusterNamespaces", + Response: ResponseData{ + StatusCode: http.StatusNoContent, + Payload: map[string]interface{}{"UID": generateRandomStringUID()}, }, }, { Method: "DELETE", Path: "/v1/workspaces/{uid}", Response: ResponseData{ - StatusCode: 204, + StatusCode: http.StatusNoContent, Payload: nil, }, }, + } +} + +func WorkspaceNegativeRoutes() []Route { + return []Route{ + { + Method: "POST", + Path: "/v1/workspaces", + Response: ResponseData{ + StatusCode: http.StatusConflict, + Payload: getError(strconv.Itoa(http.StatusConflict), "workspaces already exist"), + }, + }, { Method: "GET", Path: "/v1/workspaces/{uid}", Response: ResponseData{ - StatusCode: 0, - Payload: &models.V1Workspace{ - Metadata: &models.V1ObjectMeta{ - Annotations: nil, - Labels: nil, - Name: "test-ws-1", - UID: "test-ws-1-id", - }, - Spec: &models.V1WorkspaceSpec{ - ClusterNamespaces: []*models.V1WorkspaceClusterNamespace{ - { - Image: &models.V1WorkspaceNamespaceImage{ - BlackListedImages: []string{"image1"}, - }, - IsRegex: false, - Name: "test-ws-ns", - NamespaceResourceAllocation: &models.V1WorkspaceNamespaceResourceAllocation{ - ClusterResourceAllocations: []*models.V1ClusterResourceAllocation{ - { - ClusterUID: "test-cluster-uid", - ResourceAllocation: &models.V1WorkspaceResourceAllocation{ - CPUCores: 2, - MemoryMiB: 100, - }, - }, - }, - DefaultResourceAllocation: &models.V1WorkspaceResourceAllocation{ - CPUCores: 2, - MemoryMiB: 100, - }, - }, - }, - }, - ClusterRbacs: []*models.V1ClusterRbac{ - { - Metadata: &models.V1ObjectMeta{ - Name: "test-rbac-name", - UID: "test-rbac-id", - }, - Spec: &models.V1ClusterRbacSpec{ - Bindings: []*models.V1ClusterRbacBinding{ - { - Namespace: "test-ns", - Role: nil, - Subjects: nil, - Type: "ns", - }, - }, - RelatedObject: &models.V1RelatedObject{ - Kind: "test", - Name: "test-ro", - UID: "test-ro-id", - }, - }, - Status: &models.V1ClusterRbacStatus{ - Errors: nil, - }, - }, - }, - ClusterRefs: []*models.V1WorkspaceClusterRef{ - { - ClusterName: "test-cluster-name", - ClusterUID: "test-cluster-id", - }, - }, - Policies: &models.V1WorkspacePolicies{ - BackupPolicy: &models.V1WorkspaceBackupConfigEntity{ - BackupConfig: &models.V1ClusterBackupConfig{ - BackupLocationName: "test-bl", - BackupLocationUID: "uid", - BackupName: "test-back-name", - BackupPrefix: "prefix", - DurationInHours: 0, - IncludeAllDisks: false, - IncludeClusterResources: false, - LocationType: "test-location", - Namespaces: nil, - Schedule: nil, - }, - ClusterUids: []string{"c-uid"}, - IncludeAllClusters: false, - }, - }, - Quota: &models.V1WorkspaceQuota{ - ResourceAllocation: &models.V1WorkspaceResourceAllocation{ - CPUCores: 2, - MemoryMiB: 100, - }, - }, - }, - Status: &models.V1WorkspaceStatus{ - Errors: nil, - }, - }, + StatusCode: http.StatusForbidden, + Payload: getError(strconv.Itoa(http.StatusOK), "workspaces not found"), + }, + }, + { + Method: "GET", + Path: "/v1/workspaces/{uid}/backup", + Response: ResponseData{ + StatusCode: http.StatusNotFound, + Payload: getError(strconv.Itoa(http.StatusOK), "backup not found"), + }, + }, + { + Method: "PUT", + Path: "/v1/workspaces/{uid}/clusterNamespaces", + Response: ResponseData{ + StatusCode: http.StatusMethodNotAllowed, + Payload: getError(strconv.Itoa(http.StatusNoContent), "Operation not allowed"), + }, + }, + { + Method: "DELETE", + Path: "/v1/workspaces/{uid}", + Response: ResponseData{ + StatusCode: http.StatusNotFound, + Payload: getError(strconv.Itoa(http.StatusOK), "workspaces not found"), }, }, }