Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AWS/Azure to required features list. #7218

Merged
merged 7 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions test/functional/shared/resources/aws_s3_bucket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,6 @@ func Test_AWS_S3Bucket_Existing(t *testing.T) {
},
})

test.RequiredFeatures = []shared.RequiredFeature{shared.FeatureAWS}
Copy link
Contributor Author

@vinayada1 vinayada1 Feb 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar changes will be made in subsequent PRs once the tests are separated out and reorganized

test.Test(t)
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,6 @@ func Test_AzureConnections(t *testing.T) {
},
})

test.RequiredFeatures = []shared.RequiredFeature{shared.FeatureAzure}
test.Test(t)
}
52 changes: 46 additions & 6 deletions test/functional/shared/rptest.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ const (
daprFeatureMessage = "This test requires Dapr installed in your Kubernetes cluster. Please install Dapr by following the instructions at https://docs.dapr.io/operations/hosting/kubernetes/kubernetes-deploy/."
secretProviderClassesCRD = "secretproviderclasses.secrets-store.csi.x-k8s.io"
csiDriverMessage = "This test requires secret store CSI driver. Please install it by following https://secrets-store-csi-driver.sigs.k8s.io/."
awsMessage = "This test requires AWS. Please configure the test environment to include an AWS provider."
azureMessage = "This test requires Azure. Please configure the test environment to include an Azure provider."
)

// RequiredFeature is used to specify an optional feature that is required
Expand All @@ -67,6 +69,23 @@ const (
// FeatureCSIDriver should be used with required features to indicate a test dependency
// on the CSI driver.
FeatureCSIDriver RequiredFeature = "CSIDriver"

// FeatureAWS should be used with required features to indicate a test dependency on AWS cloud provider.
FeatureAWS RequiredFeature = "AWS"

// FeatureAzure should be used with required features to indicate a test dependency on Azure cloud provider.
FeatureAzure RequiredFeature = "Azure"
)

// RequiredFeatureValidatorType is used to specify the type of validator to use
type RequiredFeatureValidatorType string

const (
// Use CRD to check for required features
RequiredFeatureValidatorTypeCRD = "ValidatorCRD"

// Use cloud provider API to check for required features
RequiredFeatureValidatorTypeCloud = "ValidatorCloud"
vinayada1 marked this conversation as resolved.
Show resolved Hide resolved
)

