@@ -25,6 +25,7 @@ import (
2525 "github.com/nephio-project/porch/pkg/externalrepo/fake"
2626 "github.com/nephio-project/porch/pkg/repository"
2727 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28+ "k8s.io/apimachinery/pkg/runtime"
2829 "k8s.io/apimachinery/pkg/watch"
2930)
3031
@@ -97,3 +98,112 @@ func (f *fakePackageReader) watchPackages(ctx context.Context, filter repository
9798func (f * fakePackageReader ) listPackageRevisions (ctx context.Context , filter repository.ListPackageRevisionFilter , callback func (ctx context.Context , p repository.PackageRevision ) error ) error {
9899 return nil
99100}
101+ func TestWatcherNilObject (t * testing.T ) {
102+ tests := []struct {
103+ name string
104+ packages []repository.PackageRevision
105+ waitForStreaming bool
106+ sendEvent bool
107+ }{
108+ {
109+ name : "backlog phase" ,
110+ packages : nil ,
111+ sendEvent : false ,
112+ },
113+ {
114+ name : "streaming phase" ,
115+ packages : nil ,
116+ waitForStreaming : true ,
117+ sendEvent : true ,
118+ },
119+ {
120+ name : "list phase" ,
121+ packages : []repository.PackageRevision {
122+ & fake.FakePackageRevision {
123+ PackageRevision : & porchapi.PackageRevision {
124+ ObjectMeta : metav1.ObjectMeta {
125+ Labels : make (map [string ]string ),
126+ },
127+ },
128+ },
129+ },
130+ },
131+ }
132+
133+ for _ , tt := range tests {
134+ t .Run (tt .name , func (t * testing.T ) {
135+ ctx , cancelFunc := context .WithCancel (context .Background ())
136+ defer cancelFunc ()
137+
138+ w := & watcher {
139+ cancel : cancelFunc ,
140+ resultChan : make (chan watch.Event , 64 ),
141+ extractor : func (ctx context.Context , pr repository.PackageRevision ) (runtime.Object , error ) {
142+ return nil , nil
143+ },
144+ }
145+
146+ r := & nilCheckFakeReader {
147+ packages : tt .packages ,
148+ sendEventInBacklog : tt .name == "backlog phase" ,
149+ }
150+ r .Add (1 )
151+ var filter repository.ListPackageRevisionFilter
152+ go w .listAndWatch (ctx , r , filter )
153+ r .Wait ()
154+
155+ if tt .waitForStreaming {
156+ time .Sleep (100 * time .Millisecond )
157+ }
158+
159+ if tt .sendEvent {
160+ pkgRev := & fake.FakePackageRevision {
161+ PackageRevision : & porchapi.PackageRevision {
162+ ObjectMeta : metav1.ObjectMeta {
163+ Labels : make (map [string ]string ),
164+ },
165+ },
166+ }
167+ cont := r .callback .OnPackageRevisionChange (watch .Modified , pkgRev )
168+ if ! cont {
169+ t .Error ("Expected callback to return true for nil object" )
170+ }
171+ } else {
172+ time .Sleep (10 * time .Millisecond )
173+ }
174+ })
175+ }
176+ }
177+
178+ type nilCheckFakeReader struct {
179+ sync.WaitGroup
180+ callback engine.ObjectWatcher
181+ packages []repository.PackageRevision
182+ sendEventInBacklog bool
183+ }
184+
185+ func (f * nilCheckFakeReader ) watchPackages (ctx context.Context , filter repository.ListPackageRevisionFilter , callback engine.ObjectWatcher ) error {
186+ f .callback = callback
187+ if f .sendEventInBacklog {
188+ // Send event synchronously in backlog phase
189+ pkgRev := & fake.FakePackageRevision {
190+ PackageRevision : & porchapi.PackageRevision {
191+ ObjectMeta : metav1.ObjectMeta {
192+ Labels : make (map [string ]string ),
193+ },
194+ },
195+ }
196+ callback .OnPackageRevisionChange (watch .Modified , pkgRev )
197+ }
198+ f .Done ()
199+ return nil
200+ }
201+
202+ func (f * nilCheckFakeReader ) listPackageRevisions (ctx context.Context , filter repository.ListPackageRevisionFilter , callback func (ctx context.Context , p repository.PackageRevision ) error ) error {
203+ for _ , pkg := range f .packages {
204+ if err := callback (ctx , pkg ); err != nil {
205+ return err
206+ }
207+ }
208+ return nil
209+ }
0 commit comments