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

[WIP] implemented test cases for network package #677

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

anandpulakala
Copy link

@anandpulakala anandpulakala commented Mar 5, 2025

added test cases for network package

JIRA Ticket:
https://issues.redhat.com/browse/OSD-28425

@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 5, 2025
Copy link
Contributor

openshift-ci bot commented Mar 5, 2025

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

Copy link
Contributor

openshift-ci bot commented Mar 5, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: anandpulakala
Once this PR has been reviewed and has the lgtm label, please assign fahlmant for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/ec2"
hivev1 "github.com/openshift/hive/apis/hive/v1"

"reflect"

Choose a reason for hiding this comment

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

nit: std lib packages should always be together

Copy link

Choose a reason for hiding this comment

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

Yeah, using tooling like goimports will help with that.

Copy link
Author

Choose a reason for hiding this comment

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

@christophermancini , @btoll ,
incorporated the changes mentioned above.

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client/fake"

Choose a reason for hiding this comment

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

nit: non-stdlib imports should be grouped, sorted

Copy link
Author

Choose a reason for hiding this comment

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

@christophermancini ,
incorporated the changes mentioned above.

Comment on lines 28 to 47
ginkgo.Context("When running the network command", func() {

ginkgo.It("should create the network command", func() {
gomega.Expect(cmd.Use).To(gomega.Equal("network"))
gomega.Expect(cmd.Short).To(gomega.Equal("network related utilities"))
gomega.Expect(len(cmd.Commands())).To(gomega.BeNumerically(">", 0))
})

ginkgo.It("should add the correct subcommands", func() {
gomega.Expect(len(cmd.Commands())).To(gomega.BeNumerically(">", 1))
subCmd := cmd.Commands()[0]
gomega.Expect(subCmd.Use).To(gomega.Equal("packet-capture"))
})

ginkgo.It("should execute the network command without errors", func() {
cmd.SetArgs([]string{})
err := cmd.Execute()
gomega.Expect(err).To(gomega.BeNil())
})
})
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you share a ticket for this work? I am curious the motivation for this work (more testing is good!).

However, I would question the benefit of testing things like cobra command setup. You are essentially testing that it compiles, which is already validated. I would also prefer to see basic testing done without using ginkgo, but I realize a lot of our projects have already pulled it in for some cases.

Copy link
Author

@anandpulakala anandpulakala Mar 6, 2025

Choose a reason for hiding this comment

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

We are trying to achieve 50% of the code coverage.

The tickets for this task are below:
https://issues.redhat.com/browse/SDE-2844
https://issues.redhat.com/browse/OSD-27869
https://issues.redhat.com/browse/OSD-27870

As part of 50% code coverage, we are testing cobra command setup as well, also as part of the tickets the recommendation was to use ginkgo for testing and hence we went ahead and created the test cases based on the direction provided.

Copy link

Choose a reason for hiding this comment

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

I agree with @joshbranham, we don't want to be testing the prerogatives of the cobra package, which I believe these tests are doing. We need to trust that the cobra team has already done their due diligence, leaving us free to test what we've done.

Choose a reason for hiding this comment

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

I am inclined to agree with Ben and Josh.

Copy link
Contributor

Choose a reason for hiding this comment

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

I will review this PR but I still would ask you remove testing for basic cobra behavior here. As far as "meeting 50% coverage" I personally will not hold your PR up for that, assuming we have added tests for our business logic 👍

Copy link
Author

Choose a reason for hiding this comment

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

Hi @joshbranham,
As per your comment, I have removed the cmd_test.go file as it only has test case for cobra command.
Below is the commit id for your reference:
0c3d955

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
got := generateServiceLog(tc.output, tc.clusterId)
if !reflect.DeepEqual(got, tc.want) {
Copy link

Choose a reason for hiding this comment

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

I was recently looking into comparing objects and the reflect package and came across this that you may find interesting:
https://github.com/google/go-cmp

Copy link

Choose a reason for hiding this comment

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

In my view, we should be using go-cmp instead of reflect.DeepEqual. There's good information in that link I provided, and the package is by the Go team.

Choose a reason for hiding this comment

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

+1 for go-cmp package

Copy link
Author

Choose a reason for hiding this comment

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

@christophermancini , @btoll

On going through the code, I found multiple references to the reflect package, one of them being the below file

https://github.com/openshift/osdctl/blob/e049bffecfb689c003fb4750ee58653afd4b8b57/cmd/account/mgmt/account-list_test.go

Hence, the decision was taken to use the reflect package.

Also, using go-cmp package will result in dependencies being installed which we would want to ideally avoid.

Copy link

Choose a reason for hiding this comment

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

My thoughts on this is that even though the reflect package is used in other areas, that doesn't mean that we can't update that to use a better alternative. The commit that introduced the reflect package in account-list_test.go is four years old.

When using caching, the next build will be significantly faster. I don't know if a run is able to use the cache, though.

Copy link

Choose a reason for hiding this comment

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

Also, since you brought in the assert library, why not do:

    for _, tc := range testCases {                                                                                                                                                              
        t.Run(tc.name, func(t *testing.T) {                                                                                                                                                     
            got := generateServiceLog(tc.output, tc.clusterId)                                                                                                                                  
            assert.Equal(t, tc.want.Template, got.Template)                                                                                                                                     
            assert.Equal(t, tc.want.ClusterId, got.ClusterId)                                                                                                                                   
            assert.Equal(t, tc.want.TemplateParams, got.TemplateParams)                                                                                                                         
        })                                                                                                                                                                                      
    } 

Copy link
Author

@anandpulakala anandpulakala Mar 21, 2025

Choose a reason for hiding this comment

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

changed as suggested

Choose a reason for hiding this comment

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

Also, go-cmp is a readily used and respected dependency with low overhead. It would only be included in the test binary, I feel confident it would be acceptable to add. In fact, it appears to be used heavily within the org already: https://github.com/search?type=code&q=org%3Aopenshift+go-cmp

want: "",
wantErr: false,
},
// Add more test cases for different scenarios
Copy link

