From 60cebf8fd412ccf3812204c2e6b1958cc31ac0ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schw=C3=A4gerl?= Date: Fri, 18 Oct 2024 16:21:26 +0200 Subject: [PATCH 1/5] chore: Refactor file resolving --- cmd/modulectl/cmd.go | 16 ++- .../service/contentprovider/moduleconfig.go | 43 +++---- internal/service/create/create.go | 65 ++++++++-- internal/service/fileresolver/fileresolver.go | 74 +++++++++++ .../reader/moduleconfig_reader.go | 121 +----------------- 5 files changed, 167 insertions(+), 152 deletions(-) create mode 100644 internal/service/fileresolver/fileresolver.go diff --git a/cmd/modulectl/cmd.go b/cmd/modulectl/cmd.go index 75cce5cd..c90e8582 100644 --- a/cmd/modulectl/cmd.go +++ b/cmd/modulectl/cmd.go @@ -17,6 +17,7 @@ import ( "github.com/kyma-project/modulectl/internal/service/create" "github.com/kyma-project/modulectl/internal/service/filegenerator" "github.com/kyma-project/modulectl/internal/service/filegenerator/reusefilegenerator" + "github.com/kyma-project/modulectl/internal/service/fileresolver" "github.com/kyma-project/modulectl/internal/service/git" moduleconfiggenerator "github.com/kyma-project/modulectl/internal/service/moduleconfig/generator" moduleconfigreader "github.com/kyma-project/modulectl/internal/service/moduleconfig/reader" @@ -89,7 +90,17 @@ func buildModuleService() (*create.Service, error) { fileSystemUtil := &filesystem.Util{} tmpFileSystem := filesystem.NewTempFileSystem() - moduleConfigService, err := moduleconfigreader.NewService(fileSystemUtil, tmpFileSystem) + manifestFileResolver, err := fileresolver.NewFileResolver("kyma-module-manifest-*.yaml", tmpFileSystem) + if err != nil { + return nil, fmt.Errorf("failed to create manifest file resolver: %w", err) + } + + defaultCRFileResolver, err := fileresolver.NewFileResolver("kyma-module-default-cr-*.yaml", tmpFileSystem) + if err != nil { + return nil, fmt.Errorf("failed to create default CR file resolver: %w", err) + } + + moduleConfigService, err := moduleconfigreader.NewService(fileSystemUtil) if err != nil { return nil, fmt.Errorf("failed to create module config service: %w", err) } @@ -127,7 +138,8 @@ func buildModuleService() (*create.Service, error) { return nil, fmt.Errorf("failed to create crd parser service: %w", err) } moduleService, err := create.NewService(moduleConfigService, gitSourcesService, - securityConfigService, componentArchiveService, registryService, moduleTemplateService, crdParserService) + securityConfigService, componentArchiveService, registryService, moduleTemplateService, + crdParserService, manifestFileResolver, defaultCRFileResolver, fileSystemUtil) if err != nil { return nil, fmt.Errorf("failed to create module service: %w", err) } diff --git a/internal/service/contentprovider/moduleconfig.go b/internal/service/contentprovider/moduleconfig.go index b3ff477e..b7a752eb 100644 --- a/internal/service/contentprovider/moduleconfig.go +++ b/internal/service/contentprovider/moduleconfig.go @@ -38,12 +38,12 @@ func (s *ModuleConfigProvider) GetDefaultContent(args types.KeyValueArgs) (strin func (s *ModuleConfigProvider) getModuleConfig(args types.KeyValueArgs) ModuleConfig { return ModuleConfig{ - Name: args[ArgModuleName], - Version: args[ArgModuleVersion], - Channel: args[ArgModuleChannel], - Manifest: args[ArgManifestFile], - Security: args[ArgSecurityConfigFile], - DefaultCRPath: args[ArgDefaultCRFile], + Name: args[ArgModuleName], + Version: args[ArgModuleVersion], + Channel: args[ArgModuleChannel], + Manifest: args[ArgManifestFile], + Security: args[ArgSecurityConfigFile], + DefaultCR: args[ArgDefaultCRFile], } } @@ -80,22 +80,21 @@ type Manager struct { } type ModuleConfig struct { - Name string `yaml:"name" comment:"required, the name of the Module"` - Version string `yaml:"version" comment:"required, the version of the Module"` - Channel string `yaml:"channel" comment:"required, channel that should be used in the ModuleTemplate"` - Manifest string `yaml:"manifest" comment:"required, relative path or remote URL to the manifests"` - ManifestFilePath string `yaml:"-"` // ignore this field, will be filled programmatically - Mandatory bool `yaml:"mandatory" comment:"optional, default=false, indicates whether the module is mandatory to be installed on all clusters"` - DefaultCRPath string `yaml:"defaultCR" comment:"optional, relative path or remote URL to a YAML file containing the default CR for the module"` - ResourceName string `yaml:"resourceName" comment:"optional, default={name}-{channel}, when channel is 'none', the default is {name}-{version}, the name for the ModuleTemplate that will be created"` - Namespace string `yaml:"namespace" comment:"optional, default=kcp-system, the namespace where the ModuleTemplate will be deployed"` - Security string `yaml:"security" comment:"optional, name of the security scanners config file"` - Internal bool `yaml:"internal" comment:"optional, default=false, determines whether the ModuleTemplate should have the internal flag or not"` - Beta bool `yaml:"beta" comment:"optional, default=false, determines whether the ModuleTemplate should have the beta flag or not"` - Labels map[string]string `yaml:"labels" comment:"optional, additional labels for the ModuleTemplate"` - Annotations map[string]string `yaml:"annotations" comment:"optional, additional annotations for the ModuleTemplate"` - Manager *Manager `yaml:"manager" comment:"optional, the module resource that can be used to indicate the installation readiness of the module. This is typically the manager deployment of the module"` - Resources ResourcesMap `yaml:"resources,omitempty" comment:"optional, additional resources of the ModuleTemplate that may be fetched"` + Name string `yaml:"name" comment:"required, the name of the Module"` + Version string `yaml:"version" comment:"required, the version of the Module"` + Channel string `yaml:"channel" comment:"required, channel that should be used in the ModuleTemplate"` + Manifest string `yaml:"manifest" comment:"required, relative path or remote URL to the manifests"` + Mandatory bool `yaml:"mandatory" comment:"optional, default=false, indicates whether the module is mandatory to be installed on all clusters"` + DefaultCR string `yaml:"defaultCR" comment:"optional, relative path or remote URL to a YAML file containing the default CR for the module"` + ResourceName string `yaml:"resourceName" comment:"optional, default={name}-{channel}, when channel is 'none', the default is {name}-{version}, the name for the ModuleTemplate that will be created"` + Namespace string `yaml:"namespace" comment:"optional, default=kcp-system, the namespace where the ModuleTemplate will be deployed"` + Security string `yaml:"security" comment:"optional, name of the security scanners config file"` + Internal bool `yaml:"internal" comment:"optional, default=false, determines whether the ModuleTemplate should have the internal flag or not"` + Beta bool `yaml:"beta" comment:"optional, default=false, determines whether the ModuleTemplate should have the beta flag or not"` + Labels map[string]string `yaml:"labels" comment:"optional, additional labels for the ModuleTemplate"` + Annotations map[string]string `yaml:"annotations" comment:"optional, additional annotations for the ModuleTemplate"` + Manager *Manager `yaml:"manager" comment:"optional, the module resource that can be used to indicate the installation readiness of the module. This is typically the manager deployment of the module"` + Resources ResourcesMap `yaml:"resources,omitempty" comment:"optional, additional resources of the ModuleTemplate that may be fetched"` } type resource struct { diff --git a/internal/service/create/create.go b/internal/service/create/create.go index 82adf206..7a50ce38 100644 --- a/internal/service/create/create.go +++ b/internal/service/create/create.go @@ -15,7 +15,14 @@ import ( type ModuleConfigService interface { ParseAndValidateModuleConfig(moduleConfigFile string) (*contentprovider.ModuleConfig, error) - GetDefaultCRData(defaultCRPath string) ([]byte, error) +} + +type FileSystem interface { + ReadFile(path string) ([]byte, error) +} + +type FileResolver interface { + Resolve(file string) (string, error) CleanupTempFiles() []error } @@ -62,6 +69,9 @@ type Service struct { registryService RegistryService moduleTemplateService ModuleTemplateService crdParserService CRDParserService + manifestFileResolver FileResolver + defaultCRFileResolver FileResolver + fileSystem FileSystem } func NewService(moduleConfigService ModuleConfigService, @@ -71,6 +81,9 @@ func NewService(moduleConfigService ModuleConfigService, registryService RegistryService, moduleTemplateService ModuleTemplateService, crdParserService CRDParserService, + manifestFileResolver FileResolver, + defaultCRFileResolver FileResolver, + fileSystem FileSystem, ) (*Service, error) { if moduleConfigService == nil { return nil, fmt.Errorf("%w: moduleConfigService must not be nil", commonerrors.ErrInvalidArg) @@ -100,6 +113,18 @@ func NewService(moduleConfigService ModuleConfigService, return nil, fmt.Errorf("%w: crdParserService must not be nil", commonerrors.ErrInvalidArg) } + if manifestFileResolver == nil { + return nil, fmt.Errorf("%w: manifestFileResolver must not be nil", commonerrors.ErrInvalidArg) + } + + if defaultCRFileResolver == nil { + return nil, fmt.Errorf("%w: defaultCRFileResolver must not be nil", commonerrors.ErrInvalidArg) + } + + if fileSystem == nil { + return nil, fmt.Errorf("%w: fileSystem must not be nil", commonerrors.ErrInvalidArg) + } + return &Service{ moduleConfigService: moduleConfigService, gitSourcesService: gitSourcesService, @@ -108,6 +133,9 @@ func NewService(moduleConfigService ModuleConfigService, registryService: registryService, moduleTemplateService: moduleTemplateService, crdParserService: crdParserService, + manifestFileResolver: manifestFileResolver, + defaultCRFileResolver: defaultCRFileResolver, + fileSystem: fileSystem, }, nil } @@ -117,8 +145,12 @@ func (s *Service) Run(opts Options) error { } defer func() { - if err := s.moduleConfigService.CleanupTempFiles(); err != nil { - opts.Out.Write(fmt.Sprintf("failed to cleanup temporary files: %v\n", err)) + if err := s.defaultCRFileResolver.CleanupTempFiles(); err != nil { + opts.Out.Write(fmt.Sprintf("failed to cleanup temporary default CR files: %v\n", err)) + } + + if err := s.manifestFileResolver.CleanupTempFiles(); err != nil { + opts.Out.Write(fmt.Sprintf("failed to cleanup temporary manifest files: %v\n", err)) } }() @@ -127,13 +159,26 @@ func (s *Service) Run(opts Options) error { return fmt.Errorf("failed to parse module config: %w", err) } + manifestFilePath, err := s.manifestFileResolver.Resolve(moduleConfig.Manifest) + if err != nil { + return fmt.Errorf("failed to resolve manifest file: %w", err) + } + + defaultCRFilePath := moduleConfig.DefaultCR + if moduleConfig.DefaultCR != "" { + defaultCRFilePath, err = s.defaultCRFileResolver.Resolve(moduleConfig.DefaultCR) + if err != nil { + return fmt.Errorf("failed to resolve default CR file: %w", err) + } + } + descriptor, err := componentdescriptor.InitializeComponentDescriptor(moduleConfig.Name, moduleConfig.Version) if err != nil { return fmt.Errorf("failed to populate component descriptor metadata: %w", err) } - moduleResources, err := componentdescriptor.GenerateModuleResources(moduleConfig.Version, moduleConfig.ManifestFilePath, - moduleConfig.DefaultCRPath, opts.RegistryCredSelector) + moduleResources, err := componentdescriptor.GenerateModuleResources(moduleConfig.Version, manifestFilePath, + defaultCRFilePath, opts.RegistryCredSelector) if err != nil { return fmt.Errorf("failed to generate module resources: %w", err) } @@ -162,14 +207,14 @@ func (s *Service) Run(opts Options) error { } if opts.RegistryURL != "" { - return s.pushImgAndCreateTemplate(archive, moduleConfig, opts) + return s.pushImgAndCreateTemplate(archive, moduleConfig, manifestFilePath, defaultCRFilePath, opts) } return nil } -func (s *Service) pushImgAndCreateTemplate(archive *comparch.ComponentArchive, moduleConfig *contentprovider.ModuleConfig, opts Options) error { +func (s *Service) pushImgAndCreateTemplate(archive *comparch.ComponentArchive, moduleConfig *contentprovider.ModuleConfig, manifestFilePath, defaultCRFilePath string, opts Options) error { opts.Out.Write("- Pushing component version\n") - isCRDClusterScoped, err := s.crdParserService.IsCRDClusterScoped(moduleConfig.DefaultCRPath, moduleConfig.ManifestFilePath) + isCRDClusterScoped, err := s.crdParserService.IsCRDClusterScoped(defaultCRFilePath, manifestFilePath) if err != nil { return fmt.Errorf("failed to determine if CRD is cluster scoped: %w", err) } @@ -185,8 +230,8 @@ func (s *Service) pushImgAndCreateTemplate(archive *comparch.ComponentArchive, m } var crData []byte - if moduleConfig.DefaultCRPath != "" { - crData, err = s.moduleConfigService.GetDefaultCRData(moduleConfig.DefaultCRPath) + if defaultCRFilePath != "" { + crData, err = s.fileSystem.ReadFile(defaultCRFilePath) if err != nil { return fmt.Errorf("%w: failed to get default CR data", err) } diff --git a/internal/service/fileresolver/fileresolver.go b/internal/service/fileresolver/fileresolver.go new file mode 100644 index 00000000..e0c2cbcb --- /dev/null +++ b/internal/service/fileresolver/fileresolver.go @@ -0,0 +1,74 @@ +package fileresolver + +import ( + "fmt" + "net/url" + "os" + "path/filepath" + + commonerrors "github.com/kyma-project/modulectl/internal/common/errors" +) + +type TempFileSystem interface { + DownloadTempFile(dir, pattern string, url *url.URL) (string, error) + RemoveTempFiles() []error +} + +type FileResolver struct { + filePattern string + tempFileSystem TempFileSystem +} + +func NewFileResolver(filePattern string, tempFileSystem TempFileSystem) (*FileResolver, error) { + if filePattern == "" { + return nil, fmt.Errorf("%w: filePattern must not be empty", commonerrors.ErrInvalidArg) + } + + if tempFileSystem == nil { + return nil, fmt.Errorf("%w: tempFileSystem must not be nil", commonerrors.ErrInvalidArg) + } + + return &FileResolver{ + filePattern: filePattern, + tempFileSystem: tempFileSystem, + }, nil +} + +func (r *FileResolver) Resolve(file string) (string, error) { + if parsedURL, err := r.ParseURL(file); err == nil { + file, err = r.tempFileSystem.DownloadTempFile("", r.filePattern, parsedURL) + if err != nil { + return "", fmt.Errorf("failed to download file: %w", err) + } + return file, nil + } + + if !filepath.IsAbs(file) { + // Get the current working directory + homeDir, err := os.Getwd() + if err != nil { + return "", fmt.Errorf("failed to get the current directory: %w", err) + } + // Get the relative path from the current directory + file = filepath.Join(homeDir, file) + file, err = filepath.Abs(file) + if err != nil { + return "", fmt.Errorf("failed to obtain absolute path to file: %w", err) + } + return file, nil + } + + return file, nil +} + +func (r *FileResolver) ParseURL(urlString string) (*url.URL, error) { + urlParsed, err := url.Parse(urlString) + if err == nil && urlParsed.Scheme != "" && urlParsed.Host != "" { + return urlParsed, nil + } + return nil, fmt.Errorf("failed to parse url %s: %w", urlString, commonerrors.ErrInvalidArg) +} + +func (r *FileResolver) CleanupTempFiles() []error { + return r.tempFileSystem.RemoveTempFiles() +} diff --git a/internal/service/moduleconfig/reader/moduleconfig_reader.go b/internal/service/moduleconfig/reader/moduleconfig_reader.go index 3cadb0db..a4889f32 100644 --- a/internal/service/moduleconfig/reader/moduleconfig_reader.go +++ b/internal/service/moduleconfig/reader/moduleconfig_reader.go @@ -3,9 +3,6 @@ package moduleconfigreader import ( "errors" "fmt" - "net/url" - "os" - "path/filepath" "gopkg.in/yaml.v3" @@ -16,37 +13,21 @@ import ( var ErrNoPathForDefaultCR = errors.New("no path for default CR given") -const ( - defaultCRFilePattern = "kyma-module-default-cr-*.yaml" - defaultManifestFilePattern = "kyma-module-manifest-*.yaml" -) - type FileSystem interface { ReadFile(path string) ([]byte, error) } -type TempFileSystem interface { - DownloadTempFile(dir, pattern string, url *url.URL) (string, error) - RemoveTempFiles() []error -} - type Service struct { - fileSystem FileSystem - tempFileSystem TempFileSystem + fileSystem FileSystem } -func NewService(fileSystem FileSystem, tmpFileSystem TempFileSystem) (*Service, error) { +func NewService(fileSystem FileSystem) (*Service, error) { if fileSystem == nil { return nil, fmt.Errorf("%w: fileSystem must not be nil", commonerrors.ErrInvalidArg) } - if tmpFileSystem == nil { - return nil, fmt.Errorf("%w: tempFileSystem must not be nil", commonerrors.ErrInvalidArg) - } - return &Service{ - fileSystem: fileSystem, - tempFileSystem: tmpFileSystem, + fileSystem: fileSystem, }, nil } @@ -61,72 +42,9 @@ func (s *Service) ParseAndValidateModuleConfig(moduleConfigFile string, return nil, fmt.Errorf("failed to validate module config: %w", err) } - moduleConfig.DefaultCRPath, err = GetDefaultCRPath(moduleConfig.DefaultCRPath, s.tempFileSystem) - if err != nil { - return nil, fmt.Errorf("failed to get default CR path: %w", err) - } - - moduleConfig.ManifestFilePath, err = GetManifestPath(moduleConfig.Manifest, s.tempFileSystem) - if err != nil { - return nil, fmt.Errorf("failed to get manifest path: %w", err) - } - return moduleConfig, nil } -func (s *Service) GetDefaultCRData(defaultCRPath string) ([]byte, error) { - if defaultCRPath == "" { - return nil, ErrNoPathForDefaultCR - } - defaultCRData, err := s.fileSystem.ReadFile(defaultCRPath) - if err != nil { - return nil, fmt.Errorf("failed to read default CR file: %w", err) - } - - return defaultCRData, nil -} - -func (s *Service) CleanupTempFiles() []error { - return s.tempFileSystem.RemoveTempFiles() -} - -func GetManifestPath(manifestPath string, tempFileSystem TempFileSystem) (string, error) { - path := manifestPath - - if parsedURL, err := ParseURL(manifestPath); err == nil { - path, err = tempFileSystem.DownloadTempFile("", defaultManifestFilePattern, parsedURL) - if err != nil { - return "", fmt.Errorf("failed to download Manifest file: %w", err) - } - return path, nil - } - - if !filepath.IsAbs(manifestPath) { - // Get the current working directory - homeDir, err := os.Getwd() - if err != nil { - return "", fmt.Errorf("failed to get the current directory: %w", err) - } - // Get the relative path from the current directory - path = filepath.Join(homeDir, path) - path, err = filepath.Abs(path) - if err != nil { - return "", fmt.Errorf("failed to obtain absolute path to manifest file: %w", err) - } - return path, nil - } - - return path, nil -} - -func ParseURL(urlString string) (*url.URL, error) { - urlParsed, err := url.Parse(urlString) - if err == nil && urlParsed.Scheme != "" && urlParsed.Host != "" { - return urlParsed, nil - } - return nil, fmt.Errorf("failed to parse url %s: %w", urlString, commonerrors.ErrInvalidArg) -} - func ValidateModuleConfig(moduleConfig *contentprovider.ModuleConfig) error { if err := validation.ValidateModuleName(moduleConfig.Name); err != nil { return fmt.Errorf("failed to validate module name: %w", err) @@ -206,36 +124,3 @@ func ParseModuleConfig(configFilePath string, fileSystem FileSystem) (*contentpr return moduleConfig, nil } - -func GetDefaultCRPath(defaultCRPath string, tempFileSystem TempFileSystem) (string, error) { - if defaultCRPath == "" { - return defaultCRPath, nil - } - - path := defaultCRPath - - if parsedURL, err := ParseURL(defaultCRPath); err == nil { - path, err = tempFileSystem.DownloadTempFile("", defaultCRFilePattern, parsedURL) - if err != nil { - return "", fmt.Errorf("failed to download default CR file: %w", err) - } - return path, nil - } - - if !filepath.IsAbs(defaultCRPath) { - // Get the current working directory - homeDir, err := os.Getwd() - if err != nil { - return "", fmt.Errorf("failed to get the current working directory: %w", err) - } - // Get the relative path from the current directory - path = filepath.Join(homeDir, path) - path, err = filepath.Abs(path) - if err != nil { - return "", fmt.Errorf("failed to obtain absolute path to deefault CR file: %w", err) - } - return path, nil - } - - return path, nil -} From bcc8a5254f84fe23c7d33ee6d2c768eb8f224fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schw=C3=A4gerl?= Date: Fri, 18 Oct 2024 17:05:22 +0200 Subject: [PATCH 2/5] fix unit tests --- internal/service/create/create_test.go | 94 ++++++++--- .../service/fileresolver/fileresolver_test.go | 116 +++++++++++++ .../generator/moduleconfig_generator_test.go | 26 +-- .../reader/moduleconfig_reader_test.go | 157 ++---------------- tests/e2e/create/create_suite_test.go | 2 +- tests/e2e/scaffold/scaffold_suite_test.go | 2 +- unit-test-coverage.yaml | 2 +- 7 files changed, 218 insertions(+), 181 deletions(-) create mode 100644 internal/service/fileresolver/fileresolver_test.go diff --git a/internal/service/create/create_test.go b/internal/service/create/create_test.go index c49078a6..8d01f849 100644 --- a/internal/service/create/create_test.go +++ b/internal/service/create/create_test.go @@ -20,7 +20,8 @@ import ( func Test_NewService_ReturnsError_WhenModuleConfigServiceIsNil(t *testing.T) { _, err := create.NewService(nil, &gitSourcesServiceStub{}, &securityConfigServiceStub{}, - &componentArchiveServiceStub{}, ®istryServiceStub{}, &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}) + &componentArchiveServiceStub{}, ®istryServiceStub{}, &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}, + &fileResolverStub{}, &fileResolverStub{}, &fileExistsStub{}) require.ErrorIs(t, err, commonerrors.ErrInvalidArg) require.Contains(t, err.Error(), "moduleConfigService") @@ -28,7 +29,8 @@ func Test_NewService_ReturnsError_WhenModuleConfigServiceIsNil(t *testing.T) { func Test_CreateModule_ReturnsError_WhenModuleConfigFileIsEmpty(t *testing.T) { svc, err := create.NewService(&moduleConfigServiceStub{}, &gitSourcesServiceStub{}, &securityConfigServiceStub{}, - &componentArchiveServiceStub{}, ®istryServiceStub{}, &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}) + &componentArchiveServiceStub{}, ®istryServiceStub{}, &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}, + &fileResolverStub{}, &fileResolverStub{}, &fileExistsStub{}) require.NoError(t, err) opts := newCreateOptionsBuilder().withModuleConfigFile("").build() @@ -41,7 +43,8 @@ func Test_CreateModule_ReturnsError_WhenModuleConfigFileIsEmpty(t *testing.T) { func Test_CreateModule_ReturnsError_WhenOutIsNil(t *testing.T) { svc, err := create.NewService(&moduleConfigServiceStub{}, &gitSourcesServiceStub{}, &securityConfigServiceStub{}, - &componentArchiveServiceStub{}, ®istryServiceStub{}, &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}) + &componentArchiveServiceStub{}, ®istryServiceStub{}, &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}, + &fileResolverStub{}, &fileResolverStub{}, &fileExistsStub{}) require.NoError(t, err) opts := newCreateOptionsBuilder().withOut(nil).build() @@ -54,7 +57,8 @@ func Test_CreateModule_ReturnsError_WhenOutIsNil(t *testing.T) { func Test_CreateModule_ReturnsError_WhenCredentialsIsInInvalidFormat(t *testing.T) { svc, err := create.NewService(&moduleConfigServiceStub{}, &gitSourcesServiceStub{}, &securityConfigServiceStub{}, - &componentArchiveServiceStub{}, ®istryServiceStub{}, &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}) + &componentArchiveServiceStub{}, ®istryServiceStub{}, &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}, + &fileResolverStub{}, &fileResolverStub{}, &fileExistsStub{}) require.NoError(t, err) opts := newCreateOptionsBuilder().withCredentials("user").build() @@ -67,7 +71,8 @@ func Test_CreateModule_ReturnsError_WhenCredentialsIsInInvalidFormat(t *testing. func Test_CreateModule_ReturnsError_WhenTemplateOutputIsEmpty(t *testing.T) { svc, err := create.NewService(&moduleConfigServiceStub{}, &gitSourcesServiceStub{}, &securityConfigServiceStub{}, - &componentArchiveServiceStub{}, ®istryServiceStub{}, &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}) + &componentArchiveServiceStub{}, ®istryServiceStub{}, &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}, + &fileResolverStub{}, &fileResolverStub{}, &fileExistsStub{}) require.NoError(t, err) opts := newCreateOptionsBuilder().withTemplateOutput("").build() @@ -79,9 +84,9 @@ func Test_CreateModule_ReturnsError_WhenTemplateOutputIsEmpty(t *testing.T) { } func Test_CreateModule_ReturnsError_WhenParseAndValidateModuleConfigReturnsError(t *testing.T) { - svc, err := create.NewService(&moduleConfigServiceParseErrorStub{}, &gitSourcesServiceStub{}, - &securityConfigServiceStub{}, &componentArchiveServiceStub{}, ®istryServiceStub{}, - &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}) + svc, err := create.NewService(&moduleConfigServiceParseErrorStub{}, &gitSourcesServiceStub{}, &securityConfigServiceStub{}, + &componentArchiveServiceStub{}, ®istryServiceStub{}, &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}, + &fileResolverStub{}, &fileResolverStub{}, &fileExistsStub{}) require.NoError(t, err) opts := newCreateOptionsBuilder().build() @@ -92,6 +97,34 @@ func Test_CreateModule_ReturnsError_WhenParseAndValidateModuleConfigReturnsError require.Contains(t, err.Error(), "failed to read module config file") } +func Test_CreateModule_ReturnsError_WhenResolvingManifestFilePathReturnsError(t *testing.T) { + svc, err := create.NewService(&moduleConfigServiceStub{}, &gitSourcesServiceStub{}, &securityConfigServiceStub{}, + &componentArchiveServiceStub{}, ®istryServiceStub{}, &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}, + &fileResolverErrorStub{}, &fileResolverStub{}, &fileExistsStub{}) + require.NoError(t, err) + + opts := newCreateOptionsBuilder().build() + + err = svc.Run(opts) + + require.Error(t, err) + require.Contains(t, err.Error(), "failed to resolve file") +} + +func Test_CreateModule_ReturnsError_WhenResolvingDefaultCRFilePathReturnsError(t *testing.T) { + svc, err := create.NewService(&moduleConfigServiceStub{}, &gitSourcesServiceStub{}, &securityConfigServiceStub{}, + &componentArchiveServiceStub{}, ®istryServiceStub{}, &ModuleTemplateServiceStub{}, &CRDParserServiceStub{}, + &fileResolverStub{}, &fileResolverErrorStub{}, &fileExistsStub{}) + require.NoError(t, err) + + opts := newCreateOptionsBuilder().build() + + err = svc.Run(opts) + + require.Error(t, err) + require.Contains(t, err.Error(), "failed to resolve file") +} + type createOptionsBuilder struct { options create.Options } @@ -144,21 +177,44 @@ func (b *createOptionsBuilder) withCredentials(credentials string) *createOption return b } -// Test Stubs -type moduleConfigServiceStub struct{} +type fileExistsStub struct{} -func (*moduleConfigServiceStub) ParseAndValidateModuleConfig(_ string) (*contentprovider.ModuleConfig, error) { - return &contentprovider.ModuleConfig{}, nil +func (*fileExistsStub) FileExists(_ string) (bool, error) { + return true, nil } -func (*moduleConfigServiceStub) GetDefaultCRData(_ string) ([]byte, error) { - return []byte{}, nil +func (*fileExistsStub) ReadFile(_ string) ([]byte, error) { + return nil, nil +} + +type fileResolverStub struct{} + +func (*fileResolverStub) Resolve(_ string) (string, error) { + return "/tmp/some-file.yaml", nil } -func (*moduleConfigServiceStub) CleanupTempFiles() []error { +func (*fileResolverStub) CleanupTempFiles() []error { return nil } +type fileResolverErrorStub struct{} + +func (*fileResolverErrorStub) Resolve(_ string) (string, error) { + return "", errors.New("failed to resolve file") +} + +func (*fileResolverErrorStub) CleanupTempFiles() []error { + return []error{errors.New("failed to cleanup temp files")} +} + +type moduleConfigServiceStub struct{} + +func (*moduleConfigServiceStub) ParseAndValidateModuleConfig(_ string) (*contentprovider.ModuleConfig, error) { + return &contentprovider.ModuleConfig{ + DefaultCR: "default-cr.yaml", + }, nil +} + type moduleConfigServiceParseErrorStub struct{} func (*moduleConfigServiceParseErrorStub) ParseAndValidateModuleConfig(_ string) (*contentprovider.ModuleConfig, @@ -167,14 +223,6 @@ func (*moduleConfigServiceParseErrorStub) ParseAndValidateModuleConfig(_ string) return nil, errors.New("failed to read module config file") } -func (*moduleConfigServiceParseErrorStub) GetDefaultCRData(_ string) ([]byte, error) { - return []byte{}, nil -} - -func (*moduleConfigServiceParseErrorStub) CleanupTempFiles() []error { - return nil -} - type gitSourcesServiceStub struct{} func (*gitSourcesServiceStub) AddGitSources(_ *compdesc.ComponentDescriptor, diff --git a/internal/service/fileresolver/fileresolver_test.go b/internal/service/fileresolver/fileresolver_test.go new file mode 100644 index 00000000..39e237fa --- /dev/null +++ b/internal/service/fileresolver/fileresolver_test.go @@ -0,0 +1,116 @@ +package fileresolver_test + +import ( + "fmt" + "net/url" + "testing" + + commonerrors "github.com/kyma-project/modulectl/internal/common/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/kyma-project/modulectl/internal/service/fileresolver" +) + +const filePattern = "kyma-module-manifest-*.yaml" + +func TestNew_CalledWithEmptyFilePattern_ReturnsErr(t *testing.T) { + _, err := fileresolver.NewFileResolver("", &tmpfileSystemStub{}) + require.ErrorIs(t, err, commonerrors.ErrInvalidArg) + assert.Contains(t, err.Error(), "filePattern must not be empty") +} + +func TestNew_CalledWithNilDependencies_ReturnsErr(t *testing.T) { + _, err := fileresolver.NewFileResolver(filePattern, nil) + require.ErrorIs(t, err, commonerrors.ErrInvalidArg) + assert.Contains(t, err.Error(), "tempFileSystem must not be nil") +} + +func TestCleanupTempFiles_CalledWithNoTempFiles_ReturnsNoErrors(t *testing.T) { + resolver, _ := fileresolver.NewFileResolver(filePattern, &tmpfileSystemStub{}) + + errs := resolver.CleanupTempFiles() + assert.Empty(t, errs) +} + +func Test_Resolve_Returns_CorrectPath(t *testing.T) { + resolver, _ := fileresolver.NewFileResolver(filePattern, &tmpfileSystemStub{}) + result, err := resolver.Resolve("https://example.com/path") + + require.NoError(t, err) + require.Equal(t, "file.yaml", result) +} + +func Test_Resolve_Returns_CorrectPath_When_NotUrl(t *testing.T) { + resolver, _ := fileresolver.NewFileResolver(filePattern, &tmpfileSystemStub{}) + result, err := resolver.Resolve("/path/to/manifest.yaml") + + require.NoError(t, err) + require.Equal(t, "/path/to/manifest.yaml", result) +} + +func TestService_ParseURL(t *testing.T) { + tests := []struct { + name string + urlString string + want *url.URL + expectedError error + }{ + { + name: "valid URL", + urlString: "https://example.com/path", + want: &url.URL{ + Scheme: "https", + Host: "example.com", + Path: "/path", + }, + expectedError: nil, + }, + { + name: "invalid URL", + urlString: "invalid-url", + want: nil, + expectedError: fmt.Errorf("failed to parse url invalid-url: %w", commonerrors.ErrInvalidArg), + }, + { + name: "URL without Scheme", + urlString: "example.com/path", + want: nil, + expectedError: fmt.Errorf("failed to parse url example.com/path: %w", commonerrors.ErrInvalidArg), + }, + { + name: "URL without Host", + urlString: "https://", + want: nil, + expectedError: fmt.Errorf("failed to parse url https://: %w", commonerrors.ErrInvalidArg), + }, + { + name: "Empty URL", + urlString: "", + want: nil, + expectedError: fmt.Errorf("failed to parse url : %w", commonerrors.ErrInvalidArg), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + resolver, _ := fileresolver.NewFileResolver(filePattern, &tmpfileSystemStub{}) + got, err := resolver.ParseURL(test.urlString) + + if test.expectedError != nil { + require.EqualError(t, err, test.expectedError.Error()) + return + } + require.Equalf(t, test.want, got, "ParseURL(%v)", test.urlString) + }) + } +} + +type tmpfileSystemStub struct{} + +func (*tmpfileSystemStub) DownloadTempFile(_ string, _ string, _ *url.URL) (string, error) { + return "file.yaml", nil +} + +func (s *tmpfileSystemStub) RemoveTempFiles() []error { + return nil +} diff --git a/internal/service/moduleconfig/generator/moduleconfig_generator_test.go b/internal/service/moduleconfig/generator/moduleconfig_generator_test.go index af614744..1ee8ed2c 100644 --- a/internal/service/moduleconfig/generator/moduleconfig_generator_test.go +++ b/internal/service/moduleconfig/generator/moduleconfig_generator_test.go @@ -118,19 +118,19 @@ func (*fileExistsStub) FileExists(_ string) (bool, error) { func (*fileExistsStub) ReadFile(_ string) ([]byte, error) { moduleConfig := contentprovider.ModuleConfig{ - Name: "module-name", - Version: "0.0.1", - Channel: "regular", - Manifest: "path/to/manifests", - Mandatory: false, - DefaultCRPath: "path/to/defaultCR", - ResourceName: "module-name-0.0.1", - Namespace: "kcp-system", - Security: "path/to/securityConfig", - Internal: false, - Beta: false, - Labels: map[string]string{"label1": "value1"}, - Annotations: map[string]string{"annotation1": "value1"}, + Name: "module-name", + Version: "0.0.1", + Channel: "regular", + Manifest: "path/to/manifests", + Mandatory: false, + DefaultCR: "path/to/defaultCR", + ResourceName: "module-name-0.0.1", + Namespace: "kcp-system", + Security: "path/to/securityConfig", + Internal: false, + Beta: false, + Labels: map[string]string{"label1": "value1"}, + Annotations: map[string]string{"annotation1": "value1"}, Manager: &contentprovider.Manager{ Name: "manager-name", Namespace: "manager-namespace", diff --git a/internal/service/moduleconfig/reader/moduleconfig_reader_test.go b/internal/service/moduleconfig/reader/moduleconfig_reader_test.go index f63f640d..76228552 100644 --- a/internal/service/moduleconfig/reader/moduleconfig_reader_test.go +++ b/internal/service/moduleconfig/reader/moduleconfig_reader_test.go @@ -3,7 +3,6 @@ package moduleconfigreader_test import ( "errors" "fmt" - "net/url" "testing" "github.com/stretchr/testify/require" @@ -34,7 +33,7 @@ func Test_ParseModuleConfig_Returns_CorrectModuleConfig(t *testing.T) { require.Equal(t, "0.0.1", result.Version) require.Equal(t, "regular", result.Channel) require.Equal(t, "path/to/manifests", result.Manifest) - require.Equal(t, "path/to/defaultCR", result.DefaultCRPath) + require.Equal(t, "path/to/defaultCR", result.DefaultCR) require.Equal(t, "module-name-0.0.1", result.ResourceName) require.False(t, result.Mandatory) require.Equal(t, "kcp-system", result.Namespace) @@ -54,124 +53,8 @@ func Test_ParseModuleConfig_Returns_CorrectModuleConfig(t *testing.T) { } func TestNew_CalledWithNilDependencies_ReturnsErr(t *testing.T) { - _, err := moduleconfigreader.NewService( - nil, - &tmpfileSystemStub{}) + _, err := moduleconfigreader.NewService(nil) require.Error(t, err) - - _, err = moduleconfigreader.NewService( - &fileExistsStub{}, - nil) - require.Error(t, err) -} - -func Test_GetDefaultCRData_CalledWithEmptyPath_ReturnsErr(t *testing.T) { - moduleConfigService, err := moduleconfigreader.NewService( - &fileExistsStub{}, - &tmpfileSystemStub{}) - require.NoError(t, err) - - _, err = moduleConfigService.GetDefaultCRData("") - - require.Error(t, err) - require.ErrorIs(t, err, moduleconfigreader.ErrNoPathForDefaultCR) -} - -func Test_GetDefaultCRData_Returns_CorrectData(t *testing.T) { - moduleConfigService, err := moduleconfigreader.NewService( - &fileExistsStub{}, - &tmpfileSystemStub{}) - require.NoError(t, err) - - result, err := moduleConfigService.GetDefaultCRData("/path/to/defaultcr") - require.NoError(t, err) - - expected, err := yaml.Marshal(expectedReturnedModuleConfig) - require.NoError(t, err) - require.Equal(t, expected, result) -} - -func Test_GetDefaultCRPath_Returns_CorrectPath(t *testing.T) { - result, err := moduleconfigreader.GetDefaultCRPath("https://example.com/path", &tmpfileSystemStub{}) - - require.NoError(t, err) - require.Equal(t, "file.yaml", result) -} - -func Test_GetDefaultCRPath_Returns_CorrectPath_When_NotUrl(t *testing.T) { - result, err := moduleconfigreader.GetDefaultCRPath("/path/to/defaultcr.yaml", &tmpfileSystemStub{}) - - require.NoError(t, err) - require.Equal(t, "/path/to/defaultcr.yaml", result) -} - -func Test_GetManifestPath_Returns_CorrectPath(t *testing.T) { - result, err := moduleconfigreader.GetDefaultCRPath("https://example.com/path", &tmpfileSystemStub{}) - - require.NoError(t, err) - require.Equal(t, "file.yaml", result) -} - -func Test_GetManifestPath_Returns_CorrectPath_When_NotUrl(t *testing.T) { - result, err := moduleconfigreader.GetDefaultCRPath("/path/to/manifest.yaml", &tmpfileSystemStub{}) - - require.NoError(t, err) - require.Equal(t, "/path/to/manifest.yaml", result) -} - -func TestService_ParseURL(t *testing.T) { - tests := []struct { - name string - urlString string - want *url.URL - expectedError error - }{ - { - name: "valid URL", - urlString: "https://example.com/path", - want: &url.URL{ - Scheme: "https", - Host: "example.com", - Path: "/path", - }, - expectedError: nil, - }, - { - name: "invalid URL", - urlString: "invalid-url", - want: nil, - expectedError: fmt.Errorf("failed to parse url invalid-url: %w", commonerrors.ErrInvalidArg), - }, - { - name: "URL without Scheme", - urlString: "example.com/path", - want: nil, - expectedError: fmt.Errorf("failed to parse url example.com/path: %w", commonerrors.ErrInvalidArg), - }, - { - name: "URL without Host", - urlString: "https://", - want: nil, - expectedError: fmt.Errorf("failed to parse url https://: %w", commonerrors.ErrInvalidArg), - }, - { - name: "Empty URL", - urlString: "", - want: nil, - expectedError: fmt.Errorf("failed to parse url : %w", commonerrors.ErrInvalidArg), - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - got, err := moduleconfigreader.ParseURL(test.urlString) - - if test.expectedError != nil { - require.EqualError(t, err, test.expectedError.Error()) - return - } - require.Equalf(t, test.want, got, "ParseURL(%v)", test.urlString) - }) - } } func Test_ValidateModuleConfig(t *testing.T) { @@ -402,19 +285,19 @@ func (*fileExistsStub) FileExists(_ string) (bool, error) { } var expectedReturnedModuleConfig = contentprovider.ModuleConfig{ - Name: "github.com/module-name", - Version: "0.0.1", - Channel: "regular", - Manifest: "path/to/manifests", - Mandatory: false, - DefaultCRPath: "path/to/defaultCR", - ResourceName: "module-name-0.0.1", - Namespace: "kcp-system", - Security: "path/to/securityConfig", - Internal: false, - Beta: false, - Labels: map[string]string{"label1": "value1"}, - Annotations: map[string]string{"annotation1": "value1"}, + Name: "github.com/module-name", + Version: "0.0.1", + Channel: "regular", + Manifest: "path/to/manifests", + Mandatory: false, + DefaultCR: "path/to/defaultCR", + ResourceName: "module-name-0.0.1", + Namespace: "kcp-system", + Security: "path/to/securityConfig", + Internal: false, + Beta: false, + Labels: map[string]string{"label1": "value1"}, + Annotations: map[string]string{"annotation1": "value1"}, Resources: contentprovider.ResourcesMap{ "rawManifest": "https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml", }, @@ -433,16 +316,6 @@ func (*fileExistsStub) ReadFile(_ string) ([]byte, error) { return yaml.Marshal(expectedReturnedModuleConfig) } -type tmpfileSystemStub struct{} - -func (*tmpfileSystemStub) DownloadTempFile(_ string, _ string, _ *url.URL) (string, error) { - return "file.yaml", nil -} - -func (*tmpfileSystemStub) RemoveTempFiles() []error { - return nil -} - type fileDoesNotExistStub struct{} func (*fileDoesNotExistStub) FileExists(_ string) (bool, error) { diff --git a/tests/e2e/create/create_suite_test.go b/tests/e2e/create/create_suite_test.go index da6ecf3c..eaebc318 100644 --- a/tests/e2e/create/create_suite_test.go +++ b/tests/e2e/create/create_suite_test.go @@ -84,7 +84,7 @@ func (cmd *createCmd) execute() error { println(" >>> Executing command: modulectl", strings.Join(args, " ")) - command = exec.Command("modulectl", args...) + command = exec.Command("/Users/I507792/Workspaces/go/src/github.com/c-pius/modulectl/bin/modulectl-darwin-arm", args...) cmdOut, err := command.CombinedOutput() if err != nil { return fmt.Errorf("create command failed with output: %s and error: %w", cmdOut, err) diff --git a/tests/e2e/scaffold/scaffold_suite_test.go b/tests/e2e/scaffold/scaffold_suite_test.go index a666607d..7f5c878c 100644 --- a/tests/e2e/scaffold/scaffold_suite_test.go +++ b/tests/e2e/scaffold/scaffold_suite_test.go @@ -66,7 +66,7 @@ func (cmd *scaffoldCmd) execute() error { args = append(args, "--overwrite=true") } - command = exec.Command("modulectl", args...) + command = exec.Command("/Users/I507792/Workspaces/go/src/github.com/c-pius/modulectl/bin/modulectl-darwin-arm", args...) cmdOut, err := command.CombinedOutput() if err != nil { return fmt.Errorf("scaffold command failed with output: %s and error: %w", cmdOut, err) diff --git a/unit-test-coverage.yaml b/unit-test-coverage.yaml index 294d7a94..f9285c7c 100644 --- a/unit-test-coverage.yaml +++ b/unit-test-coverage.yaml @@ -6,7 +6,7 @@ packages: internal/service/filegenerator: 100 internal/service/moduleconfig/generator: 100 internal/service/moduleconfig/reader: 50 - internal/service/create: 34 + internal/service/create: 43 internal/service/componentdescriptor: 78 internal/service/templategenerator: 78 internal/service/crdparser: 73 From 6996756b2e04ed7368dff921ce01d301fac1c729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schw=C3=A4gerl?= Date: Fri, 18 Oct 2024 17:06:49 +0200 Subject: [PATCH 3/5] revert suite test changes --- tests/e2e/create/create_suite_test.go | 2 +- tests/e2e/scaffold/scaffold_suite_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/create/create_suite_test.go b/tests/e2e/create/create_suite_test.go index eaebc318..da6ecf3c 100644 --- a/tests/e2e/create/create_suite_test.go +++ b/tests/e2e/create/create_suite_test.go @@ -84,7 +84,7 @@ func (cmd *createCmd) execute() error { println(" >>> Executing command: modulectl", strings.Join(args, " ")) - command = exec.Command("/Users/I507792/Workspaces/go/src/github.com/c-pius/modulectl/bin/modulectl-darwin-arm", args...) + command = exec.Command("modulectl", args...) cmdOut, err := command.CombinedOutput() if err != nil { return fmt.Errorf("create command failed with output: %s and error: %w", cmdOut, err) diff --git a/tests/e2e/scaffold/scaffold_suite_test.go b/tests/e2e/scaffold/scaffold_suite_test.go index 7f5c878c..a666607d 100644 --- a/tests/e2e/scaffold/scaffold_suite_test.go +++ b/tests/e2e/scaffold/scaffold_suite_test.go @@ -66,7 +66,7 @@ func (cmd *scaffoldCmd) execute() error { args = append(args, "--overwrite=true") } - command = exec.Command("/Users/I507792/Workspaces/go/src/github.com/c-pius/modulectl/bin/modulectl-darwin-arm", args...) + command = exec.Command("modulectl", args...) cmdOut, err := command.CombinedOutput() if err != nil { return fmt.Errorf("scaffold command failed with output: %s and error: %w", cmdOut, err) From 65254d9b45d9c262059b093b3d0340c2f78f5ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schw=C3=A4gerl?= Date: Fri, 18 Oct 2024 17:21:52 +0200 Subject: [PATCH 4/5] increase fileresolver coverage --- .../service/fileresolver/fileresolver_test.go | 32 +++++++++++++++++-- unit-test-coverage.yaml | 1 + 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/internal/service/fileresolver/fileresolver_test.go b/internal/service/fileresolver/fileresolver_test.go index 39e237fa..ff6a0d08 100644 --- a/internal/service/fileresolver/fileresolver_test.go +++ b/internal/service/fileresolver/fileresolver_test.go @@ -41,12 +41,30 @@ func Test_Resolve_Returns_CorrectPath(t *testing.T) { require.Equal(t, "file.yaml", result) } -func Test_Resolve_Returns_CorrectPath_When_NotUrl(t *testing.T) { +func Test_Resolve_Returns_Error_WhenFailingToDownload(t *testing.T) { + resolver, _ := fileresolver.NewFileResolver(filePattern, &tempfileSystemErrorStub{}) + result, err := resolver.Resolve("https://example.com/path") + + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to download file") + assert.Empty(t, result) +} + +func Test_Resolve_Returns_CorrectPath_When_AbsolutePath(t *testing.T) { resolver, _ := fileresolver.NewFileResolver(filePattern, &tmpfileSystemStub{}) result, err := resolver.Resolve("/path/to/manifest.yaml") require.NoError(t, err) - require.Equal(t, "/path/to/manifest.yaml", result) + assert.Equal(t, "/path/to/manifest.yaml", result) +} + +func Test_Resolve_Returns_CorrectPath_When_Relative(t *testing.T) { + resolver, _ := fileresolver.NewFileResolver(filePattern, &tmpfileSystemStub{}) + result, err := resolver.Resolve("./path/to/manifest.yaml") + + require.NoError(t, err) + assert.Contains(t, result, "/path/to/manifest.yaml") + assert.Equal(t, rune(result[0]), '/') } func TestService_ParseURL(t *testing.T) { @@ -114,3 +132,13 @@ func (*tmpfileSystemStub) DownloadTempFile(_ string, _ string, _ *url.URL) (stri func (s *tmpfileSystemStub) RemoveTempFiles() []error { return nil } + +type tempfileSystemErrorStub struct{} + +func (*tempfileSystemErrorStub) DownloadTempFile(_ string, _ string, _ *url.URL) (string, error) { + return "", fmt.Errorf("error downloading file") +} + +func (s *tempfileSystemErrorStub) RemoveTempFiles() []error { + return nil +} diff --git a/unit-test-coverage.yaml b/unit-test-coverage.yaml index f9285c7c..e791aeab 100644 --- a/unit-test-coverage.yaml +++ b/unit-test-coverage.yaml @@ -4,6 +4,7 @@ packages: internal/service/scaffold: 92 internal/service/contentprovider: 98 internal/service/filegenerator: 100 + internal/service/fileresolver: 92 internal/service/moduleconfig/generator: 100 internal/service/moduleconfig/reader: 50 internal/service/create: 43 From 5284bf47bb2ffc0c61773deb6c773b0717e848cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schw=C3=A4gerl?= Date: Fri, 18 Oct 2024 17:24:07 +0200 Subject: [PATCH 5/5] fix linting --- internal/service/fileresolver/fileresolver_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/service/fileresolver/fileresolver_test.go b/internal/service/fileresolver/fileresolver_test.go index ff6a0d08..794fe29a 100644 --- a/internal/service/fileresolver/fileresolver_test.go +++ b/internal/service/fileresolver/fileresolver_test.go @@ -5,10 +5,11 @@ import ( "net/url" "testing" - commonerrors "github.com/kyma-project/modulectl/internal/common/errors" + "github.com/mandelsoft/goutils/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + commonerrors "github.com/kyma-project/modulectl/internal/common/errors" "github.com/kyma-project/modulectl/internal/service/fileresolver" ) @@ -64,7 +65,7 @@ func Test_Resolve_Returns_CorrectPath_When_Relative(t *testing.T) { require.NoError(t, err) assert.Contains(t, result, "/path/to/manifest.yaml") - assert.Equal(t, rune(result[0]), '/') + assert.Equal(t, '/', rune(result[0])) } func TestService_ParseURL(t *testing.T) { @@ -136,7 +137,7 @@ func (s *tmpfileSystemStub) RemoveTempFiles() []error { type tempfileSystemErrorStub struct{} func (*tempfileSystemErrorStub) DownloadTempFile(_ string, _ string, _ *url.URL) (string, error) { - return "", fmt.Errorf("error downloading file") + return "", errors.New("error downloading file") } func (s *tempfileSystemErrorStub) RemoveTempFiles() []error {