type TestStep struct {
Expand Down Expand Up @@ -185,23 +204,44 @@ func (ct RPTest) CleanUpExtensionResources(resources []unstructured.Unstructured
// returns an error if there is an issue.
func (ct RPTest) CheckRequiredFeatures(ctx context.Context, t *testing.T) {
for _, feature := range ct.RequiredFeatures {
var crd, message string
var crd, message, credential string
var validatorType RequiredFeatureValidatorType
switch feature {
case FeatureDapr:
crd = daprComponentCRD
message = daprFeatureMessage
validatorType = RequiredFeatureValidatorTypeCRD
case FeatureCSIDriver:
crd = secretProviderClassesCRD
message = csiDriverMessage
validatorType = RequiredFeatureValidatorTypeCRD
case FeatureAWS:
message = awsMessage
credential = "aws"
validatorType = RequiredFeatureValidatorTypeCloud
case FeatureAzure:
message = azureMessage
credential = "azure"
validatorType = RequiredFeatureValidatorTypeCloud
default:
panic(fmt.Sprintf("unsupported feature: %s", feature))
}

err := ct.Options.Client.Get(ctx, client.ObjectKey{Name: crd}, &apiextv1.CustomResourceDefinition{})
if apierrors.IsNotFound(err) {
t.Skip(message)
} else if err != nil {
require.NoError(t, err, "failed to check for required features")
switch validatorType {
case RequiredFeatureValidatorTypeCRD:
err := ct.Options.Client.Get(ctx, client.ObjectKey{Name: crd}, &apiextv1.CustomResourceDefinition{})
if apierrors.IsNotFound(err) {
t.Skip(message)
} else if err != nil {
require.NoError(t, err, "failed to check for required features")
}
case RequiredFeatureValidatorTypeCloud:
exists := validation.DoesCredentialExist(t, credential)
if !exists {
t.Skip(message)
}
default:
panic(fmt.Sprintf("unsupported required features validator type: %s", validatorType))
}
}
}
Expand Down
1 change: 1 addition & 0 deletions test/functional/ucp/aws_credential_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func Test_AWS_Credential_Operations(t *testing.T) {
runAWSCredentialTests(t, resourceURL, collectionURL, roundTripper, getAWSTestCredentialObject(), getExpectedAWSTestCredentialObject())
})

test.RequiredFeatures = []RequiredFeature{"AWS"}
test.Test(t)
}

Expand Down
12 changes: 6 additions & 6 deletions test/functional/ucp/aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,9 @@ var (
func Test_AWS_DeleteResource(t *testing.T) {
ctx := context.Background()

bucketName := generateS3BucketName()
setupTestAWSResource(t, ctx, bucketName)

test := NewUCPTest(t, "Test_AWS_DeleteResource", func(t *testing.T, url string, roundTripper http.RoundTripper) {
bucketName := generateS3BucketName()
setupTestAWSResource(t, ctx, bucketName)
resourceID, err := validation.GetResourceIdentifier(ctx, s3BucketResourceType, bucketName)
require.NoError(t, err)

Expand Down Expand Up @@ -101,16 +100,16 @@ func Test_AWS_DeleteResource(t *testing.T) {
require.True(t, deleteSucceeded)
})

test.RequiredFeatures = []RequiredFeature{FeatureAWS}
test.Test(t)
}

func Test_AWS_ListResources(t *testing.T) {
ctx := context.Background()

var bucketName = generateS3BucketName()
setupTestAWSResource(t, ctx, bucketName)

test := NewUCPTest(t, "Test_AWS_ListResources", func(t *testing.T, url string, roundTripper http.RoundTripper) {
var bucketName = generateS3BucketName()
setupTestAWSResource(t, ctx, bucketName)
resourceID, err := validation.GetResourceIdentifier(ctx, s3BucketResourceType, bucketName)
require.NoError(t, err)

Expand Down Expand Up @@ -140,6 +139,7 @@ func Test_AWS_ListResources(t *testing.T) {
require.GreaterOrEqual(t, len(body["value"]), 1)
})

test.RequiredFeatures = []RequiredFeature{FeatureAWS}
test.Test(t)
}

Expand Down
1 change: 1 addition & 0 deletions test/functional/ucp/azure_credential_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func Test_Azure_Credential_Operations(t *testing.T) {
runAzureCredentialTests(t, resourceURL, collectionURL, roundTripper, getAzureTestCredentialObject(), getExpectedAzureTestCredentialObject())
})

test.RequiredFeatures = []RequiredFeature{"Azure"}
test.Test(t)
}

Expand Down
49 changes: 48 additions & 1 deletion test/functional/ucp/ucptest.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package ucp

import (
"context"
"fmt"
"io"
"net/http"
"os"
Expand All @@ -31,17 +33,36 @@ import (
"github.com/stretchr/testify/require"
)

const ContainerLogPathEnvVar = "RADIUS_CONTAINER_LOG_PATH"
const (
ContainerLogPathEnvVar = "RADIUS_CONTAINER_LOG_PATH"
awsMessage = "This test requires AWS. Please configure the test environment to include an AWS provider."
azureMessage = "This test requires Azure. Please configure the test environment to include an Azure provider."
)

var radiusControllerLogSync sync.Once

type TestRunMethod func(t *testing.T, url string, roundtripper http.RoundTripper)

// RequiredFeature is used to specify an optional feature that is required
// for the test to run.
type RequiredFeature string

const (
// FeatureAWS should be used with required features to indicate a test dependency on AWS cloud provider.
FeatureAWS RequiredFeature = "AWS"

// FeatureAzure should be used with required features to indicate a test dependency on Azure cloud provider.
FeatureAzure RequiredFeature = "Azure"
)

type UCPTest struct {
Options test.TestOptions
Name string
Description string
RunMethod TestRunMethod

// RequiredFeatures is a list of features that are required for the test to run.
RequiredFeatures []RequiredFeature
}

type TestStep struct {
Expand All @@ -59,6 +80,9 @@ func NewUCPTest(t *testing.T, name string, runMethod TestRunMethod) UCPTest {

func (ucptest UCPTest) Test(t *testing.T) {
ctx, cancel := testcontext.NewWithCancel(t)

ucptest.CheckRequiredFeatures(ctx, t)

t.Cleanup(cancel)

t.Parallel()
Expand Down Expand Up @@ -104,3 +128,26 @@ func NewUCPRequest(method string, url string, body io.Reader) (*http.Request, er

return req, nil
}

// CheckRequiredFeatures checks the test environment for the features that the test requires and skips the test if not, otherwise
// returns an error if there is an issue.
func (ct UCPTest) CheckRequiredFeatures(ctx context.Context, t *testing.T) {
for _, feature := range ct.RequiredFeatures {
var credential, message string
switch feature {
case FeatureAWS:
message = awsMessage
credential = "aws"
case FeatureAzure:
message = azureMessage
credential = "azure"
default:
panic(fmt.Sprintf("unsupported feature: %s", feature))
}

exists := validation.DoesCredentialExist(t, credential)
if !exists {
t.Skip(message)
}
}
}
24 changes: 24 additions & 0 deletions test/validation/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@ import (
"testing"

"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/radius-project/radius/pkg/cli"
"github.com/radius-project/radius/pkg/cli/clients"
"github.com/radius-project/radius/pkg/cli/connections"
"github.com/radius-project/radius/pkg/cli/output"
"github.com/stretchr/testify/require"

"github.com/radius-project/radius/test/radcli"
"github.com/radius-project/radius/test/testcontext"
)

const (
Expand Down Expand Up @@ -169,3 +172,24 @@ func ValidateRPResources(ctx context.Context, t *testing.T, expected *RPResource
}
}
}

// DoesCredentialExist checks if the credential is registered in the workspace and returns a boolean value.
func DoesCredentialExist(t *testing.T, credential string) bool {
vinayada1 marked this conversation as resolved.
Show resolved Hide resolved
ctx := testcontext.New(t)

config, err := cli.LoadConfig("")
require.NoError(t, err, "failed to read radius config")

workspace, err := cli.GetWorkspace(config, "")
require.NoError(t, err, "failed to read default workspace")
require.NotNil(t, workspace, "default workspace is not set")

t.Logf("Loaded workspace: %s (%s)", workspace.Name, workspace.FmtConnection())

credentialsClient, err := connections.DefaultFactory.CreateCredentialManagementClient(ctx, *workspace)
require.NoError(t, err, "failed to create credentials client")
cred, err := credentialsClient.Get(ctx, credential)
require.NoError(t, err, "failed to get credentials")

return cred.CloudProviderStatus.Enabled
}
Loading