Choose a reason for hiding this comment

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

Is this something that can be done now? :)

Copy link

@christophermancini christophermancini Mar 7, 2025

Choose a reason for hiding this comment

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

If we don't know what those scenarios are yet and creating them is out of scope for the current ticket, then lets remove the comment. It would be better to add a JIRA ticket to the backlog to define and add more test scenarios, than merge the comment to the main branch.

Copy link
Author

Choose a reason for hiding this comment

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

As requested, the extra comment has been removed.

Copy link

Choose a reason for hiding this comment

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

I'm looking again at this, and it's in scope to create more unit tests for this particular method. For instance, the getCaBundleFromManagementCluster and getCaBundleFromHive could possibly have their paths tested.

The logic is somewhat confusing, too. Passing it an empty string won't return an error, so why have a wantErr field in the struct?

Copy link
Author

Choose a reason for hiding this comment

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

Hi @btoll ,
I have removed all unnecessary cases and only added case for nill error,
If we go inside fetchCluster() it requires utils.createconnection mocking and as of now we are skipping it because to mock utils we needs update its implementation from tightly coupled struct to interface based.

@anandpulakala
Copy link
Author

/test all

@anandpulakala anandpulakala marked this pull request as ready for review March 10, 2025 07:06
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 10, 2025
@openshift-ci openshift-ci bot requested review from clcollins and fahlmant March 10, 2025 07:06
Copy link
Contributor

openshift-ci bot commented Mar 10, 2025

@anandpulakala: all tests passed!

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@anandpulakala anandpulakala marked this pull request as draft March 18, 2025 07:01
@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 18, 2025
@anandpulakala anandpulakala changed the title implemented test cases for network package [WIP] implemented test cases for network package Mar 18, 2025
@btoll
Copy link

btoll commented Mar 20, 2025

I think there are problems with the Test_egressVerificationGetPlatform test, specifically the following, which I believe is confusing why it is not raising an error:

        {                                                                                                                                                                                       
            name: "invalid",                                                                                                                                                                    
            e: &EgressVerification{                                                                                                                                                             
                cluster: newTestCluster(t, cmv1.NewCluster().CloudProvider(cmv1.NewCloudProvider().ID("foo"))),                                                                                 
                log:     newTestLogger(t),                                                                                                                                                      
            },        
            expectErr: true,                                                                                                                                                                          
        }, 

I think it should be more explicit that it is expected to fail.

cmd := NewCmdValidateEgress()
assert.NotNil(t, cmd)
assert.Equal(t, "verify-egress", cmd.Use)
}
Copy link

Choose a reason for hiding this comment

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

This can be removed, it's just testing cobra.

Copy link
Author

Choose a reason for hiding this comment

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

removed as suggested

}
}

func TestEgressVerification_GetPlatform(t *testing.T) {
Copy link

Choose a reason for hiding this comment

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

I think it would be valuable to separate these into two distinct tests, one that tests .platformName and one that tests .cluster.

Copy link
Author

Choose a reason for hiding this comment

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

seperated to two distinct tests as suggested

return &LazyClient{
client: c,
}
}
Copy link

Choose a reason for hiding this comment

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

Since this is only be used by a test suite, let's move it into that suite.

Copy link
Author

Choose a reason for hiding this comment

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

client is private to k8s.LazyClient, that's why I have put LazyClientMock() in K8s.

Copy link

Choose a reason for hiding this comment

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

In that case, we can use an interface which the mock would implement. We can then remove these additions from that package.

Copy link
Author

Choose a reason for hiding this comment

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

