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

Update CLI client code and add tests #7594

Merged
merged 1 commit into from
May 16, 2024

Conversation

rynowak
Copy link
Contributor

@rynowak rynowak commented May 14, 2024

Description

This change is a major update to the CLI's client code for interacting with the Radius API.

The client grew organically over time as we added features. Since it's client code it wasn't well tested because testing it would require a lot of mocking. Unfortunately in some places we do have complex logic in this code and unfortunately we also have some bugs.

I'm working on another fix to address #7520, and encountered a lot of limitations with the client code so I decided to fix it.

This change addresses the following:

Type of change

  • This pull request is a minor refactor, code cleanup, test improvement, or other maintenance task and doesn't change the functionality of Radius (issue link optional).

@rynowak rynowak requested review from a team as code owners May 14, 2024 16:21
ListAllResourcesByEnvironment(ctx context.Context, environmentName string) ([]generated.GenericResource, error)
ShowResource(ctx context.Context, resourceType string, resourceName string) (generated.GenericResource, error)
DeleteResource(ctx context.Context, resourceType string, resourceName string) (bool, error)
// ListResourcesOfType lists all resources of a given type in the configured scope.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is where I did a major pass for consistency of the APIs.

applicationResourceClientFactory func(scope string) (applicationResourceClient, error)
environmentResourceClientFactory func(scope string) (environmentResourceClient, error)
resourceGroupClientFactory func() (resourceGroupClient, error)
capture func(ctx context.Context, capture **http.Response) context.Context
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please review this file in detail. Each of these functions have been updated to be more consistent (naming, structure, etc).

Adding mocks was pretty complex.

}

return corerpv20231001.RecipeGetMetadataResponse(resp.RecipeGetMetadataResponse), nil
return amc.capture(ctx, capture)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mocking the behavior of runtime.WithCaptureResponse is ugllllly....

ucpv20231001 "github.com/radius-project/radius/pkg/ucp/api/v20231001preview"
)

// We define interfaces so we can mock the interactions with the Radius API. These
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is everything that was required to mock the client code 😓

