Skip to content

Commit

Permalink
Add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nesmabadr committed Sep 11, 2024
1 parent 334b96b commit ed4cefb
Show file tree
Hide file tree
Showing 9 changed files with 317 additions and 42 deletions.
1 change: 0 additions & 1 deletion cmd/modulectl/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ func NewCmd() (*cobra.Command, error) {
func buildModuleService() (*create.Service, error) {
fileSystemUtil := &filesystem.Util{}
tmpFileSystem := filesystem.NewTempFileSystem()
defer tmpFileSystem.RemoveTempFiles()

moduleConfigService, err := moduleconfigreader.NewService(fileSystemUtil, tmpFileSystem)
if err != nil {
Expand Down
2 changes: 0 additions & 2 deletions cmd/modulectl/create/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ func Test_Execute_ParsesAllModuleOptions(t *testing.T) {
templateOutput := testutils.RandomName(10)
registryURL := testutils.RandomName(10)
registryCredSelector := testutils.RandomName(10)
secScannerConfig := testutils.RandomName(10)

os.Args = []string{
"create",
Expand All @@ -64,7 +63,6 @@ func Test_Execute_ParsesAllModuleOptions(t *testing.T) {
"--output", templateOutput,
"--registry", registryURL,
"--registry-cred-selector", registryCredSelector,
"--sec-scanners-config", secScannerConfig,
}

svc := &moduleServiceStub{}
Expand Down
7 changes: 5 additions & 2 deletions cmd/modulectl/create/flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ func Test_ScaffoldFlagsDefaults(t *testing.T) {
value string
expected string
}{
{name: createcmd.ModuleConfigFileFlagName, value: createcmd.ModuleConfigFileFlagDefault, expected: "module-config.yaml"},
{
name: createcmd.ModuleConfigFileFlagName,
value: createcmd.ModuleConfigFileFlagDefault,
expected: "module-config.yaml",
},
{name: createcmd.CredentialsFlagName, value: createcmd.CredentialsFlagDefault, expected: ""},
{name: createcmd.GitRemoteFlagName, value: createcmd.GitRemoteFlagDefault, expected: "origin"},
{name: createcmd.InsecureFlagName, value: strconv.FormatBool(createcmd.InsecureFlagDefault), expected: "false"},
{name: createcmd.TemplateOutputFlagName, value: createcmd.TemplateOutputFlagDefault, expected: "template.yaml"},
{name: createcmd.RegistryURLFlagName, value: createcmd.RegistryURLFlagDefault, expected: ""},
{name: createcmd.RegistryCredSelectorFlagName, value: createcmd.RegistryCredSelectorFlagDefault, expected: ""},
{name: createcmd.SecScannersConfigFlagName, value: createcmd.SecScannersConfigFlagDefault, expected: "sec-scanners-config.yaml"},
}

for _, testcase := range tests {
Expand Down
13 changes: 2 additions & 11 deletions internal/service/componentdescriptor/component_descriptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,8 @@ import (
)

type ModuleDefinition struct {
Name string
Version string
SchemaVersion string

// TODO: Define Layer struct based on the new ocm and remember to add the raw-manifest layer
// Layers []Layer

Name string
Version string
}

func (d *ModuleDefinition) ValidateModuleDefinition() error {
Expand All @@ -25,9 +20,5 @@ func (d *ModuleDefinition) ValidateModuleDefinition() error {
return fmt.Errorf("%w: module version must not be empty", commonerrors.ErrInvalidArg)
}

if d.SchemaVersion == "" {
return fmt.Errorf("%w: module schema version must not be empty", commonerrors.ErrInvalidArg)
}

return nil
}
3 changes: 3 additions & 0 deletions internal/service/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type ModuleConfigService interface {
ValidateModuleConfig(moduleConfig *contentprovider.ModuleConfig) error
GetDefaultCRPath(defaultCRPath string) (string, error)
GetManifestPath(manifestPath string) (string, error)
CleanupTempFiles() []error
}

type Service struct {
Expand All @@ -33,6 +34,8 @@ func (s *Service) CreateModule(opts Options) error {
return err
}

defer s.moduleConfigService.CleanupTempFiles()

moduleConfig, err := s.moduleConfigService.ParseModuleConfig(opts.ModuleConfigFile)
if err != nil {
return fmt.Errorf("%w: failed to parse module config file", err)
Expand Down
204 changes: 185 additions & 19 deletions internal/service/create/create_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package create_test

import (
"errors"
"io"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -10,7 +12,6 @@ import (
"github.com/kyma-project/modulectl/internal/service/contentprovider"
"github.com/kyma-project/modulectl/internal/service/create"
iotools "github.com/kyma-project/modulectl/tools/io"
"io"
)

func Test_NewService_ReturnsError_WhenModuleConfigServiceIsNil(t *testing.T) {
Expand All @@ -20,46 +21,112 @@ func Test_NewService_ReturnsError_WhenModuleConfigServiceIsNil(t *testing.T) {
assert.Contains(t, err.Error(), "moduleConfigService")
}

type moduleConfigServiceMock struct{}
func Test_CreateModule_ReturnsError_WhenModuleConfigFileIsEmpty(t *testing.T) {
svc, err := create.NewService(&moduleConfigServiceStub{})
require.NoError(t, err)

opts := newCreateOptionsBuilder().withModuleConfigFile("").build()

err = svc.CreateModule(opts)

func (*moduleConfigServiceMock) ParseModuleConfig(_ string) (*contentprovider.ModuleConfig, error) {
return nil, nil
require.ErrorIs(t, err, commonerrors.ErrInvalidOption)
assert.Contains(t, err.Error(), "opts.ModuleConfigFile")
}

func (*moduleConfigServiceMock) ValidateModuleConfig(_ *contentprovider.ModuleConfig) error {
return nil
func Test_CreateModule_ReturnsError_WhenOutIsNil(t *testing.T) {
svc, err := create.NewService(&moduleConfigServiceStub{})
require.NoError(t, err)

opts := newCreateOptionsBuilder().withOut(nil).build()

err = svc.CreateModule(opts)

require.ErrorIs(t, err, commonerrors.ErrInvalidOption)
assert.Contains(t, err.Error(), "opts.Out")
}

func (*moduleConfigServiceMock) GetDefaultCRPath(_ string) (string, error) {
return "", nil
func Test_CreateModule_ReturnsError_WhenGitRemoteIsEmpty(t *testing.T) {
svc, err := create.NewService(&moduleConfigServiceStub{})
require.NoError(t, err)

opts := newCreateOptionsBuilder().withGitRemote("").build()

err = svc.CreateModule(opts)

require.ErrorIs(t, err, commonerrors.ErrInvalidOption)
assert.Contains(t, err.Error(), "opts.GitRemote")
}

func (*moduleConfigServiceMock) GetManifestPath(_ string) (string, error) {
return "", nil
func Test_CreateModule_ReturnsError_WhenCredentialsIsInInvalidFormat(t *testing.T) {
svc, err := create.NewService(&moduleConfigServiceStub{})
require.NoError(t, err)

opts := newCreateOptionsBuilder().withCredentials("user").build()

err = svc.CreateModule(opts)

require.ErrorIs(t, err, commonerrors.ErrInvalidOption)
assert.Contains(t, err.Error(), "opts.Credentials")
}

func Test_CreateModule_ReturnsError_WhenModuleConfigFileIsEmpty(t *testing.T) {
svc, err := create.NewService(&moduleConfigServiceMock{})
func Test_CreateModule_ReturnsError_WhenTemplateOutputIsEmpty(t *testing.T) {
svc, err := create.NewService(&moduleConfigServiceStub{})
require.NoError(t, err)

opts := newCreateOptionsBuilder().withModuleConfigFile("").build()
opts := newCreateOptionsBuilder().withTemplateOutput("").build()

err = svc.CreateModule(opts)

require.ErrorIs(t, err, commonerrors.ErrInvalidOption)
assert.Contains(t, err.Error(), "opts.ModuleConfigFile")
assert.Contains(t, err.Error(), "opts.TemplateOutput")
}

func Test_CreateModule_ReturnsError_WhenOutIsNil(t *testing.T) {
svc, err := create.NewService(&moduleConfigServiceMock{})
func Test_CreateModule_ReturnsError_WhenRegistryURLIsInInvalidFormat(t *testing.T) {
svc, err := create.NewService(&moduleConfigServiceStub{})
require.NoError(t, err)

opts := newCreateOptionsBuilder().withOut(nil).build()
opts := newCreateOptionsBuilder().withRegistryURL("test").build()

err = svc.CreateModule(opts)

require.ErrorIs(t, err, commonerrors.ErrInvalidOption)
assert.Contains(t, err.Error(), "opts.Out")
assert.Contains(t, err.Error(), "opts.RegistryURL")
}

func Test_CreateModule_ReturnsError_WhenParseModuleConfigReturnsError(t *testing.T) {
svc, err := create.NewService(&moduleConfigServiceParseErrorStub{})
require.NoError(t, err)

opts := newCreateOptionsBuilder().build()

err = svc.CreateModule(opts)

require.Error(t, err)
assert.Contains(t, err.Error(), "failed to parse module config file")
}

func Test_CreateModule_ReturnsError_WhenGetDefaultCRPathReturnsError(t *testing.T) {
svc, err := create.NewService(&moduleConfigServiceDefaultCRErrorStub{})
require.NoError(t, err)

opts := newCreateOptionsBuilder().build()

err = svc.CreateModule(opts)

require.Error(t, err)
assert.Contains(t, err.Error(), "failed to download default CR file")
}

func Test_CreateModule_ReturnsError_WhenGetManifestPathReturnsError(t *testing.T) {
svc, err := create.NewService(&moduleConfigServiceManifestErrorStub{})
require.NoError(t, err)

opts := newCreateOptionsBuilder().build()

err = svc.CreateModule(opts)

require.Error(t, err)
assert.Contains(t, err.Error(), "failed to download Manifest file")
}

type createOptionsBuilder struct {
Expand All @@ -76,7 +143,8 @@ func newCreateOptionsBuilder() *createOptionsBuilder {
withModuleConfigFile("create-module-config.yaml").
withRegistryURL("https://registry.kyma.cx").
withGitRemote("origin").
withTemplateOutput("test")
withTemplateOutput("test").
withCredentials("user:password")
}

func (b *createOptionsBuilder) build() create.Options {
Expand Down Expand Up @@ -107,3 +175,101 @@ func (b *createOptionsBuilder) withTemplateOutput(templateOutput string) *create
b.options.TemplateOutput = templateOutput
return b
}

func (b *createOptionsBuilder) withCredentials(credentials string) *createOptionsBuilder {
b.options.Credentials = credentials
return b
}

// Test Stubs
type moduleConfigServiceStub struct{}

func (*moduleConfigServiceStub) ParseModuleConfig(_ string) (*contentprovider.ModuleConfig, error) {
return &contentprovider.ModuleConfig{}, nil
}

func (*moduleConfigServiceStub) ValidateModuleConfig(_ *contentprovider.ModuleConfig) error {
return nil
}

func (*moduleConfigServiceStub) GetDefaultCRPath(_ string) (string, error) {
return "", nil
}

func (*moduleConfigServiceStub) GetManifestPath(_ string) (string, error) {
return "", nil
}

func (*moduleConfigServiceStub) CleanupTempFiles() []error {
return nil
}

type moduleConfigServiceParseErrorStub struct{}

func (*moduleConfigServiceParseErrorStub) ParseModuleConfig(_ string) (*contentprovider.ModuleConfig, error) {
return nil, errors.New("failed to read module config file")
}

func (*moduleConfigServiceParseErrorStub) ValidateModuleConfig(_ *contentprovider.ModuleConfig) error {
return nil
}

func (*moduleConfigServiceParseErrorStub) GetDefaultCRPath(_ string) (string, error) {
return "", nil
}

func (*moduleConfigServiceParseErrorStub) GetManifestPath(_ string) (string, error) {
return "", nil
}

func (*moduleConfigServiceParseErrorStub) CleanupTempFiles() []error {
return nil
}

type moduleConfigServiceDefaultCRErrorStub struct{}

func (*moduleConfigServiceDefaultCRErrorStub) ParseModuleConfig(_ string) (*contentprovider.ModuleConfig, error) {
return &contentprovider.ModuleConfig{
DefaultCRPath: "test",
}, nil
}

func (*moduleConfigServiceDefaultCRErrorStub) ValidateModuleConfig(_ *contentprovider.ModuleConfig) error {
return nil
}

func (*moduleConfigServiceDefaultCRErrorStub) GetDefaultCRPath(_ string) (string, error) {
return "", errors.New("failed to download default CR file")
}

func (*moduleConfigServiceDefaultCRErrorStub) GetManifestPath(_ string) (string, error) {
return "", nil
}

func (*moduleConfigServiceDefaultCRErrorStub) CleanupTempFiles() []error {
return nil
}

type moduleConfigServiceManifestErrorStub struct{}

func (*moduleConfigServiceManifestErrorStub) ParseModuleConfig(_ string) (*contentprovider.ModuleConfig, error) {
return &contentprovider.ModuleConfig{
ManifestPath: "test",
}, nil
}

func (*moduleConfigServiceManifestErrorStub) ValidateModuleConfig(_ *contentprovider.ModuleConfig) error {
return nil
}

func (*moduleConfigServiceManifestErrorStub) GetDefaultCRPath(_ string) (string, error) {
return "", nil
}

func (*moduleConfigServiceManifestErrorStub) GetManifestPath(_ string) (string, error) {
return "", errors.New("failed to download Manifest file")
}

func (*moduleConfigServiceManifestErrorStub) CleanupTempFiles() []error {
return nil
}
8 changes: 6 additions & 2 deletions internal/service/moduleconfig/reader/moduleconfig_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (s *Service) GetManifestPath(manifestPath string) (string, error) {
if parsedURL, err := s.ParseURL(manifestPath); err == nil {
path, err = s.tmpFileSystem.DownloadTempFile("", defaultManifestFilePattern, parsedURL)
if err != nil {
return "", fmt.Errorf("failed to download default CR file: %w", err)
return "", fmt.Errorf("failed to download Manifest file: %w", err)
}
}

Expand All @@ -89,7 +89,7 @@ func (s *Service) GetManifestPath(manifestPath string) (string, error) {

func (s *Service) ParseURL(urlString string) (*url.URL, error) {
urlParsed, err := url.Parse(urlString)
if err != nil && urlParsed.Scheme != "" && urlParsed.Host != "" {
if err == nil && urlParsed.Scheme != "" && urlParsed.Host != "" {
return urlParsed, nil
}
return nil, fmt.Errorf("%w: parsing url failed for %s", commonerrors.ErrInvalidArg, urlString)
Expand Down Expand Up @@ -118,3 +118,7 @@ func (*Service) ValidateModuleConfig(moduleConfig *contentprovider.ModuleConfig)

return nil
}

func (s *Service) CleanupTempFiles() []error {
return s.tmpFileSystem.RemoveTempFiles()
}
Loading

0 comments on commit ed4cefb

Please sign in to comment.