Skip to content

Commit

Permalink
Add AWS/Azure to required features list. (radius-project#7218)
Browse files Browse the repository at this point in the history
# Description

As a part of radius-project#6588, as proposed by
radius-project/design-notes#35, we will use
RequiredFeatures check to separate AWS and Azure specific tests. This is
Part1 of a multi-part PR to change the organization of the tests

## Type of change

<!--

Please select **one** of the following options that describes your
change and delete the others. Clearly identifying the type of change you
are making will help us review your PR faster, and is used in authoring
release notes.

If you are making a bug fix or functionality change to Radius and do not
have an associated issue link please create one now.

-->

- This pull request adds or changes features of Radius and has an
approved issue (radius-project#6588 ).


<!--

Please update the following to link the associated issue. This is
required for some kinds of changes (see above).

-->

Fixes: A part of radius-project#6588 but multiple PRs to follow to fix completely

---------

Signed-off-by: vinayada1 <28875764+vinayada1@users.noreply.github.com>
Co-authored-by: Young Bu Park <youngp@microsoft.com>
  • Loading branch information
2 people authored and willdavsmith committed Mar 4, 2024
1 parent b2a80c5 commit e087903
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 13 deletions.
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}
test.Test(t)
}
1 change: 1 addition & 0 deletions test/functional/shared/resources/azure_connections_test.go
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 RequiredFeatureValidatorType = "ValidatorCRD"

// Use cloud provider API to check for required features
RequiredFeatureValidatorTypeCloud RequiredFeatureValidatorType = "ValidatorCloud"
)

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 {
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
}

0 comments on commit e087903

Please sign in to comment.