From 5551a7c4c2ad590f47556898a4c74f11ec7ff8f9 Mon Sep 17 00:00:00 2001 From: Bharath Joginapally Date: Wed, 28 Dec 2022 18:33:29 -0800 Subject: [PATCH 1/4] Add functional tests for credential operations --- test/functional/ucp/credential_test.go | 197 +++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 test/functional/ucp/credential_test.go diff --git a/test/functional/ucp/credential_test.go b/test/functional/ucp/credential_test.go new file mode 100644 index 0000000000..b3387e94c4 --- /dev/null +++ b/test/functional/ucp/credential_test.go @@ -0,0 +1,197 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +package ucp + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "github.com/project-radius/radius/pkg/ucp/api/v20220901privatepreview" + ucp "github.com/project-radius/radius/pkg/ucp/api/v20220901privatepreview" + "github.com/stretchr/testify/require" + "gotest.tools/assert" +) + +func Test_Azure_Credential_Operations(t *testing.T) { + test := NewUCPTest(t, "Test_Azure_Credential_Operations", func(t *testing.T, url string, roundTripper http.RoundTripper) { + credentialResourceID := "/planes/azure/azurecloud/providers/System.Azure/credentials/default" + credentialCollectionID := "/planes/azure/azurecloud/providers/System.Azure/credentials" + credentialResourceURL := fmt.Sprintf("%s%s?api-version=%s", url, credentialResourceID, ucp.Version) + credentialCollectionURL := fmt.Sprintf("%s%s?api-version=%s", url, credentialCollectionID, ucp.Version) + credentialOperations(t, credentialResourceURL, credentialCollectionURL, roundTripper, getAzureCredentialObject()) + }) + + test.Test(t) +} + +func Test_AWS_Credential_Operations(t *testing.T) { + test := NewUCPTest(t, "Test_AWS_Credential_Operations", func(t *testing.T, url string, roundTripper http.RoundTripper) { + credentialResourceID := "/planes/aws/awscloud/providers/System.AWS/credentials/default" + credentialCollectionID := "/planes/aws/awscloud/providers/System.AWS/credentials" + credentialResourceURL := fmt.Sprintf("%s%s?api-version=%s", url, credentialResourceID, ucp.Version) + credentialCollectionURL := fmt.Sprintf("%s%s?api-version=%s", url, credentialCollectionID, ucp.Version) + credentialOperations(t, credentialResourceURL, credentialCollectionURL, roundTripper, getAWSCredentialObject()) + }) + + test.Test(t) +} + +func credentialOperations(t *testing.T, resourceUrl string, collectionUrl string, roundTripper http.RoundTripper, credential ucp.CredentialResource) { + // Create credential operation + createCredential(t, roundTripper, resourceUrl, credential) + // Create duplicate credential + createCredential(t, roundTripper, resourceUrl, credential) + // List credential operation + credentialList := listCredential(t, roundTripper, collectionUrl) + require.Equal(t, len(credentialList), 1) + assert.DeepEqual(t, credentialList[0], credential) + + // // Check for correctness of credential + credential, statusCode := getCredential(t, roundTripper, resourceUrl) + require.Equal(t, http.StatusOK, statusCode) + assert.DeepEqual(t, credential, credential) + + // Delete credential operation + statusCode, err := deleteCredential(t, roundTripper, resourceUrl) + require.NoError(t, err) + require.Equal(t, http.StatusOK, statusCode) + + // Delete non-existent credential + statusCode, err = deleteCredential(t, roundTripper, resourceUrl) + require.NoError(t, err) + require.Equal(t, http.StatusNotFound, statusCode) +} + +func createCredential(t *testing.T, roundTripper http.RoundTripper, url string, credential ucp.CredentialResource) { + body, err := json.Marshal(credential) + require.NoError(t, err) + createRequest, err := http.NewRequest( + http.MethodPut, + url, + bytes.NewBuffer(body)) + require.NoError(t, err, "") + + res, err := roundTripper.RoundTrip(createRequest) + require.NoError(t, err, "") + + require.Equal(t, http.StatusOK, res.StatusCode) + t.Logf("Credential: %s created/updated successfully", url) +} + +func getCredential(t *testing.T, roundTripper http.RoundTripper, url string) (ucp.CredentialResource, int) { + getCredentialRequest, err := http.NewRequest( + http.MethodGet, + url, + nil, + ) + require.NoError(t, err, "") + + result, err := roundTripper.RoundTrip(getCredentialRequest) + require.NoError(t, err, "") + + body := result.Body + defer body.Close() + payload, err := io.ReadAll(body) + require.NoError(t, err) + + credential := ucp.CredentialResource{} + err = json.Unmarshal(payload, &credential) + require.NoError(t, err) + + return credential, result.StatusCode +} + +func deleteCredential(t *testing.T, roundTripper http.RoundTripper, url string) (int, error) { + deleteCredentialRequest, err := http.NewRequest( + http.MethodDelete, + url, + nil, + ) + require.NoError(t, err, "") + + res, err := roundTripper.RoundTrip(deleteCredentialRequest) + return res.StatusCode, err +} + +func listCredential(t *testing.T, roundTripper http.RoundTripper, url string) []ucp.CredentialResource { + listCredentialRequest, err := http.NewRequest( + http.MethodGet, + url, + nil, + ) + require.NoError(t, err, "") + + res, err := roundTripper.RoundTrip(listCredentialRequest) + require.NoError(t, err) + return getCredentialList(t, res) +} + +func getCredentialList(t *testing.T, res *http.Response) []ucp.CredentialResource { + var data map[string]interface{} + body := res.Body + defer body.Close() + err := json.NewDecoder(body).Decode(&data) + require.NoError(t, err) + list, ok := data["value"].([]interface{}) + require.Equal(t, ok, true) + var credentialList []ucp.CredentialResource + for _, item := range list { + s, err := json.Marshal(item) + require.NoError(t, err) + credential := ucp.CredentialResource{} + err = json.Unmarshal(s, &credential) + require.NoError(t, err) + credentialList = append(credentialList, credential) + } + return credentialList +} + +func getAzureCredentialObject() ucp.CredentialResource { + return ucp.CredentialResource{ + Location: to.Ptr("west-us-2"), + ID: to.Ptr("/planes/azure/azurecloud/providers/System.Azure/credentials/default"), + Name: to.Ptr("default"), + Type: to.Ptr("System.Azure/credentials"), + Tags: map[string]*string{ + "env": to.Ptr("dev"), + }, + Properties: &ucp.AzureServicePrincipalProperties{ + ClientID: to.Ptr("00000000-0000-0000-0000-000000000000"), + TenantID: to.Ptr("00000000-0000-0000-0000-000000000000"), + Kind: to.Ptr("azure.com.serviceprincipal"), + Storage: &ucp.InternalCredentialStorageProperties{ + Kind: to.Ptr(v20220901privatepreview.CredentialStorageKindInternal), + SecretName: to.Ptr("azure_azurecloud_default"), + }, + }, + } +} + +func getAWSCredentialObject() ucp.CredentialResource { + return ucp.CredentialResource{ + Location: to.Ptr("west-us-2"), + ID: to.Ptr("/planes/aws/awscloud/providers/System.AWS/credentials/default"), + Name: to.Ptr("default"), + Type: to.Ptr("System.AWS/credentials"), + Tags: map[string]*string{ + "env": to.Ptr("dev"), + }, + Properties: &v20220901privatepreview.AWSCredentialProperties{ + AccessKeyID: to.Ptr("00000000-0000-0000-0000-000000000000"), + SecretAccessKey: to.Ptr("00000000-0000-0000-0000-000000000000"), + Kind: to.Ptr("aws.com.iam"), + Storage: &v20220901privatepreview.InternalCredentialStorageProperties{ + Kind: to.Ptr(v20220901privatepreview.CredentialStorageKindInternal), + SecretName: to.Ptr("aws_awscloud_default"), + }, + }, + } +} From 06973392b61f26071d0fa99d5d8d93e7c3cda1b9 Mon Sep 17 00:00:00 2001 From: Bharath Joginapally Date: Thu, 29 Dec 2022 10:28:29 -0800 Subject: [PATCH 2/4] Correct expected value for second delete --- test/functional/ucp/credential_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/ucp/credential_test.go b/test/functional/ucp/credential_test.go index b3387e94c4..3d3a996836 100644 --- a/test/functional/ucp/credential_test.go +++ b/test/functional/ucp/credential_test.go @@ -67,7 +67,7 @@ func credentialOperations(t *testing.T, resourceUrl string, collectionUrl string // Delete non-existent credential statusCode, err = deleteCredential(t, roundTripper, resourceUrl) require.NoError(t, err) - require.Equal(t, http.StatusNotFound, statusCode) + require.Equal(t, http.StatusNoContent, statusCode) } func createCredential(t *testing.T, roundTripper http.RoundTripper, url string, credential ucp.CredentialResource) { From fac8c630f574946bfca22ce87ce625ed8f14db2e Mon Sep 17 00:00:00 2001 From: Bharath Joginapally Date: Fri, 30 Dec 2022 14:49:02 -0800 Subject: [PATCH 3/4] Misc corrections --- test/functional/ucp/credential_test.go | 48 +++++++++----------------- 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/test/functional/ucp/credential_test.go b/test/functional/ucp/credential_test.go index 3d3a996836..7b64696bda 100644 --- a/test/functional/ucp/credential_test.go +++ b/test/functional/ucp/credential_test.go @@ -22,11 +22,10 @@ import ( func Test_Azure_Credential_Operations(t *testing.T) { test := NewUCPTest(t, "Test_Azure_Credential_Operations", func(t *testing.T, url string, roundTripper http.RoundTripper) { - credentialResourceID := "/planes/azure/azurecloud/providers/System.Azure/credentials/default" - credentialCollectionID := "/planes/azure/azurecloud/providers/System.Azure/credentials" - credentialResourceURL := fmt.Sprintf("%s%s?api-version=%s", url, credentialResourceID, ucp.Version) - credentialCollectionURL := fmt.Sprintf("%s%s?api-version=%s", url, credentialCollectionID, ucp.Version) - credentialOperations(t, credentialResourceURL, credentialCollectionURL, roundTripper, getAzureCredentialObject()) + resourceTypePath := "/planes/azure/azurecloud/providers/System.Azure/credentials" + resourceURL := fmt.Sprintf("%s%s/default?api-version=%s", url, resourceTypePath, ucp.Version) + collectionURL := fmt.Sprintf("%s%s?api-version=%s", url, resourceTypePath, ucp.Version) + runCredentialTests(t, resourceURL, collectionURL, roundTripper, getAzureCredentialObject()) }) test.Test(t) @@ -34,17 +33,16 @@ func Test_Azure_Credential_Operations(t *testing.T) { func Test_AWS_Credential_Operations(t *testing.T) { test := NewUCPTest(t, "Test_AWS_Credential_Operations", func(t *testing.T, url string, roundTripper http.RoundTripper) { - credentialResourceID := "/planes/aws/awscloud/providers/System.AWS/credentials/default" - credentialCollectionID := "/planes/aws/awscloud/providers/System.AWS/credentials" - credentialResourceURL := fmt.Sprintf("%s%s?api-version=%s", url, credentialResourceID, ucp.Version) - credentialCollectionURL := fmt.Sprintf("%s%s?api-version=%s", url, credentialCollectionID, ucp.Version) - credentialOperations(t, credentialResourceURL, credentialCollectionURL, roundTripper, getAWSCredentialObject()) + resourceTypePath := "/planes/aws/awscloud/providers/System.AWS/credentials" + resourceURL := fmt.Sprintf("%s%s/default?api-version=%s", url, resourceTypePath, ucp.Version) + collectionURL := fmt.Sprintf("%s%s?api-version=%s", url, resourceTypePath, ucp.Version) + runCredentialTests(t, resourceURL, collectionURL, roundTripper, getAWSCredentialObject()) }) test.Test(t) } -func credentialOperations(t *testing.T, resourceUrl string, collectionUrl string, roundTripper http.RoundTripper, credential ucp.CredentialResource) { +func runCredentialTests(t *testing.T, resourceUrl string, collectionUrl string, roundTripper http.RoundTripper, credential ucp.CredentialResource) { // Create credential operation createCredential(t, roundTripper, resourceUrl, credential) // Create duplicate credential @@ -73,10 +71,7 @@ func credentialOperations(t *testing.T, resourceUrl string, collectionUrl string func createCredential(t *testing.T, roundTripper http.RoundTripper, url string, credential ucp.CredentialResource) { body, err := json.Marshal(credential) require.NoError(t, err) - createRequest, err := http.NewRequest( - http.MethodPut, - url, - bytes.NewBuffer(body)) + createRequest, err := http.NewRequest(http.MethodPut, url, bytes.NewBuffer(body)) require.NoError(t, err, "") res, err := roundTripper.RoundTrip(createRequest) @@ -87,11 +82,7 @@ func createCredential(t *testing.T, roundTripper http.RoundTripper, url string, } func getCredential(t *testing.T, roundTripper http.RoundTripper, url string) (ucp.CredentialResource, int) { - getCredentialRequest, err := http.NewRequest( - http.MethodGet, - url, - nil, - ) + getCredentialRequest, err := http.NewRequest(http.MethodGet, url, nil) require.NoError(t, err, "") result, err := roundTripper.RoundTrip(getCredentialRequest) @@ -110,11 +101,7 @@ func getCredential(t *testing.T, roundTripper http.RoundTripper, url string) (uc } func deleteCredential(t *testing.T, roundTripper http.RoundTripper, url string) (int, error) { - deleteCredentialRequest, err := http.NewRequest( - http.MethodDelete, - url, - nil, - ) + deleteCredentialRequest, err := http.NewRequest(http.MethodDelete, url, nil) require.NoError(t, err, "") res, err := roundTripper.RoundTrip(deleteCredentialRequest) @@ -122,11 +109,7 @@ func deleteCredential(t *testing.T, roundTripper http.RoundTripper, url string) } func listCredential(t *testing.T, roundTripper http.RoundTripper, url string) []ucp.CredentialResource { - listCredentialRequest, err := http.NewRequest( - http.MethodGet, - url, - nil, - ) + listCredentialRequest, err := http.NewRequest(http.MethodGet, url, nil) require.NoError(t, err, "") res, err := roundTripper.RoundTrip(listCredentialRequest) @@ -135,12 +118,13 @@ func listCredential(t *testing.T, roundTripper http.RoundTripper, url string) [] } func getCredentialList(t *testing.T, res *http.Response) []ucp.CredentialResource { - var data map[string]interface{} body := res.Body defer body.Close() + + var data map[string]any err := json.NewDecoder(body).Decode(&data) require.NoError(t, err) - list, ok := data["value"].([]interface{}) + list, ok := data["value"].([]any) require.Equal(t, ok, true) var credentialList []ucp.CredentialResource for _, item := range list { From 582175f2131fb9cdc4af156104aa59c6f003bc9e Mon Sep 17 00:00:00 2001 From: Bharath Joginapally Date: Fri, 30 Dec 2022 15:38:02 -0800 Subject: [PATCH 4/4] Correct credential comparison --- test/functional/ucp/credential_test.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/functional/ucp/credential_test.go b/test/functional/ucp/credential_test.go index 7b64696bda..2e3e1ae972 100644 --- a/test/functional/ucp/credential_test.go +++ b/test/functional/ucp/credential_test.go @@ -52,10 +52,10 @@ func runCredentialTests(t *testing.T, resourceUrl string, collectionUrl string, require.Equal(t, len(credentialList), 1) assert.DeepEqual(t, credentialList[0], credential) - // // Check for correctness of credential - credential, statusCode := getCredential(t, roundTripper, resourceUrl) + // Check for correctness of credential + createdCredential, statusCode := getCredential(t, roundTripper, resourceUrl) require.Equal(t, http.StatusOK, statusCode) - assert.DeepEqual(t, credential, credential) + assert.DeepEqual(t, createdCredential, credential) // Delete credential operation statusCode, err := deleteCredential(t, roundTripper, resourceUrl) @@ -72,10 +72,10 @@ func createCredential(t *testing.T, roundTripper http.RoundTripper, url string, body, err := json.Marshal(credential) require.NoError(t, err) createRequest, err := http.NewRequest(http.MethodPut, url, bytes.NewBuffer(body)) - require.NoError(t, err, "") + require.NoError(t, err) res, err := roundTripper.RoundTrip(createRequest) - require.NoError(t, err, "") + require.NoError(t, err) require.Equal(t, http.StatusOK, res.StatusCode) t.Logf("Credential: %s created/updated successfully", url) @@ -83,10 +83,10 @@ func createCredential(t *testing.T, roundTripper http.RoundTripper, url string, func getCredential(t *testing.T, roundTripper http.RoundTripper, url string) (ucp.CredentialResource, int) { getCredentialRequest, err := http.NewRequest(http.MethodGet, url, nil) - require.NoError(t, err, "") + require.NoError(t, err) result, err := roundTripper.RoundTrip(getCredentialRequest) - require.NoError(t, err, "") + require.NoError(t, err) body := result.Body defer body.Close() @@ -102,7 +102,7 @@ func getCredential(t *testing.T, roundTripper http.RoundTripper, url string) (uc func deleteCredential(t *testing.T, roundTripper http.RoundTripper, url string) (int, error) { deleteCredentialRequest, err := http.NewRequest(http.MethodDelete, url, nil) - require.NoError(t, err, "") + require.NoError(t, err) res, err := roundTripper.RoundTrip(deleteCredentialRequest) return res.StatusCode, err @@ -110,7 +110,7 @@ func deleteCredential(t *testing.T, roundTripper http.RoundTripper, url string) func listCredential(t *testing.T, roundTripper http.RoundTripper, url string) []ucp.CredentialResource { listCredentialRequest, err := http.NewRequest(http.MethodGet, url, nil) - require.NoError(t, err, "") + require.NoError(t, err) res, err := roundTripper.RoundTrip(listCredentialRequest) require.NoError(t, err)