edge-connect-client/internal/delete/v2/planner_test.go

220 lines
6.2 KiB
Go
Raw Normal View History

// ABOUTME: Tests for EdgeConnect deletion planner with mock scenarios
// ABOUTME: Tests deletion planning logic and resource discovery
package v2
import (
"context"
"os"
"path/filepath"
"testing"
"edp.buildth.ing/DevFW-CICD/edge-connect-client/v2/internal/config"
v2 "edp.buildth.ing/DevFW-CICD/edge-connect-client/v2/sdk/edgeconnect/v2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
// MockEdgeConnectClient is a mock implementation of the EdgeConnect client
type MockEdgeConnectClient struct {
mock.Mock
}
func (m *MockEdgeConnectClient) ShowApp(ctx context.Context, appKey v2.AppKey, region string) (v2.App, error) {
args := m.Called(ctx, appKey, region)
if args.Get(0) == nil {
return v2.App{}, args.Error(1)
}
return args.Get(0).(v2.App), args.Error(1)
}
func (m *MockEdgeConnectClient) ShowAppInstances(ctx context.Context, instanceKey v2.AppInstanceKey, appKey v2.AppKey, region string) ([]v2.AppInstance, error) {
args := m.Called(ctx, instanceKey, region)
if args.Get(0) == nil {
return nil, args.Error(1)
}
return args.Get(0).([]v2.AppInstance), args.Error(1)
}
func (m *MockEdgeConnectClient) DeleteApp(ctx context.Context, appKey v2.AppKey, region string) error {
args := m.Called(ctx, appKey, region)
return args.Error(0)
}
func (m *MockEdgeConnectClient) DeleteAppInstance(ctx context.Context, instanceKey v2.AppInstanceKey, region string) error {
args := m.Called(ctx, instanceKey, region)
return args.Error(0)
}
func createTestConfig(t *testing.T) *config.EdgeConnectConfig {
// Create temporary manifest file
tempDir := t.TempDir()
manifestFile := filepath.Join(tempDir, "test-manifest.yaml")
manifestContent := "apiVersion: v1\nkind: Pod\nmetadata:\n name: test\n"
err := os.WriteFile(manifestFile, []byte(manifestContent), 0644)
require.NoError(t, err)
return &config.EdgeConnectConfig{
Kind: "edgeconnect-deployment",
Metadata: config.Metadata{
Name: "test-app",
AppVersion: "1.0.0",
Organization: "testorg",
},
Spec: config.Spec{
K8sApp: &config.K8sApp{
ManifestFile: manifestFile,
},
InfraTemplate: []config.InfraTemplate{
{
Region: "US",
CloudletOrg: "TestCloudletOrg",
CloudletName: "TestCloudlet",
FlavorName: "small",
},
},
},
}
}
func TestNewPlanner(t *testing.T) {
mockClient := &MockEdgeConnectClient{}
planner := NewPlanner(mockClient)
assert.NotNil(t, planner)
}
func TestPlanDeletion_WithExistingResources(t *testing.T) {
mockClient := &MockEdgeConnectClient{}
planner := NewPlanner(mockClient)
testConfig := createTestConfig(t)
// Mock existing app
existingApp := v2.App{
Key: v2.AppKey{
Organization: "testorg",
Name: "test-app",
Version: "1.0.0",
},
Deployment: "kubernetes",
}
// Mock existing instances
existingInstances := []v2.AppInstance{
{
Key: v2.AppInstanceKey{
Organization: "testorg",
Name: "test-app-1.0.0-instance",
CloudletKey: v2.CloudletKey{
Organization: "TestCloudletOrg",
Name: "TestCloudlet",
},
},
AppKey: v2.AppKey{
Organization: "testorg",
Name: "test-app",
Version: "1.0.0",
},
},
}
mockClient.On("ShowApp", mock.Anything, mock.AnythingOfType("v2.AppKey"), "US").
Return(existingApp, nil)
mockClient.On("ShowAppInstances", mock.Anything, mock.AnythingOfType("v2.AppInstanceKey"), "US").
Return(existingInstances, nil)
ctx := context.Background()
result, err := planner.Plan(ctx, testConfig)
require.NoError(t, err)
require.NotNil(t, result)
require.NotNil(t, result.Plan)
plan := result.Plan
assert.Equal(t, "test-app", plan.ConfigName)
assert.NotNil(t, plan.AppToDelete)
assert.Equal(t, "test-app", plan.AppToDelete.Name)
assert.Equal(t, "1.0.0", plan.AppToDelete.Version)
assert.Equal(t, "testorg", plan.AppToDelete.Organization)
require.Len(t, plan.InstancesToDelete, 1)
assert.Equal(t, "test-app-1.0.0-instance", plan.InstancesToDelete[0].Name)
assert.Equal(t, "testorg", plan.InstancesToDelete[0].Organization)
assert.Equal(t, 2, plan.TotalActions) // 1 app + 1 instance
assert.False(t, plan.IsEmpty())
mockClient.AssertExpectations(t)
}
func TestPlanDeletion_NoResourcesExist(t *testing.T) {
mockClient := &MockEdgeConnectClient{}
planner := NewPlanner(mockClient)
testConfig := createTestConfig(t)
// Mock API calls to return "not found" errors
mockClient.On("ShowApp", mock.Anything, mock.AnythingOfType("v2.AppKey"), "US").
Return(v2.App{}, &v2.APIError{StatusCode: 404, Messages: []string{"App not found"}})
mockClient.On("ShowAppInstances", mock.Anything, mock.AnythingOfType("v2.AppInstanceKey"), "US").
Return([]v2.AppInstance{}, nil)
ctx := context.Background()
result, err := planner.Plan(ctx, testConfig)
require.NoError(t, err)
require.NotNil(t, result)
require.NotNil(t, result.Plan)
plan := result.Plan
assert.Equal(t, "test-app", plan.ConfigName)
assert.Nil(t, plan.AppToDelete)
assert.Len(t, plan.InstancesToDelete, 0)
assert.Equal(t, 0, plan.TotalActions)
assert.True(t, plan.IsEmpty())
mockClient.AssertExpectations(t)
}
func TestPlanDeletion_OnlyInstancesExist(t *testing.T) {
mockClient := &MockEdgeConnectClient{}
planner := NewPlanner(mockClient)
testConfig := createTestConfig(t)
// Mock existing instances but no app
existingInstances := []v2.AppInstance{
{
Key: v2.AppInstanceKey{
Organization: "testorg",
Name: "test-app-1.0.0-instance",
CloudletKey: v2.CloudletKey{
Organization: "TestCloudletOrg",
Name: "TestCloudlet",
},
},
},
}
mockClient.On("ShowApp", mock.Anything, mock.AnythingOfType("v2.AppKey"), "US").
Return(v2.App{}, &v2.APIError{StatusCode: 404, Messages: []string{"App not found"}})
mockClient.On("ShowAppInstances", mock.Anything, mock.AnythingOfType("v2.AppInstanceKey"), "US").
Return(existingInstances, nil)
ctx := context.Background()
result, err := planner.Plan(ctx, testConfig)
require.NoError(t, err)
require.NotNil(t, result)
require.NotNil(t, result.Plan)
plan := result.Plan
assert.Nil(t, plan.AppToDelete)
assert.Len(t, plan.InstancesToDelete, 1)
assert.Equal(t, 1, plan.TotalActions)
assert.False(t, plan.IsEmpty())
mockClient.AssertExpectations(t)
}