@@ -739,3 +739,103 @@ spec:
739
739
t .Fatalf ("Failed to wait for object to be synced down: %v" , err )
740
740
}
741
741
}
742
+
743
+ func TestSyncWithWorkspacePath (t * testing.T ) {
744
+ const (
745
+ apiExportName = "kcp.example.com"
746
+ kcpGroupName = "kcp.example.com"
747
+ orgWorkspace = "sync-with-paths"
748
+ )
749
+
750
+ ctx := t .Context ()
751
+ ctrlruntime .SetLogger (logr .Discard ())
752
+
753
+ // setup a test environment in kcp
754
+ orgKubconfig := utils .CreateOrganization (t , ctx , orgWorkspace , apiExportName )
755
+
756
+ // start a service cluster
757
+ envtestKubeconfig , envtestClient , _ := utils .RunEnvtest (t , []string {
758
+ "test/crds/crontab.yaml" ,
759
+ })
760
+
761
+ // publish Crontabs and Backups
762
+ t .Logf ("Publishing CRDs…" )
763
+ prCrontabs := & syncagentv1alpha1.PublishedResource {
764
+ ObjectMeta : metav1.ObjectMeta {
765
+ Name : "publish-crontabs" ,
766
+ },
767
+ Spec : syncagentv1alpha1.PublishedResourceSpec {
768
+ Resource : syncagentv1alpha1.SourceResourceDescriptor {
769
+ APIGroup : "example.com" ,
770
+ Version : "v1" ,
771
+ Kind : "CronTab" ,
772
+ },
773
+ // These rules make finding the local object easier, but should not be used in production.
774
+ Naming : & syncagentv1alpha1.ResourceNaming {
775
+ Name : "{{ .Object.metadata.name }}" ,
776
+ Namespace : "synced-{{ .Object.metadata.namespace }}" ,
777
+ },
778
+ Projection : & syncagentv1alpha1.ResourceProjection {
779
+ Group : kcpGroupName ,
780
+ },
781
+ EnableWorkspacePaths : true ,
782
+ },
783
+ }
784
+
785
+ if err := envtestClient .Create (ctx , prCrontabs ); err != nil {
786
+ t .Fatalf ("Failed to create PublishedResource: %v" , err )
787
+ }
788
+
789
+ // start the agent in the background to update the APIExport with the CronTabs API
790
+ utils .RunAgent (ctx , t , "bob" , orgKubconfig , envtestKubeconfig , apiExportName )
791
+
792
+ // wait until the API is available
793
+ kcpClusterClient := utils .GetKcpAdminClusterClient (t )
794
+
795
+ teamClusterPath := logicalcluster .NewPath ("root" ).Join (orgWorkspace ).Join ("team-1" )
796
+ teamClient := kcpClusterClient .Cluster (teamClusterPath )
797
+
798
+ utils .WaitForBoundAPI (t , ctx , teamClient , schema.GroupVersionResource {
799
+ Group : kcpGroupName ,
800
+ Version : "v1" ,
801
+ Resource : "crontabs" ,
802
+ })
803
+
804
+ // create a Crontab object in a team workspace
805
+ t .Log ("Creating CronTab in kcp…" )
806
+ crontab := utils .YAMLToUnstructured (t , `
807
+ apiVersion: kcp.example.com/v1
808
+ kind: CronTab
809
+ metadata:
810
+ namespace: default
811
+ name: my-crontab
812
+ spec:
813
+ cronSpec: '* * *'
814
+ image: ubuntu:latest
815
+ ` )
816
+
817
+ if err := teamClient .Create (ctx , crontab ); err != nil {
818
+ t .Fatalf ("Failed to create CronTab in kcp: %v" , err )
819
+ }
820
+
821
+ // wait for the agent to sync the object down into the service cluster
822
+
823
+ t .Logf ("Wait for CronTab to be synced…" )
824
+ copy := & unstructured.Unstructured {}
825
+ copy .SetAPIVersion ("example.com/v1" )
826
+ copy .SetKind ("CronTab" )
827
+
828
+ err := wait .PollUntilContextTimeout (ctx , 500 * time .Millisecond , 30 * time .Second , false , func (ctx context.Context ) (done bool , err error ) {
829
+ copyKey := types.NamespacedName {Namespace : "synced-default" , Name : "my-crontab" }
830
+ return envtestClient .Get (ctx , copyKey , copy ) == nil , nil
831
+ })
832
+ if err != nil {
833
+ t .Fatalf ("Failed to wait for object to be synced down: %v" , err )
834
+ }
835
+
836
+ ann := "syncagent.kcp.io/remote-object-workspace-path"
837
+
838
+ if value := copy .GetAnnotations ()[ann ]; value != teamClusterPath .String () {
839
+ t .Fatalf ("Expected %s annotation to be %q, but is %q." , ann , teamClusterPath .String (), value )
840
+ }
841
+ }
0 commit comments