From a002876fb1d344d56377cc37187e94701839e647 Mon Sep 17 00:00:00 2001 From: Nadia Mayor Date: Thu, 9 May 2024 17:18:40 -0300 Subject: [PATCH] Apply changes in new matchers to return a matcher with a nil semver --- engine/grammar/matchers/datatypes/semver.go | 20 +++-- .../matchers/datatypes/semvererrors.go | 11 --- engine/grammar/matchers/matchers.go | 40 +++------- engine/grammar/matchers/semver.go | 76 +++++++++++-------- engine/grammar/matchers/semver_test.go | 17 ----- 5 files changed, 67 insertions(+), 97 deletions(-) delete mode 100644 engine/grammar/matchers/datatypes/semvererrors.go diff --git a/engine/grammar/matchers/datatypes/semver.go b/engine/grammar/matchers/datatypes/semver.go index 238294a..68710c0 100644 --- a/engine/grammar/matchers/datatypes/semver.go +++ b/engine/grammar/matchers/datatypes/semver.go @@ -2,6 +2,7 @@ package datatypes import ( "errors" + "fmt" "strconv" "strings" @@ -46,10 +47,10 @@ func BuildSemver(version string) (*Semver, error) { return nil, err } - version, preReleaseClean := processVersion(major, minor, patch, preRelease, metadata) + version, preRelease = processVersion(major, minor, patch, preRelease, metadata) return &Semver{ metadata: metadata, - preRelease: preReleaseClean, + preRelease: preRelease, major: major, minor: minor, patch: patch, @@ -125,13 +126,10 @@ func processComponents(version string) (int64, int64, int64, error) { } func processVersion(major int64, minor int64, patch int64, preRelease []string, metadata string) (string, []string) { - toReturnVersion := strconv.FormatInt(major, 10) + valueDelimiter + strconv.FormatInt(minor, 10) + valueDelimiter + strconv.FormatInt(patch, 10) + toReturnVersion := fmt.Sprintf("%d.%d.%d", major, minor, patch) if len(preRelease) != 0 { for i, _ := range preRelease { - preReleaseNumeric, err := strconv.ParseInt(preRelease[i], 10, 64) - if err == nil { - preRelease[i] = strconv.FormatInt(preReleaseNumeric, 10) - } + preRelease = sanitizeIntStr(preRelease, i) } toReturnVersion = toReturnVersion + preReleaseDelimiter + strings.Join(preRelease, valueDelimiter) } @@ -141,6 +139,14 @@ func processVersion(major int64, minor int64, patch int64, preRelease []string, return toReturnVersion, preRelease } +func sanitizeIntStr(preRelease []string, i int) []string { + preReleaseNumeric, err := strconv.ParseInt(preRelease[i], 10, 64) + if err == nil { + preRelease[i] = strconv.FormatInt(preReleaseNumeric, 10) + } + return preRelease +} + // Compare compares two semver versions func (s *Semver) Compare(toCompare Semver) int { if s.version == toCompare.version { diff --git a/engine/grammar/matchers/datatypes/semvererrors.go b/engine/grammar/matchers/datatypes/semvererrors.go deleted file mode 100644 index 56553f0..0000000 --- a/engine/grammar/matchers/datatypes/semvererrors.go +++ /dev/null @@ -1,11 +0,0 @@ -package datatypes - -// SemverValidatonError represents a semver validaton error -type SemverValidatonError struct { - Message string -} - -// Error implements golang error interface -func (f SemverValidatonError) Error() string { - return f.Message -} diff --git a/engine/grammar/matchers/matchers.go b/engine/grammar/matchers/matchers.go index 6379345..46ae669 100644 --- a/engine/grammar/matchers/matchers.go +++ b/engine/grammar/matchers/matchers.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/splitio/go-split-commons/v5/dtos" - "github.com/splitio/go-split-commons/v5/engine/grammar/matchers/datatypes" "github.com/splitio/go-toolkit/v5/injection" "github.com/splitio/go-toolkit/v5/logging" @@ -361,15 +360,12 @@ func BuildMatcher(dto *dtos.MatcherDTO, ctx *injection.Context, logger logging.L "Building EqualToSemverMatcher with negate=%t, regex=%s, attributeName=%v", dto.Negate, *dto.String, attributeName, )) - matcherSemver, err := NewEqualToSemverMatcher( + matcher = NewEqualToSemverMatcher( *dto.String, dto.Negate, attributeName, + logger, ) - if err != nil { - return nil, err - } - matcher = matcherSemver case MatcherTypeGreaterThanOrEqualToSemver: if dto.String == nil { return nil, ErrInvalidGTOESemver @@ -378,15 +374,12 @@ func BuildMatcher(dto *dtos.MatcherDTO, ctx *injection.Context, logger logging.L "Building GreaterThanOrEqualToSemverMatcher with negate=%t, semver=%s, attributeName=%v", dto.Negate, *dto.String, attributeName, )) - matcherSemver, err := NewGreaterThanOrEqualToSemverMatcher( + matcher = NewGreaterThanOrEqualToSemverMatcher( dto.Negate, *dto.String, attributeName, + logger, ) - if err != nil { - return nil, err - } - matcher = matcherSemver case MatcherTypeLessThanOrEqualToSemver: if dto.String == nil { return nil, ErrInvalidLTOESemver @@ -395,15 +388,12 @@ func BuildMatcher(dto *dtos.MatcherDTO, ctx *injection.Context, logger logging.L "Building LessThanOrEqualToSemverMatcher with negate=%t, regex=%s, attributeName=%v", dto.Negate, *dto.String, attributeName, )) - matcherSemver, err := NewLessThanOrEqualToSemverMatcher( + matcher = NewLessThanOrEqualToSemverMatcher( *dto.String, dto.Negate, attributeName, + logger, ) - if err != nil { - return nil, err - } - matcher = matcherSemver case MatcherTypeBetweenSemver: if dto.BetweenString.Start == nil || dto.BetweenString.End == nil { return nil, ErrInvalidLBetweenSemver @@ -412,16 +402,13 @@ func BuildMatcher(dto *dtos.MatcherDTO, ctx *injection.Context, logger logging.L "Building BetweenSemverMatcher with negate=%t, regexStart=%s, regexEnd=%s, attributeName=%v", dto.Negate, *dto.BetweenString.Start, *dto.BetweenString.End, attributeName, )) - matcherSemver, err := NewBetweenSemverMatcher( + matcher = NewBetweenSemverMatcher( *dto.BetweenString.Start, *dto.BetweenString.End, dto.Negate, attributeName, + logger, ) - if err != nil { - return nil, err - } - matcher = matcherSemver case MatcherTypeInListSemver: if dto.Whitelist == nil { return nil, ErrInvalidLInListSemver @@ -430,19 +417,12 @@ func BuildMatcher(dto *dtos.MatcherDTO, ctx *injection.Context, logger logging.L "Building ErrInvalidLInListSemver with negate=%t, regex=%v, attributeName=%v", dto.Negate, dto.Whitelist.Whitelist, attributeName, )) - matcherSemver, warnings := NewInListSemverMatcher( + matcher = NewInListSemverMatcher( dto.Whitelist.Whitelist, dto.Negate, attributeName, + logger, ) - if len(warnings) != 0 { - for _, err := range warnings { - if errType, ok := err.(datatypes.SemverValidatonError); ok { - logger.Warning(errType.Message) - } - } - } - matcher = matcherSemver default: return nil, errors.New("Matcher not found") } diff --git a/engine/grammar/matchers/semver.go b/engine/grammar/matchers/semver.go index bb5680f..6b80b8c 100644 --- a/engine/grammar/matchers/semver.go +++ b/engine/grammar/matchers/semver.go @@ -5,16 +5,20 @@ import ( "github.com/splitio/go-split-commons/v5/engine/grammar/matchers/datatypes" "github.com/splitio/go-toolkit/v5/datastructures/set" + "github.com/splitio/go-toolkit/v5/logging" ) // EqualToSemverMatcher struct to hold the semver to compare type EqualToSemverMatcher struct { Matcher - semver datatypes.Semver + semver *datatypes.Semver } // Match will match if the comparisonValue is equal to the matchingValue func (e *EqualToSemverMatcher) Match(key string, attributes map[string]interface{}, bucketingKey *string) bool { + if e.semver == nil { + return false + } matchingKey, err := e.matchingKey(key, attributes) if err != nil { e.logger.Warning(fmt.Sprintf("EqualToSemverMatcher: %s", err.Error())) @@ -39,24 +43,24 @@ func (e *EqualToSemverMatcher) Match(key string, attributes map[string]interface } // NewEqualToSemverMatcher returns a pointer to a new instance of EqualToSemverMatcher -func NewEqualToSemverMatcher(cmpVal string, negate bool, attributeName *string) (*EqualToSemverMatcher, error) { +func NewEqualToSemverMatcher(cmpVal string, negate bool, attributeName *string, logger logging.LoggerInterface) *EqualToSemverMatcher { semver, err := datatypes.BuildSemver(cmpVal) if err != nil { - return nil, err + logger.Error(fmt.Sprintf("couldnt't build semver %s for EQUAL_TO_SEMVER matcher: %s", cmpVal, err.Error())) } return &EqualToSemverMatcher{ Matcher: Matcher{ negate: negate, attributeName: attributeName, }, - semver: *semver, - }, nil + semver: semver, + } } // GreaterThanOrEqualToSemverMatcher struct to hold the semver to compare type GreaterThanOrEqualToSemverMatcher struct { Matcher - semver datatypes.Semver + semver *datatypes.Semver } // Match compares the semver of the key with the semver in the feature flag @@ -79,34 +83,37 @@ func (g *GreaterThanOrEqualToSemverMatcher) Match(key string, attributes map[str return false } - result := semver.Compare(g.semver) >= 0 + result := semver.Compare(*g.semver) >= 0 g.logger.Debug(fmt.Sprintf("%s >= %s | Result: %t", semver.Version(), g.semver.Version(), result)) return result } // NewGreaterThanOrEqualToSemverMatcher returns an instance of GreaterThanOrEqualToSemverMatcher -func NewGreaterThanOrEqualToSemverMatcher(negate bool, compareTo string, attributeName *string) (*GreaterThanOrEqualToSemverMatcher, error) { +func NewGreaterThanOrEqualToSemverMatcher(negate bool, compareTo string, attributeName *string, logger logging.LoggerInterface) *GreaterThanOrEqualToSemverMatcher { semver, err := datatypes.BuildSemver(compareTo) if err != nil { - return nil, err + logger.Error(fmt.Sprintf("couldnt't build semver %s for GREATER_THAN_OR_EQUAL_TO_SEMVER matcher: %s", compareTo, err.Error())) } return &GreaterThanOrEqualToSemverMatcher{ Matcher: Matcher{ negate: negate, attributeName: attributeName, }, - semver: *semver, - }, nil + semver: semver, + } } // LessThanOrEqualToSemverMatcher struct to hold the semver to compare type LessThanOrEqualToSemverMatcher struct { Matcher - semver datatypes.Semver + semver *datatypes.Semver } // Match will match if the comparisonValue is less or equal to the matchingValue func (l *LessThanOrEqualToSemverMatcher) Match(key string, attributes map[string]interface{}, bucketingKey *string) bool { + if l.semver == nil { + return false + } matchingKey, err := l.matchingKey(key, attributes) if err != nil { l.logger.Warning(fmt.Sprintf("LessThanOrEqualToSemverMatcher: %s", err.Error())) @@ -125,35 +132,38 @@ func (l *LessThanOrEqualToSemverMatcher) Match(key string, attributes map[string return false } - result := semver.Compare(l.semver) <= 0 + result := semver.Compare(*l.semver) <= 0 l.logger.Debug(fmt.Sprintf("%s >= %s | Result: %t", semver.Version(), l.semver.Version(), result)) return result } // NewLessThanOrEqualToSemverMatcher returns a pointer to a new instance of LessThanOrEqualToSemverMatcher -func NewLessThanOrEqualToSemverMatcher(compareTo string, negate bool, attributeName *string) (*LessThanOrEqualToSemverMatcher, error) { +func NewLessThanOrEqualToSemverMatcher(compareTo string, negate bool, attributeName *string, logger logging.LoggerInterface) *LessThanOrEqualToSemverMatcher { semver, err := datatypes.BuildSemver(compareTo) if err != nil { - return nil, err + logger.Error(fmt.Sprintf("couldnt't build semver %s for LESS_THAN_OR_EQUAL_TO_SEMVER matcher: %s", compareTo, err.Error())) } return &LessThanOrEqualToSemverMatcher{ Matcher: Matcher{ negate: negate, attributeName: attributeName, }, - semver: *semver, - }, nil + semver: semver, + } } // BetweenSemverMatcher struct to hold the semver to compare type BetweenSemverMatcher struct { Matcher - startSemver datatypes.Semver - endSemver datatypes.Semver + startSemver *datatypes.Semver + endSemver *datatypes.Semver } // Match will match if the comparisonValue is between to the matchingValue func (b *BetweenSemverMatcher) Match(key string, attributes map[string]interface{}, bucketingKey *string) bool { + if b.startSemver == nil || b.endSemver == nil { + return false + } matchingKey, err := b.matchingKey(key, attributes) if err != nil { b.logger.Warning(fmt.Sprintf("BetweenSemverMatcher: %s", err.Error())) @@ -172,29 +182,29 @@ func (b *BetweenSemverMatcher) Match(key string, attributes map[string]interface return false } - result := semver.Compare(b.startSemver) >= 0 && semver.Compare(b.endSemver) <= 0 + result := semver.Compare(*b.startSemver) >= 0 && semver.Compare(*b.endSemver) <= 0 b.logger.Debug(fmt.Sprintf("%s between %s and %s | Result: %t", semver.Version(), b.startSemver.Version(), b.endSemver.Version(), result)) return result } // NewBetweenSemverMatcher returns a pointer to a new instance of BetweenSemverMatcher -func NewBetweenSemverMatcher(startVal string, endVal string, negate bool, attributeName *string) (*BetweenSemverMatcher, error) { +func NewBetweenSemverMatcher(startVal string, endVal string, negate bool, attributeName *string, logger logging.LoggerInterface) *BetweenSemverMatcher { startSemver, err := datatypes.BuildSemver(startVal) if err != nil { - return nil, err + logger.Error(fmt.Sprintf("couldnt't build semver %s for BETWEEN_SEMVER matcher, ignoring: %s", startVal, err.Error())) } endSemver, err := datatypes.BuildSemver(endVal) if err != nil { - return nil, err + logger.Error(fmt.Sprintf("couldnt't build semver %s for BETWEEN_SEMVER matcher, ignoring: %s", endVal, err.Error())) } return &BetweenSemverMatcher{ Matcher: Matcher{ negate: negate, attributeName: attributeName, }, - startSemver: *startSemver, - endSemver: *endSemver, - }, nil + startSemver: startSemver, + endSemver: endSemver, + } } // InListSemverMatcher struct to hold the semver to compare @@ -205,6 +215,9 @@ type InListSemverMatcher struct { // Match will match if the comparisonValue is in list to the matchingValue func (i *InListSemverMatcher) Match(key string, attributes map[string]interface{}, bucketingKey *string) bool { + if i.semvers.IsEmpty() { + return false + } matchingKey, err := i.matchingKey(key, attributes) if err != nil { i.logger.Warning(fmt.Sprintf("InListSemverMatcher: %s", err.Error())) @@ -226,15 +239,14 @@ func (i *InListSemverMatcher) Match(key string, attributes map[string]interface{ } // NewInListSemverMatcher returns a pointer to a new instance of InListSemverMatcher -func NewInListSemverMatcher(cmpList []string, negate bool, attributeName *string) (*InListSemverMatcher, []error) { +func NewInListSemverMatcher(setVersions []string, negate bool, attributeName *string, logger logging.LoggerInterface) *InListSemverMatcher { semvers := set.NewSet() - var errs []error - for _, str := range cmpList { - semver, err := datatypes.BuildSemver(str) + for _, version := range setVersions { + semver, err := datatypes.BuildSemver(version) if err == nil { semvers.Add(semver.Version()) } else { - errs = append(errs, err) + logger.Error(fmt.Sprintf("couldnt't build semver %s for IN_LIST_SEMVER matcher, ignoring: %s", version, err.Error())) } } return &InListSemverMatcher{ @@ -243,5 +255,5 @@ func NewInListSemverMatcher(cmpList []string, negate bool, attributeName *string attributeName: attributeName, }, semvers: semvers, - }, errs + } } diff --git a/engine/grammar/matchers/semver_test.go b/engine/grammar/matchers/semver_test.go index e556ff6..e97c016 100644 --- a/engine/grammar/matchers/semver_test.go +++ b/engine/grammar/matchers/semver_test.go @@ -442,20 +442,3 @@ func TestInListInvalidSemvers(t *testing.T) { t.Error("There should be errors when building the matcher") } } - -func TestNewInListMatcherInvalidSemvers(t *testing.T) { - semvers := make([]string, 0, 3) - semvers = append(semvers, "1.alpha.2") - semvers = append(semvers, "alpha.beta.1") - semvers = append(semvers, "1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788") - attrName := "version" - _, warnings := NewInListSemverMatcher( - semvers, - false, - &attrName, - ) - - if len(warnings) != 3 { - t.Error("There should be warnings when building the matcher") - } -}