Skip to content

Commit

Permalink
feat(core): fix lint (scaleway#3730)
Browse files Browse the repository at this point in the history
feat(llm_inference): activate cli (scaleway#3729)

docs: update developers website url (scaleway#3733)

feat(llm-inference): add support llm-inference cli (scaleway#3731)

chore: enable update for github actions in dependabot (scaleway#3734)

Co-authored-by: Mia-Cross <lmarabese@scaleway.com>

feat(llm_inference): change more cli fields to positional (scaleway#3732)

Co-authored-by: Jules Casteran <jcasteran@scaleway.com>

chore(deps): bump goreleaser/goreleaser-action from 4 to 5 (scaleway#3735)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mia-Cross <lmarabese@scaleway.com>

chore(deps): bump gaurav-nelson/github-action-markdown-link-check from 1.0.13 to 1.0.15 (scaleway#3736)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

chore(deps): bump github/codeql-action from 2 to 3 (scaleway#3737)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mia-Cross <lmarabese@scaleway.com>

chore(deps): bump actions/setup-go from 3 to 5 (scaleway#3738)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mia-Cross <lmarabese@scaleway.com>

chore(deps): bump golangci/golangci-lint-action from 3 to 4 (scaleway#3739)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mia-Cross <lmarabese@scaleway.com>

chore: add support for docker in dependabot (scaleway#3741)

chore(deps): bump alpine from 3.16 to 3.19 (scaleway#3742)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

chore(deps): bump pnpm/action-setup from 2 to 3 (scaleway#3743)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mia-Cross <lmarabese@scaleway.com>

chore(deps): bump actions/checkout from 3 to 4 (scaleway#3744)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mia-Cross <lmarabese@scaleway.com>

chore(deps): bump codecov/codecov-action from 2 to 4 (scaleway#3745)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mia-Cross <lmarabese@scaleway.com>

feat(core):add test end to end

feat(core):fix lint
  • Loading branch information
scaleway-bot authored and jremy42 committed Apr 12, 2024
1 parent aaa595c commit b6575b0
Show file tree
Hide file tree
Showing 2 changed files with 283 additions and 10 deletions.
38 changes: 30 additions & 8 deletions internal/core/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ type CommandValidateFunc func(ctx context.Context, cmd *Command, cmdArgs interfa
type ArgSpecValidateFunc func(argSpec *ArgSpec, value interface{}) error

type OneOfGroupManager struct {
Groups map[string][]string // Contient les noms des arguments pour chaque groupe
RequiredGroups map[string]bool // Indique si un groupe est requis
Groups map[string][]string
RequiredGroups map[string]bool
}

// DefaultCommandValidateFunc is the default validation function for commands.
Expand Down Expand Up @@ -74,9 +74,6 @@ func validateArgValues(cmd *Command, cmdArgs interface{}) error {
// Returns nil otherwise.
// TODO refactor this method which uses a mix of reflect and string arrays
func validateRequiredArgs(cmd *Command, cmdArgs interface{}, rawArgs args.RawArgs) error {

oneOfManager := NewOneOfGroupManager(cmd)

for _, arg := range cmd.ArgSpecs {
if !arg.Required || arg.OneOfGroup != "" {
continue
Expand All @@ -103,14 +100,24 @@ func validateRequiredArgs(cmd *Command, cmdArgs interface{}, rawArgs args.RawArg
}
}
}

if err := oneOfManager.ValidateOneOfGroups(rawArgs); err != nil {
if err := validateOneOfRequiredArgs(cmd, rawArgs); err != nil {
return err
}

return nil
}

func validateOneOfRequiredArgs(cmd *Command, rawArgs args.RawArgs) error {
oneOfManager := NewOneOfGroupManager(cmd)
if err := oneOfManager.ValidateUniqueOneOfGroups(rawArgs); err != nil {
return err
}
if err := oneOfManager.ValidateRequiredOneOfGroups(rawArgs); err != nil {
return err
}
return nil
}

func ValidateNoConflict(cmd *Command, rawArgs args.RawArgs) error {
for _, arg1 := range cmd.ArgSpecs {
for _, arg2 := range cmd.ArgSpecs {
Expand Down Expand Up @@ -281,7 +288,22 @@ func NewOneOfGroupManager(cmd *Command) *OneOfGroupManager {
return manager
}

func (m *OneOfGroupManager) ValidateOneOfGroups(rawArgs args.RawArgs) error {
func (m *OneOfGroupManager) ValidateUniqueOneOfGroups(rawArgs args.RawArgs) error {
for _, groupArgs := range m.Groups {
existingArg := ""
for _, argName := range groupArgs {
if rawArgs.ExistsArgByName(argName) {
if existingArg != "" {
return fmt.Errorf("arguments '%s' and '%s' are mutually exclusive", existingArg, argName)
}
existingArg = argName
}
}
}
return nil
}

func (m *OneOfGroupManager) ValidateRequiredOneOfGroups(rawArgs args.RawArgs) error {
for group, required := range m.RequiredGroups {
if required {
found := false
Expand Down
255 changes: 253 additions & 2 deletions internal/core/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ func TestNewOneOfGroupManager(t *testing.T) {
}
}

func TestValidateOneOfGroups(t *testing.T) {
func TestValidateRequiredOneOfGroups(t *testing.T) {
tests := []struct {
name string
setupManager func() *core.OneOfGroupManager
Expand Down Expand Up @@ -522,7 +522,7 @@ func TestValidateOneOfGroups(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
manager := tt.setupManager()
err := manager.ValidateOneOfGroups(tt.rawArgs)
err := manager.ValidateRequiredOneOfGroups(tt.rawArgs)

if tt.expectedError == "" {
assert.NoError(t, err, "Expected no error, got %v", err)
Expand All @@ -532,3 +532,254 @@ func TestValidateOneOfGroups(t *testing.T) {
})
}
}

func TestValidateUniqueOneOfGroups(t *testing.T) {
tests := []struct {
name string
setupManager func() *core.OneOfGroupManager
rawArgs args.RawArgs
expectedError string
}{
{
name: "Required group satisfied with first argument",
setupManager: func() *core.OneOfGroupManager {
return &core.OneOfGroupManager{
Groups: map[string][]string{"group1": {"a", "b"}},
}
},
rawArgs: []string{"a=true"},
expectedError: "",
},
{
name: "No arguments passed",
setupManager: func() *core.OneOfGroupManager {
return &core.OneOfGroupManager{
Groups: map[string][]string{"group1": {"a", "b"}},
}
},
rawArgs: []string{},
expectedError: "",
},
{
name: "Multiple groups, all satisfied",
setupManager: func() *core.OneOfGroupManager {
return &core.OneOfGroupManager{
Groups: map[string][]string{
"group1": {"a", "b"},
"group2": {"c", "d"},
},
}
},
rawArgs: []string{"a=true", "c=true"},
expectedError: "",
},
{
name: "Multiple groups, one satisfied",
setupManager: func() *core.OneOfGroupManager {
return &core.OneOfGroupManager{
Groups: map[string][]string{
"group1": {"a", "b"},
"group2": {"c", "d"},
},
}
},
rawArgs: []string{"a=true"},
expectedError: "",
},
{
name: "Multiple groups, not exclusive argument for groups 2",
setupManager: func() *core.OneOfGroupManager {
return &core.OneOfGroupManager{
Groups: map[string][]string{
"group1": {"a", "b"},
"group2": {"c", "d"},
},
}
},
rawArgs: []string{"a=true", "c=true", "d=true"},
expectedError: "arguments 'c' and 'd' are mutually exclusive",
},
{
name: "Multiple groups, not exclusive argument for groups 1",
setupManager: func() *core.OneOfGroupManager {
return &core.OneOfGroupManager{
Groups: map[string][]string{
"group1": {"a", "b"},
"group2": {"c", "d"},
},
}
},
rawArgs: []string{"a=true", "b=true", "c=true"},
expectedError: "arguments 'a' and 'b' are mutually exclusive",
},
{
name: "One group, not exclusive argument for groups 1",
setupManager: func() *core.OneOfGroupManager {
return &core.OneOfGroupManager{
Groups: map[string][]string{
"group1": {"a", "b", "c", "d"},
},
}
},
rawArgs: []string{"a=true", "d=true"},
expectedError: "arguments 'a' and 'd' are mutually exclusive",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
manager := tt.setupManager()
err := manager.ValidateUniqueOneOfGroups(tt.rawArgs)
if tt.expectedError == "" {
assert.NoError(t, err, "Expected no error, got %v", err)
} else {
assert.EqualError(t, err, tt.expectedError, fmt.Sprintf("Expected error message '%s', got '%v'", tt.expectedError, err))
}
})
}
}

func Test_ValidateOneOf(t *testing.T) {
t.Run("Validate OneOf", core.Test(&core.TestConfig{
Commands: core.NewCommands(&core.Command{
Namespace: "oneof",
ArgsType: reflect.TypeOf(args.RawArgs{}),
AllowAnonymousClient: true,
Run: func(_ context.Context, _ interface{}) (i interface{}, e error) {
return &core.SuccessResult{}, nil
},
ArgSpecs: core.ArgSpecs{
{
Name: "a",
OneOfGroup: "groups1",
},
{
Name: "b",
OneOfGroup: "groups1",
},
},
}),
Cmd: "scw oneof a=yo",
Check: core.TestCheckCombine(
core.TestCheckExitCode(0),
),
}))
t.Run("Required group satisfied", func(t *testing.T) {
core.Test(&core.TestConfig{
Commands: core.NewCommands(&core.Command{
Namespace: "oneof",
ArgsType: reflect.TypeOf(args.RawArgs{}),
AllowAnonymousClient: true,
Run: func(_ context.Context, _ interface{}) (i interface{}, e error) {
return &core.SuccessResult{}, nil
},
ArgSpecs: core.ArgSpecs{
{
Name: "a",
OneOfGroup: "group1",
Required: true,
},
{
Name: "b",
OneOfGroup: "group1",
Required: true,
},
},
}),
Cmd: "scw oneof b=yo",
Check: core.TestCheckCombine(
core.TestCheckExitCode(0),
),
})(t)
})

t.Run("Required group not satisfied", func(t *testing.T) {
core.Test(&core.TestConfig{
Commands: core.NewCommands(&core.Command{
Namespace: "oneof",
ArgsType: reflect.TypeOf(args.RawArgs{}),
AllowAnonymousClient: true,
Run: func(_ context.Context, _ interface{}) (i interface{}, e error) {
return &core.SuccessResult{}, nil
},
ArgSpecs: core.ArgSpecs{
{
Name: "a",
OneOfGroup: "group1",
Required: true,
},
{
Name: "b",
OneOfGroup: "group1",
Required: true,
},
},
}),
Cmd: "scw oneof c=yo",
Check: core.TestCheckCombine(
core.TestCheckExitCode(1),
core.TestCheckError(fmt.Errorf("at least one argument from the 'group1' group is required")),
),
})(t)
})

t.Run("Arguments are mutually exclusive", func(t *testing.T) {
core.Test(&core.TestConfig{
Commands: core.NewCommands(&core.Command{
Namespace: "oneof",
ArgsType: reflect.TypeOf(args.RawArgs{}),
AllowAnonymousClient: true,
Run: func(_ context.Context, _ interface{}) (i interface{}, e error) {
return &core.SuccessResult{}, nil
},
ArgSpecs: core.ArgSpecs{
{
Name: "a",
OneOfGroup: "group1",
},
{
Name: "b",
OneOfGroup: "group1",
},
},
}),
Cmd: "scw oneof a=yo b=no",
Check: core.TestCheckCombine(
core.TestCheckExitCode(1),
core.TestCheckError(fmt.Errorf("arguments 'a' and 'b' are mutually exclusive")),
),
})(t)
})

t.Run("Arguments are mutually exclusive with 3 arguments", func(t *testing.T) {
core.Test(&core.TestConfig{
Commands: core.NewCommands(&core.Command{
Namespace: "oneof",
ArgsType: reflect.TypeOf(args.RawArgs{}),
AllowAnonymousClient: true,
Run: func(_ context.Context, _ interface{}) (i interface{}, e error) {
return &core.SuccessResult{}, nil
},
ArgSpecs: core.ArgSpecs{
{
Name: "a",
OneOfGroup: "group1",
},
{
Name: "b",
OneOfGroup: "group1",
},
{
Name: "c",
OneOfGroup: "group1",
},
},
}),
Cmd: "scw oneof a=yo c=no",
Check: core.TestCheckCombine(
core.TestCheckExitCode(1),
core.TestCheckError(fmt.Errorf("arguments 'a' and 'c' are mutually exclusive")),
),
})(t)
})
}

0 comments on commit b6575b0

Please sign in to comment.