@@ -122,7 +122,7 @@ spec:
122122 copy .SetAPIVersion ("example.com/v1" )
123123 copy .SetKind ("CronTab" )
124124
125- err := wait .PollUntilContextTimeout (ctx , 500 * time .Millisecond , 1 * time .Minute , false , func (ctx context.Context ) (done bool , err error ) {
125+ err := wait .PollUntilContextTimeout (ctx , 500 * time .Millisecond , 30 * time .Second , false , func (ctx context.Context ) (done bool , err error ) {
126126 copyKey := types.NamespacedName {Namespace : "synced-default" , Name : "my-crontab" }
127127 return envtestClient .Get (ctx , copyKey , copy ) == nil , nil
128128 })
@@ -210,7 +210,7 @@ spec:
210210 copy .SetAPIVersion ("example.com/v1" )
211211 copy .SetKind ("CronTab" )
212212
213- err := wait .PollUntilContextTimeout (ctx , 500 * time .Millisecond , 1 * time .Minute , false , func (ctx context.Context ) (done bool , err error ) {
213+ err := wait .PollUntilContextTimeout (ctx , 500 * time .Millisecond , 30 * time .Second , false , func (ctx context.Context ) (done bool , err error ) {
214214 return envtestClient .Get (ctx , copyKey , copy ) == nil , nil
215215 })
216216 if err != nil {
@@ -244,7 +244,7 @@ spec:
244244
245245 // wait for the agent to sync again
246246 t .Logf ("Waiting for the agent to sync again…" )
247- err = wait .PollUntilContextTimeout (ctx , 500 * time .Millisecond , 1 * time .Minute , false , func (ctx context.Context ) (done bool , err error ) {
247+ err = wait .PollUntilContextTimeout (ctx , 500 * time .Millisecond , 30 * time .Second , false , func (ctx context.Context ) (done bool , err error ) {
248248 if err := envtestClient .Get (ctx , copyKey , copy ); err != nil {
249249 return false , err
250250 }
@@ -293,7 +293,7 @@ spec:
293293
294294 // wait for the agent to sync again
295295 t .Logf ("Waiting for the agent to sync again…" )
296- err = wait .PollUntilContextTimeout (ctx , 500 * time .Millisecond , 1 * time .Minute , false , func (ctx context.Context ) (done bool , err error ) {
296+ err = wait .PollUntilContextTimeout (ctx , 500 * time .Millisecond , 30 * time .Second , false , func (ctx context.Context ) (done bool , err error ) {
297297 if err := envtestClient .Get (ctx , copyKey , copy ); err != nil {
298298 return false , err
299299 }
@@ -332,3 +332,120 @@ func yamlToUnstructured(t *testing.T, data string) *unstructured.Unstructured {
332332
333333 return & unstructured.Unstructured {Object : unstructuredMap }
334334}
335+
336+ func TestResourceFilter (t * testing.T ) {
337+ const (
338+ apiExportName = "kcp.example.com"
339+ orgWorkspace = "sync-resource-filter"
340+ )
341+
342+ ctx := context .Background ()
343+ ctrlruntime .SetLogger (logr .Discard ())
344+
345+ // setup a test environment in kcp
346+ orgKubconfig := utils .CreateOrganization (t , ctx , orgWorkspace , apiExportName )
347+
348+ // start a service cluster
349+ envtestKubeconfig , envtestClient , _ := utils .RunEnvtest (t , []string {
350+ "test/crds/crontab.yaml" ,
351+ })
352+
353+ // publish Crontabs and Backups
354+ t .Logf ("Publishing CRDs…" )
355+ prCrontabs := & syncagentv1alpha1.PublishedResource {
356+ ObjectMeta : metav1.ObjectMeta {
357+ Name : "publish-crontabs" ,
358+ },
359+ Spec : syncagentv1alpha1.PublishedResourceSpec {
360+ Resource : syncagentv1alpha1.SourceResourceDescriptor {
361+ APIGroup : "example.com" ,
362+ Version : "v1" ,
363+ Kind : "CronTab" ,
364+ },
365+ // These rules make finding the local object easier, but should not be used in production.
366+ Naming : & syncagentv1alpha1.ResourceNaming {
367+ Name : "$remoteName" ,
368+ Namespace : "synced-$remoteNamespace" ,
369+ },
370+ Filter : & syncagentv1alpha1.ResourceFilter {
371+ Resource : & metav1.LabelSelector {
372+ MatchLabels : map [string ]string {
373+ "include" : "me" ,
374+ },
375+ },
376+ },
377+ },
378+ }
379+
380+ if err := envtestClient .Create (ctx , prCrontabs ); err != nil {
381+ t .Fatalf ("Failed to create PublishedResource: %v" , err )
382+ }
383+
384+ // start the agent in the background to update the APIExport with the CronTabs API
385+ utils .RunAgent (ctx , t , "bob" , orgKubconfig , envtestKubeconfig , apiExportName )
386+
387+ // wait until the API is available
388+ teamCtx := kontext .WithCluster (ctx , logicalcluster .Name (fmt .Sprintf ("root:%s:team-1" , orgWorkspace )))
389+ kcpClient := utils .GetKcpAdminClusterClient (t )
390+ utils .WaitForBoundAPI (t , teamCtx , kcpClient , schema.GroupVersionResource {
391+ Group : apiExportName ,
392+ Version : "v1" ,
393+ Resource : "crontabs" ,
394+ })
395+
396+ // create two Crontab objects in a team workspace
397+ t .Log ("Creating CronTab in kcp…" )
398+ ignoredCrontab := yamlToUnstructured (t , `
399+ apiVersion: kcp.example.com/v1
400+ kind: CronTab
401+ metadata:
402+ namespace: default
403+ name: ignored
404+ spec:
405+ image: ubuntu:latest
406+ ` )
407+
408+ if err := kcpClient .Create (teamCtx , ignoredCrontab ); err != nil {
409+ t .Fatalf ("Failed to create CronTab in kcp: %v" , err )
410+ }
411+
412+ includedCrontab := yamlToUnstructured (t , `
413+ apiVersion: kcp.example.com/v1
414+ kind: CronTab
415+ metadata:
416+ namespace: default
417+ name: included
418+ labels:
419+ include: me
420+ spec:
421+ image: debian:12
422+ ` )
423+
424+ if err := kcpClient .Create (teamCtx , includedCrontab ); err != nil {
425+ t .Fatalf ("Failed to create CronTab in kcp: %v" , err )
426+ }
427+
428+ // wait for the agent to sync only one of the objects down into the service cluster
429+
430+ t .Logf ("Wait for CronTab to be synced…" )
431+ copy := & unstructured.Unstructured {}
432+ copy .SetAPIVersion ("example.com/v1" )
433+ copy .SetKind ("CronTab" )
434+
435+ err := wait .PollUntilContextTimeout (ctx , 500 * time .Millisecond , 30 * time .Second , false , func (ctx context.Context ) (done bool , err error ) {
436+ copyKey := types.NamespacedName {Namespace : "synced-default" , Name : "included" }
437+ return envtestClient .Get (ctx , copyKey , copy ) == nil , nil
438+ })
439+ if err != nil {
440+ t .Fatalf ("Failed to wait for object to be synced down: %v" , err )
441+ }
442+
443+ // the only good negative check is to wait for a timeout
444+ err = wait .PollUntilContextTimeout (ctx , 500 * time .Millisecond , 30 * time .Second , false , func (ctx context.Context ) (done bool , err error ) {
445+ copyKey := types.NamespacedName {Namespace : "synced-default" , Name : "ignored" }
446+ return envtestClient .Get (ctx , copyKey , copy ) == nil , nil
447+ })
448+ if err == nil {
449+ t .Fatal ("Expected no ignored object to be found on the service cluster, but did." )
450+ }
451+ }
0 commit comments