@@ -32,18 +32,23 @@ import (
3232 "github.com/kcp-dev/apimachinery/pkg/logicalcluster"
3333 "github.com/stretchr/testify/require"
3434
35+ appsv1 "k8s.io/api/apps/v1"
3536 corev1 "k8s.io/api/core/v1"
3637 apierrors "k8s.io/apimachinery/pkg/api/errors"
3738 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
39+ "k8s.io/apimachinery/pkg/runtime"
40+ "k8s.io/apimachinery/pkg/runtime/schema"
3841 "k8s.io/apimachinery/pkg/util/sets"
3942 "k8s.io/apimachinery/pkg/util/wait"
43+ "k8s.io/client-go/dynamic"
4044 "k8s.io/client-go/kubernetes"
4145 kubernetesclientset "k8s.io/client-go/kubernetes"
4246 "k8s.io/client-go/rest"
4347 "k8s.io/client-go/tools/clientcmd"
4448 clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
4549 "k8s.io/klog/v2"
4650
51+ apiresourcev1alpha1 "github.com/kcp-dev/kcp/pkg/apis/apiresource/v1alpha1"
4752 tenancyv1alpha1 "github.com/kcp-dev/kcp/pkg/apis/tenancy/v1alpha1"
4853 kcpclient "github.com/kcp-dev/kcp/pkg/client/clientset/versioned"
4954 kcpclientset "github.com/kcp-dev/kcp/pkg/client/clientset/versioned"
@@ -183,6 +188,10 @@ func LogToConsoleEnvSet() bool {
183188 return inProcess
184189}
185190
191+ func preserveTestResources () bool {
192+ return os .Getenv ("PRESERVE" ) != ""
193+ }
194+
186195func NewOrganizationFixture (t * testing.T , server RunningServer ) (orgClusterName logicalcluster.LogicalCluster ) {
187196 ctx , cancelFunc := context .WithCancel (context .Background ())
188197 t .Cleanup (cancelFunc )
@@ -202,6 +211,10 @@ func NewOrganizationFixture(t *testing.T, server RunningServer) (orgClusterName
202211 require .NoError (t , err , "failed to create organization workspace" )
203212
204213 t .Cleanup (func () {
214+ if preserveTestResources () {
215+ return
216+ }
217+
205218 ctx , cancelFn := context .WithDeadline (context .Background (), time .Now ().Add (time .Second * 30 ))
206219 defer cancelFn ()
207220
@@ -257,6 +270,10 @@ func NewWorkspaceWithWorkloads(t *testing.T, server RunningServer, orgClusterNam
257270 require .NoError (t , err , "failed to create workspace" )
258271
259272 t .Cleanup (func () {
273+ if preserveTestResources () {
274+ return
275+ }
276+
260277 ctx , cancelFn := context .WithDeadline (context .Background (), time .Now ().Add (time .Second * 30 ))
261278 defer cancelFn ()
262279
@@ -385,35 +402,86 @@ func (sf SyncerFixture) Start(t *testing.T) *StartedSyncerFixture {
385402 downstreamKubeClient , err := kubernetesclientset .NewForConfig (downstreamConfig )
386403 require .NoError (t , err )
387404
388- if useDeployedSyncer {
389- // Ensure cleanup of pcluster resources
405+ artifactDir , err := CreateTempDirForTest (t , "artifacts" )
406+ if err != nil {
407+ t .Errorf ("failed to create temp dir for syncer artifacts: %v" , err )
408+ }
409+
410+ // collect both in deployed and in-process mode
411+ t .Cleanup (func () {
412+ ctx , cancelFn := context .WithDeadline (context .Background (), time .Now ().Add (time .Second * 30 ))
413+ defer cancelFn ()
414+
415+ t .Logf ("Collecting imported resource info" )
416+ upstreamCfg := sf .UpstreamServer .DefaultConfig (t )
417+
418+ gather := func (client dynamic.Interface , gvr schema.GroupVersionResource ) {
419+ resourceClient := client .Resource (gvr )
420+
421+ t .Logf ("gathering %q" , gvr )
422+ list , err := resourceClient .List (ctx , metav1.ListOptions {})
423+ if err != nil {
424+ // Don't fail the test
425+ t .Logf ("Error gathering %s: %v" , gvr , err )
426+ return
427+ }
390428
429+ t .Logf ("got %d items" , len (list .Items ))
430+
431+ for i := range list .Items {
432+ item := list .Items [i ]
433+ sf .UpstreamServer .Artifact (t , func () (runtime.Object , error ) {
434+ return & item , nil
435+ })
436+ }
437+ }
438+
439+ upstreamDynamic , err := dynamic .NewClusterForConfig (upstreamCfg )
440+ require .NoError (t , err , "error creating upstream dynamic client" )
441+
442+ downstreamDynamic , err := dynamic .NewForConfig (downstreamConfig )
443+ require .NoError (t , err , "error creating downstream dynamic client" )
444+
445+ gather (upstreamDynamic .Cluster (sf .WorkspaceClusterName ), apiresourcev1alpha1 .SchemeGroupVersion .WithResource ("apiresourceimports" ))
446+ gather (upstreamDynamic .Cluster (sf .WorkspaceClusterName ), apiresourcev1alpha1 .SchemeGroupVersion .WithResource ("negotiatedapiresources" ))
447+ gather (upstreamDynamic .Cluster (sf .WorkspaceClusterName ), corev1 .SchemeGroupVersion .WithResource ("namespaces" ))
448+ gather (downstreamDynamic , corev1 .SchemeGroupVersion .WithResource ("namespaces" ))
449+ gather (upstreamDynamic .Cluster (sf .WorkspaceClusterName ), appsv1 .SchemeGroupVersion .WithResource ("deployments" ))
450+ gather (downstreamDynamic , appsv1 .SchemeGroupVersion .WithResource ("deployments" ))
451+ })
452+
453+ if useDeployedSyncer {
391454 syncerID := syncerConfig .ID ()
392455 t .Cleanup (func () {
393- if useDeployedSyncer {
394- t .Logf ("Collecting syncer %s logs" , syncerID )
395-
396- ctx , cancelFn := context .WithDeadline (context .Background (), time .Now ().Add (time .Second * 30 ))
397- defer cancelFn ()
456+ ctx , cancelFn := context .WithDeadline (context .Background (), time .Now ().Add (time .Second * 30 ))
457+ defer cancelFn ()
398458
459+ // collect syncer logs
460+ t .Logf ("Collecting syncer pod logs" )
461+ func () {
462+ t .Logf ("Listing downstream pods in namespace %s" , syncerID )
399463 pods , err := downstreamKubeClient .CoreV1 ().Pods (syncerID ).List (ctx , metav1.ListOptions {})
400464 if err != nil {
401- t .Errorf ("failed to list pods in %s: %v" , syncerID , err )
402- }
403- artifactDir , err := CreateTempDirForTest (t , "artifacts" )
404- if err != nil {
405- t .Errorf ("failed to create temp dir for syncer artifacts: %v" , err )
465+ t .Logf ("failed to list pods in %s: %v" , syncerID , err )
466+ return
406467 }
468+
407469 for _ , pod := range pods .Items {
408470 t .Logf ("Collecting downstream logs for pod %s/%s" , syncerID , pod .Name )
409471 logs := Kubectl (t , downstreamKubeconfigPath , "-n" , syncerID , "logs" , pod .Name )
472+
410473 artifactPath := filepath .Join (artifactDir , fmt .Sprintf ("syncer-%s-%s.log" , syncerID , pod .Name ))
474+
411475 err = ioutil .WriteFile (artifactPath , logs , 0644 )
412476 if err != nil {
413477 t .Logf ("failed to write logs for pod %s in %s to %s: %v" , pod .Name , syncerID , artifactPath , err )
414478 continue // not fatal
415479 }
416480 }
481+ }()
482+
483+ if preserveTestResources () {
484+ return
417485 }
418486
419487 t .Logf ("Deleting syncer resources for logical cluster %q, workload cluster %q" , syncerConfig .KCPClusterName , syncerConfig .WorkloadClusterName )
@@ -455,10 +523,8 @@ func (sf SyncerFixture) Start(t *testing.T) *StartedSyncerFixture {
455523 }
456524 }
457525 })
458-
459526 } else {
460527 // Start an in-process syncer
461-
462528 err := syncer .StartSyncer (ctx , syncerConfig , 2 , 5 * time .Second )
463529 require .NoError (t , err , "syncer failed to start" )
464530 }
0 commit comments