Skip to content

Commit aac437f

Browse files
committed
test
Signed-off-by: Ryan Zhang <[email protected]>
1 parent 49671bf commit aac437f

File tree

29 files changed

+7949
-387
lines changed

29 files changed

+7949
-387
lines changed

.github/.copilot/breadcrumbs/2025-06-05-1700-combined-scheduler-interface-refactor.md

Lines changed: 349 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# naming convention
2+
All APIs whose name starts with Cluster are clusterScoped resources while its counterpart whose name matches the remainder of the API represents a namespace scoped resource.
3+
For example, we have ClusterResourcePlacement API and ResourcePlacement API. The former is cluster scoped while the latter is namespace scoped.
4+
# The difference between cluster scoped and namespace scoped resources
5+
The main difference between cluster scoped and namespace scoped resources is that cluster scoped resources are not bound to a specific namespace and can be accessed across the entire cluster, while namespace scoped resources are bound to a specific namespace and can only be accessed within that namespace. This translates to the following differences in how to get, list, create, update, and delete these resources:
6+
## Cluster Scoped Resources
7+
When one does CRUD on a cluster scoped resources, it only needs to know its name and type, i.e. something like this client.Get(ctx, types.NamespacedName{Name: string(name)}, crp)
8+
## Namespace Scoped Resources
9+
When one does CRUD on a namespace scoped resources, it needs to know its name, type, and namespace, i.e. something like this client.Get(ctx, types.NamespacedName{Name: string(name), Namespace: namespace}, rp)

