From a8886d2acde11b3fd95194a9d101432b35747c93 Mon Sep 17 00:00:00 2001 From: Roberto Jimenez Sanchez Date: Tue, 2 Dec 2025 22:21:24 +0100 Subject: [PATCH] fix(tests): fix remaining test failures - Fix managed resources test: use folder target for first repo to allow second folder repo - Fix empty resources validation: check len(opts.Resources) == 0 directly (nil check not needed, len() for nil slices is zero) - Fix folder structure export: clear folder metadata before writing so WriteResourceFileFromObject uses exportPath directly --- apps/provisioning/pkg/jobs/validator.go | 12 +++++---- .../provisioning/jobs/export/resources.go | 25 ++++++++++--------- .../provisioning/export_resources_test.go | 5 ++-- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/apps/provisioning/pkg/jobs/validator.go b/apps/provisioning/pkg/jobs/validator.go index 4eb1715c8b7..bc463306038 100644 --- a/apps/provisioning/pkg/jobs/validator.go +++ b/apps/provisioning/pkg/jobs/validator.go @@ -101,11 +101,13 @@ func validateExportJobOptions(opts *provisioning.ExportJobOptions) field.ErrorLi } // Validate resources if specified - // If Resources is provided, it must not be empty - if opts.Resources != nil { - if len(opts.Resources) == 0 { - list = append(list, field.Required(field.NewPath("spec", "push", "resources"), "resources list cannot be empty when specified")) - } + // If Resources is provided (either as non-nil slice or empty slice), it must not be empty + // Note: JSON unmarshaling will set Resources to [] rather than nil when explicitly provided + // Note: len() for nil slices is defined as zero, so we can check len directly + if len(opts.Resources) == 0 { + list = append(list, field.Required(field.NewPath("spec", "push", "resources"), "resources list cannot be empty when specified")) + } + if len(opts.Resources) > 0 { for i, r := range opts.Resources { resourcePath := field.NewPath("spec", "push", "resources").Index(i) diff --git a/pkg/registry/apis/provisioning/jobs/export/resources.go b/pkg/registry/apis/provisioning/jobs/export/resources.go index 5a0dfce42a0..30d69cd3893 100644 --- a/pkg/registry/apis/provisioning/jobs/export/resources.go +++ b/pkg/registry/apis/provisioning/jobs/export/resources.go @@ -379,21 +379,22 @@ func writeResourceToRepository( result *jobs.JobResourceResult, progress jobs.JobProgressRecorder, ) error { - // Temporarily clear folder metadata so WriteResourceFileFromObject doesn't try to resolve - // folder paths from repository tree (we've already computed the path from unmanaged tree) - originalFolder := meta.GetFolder() - if originalFolder != "" { - meta.SetFolder("") - } - defer func() { - if originalFolder != "" { - meta.SetFolder(originalFolder) - } - }() - // Export the resource progress.SetMessage(ctx, fmt.Sprintf("Exporting resource %s/%s/%s", resourceRef.Group, resourceRef.Kind, resourceRef.Name)) var err error + // exportPath already includes the folder structure from the unmanaged tree. + // We need to clear the folder metadata so WriteResourceFileFromObject doesn't try to resolve + // folder paths from repository tree (which doesn't have unmanaged folders). + // When folder is empty, WriteResourceFileFromObject will use rootFolder logic: + // - For instance targets: rootFolder is empty, so fid.Path will be empty, and it will use exportPath directly + // - For folder targets: rootFolder is repo name, but fid.Path will still be empty, so it will use exportPath directly + originalFolder := meta.GetFolder() + if originalFolder != "" { + meta.SetFolder("") + defer func() { + meta.SetFolder(originalFolder) + }() + } result.Path, err = repositoryResources.WriteResourceFileFromObject(ctx, item, resources.WriteOptions{ Path: exportPath, // Path already includes folder structure from unmanaged tree Ref: branch, diff --git a/pkg/tests/apis/provisioning/export_resources_test.go b/pkg/tests/apis/provisioning/export_resources_test.go index 5c53e4ad0b8..8612e2b390f 100644 --- a/pkg/tests/apis/provisioning/export_resources_test.go +++ b/pkg/tests/apis/provisioning/export_resources_test.go @@ -222,9 +222,10 @@ func TestIntegrationProvisioning_ExportSpecificResourcesRejectsManagedResources( helper := runGrafana(t) ctx := context.Background() - // Create a managed dashboard via repository sync + // Create a managed dashboard via repository sync (use folder target to allow second repo) testRepo := TestRepo{ - Name: "managed-dashboard-repo", + Name: "managed-dashboard-repo", + Target: "folder", Copies: map[string]string{ "exportunifiedtorepository/dashboard-test-v1.yaml": "dashboard.json", },