-
Notifications
You must be signed in to change notification settings - Fork 94
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
🌱 Refactor Tester to e2e framework pkg. #565
🌱 Refactor Tester to e2e framework pkg. #565
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #565 +/- ##
==========================================
- Coverage 62.56% 62.47% -0.10%
==========================================
Files 178 178
Lines 13968 13968
==========================================
- Hits 8739 8726 -13
- Misses 4347 4358 +11
- Partials 882 884 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
35bcd8e
to
0e4915b
Compare
/assign @qiujian16 |
65f9102
to
4979dc2
Compare
4979dc2
to
2fc636d
Compare
/assign @qiujian16 |
2fc636d
to
c5d063a
Compare
// CreateAndApproveKlusterlet requires operations on both hub side and spoke side | ||
func CreateAndApproveKlusterlet( | ||
hub *Hub, spoke *Spoke, | ||
klusterletName, managedClusterName, klusterletNamespace string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if spoke already has the klusterletName/namspace, why do we still need these variables in this func?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point.
The spoke has:
KlusterletOperatorNamespace
KlusterletOperator
Which is different from KlusterletNamespace
and Klusterlet
.
One represent the operator deployment, one represent a Klusterlet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does KlusterletOperator mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a copy of:
Line 73 in 7a8e444
klusterletOperator string |
I think it represents the deployment of of klusterlet operator:
name: klusterlet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not think this needs to be a variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true, maybe we can change these 2 to const values? I can submit a another smaller PR to follow up this.
test/framework/klusterlet.go
Outdated
return realKlusterlet, nil | ||
} | ||
|
||
func CreatePureHostedKlusterlet(spoke *Spoke, name, clusterName string) (*operatorapiv1.Klusterlet, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this func, and why this is different from CreateKlusterlet. When should we use this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good question but may beyond this PR's scope, the function is directly copied from Tester so I will try to answer.
Comparing with the CreateKlusterlet
which not only create Klusterlet but also create the related reasources like namespace, bootstrapkubeconfigsecret, externalKubeconfigSecret, the CreatePureHostedKlusterlet
only create Klusterlet, no another thing.
It seems there is a case that requires only Hosted mode Klusterlet, but don't want the external managed kubeconfig, that's why we want a more Pure
function.
It("Delete klusterlet CR in Hosted mode without external managed kubeconfig", func() {
By(fmt.Sprintf("create klusterlet %v with managed cluster name %v in Hosted mode", klusterletName, clusterName))
_, err := CreatePureHostedKlusterlet(spoke, klusterletName, clusterName)
Expect(err).ToNot(HaveOccurred())
I can add a TODO on this function and the CreateKlusterlet
to try to merge them into one if we need.
} | ||
|
||
// CleanKlusterletRelatedResources needs both hub side and spoke side operations | ||
func CleanKlusterletRelatedResources( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we actually should have a clean func for spoke and hub. Something like spoke.Cleanup() and hub.Cleaup, and call these two in this func.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, this is something simply copied and pasted in the PR.
But in this case, it's not like hub.Cleanup is suitable, because hub.Cleanup is like a entire hub Cleanup, in this function, we only want to clean up the managedcluster created by the klusterlet on the hub.
And also spoke != klustelret
, spoke has multiple klusterlet during the e2e.
So I think we can have hub.Cleanup and spoke.Cleanup but not for this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this could be confusing, because to me a spoke == a klusterlet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and for hub, hub.Cleanup(cluster1) should be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
During the e2e we are deploying multiple klusterlet on the same spoke:
ocm/test/e2e/klusterlet_test.go
Line 38 in 7a8e444
_, err := t.CreateKlusterlet(klusterletName, clusterName, klusterletNamespace, "") |
In our e2e, a spoke should be a cluster that has one klusterlet operator on it, but we can deploy multiple klusterlet on one spoke.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use CleanUpManagedCluster
? Because if we use CleanUp
specifically represent to clean up a managedcluster, then clean up manifestwork, clustermanager and other resources will be confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you will need:
1: just clean klusterlet CR,
2. clean klusterlet CR and klusterlet operator
3. just clean a managedcluster CR
4. clean them all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, can I list it as a TODO in the future? because "clean the klusterlet operator" part feels need more discussion, it's a behavior change comparing with previous code.
test/framework/managedcluster.go
Outdated
clusterv1 "open-cluster-management.io/api/cluster/v1" | ||
) | ||
|
||
func GetManagedCluster(hub *Hub, clusterName string) (*clusterv1.ManagedCluster, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If these are all hub side operation, shouldn't we make it as func in hub struct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good question, I think a lot on this, whether the GetManagedCluster
and other similar code blocks be a method of hub or a function.
The reason 1 is to keep the defination and scope of a hub
clear, hub is only:
- the client
- the metadata
- the runtime data
It provide information for us to do things, but not do things for us.
Most functions doesn't need the entire hub, but only some of clients. This part can be improved in the future. We will make each function's input and output clearly what it need.
Just in this time, change the function one by one is kind of time consuming, if we can first set the framework down, and then we can make enhancement with other meaningful refactors together. Such as refactor the CreatePureHostedKlusterlet
.
The reason 2 is, the GetManagedCluster
actually doesn't need the whole hub, it only needs the clusterclient
(again it's a copied-paste issue in this PR), and if we can have:
func GetManagedCluster(clusterclient clusterclient.Interface, clusterName string) (*clusterv1.ManagedCluster, error) {
if clusterName == "" {
return nil, fmt.Errorf("the name of managedcluster should not be null")
}
return clusterclient.ClusterV1().ManagedClusters().Get(context.TODO(), clusterName, metav1.GetOptions{})
}
That means we can reuse this function and this framework not only in e2e, but also the intergration test, the addon repo's e2e and integration, the downstream repos which rely on ocm.
Currently if we develop a addon or a component that rely on ocm, we write integration and e2e part(code and scripts) indenependly but if we can provide a ocm-test-framework, I think it can reduce some effort in write and maintaining these tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To my undstanding, hub defines a hub environment. A test case could manage hub environment with the hub struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I can change to hub.GetManagedCluster
since currently we have no plan for a ultimate test-framework for all ocm related repos. But I still think GetManagedCluster
is not limit to a hub environment, in integration cases, there is not hub just controllers and fake kube-apiserver, we can still reuse GetManagedCluster
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated, all functions are moved under hub and spoke as method.
c5d063a
to
eb60ecf
Compare
Signed-off-by: xuezhaojun <zxue@redhat.com>
eb60ecf
to
c7a262c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/approve
looks good in general, just some minor comments. And I would like everyone to take a look on the change. @open-cluster-management-io/core-dev
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: qiujian16, xuezhaojun The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Hi, @qiujian16 I have synced the changes with @open-cluster-management-io/core-dev in a internal weekly meeting, is it ok now to merge the PR? |
/lgtm |
6c4292b
into
open-cluster-management-io:main
Summary
In this PR, we refactor the Tester into a e2e framework pkg. The pkg includes:
managedcluster.go
file, there areGetManagedCluster
andCheckManagedClusterStatus
.The default
e2e
has 1 hub and 1 spoke, thehub
andspoke
are global varible so developer can easily use them, for example, if in your case, you want to do something on the ManagedCluster, you can do:You can also check the file
test/e2e/framework/managedcluster.go
to see if there is already a function implement your intention. All functions are seperated by different aspect so it's easier to find.