.github/copilot-instructions.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ The main idea is that we are creating a multi-cluster application management sol
1010
- If you're waiting for my confirmation ("OK"), proceed without further prompting.
1111
- Follow the [Uber Go Style Guide](https://github.com/uber-go/guide/blob/master/style.md) if possible.
1212
- Favor using the standard library over third-party libraries.
13-
- Run "goimports" on save.
14-
- Run "golangci-lint" and "go vet" to check for errors.
15-
- Use "go mod tidy" if the dependencies are changed.
1613
- Run "make reviewable" before submitting a pull request to ensure the code is formatted correctly and all dependencies are up to date.
1714

1815
## Terminology
@@ -124,6 +121,7 @@ A breadcrumb is a collaborative scratch pad that allow the user and agent to get
124121
- **Get explicit approval** on the plan before implementation.
125122
- Update the breadcrumb **AFTER completing each significant change**.
126123
- Keep the breadcrumb as our single source of truth as it contains the most recent information.
124+
- Do not ask for approval **BEFORE** running unit tests or integration tests.
127125

128126
5. Ask me to verify the plan with: "Are you happy with this implementation plan?" before proceeding with code changes.
129127

apis/interface.go

Lines changed: 0 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ limitations under the License.
1818
package apis
1919

2020
import (
21-
"github.com/kubefleet-dev/kubefleet/apis/placement/v1beta1"
2221
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2322
"sigs.k8s.io/controller-runtime/pkg/client"
2423
)
@@ -37,91 +36,3 @@ type ConditionedObj interface {
3736
client.Object
3837
Conditioned
3938
}
40-
41-
// A PlacementSpec contains placementSpec
42-
// +kubebuilder:object:generate=false
43-
type PlacementSpec interface {
44-
GetPlacementSpec() *v1beta1.PlacementSpec
45-
SetPlacementSpec(*v1beta1.PlacementSpec)
46-
}
47-
48-
// A PlacementStatus contains placementStatus
49-
// +kubebuilder:object:generate=false
50-
type PlacementStatus interface {
51-
GetPlacementStatus() *v1beta1.PlacementStatus
52-
SetPlacementStatus(*v1beta1.PlacementStatus)
53-
}
54-
55-
// A PlacementObj is for kubernetes resource placement object.
56-
// +kubebuilder:object:generate=false
57-
type PlacementObj interface {
58-
client.Object
59-
PlacementSpec
60-
PlacementStatus
61-
}
62-
63-
// A BindingSpec contains bindingSpec
64-
// +kubebuilder:object:generate=false
65-
type BindingSpec interface {
66-
GetBindingSpec() *v1beta1.ResourceBindingSpec
67-
SetBindingSpec(*v1beta1.ResourceBindingSpec)
68-
}
69-
70-
// A BindingStatus contains bindingStatus
71-
// +kubebuilder:object:generate=false
72-
type BindingStatus interface {
73-
GetBindingStatus() *v1beta1.ResourceBindingStatus
74-
SetBindingStatus(*v1beta1.ResourceBindingStatus)
75-
}
76-
77-
// A BindingObj is for kubernetes resource binding object.
78-
// +kubebuilder:object:generate=false
79-
type BindingObj interface {
80-
client.Object
81-
BindingSpec
82-
BindingStatus
83-
}
84-
85-
// A PolicySnapshotSpec contains policy snapshot spec
86-
// +kubebuilder:object:generate=false
87-
type PolicySnapshotSpec interface {
88-
GetPolicySnapshotSpec() *v1beta1.SchedulingPolicySnapshotSpec
89-
SetPolicySnapshotSpec(*v1beta1.SchedulingPolicySnapshotSpec)
90-
}
91-
92-
// A PolicySnapshotStatus contains policy snapshot status
93-
// +kubebuilder:object:generate=false
94-
type PolicySnapshotStatus interface {
95-
GetPolicySnapshotStatus() *v1beta1.SchedulingPolicySnapshotStatus
96-
SetPolicySnapshotStatus(*v1beta1.SchedulingPolicySnapshotStatus)
97-
}
98-
99-
// A PolicySnapshotObj is for kubernetes policy snapshot object.
100-
// +kubebuilder:object:generate=false
101-
type PolicySnapshotObj interface {
102-
client.Object
103-
PolicySnapshotSpec
104-
PolicySnapshotStatus
105-
}
106-
107-
// A ResourceSnapshotSpec contains resource snapshot spec
108-
// +kubebuilder:object:generate=false
109-
type ResourceSnapshotSpec interface {
110-
GetResourceSnapshotSpec() *v1beta1.ResourceSnapshotSpec
111-
SetResourceSnapshotSpec(*v1beta1.ResourceSnapshotSpec)
112-
}
113-
114-
// A ResourceSnapshotStatus contains resource snapshot status
115-
// +kubebuilder:object:generate=false
116-
type ResourceSnapshotStatus interface {
117-
GetResourceSnapshotStatus() *v1beta1.ResourceSnapshotStatus
118-
SetResourceSnapshotStatus(*v1beta1.ResourceSnapshotStatus)
119-
}
120-
121-
// A ResourceSnapshotObj is for kubernetes resource snapshot object.
122-
// +kubebuilder:object:generate=false
123-
type ResourceSnapshotObj interface {
124-
client.Object
125-
ResourceSnapshotSpec
126-
ResourceSnapshotStatus
127-
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
Copyright 2025 The KubeFleet Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package v1beta1 contains API Schema definitions for the fleet placement v1beta1 API group
18+
19+
// +kubebuilder:object:generate=false
20+
// +k8s:deepcopy-gen=package,register
21+
// +groupName=placement.kubernetes-fleet.io
22+
package v1beta1
23+
24+
import "sigs.k8s.io/controller-runtime/pkg/client"
25+
26+
// PlacementSpecGetSetter offers the functionality to work with the placementSpec.
27+
// +kubebuilder:object:generate=false
28+
type PlacementSpecGetSetter interface {
29+
GetPlacementSpec() *PlacementSpec
30+
SetPlacementSpec(*PlacementSpec)
31+
}
32+
33+
// PlacementStatusGetSetter offers the functionality to work with the PlacementStatusGetSetter.
34+
// +kubebuilder:object:generate=false
35+
type PlacementStatusGetSetter interface {
36+
GetPlacementStatus() *PlacementStatus
37+
SetPlacementStatus(*PlacementStatus)
38+
}
39+
40+
var _ PlacementObj = &ClusterResourcePlacement{}
41+
var _ PlacementObj = &ResourcePlacement{}
42+
43+
// PlacementObj offers the functionality to work with kubernetes resource placement object.
44+
// +kubebuilder:object:generate=false
45+
type PlacementObj interface {
46+
client.Object
47+
PlacementSpecGetSetter
48+
PlacementStatusGetSetter
49+
}
50+
51+
// A BindingSpecGetSetter contains bindingSpec
52+
// +kubebuilder:object:generate=false
53+
type BindingSpecGetSetter interface {
54+
GetBindingSpec() *ResourceBindingSpec
55+
SetBindingSpec(*ResourceBindingSpec)
56+
}
57+
58+
// A BindingStatusGetSetter contains bindingStatus
59+
// +kubebuilder:object:generate=false
60+
type BindingStatusGetSetter interface {
61+
GetBindingStatus() *ResourceBindingStatus
62+
SetBindingStatus(*ResourceBindingStatus)
63+
}
64+
65+
var _ BindingObj = &ClusterResourceBinding{}
66+
var _ BindingObj = &ResourceBinding{}
67+
68+
// A BindingObj is for kubernetes resource binding object.
69+
// +kubebuilder:object:generate=false
70+
type BindingObj interface {
71+
client.Object
72+
BindingSpecGetSetter
73+
BindingStatusGetSetter
74+
}
75+
76+
// A PolicySnapshotSpecGetSetter contains policy snapshot spec
77+
// +kubebuilder:object:generate=false
78+
type PolicySnapshotSpecGetSetter interface {
79+
GetPolicySnapshotSpec() *SchedulingPolicySnapshotSpec
80+
SetPolicySnapshotSpec(*SchedulingPolicySnapshotSpec)
81+
}
82+
83+
// A PolicySnapshotStatusGetSetter contains policy snapshot status
84+
// +kubebuilder:object:generate=false
85+
type PolicySnapshotStatusGetSetter interface {
86+
GetPolicySnapshotStatus() *SchedulingPolicySnapshotStatus
87+
SetPolicySnapshotStatus(*SchedulingPolicySnapshotStatus)
88+
}
89+
90+
// A PolicySnapshotObj is for kubernetes policy snapshot object.
91+
// +kubebuilder:object:generate=false
92+
type PolicySnapshotObj interface {
93+
client.Object
94+
PolicySnapshotSpecGetSetter
95+
PolicySnapshotStatusGetSetter
96+
}
97+
98+
// A PolicySnapshotSpec contains policy snapshot spec
99+
// +kubebuilder:object:generate=false
100+
type PolicySnapshotListItemGetter interface {
101+
GetPolicySnapshotObjs() []PolicySnapshotObj
102+
}
103+
104+
// A PolicySnapshotList is for kubernetes policy snapshot list object.
105+
// +kubebuilder:object:generate=false
106+
type PolicySnapshotList interface {
107+
client.ObjectList
108+
PolicySnapshotListItemGetter
109+
}
110+
111+
// A ResourceSnapshotSpecGetSettter contains resource snapshot spec
112+
// +kubebuilder:object:generate=false
113+
type ResourceSnapshotSpecGetSettter interface {
114+
GetResourceSnapshotSpec() *ResourceSnapshotSpec
115+
SetResourceSnapshotSpec(*ResourceSnapshotSpec)
116+
}
117+
118+
// A ResourceSnapshotStatusGetSetter contains resource snapshot status
119+
// +kubebuilder:object:generate=false
120+
type ResourceSnapshotStatusGetSetter interface {
121+
GetResourceSnapshotStatus() *ResourceSnapshotStatus
122+
SetResourceSnapshotStatus(*ResourceSnapshotStatus)
123+
}
124+
125+
var _ ResourceSnapshotObj = &ClusterResourceSnapshot{}
126+
var _ ResourceSnapshotObj = &ResourceSnapshot{}
127+
128+
// A ResourceSnapshotObj is for kubernetes resource snapshot object.
129+
// +kubebuilder:object:generate=false
130+
type ResourceSnapshotObj interface {
131+
client.Object
132+
ResourceSnapshotSpecGetSettter
133+
ResourceSnapshotStatusGetSetter
134+
}

apis/placement/v1beta1/policysnapshot_types.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ const (
3232
NumberOfClustersAnnotation = fleetPrefix + "number-of-clusters"
3333
)
3434

35+
// make sure the PolicySnapshotObj and PolicySnapshotList interfaces are implemented by the
36+
// ClusterSchedulingPolicySnapshot and SchedulingPolicySnapshot types.
37+
var _ PolicySnapshotObj = &ClusterSchedulingPolicySnapshot{}
38+
var _ PolicySnapshotObj = &SchedulingPolicySnapshot{}
39+
var _ PolicySnapshotList = &ClusterSchedulingPolicySnapshotList{}
40+
var _ PolicySnapshotList = &SchedulingPolicySnapshotList{}
41+
3542
// +genclient
3643
// +genclient:nonNamespaced
3744
// +kubebuilder:object:root=true
@@ -204,6 +211,15 @@ func (m *ClusterSchedulingPolicySnapshot) GetCondition(conditionType string) *me
204211
return meta.FindStatusCondition(m.Status.Conditions, conditionType)
205212
}
206213

214+
// GetPolicySnapshotObjs returns the list of PolicySnapshotObj from the ClusterSchedulingPolicySnapshotList.
215+
func (c *ClusterSchedulingPolicySnapshotList) GetPolicySnapshotObjs() []PolicySnapshotObj {
216+
objs := make([]PolicySnapshotObj, 0, len(c.Items))
217+
for i := range c.Items {
218+
objs = append(objs, &c.Items[i])
219+
}
220+
return objs
221+
}
222+
207223
// +genclient
208224
// +genclient:Namespaced
209225
// +kubebuilder:object:root=true
@@ -288,6 +304,15 @@ func (m *SchedulingPolicySnapshot) GetCondition(conditionType string) *metav1.Co
288304
return meta.FindStatusCondition(m.Status.Conditions, conditionType)
289305
}
290306

307+
// GetPolicySnapshotObjs returns the list of PolicySnapshotObj from the SchedulingPolicySnapshotList.
308+
func (c *SchedulingPolicySnapshotList) GetPolicySnapshotObjs() []PolicySnapshotObj {
309+
objs := make([]PolicySnapshotObj, 0, len(c.Items))
310+
for i := range c.Items {
311+
objs = append(objs, &c.Items[i])
312+
}
313+
return objs
314+
}
315+
291316
func init() {
292317
SchemeBuilder.Register(&ClusterSchedulingPolicySnapshot{}, &ClusterSchedulingPolicySnapshotList{}, &SchedulingPolicySnapshot{}, &SchedulingPolicySnapshotList{})
293318
}

pkg/scheduler/framework/dummyplugin_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ const (
3030
// A no-op, dummy plugin which connects to all extension points.
3131
type DummyAllPurposePlugin struct {
3232
name string
33-
postBatchRunner func(ctx context.Context, state CycleStatePluginReadWriter, policy *placementv1beta1.ClusterSchedulingPolicySnapshot) (size int, status *Status)
34-
preFilterRunner func(ctx context.Context, state CycleStatePluginReadWriter, policy *placementv1beta1.ClusterSchedulingPolicySnapshot) (status *Status)
35-
filterRunner func(ctx context.Context, state CycleStatePluginReadWriter, policy *placementv1beta1.ClusterSchedulingPolicySnapshot, cluster *clusterv1beta1.MemberCluster) (status *Status)
36-
preScoreRunner func(ctx context.Context, state CycleStatePluginReadWriter, policy *placementv1beta1.ClusterSchedulingPolicySnapshot) (status *Status)
37-
scoreRunner func(ctx context.Context, state CycleStatePluginReadWriter, policy *placementv1beta1.ClusterSchedulingPolicySnapshot, cluster *clusterv1beta1.MemberCluster) (score *ClusterScore, status *Status)
33+
postBatchRunner func(ctx context.Context, state CycleStatePluginReadWriter, policy placementv1beta1.PolicySnapshotObj) (size int, status *Status)
34+
preFilterRunner func(ctx context.Context, state CycleStatePluginReadWriter, policy placementv1beta1.PolicySnapshotObj) (status *Status)
35+
filterRunner func(ctx context.Context, state CycleStatePluginReadWriter, policy placementv1beta1.PolicySnapshotObj, cluster *clusterv1beta1.MemberCluster) (status *Status)
36+
preScoreRunner func(ctx context.Context, state CycleStatePluginReadWriter, policy placementv1beta1.PolicySnapshotObj) (status *Status)
37+
scoreRunner func(ctx context.Context, state CycleStatePluginReadWriter, policy placementv1beta1.PolicySnapshotObj, cluster *clusterv1beta1.MemberCluster) (score *ClusterScore, status *Status)
3838
}
3939

4040
// Check that the dummy plugin implements all the interfaces at compile time.
@@ -52,27 +52,27 @@ func (p *DummyAllPurposePlugin) Name() string {
5252
}
5353

5454
// PostBatch implements the PostBatch interface for the dummy plugin.
55-
func (p *DummyAllPurposePlugin) PostBatch(ctx context.Context, state CycleStatePluginReadWriter, policy *placementv1beta1.ClusterSchedulingPolicySnapshot) (size int, status *Status) { //nolint:revive
55+
func (p *DummyAllPurposePlugin) PostBatch(ctx context.Context, state CycleStatePluginReadWriter, policy placementv1beta1.PolicySnapshotObj) (size int, status *Status) { //nolint:revive
5656
return p.postBatchRunner(ctx, state, policy)
5757
}
5858

5959
// PreFilter implements the PreFilter interface for the dummy plugin.
60-
func (p *DummyAllPurposePlugin) PreFilter(ctx context.Context, state CycleStatePluginReadWriter, policy *placementv1beta1.ClusterSchedulingPolicySnapshot) (status *Status) { //nolint:revive
60+
func (p *DummyAllPurposePlugin) PreFilter(ctx context.Context, state CycleStatePluginReadWriter, policy placementv1beta1.PolicySnapshotObj) (status *Status) { //nolint:revive
6161
return p.preFilterRunner(ctx, state, policy)
6262
}
6363

6464
// Filter implements the Filter interface for the dummy plugin.
65-
func (p *DummyAllPurposePlugin) Filter(ctx context.Context, state CycleStatePluginReadWriter, policy *placementv1beta1.ClusterSchedulingPolicySnapshot, cluster *clusterv1beta1.MemberCluster) (status *Status) { //nolint:revive
65+
func (p *DummyAllPurposePlugin) Filter(ctx context.Context, state CycleStatePluginReadWriter, policy placementv1beta1.PolicySnapshotObj, cluster *clusterv1beta1.MemberCluster) (status *Status) { //nolint:revive
6666
return p.filterRunner(ctx, state, policy, cluster)
6767
}
6868

6969
// PreScore implements the PreScore interface for the dummy plugin.
70-
func (p *DummyAllPurposePlugin) PreScore(ctx context.Context, state CycleStatePluginReadWriter, policy *placementv1beta1.ClusterSchedulingPolicySnapshot) (status *Status) { //nolint:revive
70+
func (p *DummyAllPurposePlugin) PreScore(ctx context.Context, state CycleStatePluginReadWriter, policy placementv1beta1.PolicySnapshotObj) (status *Status) { //nolint:revive
7171
return p.preScoreRunner(ctx, state, policy)
7272
}
7373

7474
// Score implements the Score interface for the dummy plugin.
75-
func (p *DummyAllPurposePlugin) Score(ctx context.Context, state CycleStatePluginReadWriter, policy *placementv1beta1.ClusterSchedulingPolicySnapshot, cluster *clusterv1beta1.MemberCluster) (score *ClusterScore, status *Status) { //nolint:revive
75+
func (p *DummyAllPurposePlugin) Score(ctx context.Context, state CycleStatePluginReadWriter, policy placementv1beta1.PolicySnapshotObj, cluster *clusterv1beta1.MemberCluster) (score *ClusterScore, status *Status) { //nolint:revive
7676
return p.scoreRunner(ctx, state, policy, cluster)
7777
}
7878

0 commit comments

Comments
 (0)