we can't mock that in packetcaptureOptions k8s.LazyClient is struct, to use mock we have to change it to interface. If we change K8s.LazyClient to interface then we have to make changes at all the places where lazyClient is being called.
if we don't want to change in client.go, then shall we skip this Test case ?

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctx := context.Background()
err := test.e.fetchCluster(ctx)
Copy link

Choose a reason for hiding this comment

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

This isn't really testing much, because when a ClusterId isn't provided it's just short-circuiting the fetchCluster method and returning nil. There's never a situation where an error would be returned.

Copy link
Author

Choose a reason for hiding this comment

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

I have removed the extra cases, now it is testing only for negative case, positive cases cannot be tested as they are using utils.createConnection(), for this we need to mock utils package.

reason: tt.reason,
kubeCli: &k8s.LazyClient{},
}
err := ops.complete(nil, nil)
Copy link

Choose a reason for hiding this comment

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

This isn't really testing much. When a reason is given, it should test the impersonated 'userName' and 'elevationReasons`.

Also, the wantErr pattern isn't useful here. The complete method will never return a legitimate error.

Copy link
Author

Choose a reason for hiding this comment

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

I have removed wantErr field, but we cannot compare userName & elevationReasons as they are private to LazyClient.

assert.Equal(t, 1, len(pod.Spec.Containers))
}

func TestNewPacketCaptureOptionsOne(t *testing.T) {
Copy link

Choose a reason for hiding this comment

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

This looks like a duplicate of TestNewPacketCaptureOptions.

Copy link
Author

Choose a reason for hiding this comment

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

I have removed the duplicate TestNewPacketCaptureOptions as suggested.

assert.Equal(t, 1, len(ds.Spec.Template.Spec.Containers))
}

func TestDesiredPacketCapturePodExist(t *testing.T) {
Copy link

Choose a reason for hiding this comment

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

Is this significantly different from TestDesiredPacketCapturePod?

Copy link
Author

Choose a reason for hiding this comment

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

removed as it is not required

assert.Equal(t, lazyClient, ops.kubeCli)
}

func TestDesiredPacketCaptureDaemonSetOne(t *testing.T) {
Copy link

Choose a reason for hiding this comment

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

How is this different from TestDesiredPacketCaptureDaemonSet? Should they be grouped?

Copy link
Author

Choose a reason for hiding this comment

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

removed as it is not required

Copy link

@christophermancini christophermancini left a comment

Choose a reason for hiding this comment

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

Several nits, but otherwise it is looking good.

"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"

"github.com/openshift/osdctl/pkg/k8s"

Choose a reason for hiding this comment

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

nit: should be grouped at minimum with other github.com packages

Copy link
Author

Choose a reason for hiding this comment

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

reordered with github.com

)

func TestHelperProcess(t *testing.T) {

Choose a reason for hiding this comment

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

A comment describing this pattern and its value, or a link to a document describing the pattern would be helpful.

Copy link
Author

Choose a reason for hiding this comment

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

removed as it is not needed

err := ops.complete(nil, nil)
if tt.wantErr {
assert.Error(t, err)
} else {

Choose a reason for hiding this comment

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

nit: would prefer use of return within if conditional instead of using an else statement.

if tt.wantError {
assert.Error(t, err)
expectedErr := fmt.Errorf("failed to delete Pod %s/%s: %v", tt.pod.Namespace, tt.pod.Name, tt.mockError)
assert.Equal(t, expectedErr.Error(), err.Error())

Choose a reason for hiding this comment

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

nit: same as above, use return instead of else.

wantErr bool
}{
{
name: "without reason",

Choose a reason for hiding this comment

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

nit: use snake_case for subtest names. Go will automatically add them, by using them in the code, a developer can copy paste the test name from terminal and paste it into CTRL+F in their IDE to find the exact test quicker.

Copy link
Author

Choose a reason for hiding this comment

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

changed to snake_case as suggested


"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/runtime"

Choose a reason for hiding this comment

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

nit: remove newline and sort

Copy link
Author

Choose a reason for hiding this comment

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

removed extra line

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/aws/aws-sdk-go-v2/service/ec2/types"

Choose a reason for hiding this comment

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

nit: remove newline and sort

Copy link
Author

Choose a reason for hiding this comment

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

removed extra line

cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
"github.com/openshift-online/ocm-sdk-go/logging"
hivev1 "github.com/openshift/hive/apis/hive/v1"

Choose a reason for hiding this comment

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

nit: remove newline and sort

Copy link
Author

Choose a reason for hiding this comment

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

removed extra line

onv "github.com/openshift/osd-network-verifier/pkg/verifier"

Choose a reason for hiding this comment

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

nit: remove newline and sort

Copy link
Author

Choose a reason for hiding this comment

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

removed extra line

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants