Skip to content

Commit

Permalink
check for attribute and print out all default command and it's import…
Browse files Browse the repository at this point in the history
… reference if any

Signed-off-by: Stephanie <yangcao@redhat.com>
  • Loading branch information
yangcao77 committed Apr 29, 2021
1 parent 4ba7837 commit a22cea8
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 95 deletions.
13 changes: 10 additions & 3 deletions pkg/validation/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func ValidateCommands(commands []v1alpha2.Command, components []v1alpha2.Compone
parentCommands := make(map[string]string)
err = validateCommand(command, parentCommands, commandMap, components)
if err != nil {
return resolveErrorMessageWithImportArrtibutes(err, command.Attributes)
return resolveErrorMessageWithImportAttributes(err, command.Attributes)
}

commandGroup := getGroup(command)
Expand Down Expand Up @@ -68,11 +68,12 @@ func validateCommand(command v1alpha2.Command, parentCommands map[string]string,
// 2. with more than one default, err out
func validateGroup(commands []v1alpha2.Command) error {
defaultCommandCount := 0

var defaultCommands []v1alpha2.Command
if len(commands) > 1 {
for _, command := range commands {
if getGroup(command).IsDefault {
defaultCommandCount++
defaultCommands = append(defaultCommands, command)
}
}
} else {
Expand All @@ -82,7 +83,13 @@ func validateGroup(commands []v1alpha2.Command) error {
if defaultCommandCount == 0 {
return fmt.Errorf("there should be exactly one default command, currently there is no default command")
} else if defaultCommandCount > 1 {
return fmt.Errorf("there should be exactly one default command, currently there is more than one default command")
var commandsReference string
for _, command := range defaultCommands {
commandsReference += resolveErrorMessageWithImportAttributes(fmt.Errorf("; command: %s", command.Id), command.Attributes).Error()
}
// example: there should be exactly one default command, currently there is more than one default command;
// command: <id1>; command: <id2>, imported from uri: http://127.0.0.1:8080, in parent overrides from main devfile"
return fmt.Errorf("there should be exactly one default command, currently there is more than one default command%s", commandsReference)
}

return nil
Expand Down
42 changes: 22 additions & 20 deletions pkg/validation/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ func generateDummyExecCommand(name, component string, group *v1alpha2.CommandGro
}

// generateDummyExecCommand returns a dummy apply command for testing
func generateDummyApplyCommand(name, component string, group *v1alpha2.CommandGroup) v1alpha2.Command {
func generateDummyApplyCommand(name, component string, group *v1alpha2.CommandGroup, cmdAttributes attributes.Attributes) v1alpha2.Command {
return v1alpha2.Command{
Id: name,
Attributes: cmdAttributes,
Id: name,
CommandUnion: v1alpha2.CommandUnion{
Apply: &v1alpha2.ApplyCommand{
LabeledCommand: v1alpha2.LabeledCommand{
Expand Down Expand Up @@ -136,7 +137,7 @@ func TestValidateCommands(t *testing.T) {
{
name: "Invalid Apply command with wrong component",
commands: []v1alpha2.Command{
generateDummyApplyCommand("command", "invalidComponent", nil),
generateDummyApplyCommand("command", "invalidComponent", nil, attributes.Attributes{}),
},
wantErr: &invalidCmdErr,
},
Expand All @@ -152,20 +153,7 @@ func TestValidateCommands(t *testing.T) {
{
name: "Invalid command with import source attribute",
commands: []v1alpha2.Command{
{
Attributes: parentOverridesFromMainDevfile,
Id: "command",
CommandUnion: v1alpha2.CommandUnion{
Apply: &v1alpha2.ApplyCommand{
LabeledCommand: v1alpha2.LabeledCommand{
BaseCommand: v1alpha2.BaseCommand{
Group: nil,
},
},
Component: "invalidComponent",
},
},
},
generateDummyApplyCommand("command", "invalidComponent", nil, parentOverridesFromMainDevfile),
},
wantErr: &invalidCmdErrWithImportAttributes,
},
Expand Down Expand Up @@ -218,11 +206,11 @@ func TestValidateCommandComponent(t *testing.T) {
},
{
name: "Valid Apply Command",
command: generateDummyApplyCommand("command", component, nil),
command: generateDummyApplyCommand("command", component, nil, attributes.Attributes{}),
},
{
name: "Invalid Apply Command with wrong component",
command: generateDummyApplyCommand("command", invalidComponent, &v1alpha2.CommandGroup{Kind: runGroup}),
command: generateDummyApplyCommand("command", invalidComponent, &v1alpha2.CommandGroup{Kind: runGroup}, attributes.Attributes{}),
wantErr: &invalidCmdErr,
},
}
Expand Down Expand Up @@ -332,7 +320,13 @@ func TestValidateGroup(t *testing.T) {
component := "alias1"

noDefaultCmdErr := ".*there should be exactly one default command, currently there is no default command"
multipleDefaultCmdErr := ".*there should be exactly one default command, currently there is more than one default command"
multipleDefaultError := ".*there should be exactly one default command, currently there is more than one default command"
multipleDefaultCmdErr := multipleDefaultError + "; command: run command; command: customcommand"

parentOverridesFromMainDevfile := attributes.Attributes{}.PutString(ImportSourceAttribute,
"uri: http://127.0.0.1:8080").PutString(ParentOverrideAttribute, "main devfile")
multipleDefaultCmdErrWithImportAttributes := multipleDefaultError +
"; command: run command; command: customcommand, imported from uri: http://127.0.0.1:8080, in parent overrides from main devfile"

tests := []struct {
name string
Expand All @@ -347,6 +341,14 @@ func TestValidateGroup(t *testing.T) {
},
wantErr: &multipleDefaultCmdErr,
},
{
name: "Two default run commands with import source attribute",
commands: []v1alpha2.Command{
generateDummyExecCommand("run command", component, &v1alpha2.CommandGroup{Kind: runGroup, IsDefault: true}),
generateDummyApplyCommand("customcommand", component, &v1alpha2.CommandGroup{Kind: runGroup, IsDefault: true}, parentOverridesFromMainDevfile),
},
wantErr: &multipleDefaultCmdErrWithImportAttributes,
},
{
name: "No default for more than one build commands",
commands: []v1alpha2.Command{
Expand Down
16 changes: 8 additions & 8 deletions pkg/validation/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func ValidateComponents(components []v1alpha2.Component) error {

err := validateEndpoints(component.Container.Endpoints, processedEndPointPort, processedEndPointName)
if err != nil {
return resolveErrorMessageWithImportArrtibutes(err, component.Attributes)
return resolveErrorMessageWithImportAttributes(err, component.Attributes)
}
case component.Volume != nil:
processedVolumes[component.Name] = true
Expand All @@ -64,37 +64,37 @@ func ValidateComponents(components []v1alpha2.Component) error {
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
if _, err := resource.ParseQuantity(component.Volume.Size); err != nil {
invalidVolErr := &InvalidVolumeError{name: component.Name, reason: fmt.Sprintf("size %s for volume component is invalid, %v. Example - 2Gi, 1024Mi", component.Volume.Size, err)}
return resolveErrorMessageWithImportArrtibutes(invalidVolErr, component.Attributes)
return resolveErrorMessageWithImportAttributes(invalidVolErr, component.Attributes)
}
}
case component.Openshift != nil:
if component.Openshift.Uri != "" {
err := ValidateURI(component.Openshift.Uri)
if err != nil {
return resolveErrorMessageWithImportArrtibutes(err, component.Attributes)
return resolveErrorMessageWithImportAttributes(err, component.Attributes)
}
}

err := validateEndpoints(component.Openshift.Endpoints, processedEndPointPort, processedEndPointName)
if err != nil {
return resolveErrorMessageWithImportArrtibutes(err, component.Attributes)
return resolveErrorMessageWithImportAttributes(err, component.Attributes)
}
case component.Kubernetes != nil:
if component.Kubernetes.Uri != "" {
err := ValidateURI(component.Kubernetes.Uri)
if err != nil {
return resolveErrorMessageWithImportArrtibutes(err, component.Attributes)
return resolveErrorMessageWithImportAttributes(err, component.Attributes)
}
}
err := validateEndpoints(component.Kubernetes.Endpoints, processedEndPointPort, processedEndPointName)
if err != nil {
return resolveErrorMessageWithImportArrtibutes(err, component.Attributes)
return resolveErrorMessageWithImportAttributes(err, component.Attributes)
}
case component.Plugin != nil:
if component.Plugin.RegistryUrl != "" {
err := ValidateURI(component.Plugin.RegistryUrl)
if err != nil {
return resolveErrorMessageWithImportArrtibutes(err, component.Attributes)
return resolveErrorMessageWithImportAttributes(err, component.Attributes)
}
}
}
Expand All @@ -107,7 +107,7 @@ func ValidateComponents(components []v1alpha2.Component) error {
for _, volumeMountName := range volumeMountNames {
if !processedVolumes[volumeMountName] {
missingVolumeMountErr := fmt.Errorf("\nvolume mount %s belonging to the container component %s", volumeMountName, componentName)
newErr := resolveErrorMessageWithImportArrtibutes(missingVolumeMountErr, processedComponentWithVolumeMounts[componentName].Attributes)
newErr := resolveErrorMessageWithImportAttributes(missingVolumeMountErr, processedComponentWithVolumeMounts[componentName].Attributes)
invalidVolumeMountsErr += newErr.Error()
}
}
Expand Down
19 changes: 5 additions & 14 deletions pkg/validation/components_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ func generateDummyKubernetesComponent(name string, endpoints []v1alpha2.Endpoint
}

// generateDummyPluginComponent returns a dummy Plugin component for testing
func generateDummyPluginComponent(name, url string) v1alpha2.Component {
func generateDummyPluginComponent(name, url string, compAttribute attributes.Attributes) v1alpha2.Component {

return v1alpha2.Component{
Name: name,
Attributes: compAttribute,
Name: name,
ComponentUnion: v1alpha2.ComponentUnion{
Plugin: &v1alpha2.PluginComponent{
ImportReference: v1alpha2.ImportReference{
Expand Down Expand Up @@ -238,24 +239,14 @@ func TestValidateComponents(t *testing.T) {
{
name: "Invalid plugin registry url",
components: []v1alpha2.Component{
generateDummyPluginComponent("abc", "http//invalidregistryurl"),
generateDummyPluginComponent("abc", "http//invalidregistryurl", attributes.Attributes{}),
},
wantErr: &invalidURIErr,
},
{
name: "Invalid component due to bad URI with import source attributes",
components: []v1alpha2.Component{
{
Attributes: pluginOverridesFromMainDevfile,
Name: "name",
ComponentUnion: v1alpha2.ComponentUnion{
Plugin: &v1alpha2.PluginComponent{
ImportReference: v1alpha2.ImportReference{
RegistryUrl: "http//invalidregistryurl",
},
},
},
},
generateDummyPluginComponent("abc", "http//invalidregistryurl", pluginOverridesFromMainDevfile),
},
wantErr: &invalidURIErrWithImportAttributes,
},
Expand Down
4 changes: 2 additions & 2 deletions pkg/validation/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ func (e *InvalidComponentError) Error() string {
return fmt.Sprintf("the component %q is invalid - %s", e.componentName, e.reason)
}

// resolveErrorMessageWithImportArrtibutes returns an updated error message
// resolveErrorMessageWithImportAttributes returns an updated error message
// with detailed information on the imported and overriden resource.
// example:
// "the component <compName> is invalid - <reason>, imported from Uri: http://example.com/devfile.yaml, in parent overrides from main devfile"
func resolveErrorMessageWithImportArrtibutes(validationErr error, attributes attributesAPI.Attributes) error {
func resolveErrorMessageWithImportAttributes(validationErr error, attributes attributesAPI.Attributes) error {
var findKeyErr error
importReference := attributes.Get(ImportSourceAttribute, &findKeyErr)

Expand Down
9 changes: 5 additions & 4 deletions pkg/validation/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/api/v2/pkg/attributes"
"github.com/stretchr/testify/assert"
)

Expand All @@ -12,8 +13,8 @@ func TestValidateEvents(t *testing.T) {
containers := []string{"container1", "container2"}

commands := []v1alpha2.Command{
generateDummyApplyCommand("apply1", containers[0], nil),
generateDummyApplyCommand("apply2", containers[0], nil),
generateDummyApplyCommand("apply1", containers[0], nil, attributes.Attributes{}),
generateDummyApplyCommand("apply2", containers[0], nil, attributes.Attributes{}),
generateDummyExecCommand("exec1", containers[1], nil),
generateDummyExecCommand("exec2", containers[1], nil),
generateDummyCompositeCommand("compositeOnlyApply", []string{"apply1", "apply2"}, nil),
Expand Down Expand Up @@ -112,8 +113,8 @@ func TestIsEventValid(t *testing.T) {
containers := []string{"container1", "container2"}

commands := []v1alpha2.Command{
generateDummyApplyCommand("apply1", containers[0], nil),
generateDummyApplyCommand("apply2", containers[0], nil),
generateDummyApplyCommand("apply1", containers[0], nil, attributes.Attributes{}),
generateDummyApplyCommand("apply2", containers[0], nil, attributes.Attributes{}),
generateDummyExecCommand("exec1", containers[1], nil),
generateDummyExecCommand("exec2", containers[1], nil),
generateDummyCompositeCommand("compositeOnlyApply", []string{"apply1", "apply2"}, nil),
Expand Down
14 changes: 7 additions & 7 deletions pkg/validation/projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ func ValidateStarterProjects(starterProjects []v1alpha2.StarterProject) error {
switch len(gitSource.Remotes) {
case 0:
starterProjectErr := fmt.Errorf("\nstarterProject %s should have at least one remote", starterProject.Name)
newErr := resolveErrorMessageWithImportArrtibutes(starterProjectErr, starterProject.Attributes)
newErr := resolveErrorMessageWithImportAttributes(starterProjectErr, starterProject.Attributes)
errString += newErr.Error()
case 1:
if gitSource.CheckoutFrom != nil && gitSource.CheckoutFrom.Remote != "" {
err := validateRemoteMap(gitSource.Remotes, gitSource.CheckoutFrom.Remote, starterProject.Name)
if err != nil {
newErr := resolveErrorMessageWithImportArrtibutes(err, starterProject.Attributes)
newErr := resolveErrorMessageWithImportAttributes(err, starterProject.Attributes)
errString += fmt.Sprintf("\n%s", newErr.Error())
}
}
default: // len(gitSource.Remotes) >= 2
starterProjectErr := fmt.Errorf("\nstarterProject %s should have one remote only", starterProject.Name)
newErr := resolveErrorMessageWithImportArrtibutes(starterProjectErr, starterProject.Attributes)
newErr := resolveErrorMessageWithImportAttributes(starterProjectErr, starterProject.Attributes)
errString += newErr.Error()
}
}
Expand Down Expand Up @@ -67,24 +67,24 @@ func ValidateProjects(projects []v1alpha2.Project) error {
switch len(gitSource.Remotes) {
case 0:
projectErr := fmt.Errorf("\nprojects %s should have at least one remote", project.Name)
newErr := resolveErrorMessageWithImportArrtibutes(projectErr, project.Attributes)
newErr := resolveErrorMessageWithImportAttributes(projectErr, project.Attributes)
errString += newErr.Error()
case 1:
if gitSource.CheckoutFrom != nil && gitSource.CheckoutFrom.Remote != "" {
if err := validateRemoteMap(gitSource.Remotes, gitSource.CheckoutFrom.Remote, project.Name); err != nil {
newErr := resolveErrorMessageWithImportArrtibutes(err, project.Attributes)
newErr := resolveErrorMessageWithImportAttributes(err, project.Attributes)
errString += fmt.Sprintf("\n%s", newErr.Error())
}
}
default: // len(gitSource.Remotes) >= 2
if gitSource.CheckoutFrom == nil || gitSource.CheckoutFrom.Remote == "" {
projectErr := fmt.Errorf("\nproject %s has more than one remote defined, but has no checkoutfrom remote defined", project.Name)
newErr := resolveErrorMessageWithImportArrtibutes(projectErr, project.Attributes)
newErr := resolveErrorMessageWithImportAttributes(projectErr, project.Attributes)
errString += newErr.Error()
continue
}
if err := validateRemoteMap(gitSource.Remotes, gitSource.CheckoutFrom.Remote, project.Name); err != nil {
newErr := resolveErrorMessageWithImportArrtibutes(err, project.Attributes)
newErr := resolveErrorMessageWithImportAttributes(err, project.Attributes)
errString += fmt.Sprintf("\n%s", newErr.Error())
}
}
Expand Down
Loading

0 comments on commit a22cea8

Please sign in to comment.