@@ -122,7 +122,7 @@ spec:
122
122
copy .SetAPIVersion ("example.com/v1" )
123
123
copy .SetKind ("CronTab" )
124
124
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 ) {
126
126
copyKey := types.NamespacedName {Namespace : "synced-default" , Name : "my-crontab" }
127
127
return envtestClient .Get (ctx , copyKey , copy ) == nil , nil
128
128
})
@@ -210,7 +210,7 @@ spec:
210
210
copy .SetAPIVersion ("example.com/v1" )
211
211
copy .SetKind ("CronTab" )
212
212
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 ) {
214
214
return envtestClient .Get (ctx , copyKey , copy ) == nil , nil
215
215
})
216
216
if err != nil {
@@ -244,7 +244,7 @@ spec:
244
244
245
245
// wait for the agent to sync again
246
246
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 ) {
248
248
if err := envtestClient .Get (ctx , copyKey , copy ); err != nil {
249
249
return false , err
250
250
}
@@ -293,7 +293,7 @@ spec:
293
293
294
294
// wait for the agent to sync again
295
295
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 ) {
297
297
if err := envtestClient .Get (ctx , copyKey , copy ); err != nil {
298
298
return false , err
299
299
}
@@ -332,3 +332,120 @@ func yamlToUnstructured(t *testing.T, data string) *unstructured.Unstructured {
332
332
333
333
return & unstructured.Unstructured {Object : unstructuredMap }
334
334
}
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