@@ -50,7 +50,7 @@ func Test_Validate(t *testing.T) {
},
ConfigureMocks: func(mocks radcli.ValidateMocks) {
mocks.ApplicationManagementClient.EXPECT().
ShowApplication(gomock.Any(), "test-app").
GetApplication(gomock.Any(), "test-app").
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The changes to the client API resulted in changes to most commands, but they are just renames.

Copy link

codecov bot commented May 14, 2024

Codecov Report

Attention: Patch coverage is 73.35423% with 85 lines in your changes are missing coverage. Please review.

Project coverage is 61.03%. Comparing base (5fba423) to head (f657d97).

❗ Current head f657d97 differs from pull request most recent head 5211238. Consider uploading reports for the commit 5211238 to get more accurate results

Files Patch % Lines
pkg/cli/clients/management.go 69.17% 48 Missing and 34 partials ⚠️
pkg/cli/cmd/radinit/init.go 0.00% 1 Missing ⚠️
pkg/cli/cmd/utils.go 0.00% 1 Missing ⚠️
pkg/cli/connections/factory.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7594      +/-   ##
==========================================
+ Coverage   60.30%   61.03%   +0.72%     
==========================================
  Files         517      517              
  Lines       26432    26511      +79     
==========================================
+ Hits        15941    16180     +239     
+ Misses       9141     8911     -230     
- Partials     1350     1420      +70     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@rynowak rynowak temporarily deployed to functional-tests May 14, 2024 16:36 — with GitHub Actions Inactive
@radius-functional-tests
Copy link

radius-functional-tests bot commented May 14, 2024

Radius functional test overview

🔍 Go to test action run

Name Value
Repository rynowak/radius
Commit ref 7d2a307
Unique ID func60f6196c97
Image tag pr-func60f6196c97
Click here to see the list of tools in the current test run
  • gotestsum 1.10.0
  • KinD: v0.20.0
  • Dapr: 1.12.0
  • Azure KeyVault CSI driver: 1.4.2
  • Azure Workload identity webhook: 1.1.0
  • Bicep recipe location ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/<name>:pr-func60f6196c97
  • Terraform recipe location http://tf-module-server.radius-test-tf-module-server.svc.cluster.local/<name>.zip (in cluster)
  • applications-rp test image location: ghcr.io/radius-project/dev/applications-rp:pr-func60f6196c97
  • controller test image location: ghcr.io/radius-project/dev/controller:pr-func60f6196c97
  • ucp test image location: ghcr.io/radius-project/dev/ucpd:pr-func60f6196c97
  • deployment-engine test image location: ghcr.io/radius-project/deployment-engine:latest

Test Status

⌛ Building Radius and pushing container images for functional tests...
✅ Container images build succeeded
⌛ Publishing Bicep Recipes for functional tests...
✅ Recipe publishing succeeded
⌛ Starting shared functional tests...
⌛ Starting ucp functional tests...
⌛ Starting daprrp functional tests...
⌛ Starting samples functional tests...
⌛ Starting msgrp functional tests...
⌛ Starting cli functional tests...
⌛ Starting datastoresrp functional tests...
❌ daprrp functional test failed. Please check the logs for more details
❌ shared functional test failed. Please check the logs for more details
❌ kubernetes functional test cancelled. Please check the logs for more details
❌ ucp functional test cancelled. Please check the logs for more details
❌ datastoresrp functional test cancelled. Please check the logs for more details
❌ samples functional test cancelled. Please check the logs for more details

GetApplication(ctx context.Context, applicationNameOrID string) (corerp.ApplicationResource, error)

// GetApplicationGraph retrieves the application graph of an application by its name (or id).
GetApplicationGraph(ctx context.Context, applicationNameOrID string) (corerp.ApplicationGraphResponse, error)
Copy link
Contributor

Choose a reason for hiding this comment

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

nice to see we can use ID or name everywhere.

Copy link
Contributor

Choose a reason for hiding this comment

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

hmm, does this make -g flag somewhat redundant? that now would make sense only if the "name" was used, not id right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not really. We'd still need to update the rest of the CLI to pass in a resource ID instead of a name. Right now the CLI only works with names and assumes the "default scope".

So this change only really improves this specific layer.

ShowResource(ctx context.Context, resourceType string, resourceName string) (generated.GenericResource, error)
DeleteResource(ctx context.Context, resourceType string, resourceName string) (bool, error)
// ListResourcesOfType lists all resources of a given type in the configured scope.
ListResourcesOfType(ctx context.Context, resourceType string) ([]generated.GenericResource, error)
Copy link
Contributor

Choose a reason for hiding this comment

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

Did we decide to remove the ability to have a single call that fetches all resources in an application?

Copy link
Contributor

@nithyatsu nithyatsu May 14, 2024

Choose a reason for hiding this comment

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

never mind, I just realized its still there. We are introducing a new ability to list all resources of type ( not filtered by env or app).

@radius-functional-tests
Copy link

radius-functional-tests bot commented May 14, 2024

Radius functional test overview

🔍 Go to test action run

Name Value
Repository rynowak/radius
Commit ref 5c98df9
Unique ID func99eec11d91
Image tag pr-func99eec11d91
Click here to see the list of tools in the current test run
  • gotestsum 1.10.0
  • KinD: v0.20.0
  • Dapr: 1.12.0
  • Azure KeyVault CSI driver: 1.4.2
  • Azure Workload identity webhook: 1.1.0
  • Bicep recipe location ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/<name>:pr-func99eec11d91
  • Terraform recipe location http://tf-module-server.radius-test-tf-module-server.svc.cluster.local/<name>.zip (in cluster)
  • applications-rp test image location: ghcr.io/radius-project/dev/applications-rp:pr-func99eec11d91
  • controller test image location: ghcr.io/radius-project/dev/controller:pr-func99eec11d91
  • ucp test image location: ghcr.io/radius-project/dev/ucpd:pr-func99eec11d91
  • deployment-engine test image location: ghcr.io/radius-project/deployment-engine:latest

Test Status

⌛ Building Radius and pushing container images for functional tests...
✅ Container images build succeeded
⌛ Publishing Bicep Recipes for functional tests...
✅ Recipe publishing succeeded
⌛ Starting samples functional tests...
⌛ Starting msgrp functional tests...
⌛ Starting daprrp functional tests...
⌛ Starting shared functional tests...
⌛ Starting ucp functional tests...
⌛ Starting cli functional tests...
⌛ Starting kubernetes functional tests...
❌ msgrp functional test failed. Please check the logs for more details
❌ samples functional test cancelled. Please check the logs for more details
❌ cli functional test cancelled. Please check the logs for more details
❌ daprrp functional test cancelled. Please check the logs for more details
❌ ucp functional test cancelled. Please check the logs for more details
❌ shared functional test cancelled. Please check the logs for more details

@rynowak
Copy link
Contributor Author

rynowak commented May 14, 2024

Looks like there's another bug for me to fix that's blocking functional tests. This is the downside of mock-based testing, you could have bugs in the code that's mocked out.

@radius-functional-tests
Copy link

radius-functional-tests bot commented May 14, 2024

Radius functional test overview

🔍 Go to test action run

Name Value
Repository rynowak/radius
Commit ref 90bf38a
Unique ID func7a574b562e
Image tag pr-func7a574b562e
Click here to see the list of tools in the current test run
  • gotestsum 1.10.0
  • KinD: v0.20.0
  • Dapr: 1.12.0
  • Azure KeyVault CSI driver: 1.4.2
  • Azure Workload identity webhook: 1.1.0
  • Bicep recipe location ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/<name>:pr-func7a574b562e
  • Terraform recipe location http://tf-module-server.radius-test-tf-module-server.svc.cluster.local/<name>.zip (in cluster)
  • applications-rp test image location: ghcr.io/radius-project/dev/applications-rp:pr-func7a574b562e
  • controller test image location: ghcr.io/radius-project/dev/controller:pr-func7a574b562e
  • ucp test image location: ghcr.io/radius-project/dev/ucpd:pr-func7a574b562e
  • deployment-engine test image location: ghcr.io/radius-project/deployment-engine:latest

Test Status

⌛ Building Radius and pushing container images for functional tests...
✅ Container images build succeeded
⌛ Publishing Bicep Recipes for functional tests...
✅ Recipe publishing succeeded
⌛ Starting cli functional tests...
⌛ Starting msgrp functional tests...
⌛ Starting shared functional tests...
⌛ Starting daprrp functional tests...
⌛ Starting ucp functional tests...
⌛ Starting datastoresrp functional tests...
⌛ Starting kubernetes functional tests...
❌ msgrp functional test failed. Please check the logs for more details
❌ samples functional test cancelled. Please check the logs for more details
❌ shared functional test cancelled. Please check the logs for more details
❌ kubernetes functional test cancelled. Please check the logs for more details
❌ datastoresrp functional test cancelled. Please check the logs for more details
❌ daprrp functional test cancelled. Please check the logs for more details
❌ ucp functional test cancelled. Please check the logs for more details

@radius-functional-tests
Copy link

radius-functional-tests bot commented May 14, 2024

Radius functional test overview

🔍 Go to test action run

Name Value
Repository rynowak/radius
Commit ref 0c49ad0
Unique ID func10090211ca
Image tag pr-func10090211ca
Click here to see the list of tools in the current test run
  • gotestsum 1.10.0
  • KinD: v0.20.0
  • Dapr: 1.12.0
  • Azure KeyVault CSI driver: 1.4.2
  • Azure Workload identity webhook: 1.1.0
  • Bicep recipe location ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/<name>:pr-func10090211ca
  • Terraform recipe location http://tf-module-server.radius-test-tf-module-server.svc.cluster.local/<name>.zip (in cluster)
  • applications-rp test image location: ghcr.io/radius-project/dev/applications-rp:pr-func10090211ca
  • controller test image location: ghcr.io/radius-project/dev/controller:pr-func10090211ca
  • ucp test image location: ghcr.io/radius-project/dev/ucpd:pr-func10090211ca
  • deployment-engine test image location: ghcr.io/radius-project/deployment-engine:latest

Test Status

⌛ Building Radius and pushing container images for functional tests...
✅ Container images build succeeded
⌛ Publishing Bicep Recipes for functional tests...
✅ Recipe publishing succeeded
⌛ Starting daprrp functional tests...
⌛ Starting ucp functional tests...
⌛ Starting shared functional tests...
⌛ Starting samples functional tests...
⌛ Starting kubernetes functional tests...
⌛ Starting datastoresrp functional tests...
✅ msgrp functional tests succeeded
✅ ucp functional tests succeeded
✅ kubernetes functional tests succeeded
✅ daprrp functional tests succeeded
✅ samples functional tests succeeded
❌ cli functional test failed. Please check the logs for more details
❌ datastoresrp functional test cancelled. Please check the logs for more details
❌ shared functional test cancelled. Please check the logs for more details

@rynowak
Copy link
Contributor Author

rynowak commented May 15, 2024

FYI - I found #7597 while troubleshooting this code and added a workaround for it.

@radius-functional-tests
Copy link

radius-functional-tests bot commented May 15, 2024

Radius functional test overview

🔍 Go to test action run

Name Value
Repository rynowak/radius
Commit ref f657d97
Unique ID func05e722e418
Image tag pr-func05e722e418
Click here to see the list of tools in the current test run
  • gotestsum 1.10.0
  • KinD: v0.20.0
  • Dapr: 1.12.0
  • Azure KeyVault CSI driver: 1.4.2
  • Azure Workload identity webhook: 1.1.0
  • Bicep recipe location ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/<name>:pr-func05e722e418
  • Terraform recipe location http://tf-module-server.radius-test-tf-module-server.svc.cluster.local/<name>.zip (in cluster)
  • applications-rp test image location: ghcr.io/radius-project/dev/applications-rp:pr-func05e722e418
  • controller test image location: ghcr.io/radius-project/dev/controller:pr-func05e722e418
  • ucp test image location: ghcr.io/radius-project/dev/ucpd:pr-func05e722e418
  • deployment-engine test image location: ghcr.io/radius-project/deployment-engine:latest

Test Status

⌛ Building Radius and pushing container images for functional tests...
✅ Container images build succeeded
⌛ Publishing Bicep Recipes for functional tests...
✅ Recipe publishing succeeded
⌛ Starting samples functional tests...
⌛ Starting ucp functional tests...
⌛ Starting datastoresrp functional tests...
⌛ Starting shared functional tests...
⌛ Starting msgrp functional tests...
⌛ Starting kubernetes functional tests...
⌛ Starting cli functional tests...
⌛ Starting daprrp functional tests...
✅ samples functional tests succeeded
✅ msgrp functional tests succeeded
✅ ucp functional tests succeeded
✅ kubernetes functional tests succeeded
✅ datastoresrp functional tests succeeded
❌ shared functional test failed. Please check the logs for more details
❌ daprrp functional test cancelled. Please check the logs for more details
❌ cli functional test cancelled. Please check the logs for more details

nithyatsu
nithyatsu previously approved these changes May 15, 2024
This change is a major update to the CLI's client code for interacting with the Radius API.

The client grew organically over time as we added features. Since it's client code it wasn't
well tested because testing it would require a lot of mocking. Unfortunately in some places
we *do* have complex logic in this code and unfortunately we also have some bugs.

I'm working on another fix to address radius-project#7520, and encountered a lot of limitations with the client
code so I decided to fix it.

This change addresses the following:

- Reviewed the API and made updates for consistency.
- Added tests for ALL of the functions on the client.
- Updated each API to accept either a resource ID or a resource name (needed for radius-project#7520).

This update does the

Signed-off-by: Ryan Nowak <nowakra@gmail.com>
@radius-functional-tests
Copy link

radius-functional-tests bot commented May 15, 2024

Radius functional test overview

🔍 Go to test action run

Name Value
Repository rynowak/radius
Commit ref 5211238
Unique ID func60a79a549e
Image tag pr-func60a79a549e
Click here to see the list of tools in the current test run
  • gotestsum 1.10.0
  • KinD: v0.20.0
  • Dapr: 1.12.0
  • Azure KeyVault CSI driver: 1.4.2
  • Azure Workload identity webhook: 1.1.0
  • Bicep recipe location ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/<name>:pr-func60a79a549e
  • Terraform recipe location http://tf-module-server.radius-test-tf-module-server.svc.cluster.local/<name>.zip (in cluster)
  • applications-rp test image location: ghcr.io/radius-project/dev/applications-rp:pr-func60a79a549e
  • controller test image location: ghcr.io/radius-project/dev/controller:pr-func60a79a549e
  • ucp test image location: ghcr.io/radius-project/dev/ucpd:pr-func60a79a549e
  • deployment-engine test image location: ghcr.io/radius-project/deployment-engine:latest

Test Status

⌛ Building Radius and pushing container images for functional tests...
✅ Container images build succeeded
⌛ Publishing Bicep Recipes for functional tests...
✅ Recipe publishing succeeded
⌛ Starting shared functional tests...
⌛ Starting msgrp functional tests...
⌛ Starting cli functional tests...
⌛ Starting samples functional tests...
⌛ Starting kubernetes functional tests...
⌛ Starting daprrp functional tests...
⌛ Starting ucp functional tests...
⌛ Starting datastoresrp functional tests...
✅ msgrp functional tests succeeded
✅ kubernetes functional tests succeeded
✅ samples functional tests succeeded
✅ ucp functional tests succeeded
✅ daprrp functional tests succeeded
✅ cli functional tests succeeded
✅ datastoresrp functional tests succeeded
✅ shared functional tests succeeded

ListResourceGroups(ctx context.Context, planeName string) ([]ucp_v20231001preview.ResourceGroupResource, error)

// GetResourceGroup retrieves a resource group by its name.
GetResourceGroup(ctx context.Context, planeName string, resourceGroupName string) (ucp_v20231001preview.ResourceGroupResource, error)
Copy link
Contributor

Choose a reason for hiding this comment

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

Are the resourcegroup APIs not with NameOrID for a reason?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought about this decided against. Right now they take the planeName and the resourceGroupName which means that they can always build the resource id fully. So taking in a resourceGroupNameOrId would make the plane name redundant.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does this sound right? any better ideas?

Copy link
Contributor

Choose a reason for hiding this comment

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

This is fine too but I feel it would be better if all APIs accept similar input formats.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What do you think the right signature is?

An API like GetEnvironment(ctx, nameOrId) works because the client has a notion of "default scope" that can be prepended to the name.

What do you think the behavior of GetResourceGroup(ctx, nameOrId) should be?

GetResource(ctx context.Context, resourceType string, resourceNameOrID string) (generated.GenericResource, error)

// DeleteResource deletes a resource by its type and name (or id).
DeleteResource(ctx context.Context, resourceType string, resourceNameOrID string) (bool, error)
Copy link
Contributor

@vinayada1 vinayada1 May 15, 2024

Choose a reason for hiding this comment

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

Common comment for all the APIs: There are no tests to test these APIs by ID

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll double check this. I don't plan to add a "name test" + "id test" for every API. The difference between the name case and the ID case are handled in common code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I looked again and there's a good mix of tests that use names and tests that use IDs. It feels like a lot of wasted effort to test both cases for each of the 15 functions. They all call into the same code to resolve the full id.

Please let me know if there's something specific you want to see added.

Copy link
Contributor

@ytimocin ytimocin left a comment

Choose a reason for hiding this comment

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

Thanks for the change and all the unit tests.

pkg/cli/clients/management.go Show resolved Hide resolved
@rynowak
Copy link
Contributor Author

rynowak commented May 16, 2024

I'm going to merge this. @vinayada1 - if you have additional feedback for me to address I'll do it in a follow-up 👍

@rynowak rynowak merged commit 427eed2 into radius-project:main May 16, 2024
15 checks passed
@rynowak rynowak deleted the cli-client-groups branch May 16, 2024 00:47
Copy link
Contributor

@kachawla kachawla left a comment

Choose a reason for hiding this comment

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

👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants