Skip to content

Commit b82d34b

Browse files
authored
using mw finalizer instead of resource finalizer (#150)
Signed-off-by: Wei Liu <liuweixa@redhat.com>
1 parent f472a9f commit b82d34b

7 files changed

Lines changed: 84 additions & 69 deletions

File tree

pkg/cloudevents/clients/common/common.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ const CloudEventsOriginalSourceLabelKey = "cloudevents.open-cluster-management.i
3030
// ResourceDeleted represents a resource is deleted.
3131
const ResourceDeleted = "Deleted"
3232

33-
const ResourceFinalizer = "cloudevents.open-cluster-management.io/resource-cleanup"
34-
3533
var ManagedClusterGK = schema.GroupKind{Group: clusterv1.GroupName, Kind: "ManagedCluster"}
3634
var ManagedClusterGR = schema.GroupResource{Group: clusterv1.GroupName, Resource: "managedclusters"}
3735

pkg/cloudevents/clients/utils/utils.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"k8s.io/client-go/tools/cache"
2222
"k8s.io/klog/v2"
2323

24-
"open-cluster-management.io/sdk-go/pkg/cloudevents/clients/common"
2524
"open-cluster-management.io/sdk-go/pkg/cloudevents/generic"
2625
)
2726

@@ -225,23 +224,6 @@ func UID(sourceID, groupResource, namespace, name string) string {
225224
return uuid.NewSHA1(uuid.NameSpaceOID, []byte(id)).String()
226225
}
227226

228-
// EnsureResourceFinalizer ensures the resource finalizer in the given finalizers
229-
func EnsureResourceFinalizer(finalizers []string) []string {
230-
has := false
231-
for _, f := range finalizers {
232-
if f == common.ResourceFinalizer {
233-
has = true
234-
break
235-
}
236-
}
237-
238-
if !has {
239-
finalizers = append(finalizers, common.ResourceFinalizer)
240-
}
241-
242-
return finalizers
243-
}
244-
245227
func IsStatusPatch(subresources []string) bool {
246228
if len(subresources) == 0 {
247229
return false

pkg/cloudevents/clients/utils/utils_test.go

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package utils
22

33
import (
44
"encoding/json"
5-
"reflect"
65
"testing"
76

87
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -453,41 +452,3 @@ func TestCompareSnowflakeSequenceIDs(t *testing.T) {
453452
})
454453
}
455454
}
456-
457-
func TestEnsureResourceFinalizer(t *testing.T) {
458-
tests := []struct {
459-
name string
460-
input []string
461-
wantOutput []string
462-
}{
463-
{
464-
name: "empty finalizers",
465-
input: []string{},
466-
wantOutput: []string{common.ResourceFinalizer},
467-
},
468-
{
469-
name: "finalizer already exists",
470-
input: []string{"other-finalizer", common.ResourceFinalizer},
471-
wantOutput: []string{"other-finalizer", common.ResourceFinalizer},
472-
},
473-
{
474-
name: "finalizer not present",
475-
input: []string{"finalizer1", "finalizer2"},
476-
wantOutput: []string{"finalizer1", "finalizer2", common.ResourceFinalizer},
477-
},
478-
{
479-
name: "nil input",
480-
input: nil,
481-
wantOutput: []string{common.ResourceFinalizer},
482-
},
483-
}
484-
485-
for _, tt := range tests {
486-
t.Run(tt.name, func(t *testing.T) {
487-
got := EnsureResourceFinalizer(tt.input)
488-
if !reflect.DeepEqual(got, tt.wantOutput) {
489-
t.Errorf("EnsureFinalizers() = %v, want %v", got, tt.wantOutput)
490-
}
491-
})
492-
}
493-
}

pkg/cloudevents/clients/utils/work.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,20 @@ func EncodeManifests(work *workv1.ManifestWork) error {
4848

4949
return nil
5050
}
51+
52+
// EnsureManifestWorkFinalizer ensures the manifestwork finalizer in the given finalizers
53+
func EnsureManifestWorkFinalizer(finalizers []string) []string {
54+
has := false
55+
for _, f := range finalizers {
56+
if f == workv1.ManifestWorkFinalizer {
57+
has = true
58+
break
59+
}
60+
}
61+
62+
if !has {
63+
finalizers = append(finalizers, workv1.ManifestWorkFinalizer)
64+
}
65+
66+
return finalizers
67+
}

pkg/cloudevents/clients/utils/work_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package utils
22

33
import (
44
"encoding/json"
5+
"reflect"
56
"testing"
67

78
corev1 "k8s.io/api/core/v1"
@@ -64,6 +65,44 @@ func TestEncodeManifests(t *testing.T) {
6465
}
6566
}
6667

68+
func TestEnsureManifestWorkFinalizer(t *testing.T) {
69+
tests := []struct {
70+
name string
71+
input []string
72+
wantOutput []string
73+
}{
74+
{
75+
name: "empty finalizers",
76+
input: []string{},
77+
wantOutput: []string{workv1.ManifestWorkFinalizer},
78+
},
79+
{
80+
name: "finalizer already exists",
81+
input: []string{"other-finalizer", workv1.ManifestWorkFinalizer},
82+
wantOutput: []string{"other-finalizer", workv1.ManifestWorkFinalizer},
83+
},
84+
{
85+
name: "finalizer not present",
86+
input: []string{"finalizer1", "finalizer2"},
87+
wantOutput: []string{"finalizer1", "finalizer2", workv1.ManifestWorkFinalizer},
88+
},
89+
{
90+
name: "nil input",
91+
input: nil,
92+
wantOutput: []string{workv1.ManifestWorkFinalizer},
93+
},
94+
}
95+
96+
for _, tt := range tests {
97+
t.Run(tt.name, func(t *testing.T) {
98+
got := EnsureManifestWorkFinalizer(tt.input)
99+
if !reflect.DeepEqual(got, tt.wantOutput) {
100+
t.Errorf("EnsureManifestWorkFinalizer() = %v, want %v", got, tt.wantOutput)
101+
}
102+
})
103+
}
104+
}
105+
67106
func configMap() *corev1.ConfigMap {
68107
return &corev1.ConfigMap{
69108
TypeMeta: metav1.TypeMeta{

pkg/cloudevents/clients/work/store/base.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ func (b *workProcessor) handleWork(work *workv1.ManifestWork) error {
155155
return nil
156156
}
157157

158-
// the work has been handled by agent, we ensure a finalizer on the work
159-
updatedWork.Finalizers = utils.EnsureResourceFinalizer(updatedWork.Finalizers)
158+
// the work has been handled by agent, we ensure the manifestwork finalizer on the work
159+
updatedWork.Finalizers = utils.EnsureManifestWorkFinalizer(updatedWork.Finalizers)
160160
updatedWork.Annotations[common.CloudEventsSequenceIDAnnotationKey] = sequenceID
161161
updatedWork.Status = work.Status
162162
// update the work with status in the local cache.

pkg/cloudevents/generic/options/grpc/protocol/heartbeat_integration_test.go

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,17 @@ func setupMockServerWithHeartbeat(t *testing.T, heartbeatInterval time.Duration,
7474
}
7575
pbv1.RegisterCloudEventServiceServer(s, service)
7676

77+
serverReady := make(chan struct{})
7778
go func() {
79+
close(serverReady)
7880
if err := s.Serve(lis); err != nil {
7981
t.Logf("Server exited with error: %v", err)
8082
}
8183
}()
8284

83-
time.Sleep(50 * time.Millisecond)
85+
// Wait for server to be ready
86+
<-serverReady
87+
time.Sleep(10 * time.Millisecond) // Small grace period for gRPC initialization
8488

8589
bufDialer := func(context.Context, string) (net.Conn, error) {
8690
return lis.Dial()
@@ -117,32 +121,32 @@ func TestProtocol_HeartbeatIntegration(t *testing.T) {
117121
heartbeatInterval: 100 * time.Millisecond,
118122
serverHealthinessTimeout: ptr.To(500 * time.Millisecond),
119123
expectHealthCheckError: false,
120-
testDuration: 800 * time.Millisecond,
124+
testDuration: 1500 * time.Millisecond, // Increased for stability
121125
stopServerAfterEvents: 0,
122126
},
123127
{
124128
name: "health check timeout when no heartbeats",
125129
heartbeatInterval: 0, // No heartbeats
126130
serverHealthinessTimeout: ptr.To(200 * time.Millisecond),
127131
expectHealthCheckError: true,
128-
testDuration: 500 * time.Millisecond,
132+
testDuration: 1000 * time.Millisecond, // Increased to allow Subscribe + timeout
129133
stopServerAfterEvents: 0,
130134
},
131135
{
132136
name: "health check disabled",
133137
heartbeatInterval: 0, // No heartbeats
134138
serverHealthinessTimeout: nil, // Disabled
135139
expectHealthCheckError: false,
136-
testDuration: 300 * time.Millisecond,
140+
testDuration: 500 * time.Millisecond, // Increased for stability
137141
stopServerAfterEvents: 0,
138142
},
139143
{
140144
name: "heartbeat stops mid-stream",
141145
heartbeatInterval: 50 * time.Millisecond,
142146
serverHealthinessTimeout: ptr.To(200 * time.Millisecond),
143147
expectHealthCheckError: true,
144-
testDuration: 600 * time.Millisecond,
145-
stopServerAfterEvents: 3, // Stop after 3 heartbeats
148+
testDuration: 1000 * time.Millisecond, // Increased to allow Subscribe + timeout
149+
stopServerAfterEvents: 3, // Stop after 3 heartbeats
146150
},
147151
}
148152

@@ -169,7 +173,10 @@ func TestProtocol_HeartbeatIntegration(t *testing.T) {
169173
ctx, cancel := context.WithTimeout(context.Background(), tt.testDuration)
170174
defer cancel()
171175

176+
// Use a channel to ensure OpenInbound has started before checking for errors
177+
started := make(chan struct{})
172178
go func() {
179+
close(started)
173180
if err := p.OpenInbound(ctx); err != nil {
174181
select {
175182
case p.reconnectErrorChan <- err:
@@ -178,6 +185,10 @@ func TestProtocol_HeartbeatIntegration(t *testing.T) {
178185
}
179186
}()
180187

188+
// Wait for goroutine to start and give Subscribe call time to establish
189+
<-started
190+
time.Sleep(100 * time.Millisecond)
191+
181192
if tt.expectHealthCheckError {
182193
select {
183194
case err := <-reconnectErrorChan:
@@ -218,7 +229,7 @@ func TestProtocol_StartEventsReceiver_HeartbeatFiltering(t *testing.T) {
218229
t.Fatal(err)
219230
}
220231

221-
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
232+
ctx, cancel := context.WithTimeout(context.Background(), 1000*time.Millisecond)
222233
defer cancel()
223234

224235
var receivedEvents atomic.Int32
@@ -232,7 +243,10 @@ func TestProtocol_StartEventsReceiver_HeartbeatFiltering(t *testing.T) {
232243
}
233244
}()
234245

246+
// Use a channel to ensure OpenInbound has started before checking for errors
247+
started := make(chan struct{})
235248
go func() {
249+
close(started)
236250
if err := p.OpenInbound(ctx); err != nil {
237251
select {
238252
case p.reconnectErrorChan <- err:
@@ -241,6 +255,10 @@ func TestProtocol_StartEventsReceiver_HeartbeatFiltering(t *testing.T) {
241255
}
242256
}()
243257

258+
// Wait for goroutine to start and give Subscribe call time to establish
259+
<-started
260+
time.Sleep(100 * time.Millisecond)
261+
244262
<-ctx.Done()
245263

246264
// Should receive 0 events since only heartbeats are sent (which are filtered out)
@@ -313,7 +331,7 @@ func TestProtocol_OpenInbound_ValidationErrors(t *testing.T) {
313331
t.Fatal(err)
314332
}
315333

316-
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
334+
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
317335
defer cancel()
318336

319337
err = p.OpenInbound(ctx)

0 commit comments

Comments
 (0)