Skip to content

Commit

Permalink
Test Validation
Browse files Browse the repository at this point in the history
  • Loading branch information
ralikio committed Feb 2, 2025
1 parent 07c477c commit dadfbf0
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 35 deletions.
20 changes: 15 additions & 5 deletions common/hyperscaler/rules/grammar/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,31 @@ type RuleListener struct {
}

func (r RuleListener) EnterEntry(c *parser.EntryContext) {
r.processed.Plan = c.PLAN().GetText()
if c.PLAN() != nil {
r.processed.Plan = c.PLAN().GetText()
}
}

func (r *RuleListener) EnterPrVal(c *parser.PrValContext) {
r.processed.PlatformRegion = c.Val().GetText()
if c.Val() != nil {
r.processed.PlatformRegion = c.Val().GetText()
}
}

func (r *RuleListener) EnterHrVal(c *parser.HrValContext) {
r.processed.HyperscalerRegion = c.Val().GetText()
if c.Val() != nil {
r.processed.HyperscalerRegion = c.Val().GetText()
}
}

func (s *RuleListener) EnterS(c *parser.SContext) {
s.processed.Shared = true
if c.S() != nil {
s.processed.Shared = true
}
}

func (s *RuleListener) EnterEu(c *parser.EuContext) {
s.processed.EuAccess = true
if c.EU() != nil {
s.processed.EuAccess = true
}
}
44 changes: 37 additions & 7 deletions common/hyperscaler/rules/grammar/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,54 @@ import (
)

type GrammarParser struct{

}

func (g* GrammarParser) Parse(ruleEntry string) *rules.Rule {
// Setup the input
func (g* GrammarParser) Parse(ruleEntry string) (*rules.Rule, error) {
is := antlr.NewInputStream(ruleEntry)

// Create the Lexer
erorrsListener := &ErrorListener{}

lexer := parser.NewRuleLexer(is)
lexer.RemoveErrorListeners()
lexer.AddErrorListener(erorrsListener)

stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)

// Create the Parser
p := parser.NewRuleParserParser(stream)

p.RemoveErrorListeners()
p.AddErrorListener(erorrsListener)

// Finally parse the expression
listener := &RuleListener{processed: &rules.Rule{}}
antlr.ParseTreeWalkerDefault.Walk(listener, p.RuleEntry())
return listener.processed

if len(erorrsListener.Errors) > 0 {
return nil, erorrsListener.Errors[0]
}

return listener.processed, nil
}

type SyntaxError struct {
line, column int
msg string
}

func (c *SyntaxError) Error() string {
return c.msg
}

type ErrorListener struct {
*antlr.DefaultErrorListener
Errors []error
}

func (c *ErrorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) {
c.Errors = append(c.Errors, &SyntaxError{
line: line,
column: column,
msg: msg,
})
}


Expand Down
5 changes: 2 additions & 3 deletions common/hyperscaler/rules/grammar/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import "testing"
import "github.com/kyma-project/kyma-environment-broker/common/hyperscaler/rules"

func TestParser(t *testing.T) {

rules.ParserTest(t, &GrammarParser{})

rules.ParserHappyPathTest(t, &GrammarParser{})
rules.ParserValidationTest(t, &GrammarParser{})
}
2 changes: 1 addition & 1 deletion common/hyperscaler/rules/parser.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package rules

type Parser interface {
Parse(ruleEntry string) *Rule
Parse(ruleEntry string) (*Rule, error)

Check failure on line 4 in common/hyperscaler/rules/parser.go

View workflow job for this annotation

GitHub Actions / run-go-linter

File is not `gofmt`-ed with `-s` (gofmt)

Check failure on line 4 in common/hyperscaler/rules/parser.go

View workflow job for this annotation

GitHub Actions / run-go-linter

File is not `goimports`-ed (goimports)
}
124 changes: 111 additions & 13 deletions common/hyperscaler/rules/parser_test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import (
"github.com/stretchr/testify/require"
)

func ParserTest(t *testing.T, parser Parser) {
func ParserHappyPathTest(t *testing.T, parser Parser) {

t.Run("with plan", func(t *testing.T) {

Check failure on line 11 in common/hyperscaler/rules/parser_test_utils.go

View workflow job for this annotation

GitHub Actions / run-go-linter

File is not `gofmt`-ed with `-s` (gofmt)

Check failure on line 11 in common/hyperscaler/rules/parser_test_utils.go

View workflow job for this annotation

GitHub Actions / run-go-linter

File is not `goimports`-ed (goimports)
rule := parser.Parse("azure")
rule, err := parser.Parse("azure")
require.NoError(t, err)

require.NotNil(t, rule)
require.Equal(t, "azure", rule.Plan)
Expand All @@ -20,8 +21,9 @@ func ParserTest(t *testing.T, parser Parser) {
require.Equal(t, false, rule.Shared)
})

t.Run("with plan and platform region", func(t *testing.T) {
rule := parser.Parse("azure(PR=westeurope)")
t.Run("with plan and single input attribute", func(t *testing.T) {
rule, err := parser.Parse("azure(PR=westeurope)")
require.NoError(t, err)

require.NotNil(t, rule)
require.Equal(t, "azure", rule.Plan)
Expand All @@ -30,10 +32,9 @@ func ParserTest(t *testing.T, parser Parser) {

require.Equal(t, false, rule.EuAccess)
require.Equal(t, false, rule.Shared)
})

t.Run("with plan and hyperscaler region", func(t *testing.T) {
rule := parser.Parse("azure(HR=westeurope)")
rule, err = parser.Parse("azure(HR=westeurope)")
require.NoError(t, err)

require.NotNil(t, rule)
require.Equal(t, "azure", rule.Plan)
Expand All @@ -44,8 +45,20 @@ func ParserTest(t *testing.T, parser Parser) {
require.Equal(t, false, rule.Shared)
})

t.Run("with plan, platform and hyperscaler region", func(t *testing.T) {
rule := parser.Parse("azure(PR=easteurope, HR=westeurope)")
t.Run("with plan all output attributes - different positions", func(t *testing.T) {
rule, err := parser.Parse("azure(PR=easteurope,HR=westeurope)")
require.NoError(t, err)

require.NotNil(t, rule)
require.Equal(t, "azure", rule.Plan)
require.Equal(t, "westeurope", rule.HyperscalerRegion)
require.Equal(t, "easteurope", rule.PlatformRegion)

require.False(t, rule.EuAccess)
require.False(t, rule.Shared)

rule, err = parser.Parse("azure(HR=westeurope,PR=easteurope)")
require.NoError(t, err)

require.NotNil(t, rule)
require.Equal(t, "azure", rule.Plan)
Expand All @@ -56,8 +69,9 @@ func ParserTest(t *testing.T, parser Parser) {
require.False(t, rule.Shared)
})

t.Run("with plan and shared", func(t *testing.T) {
rule := parser.Parse("azure->S")
t.Run("with plan and single output attribute", func(t *testing.T) {
rule, err := parser.Parse("azure->S")
require.NoError(t, err)

require.NotNil(t, rule)
require.Equal(t, "azure", rule.Plan)
Expand All @@ -66,11 +80,23 @@ func ParserTest(t *testing.T, parser Parser) {

require.False(t, rule.EuAccess)
require.True(t, rule.Shared)

rule, err = parser.Parse("azure->EU")
require.NoError(t, err)

require.NotNil(t, rule)
require.Equal(t, "azure", rule.Plan)
require.Empty(t, rule.HyperscalerRegion)
require.Empty(t, rule.PlatformRegion)

require.True(t, rule.EuAccess)
require.False(t, rule.Shared)
})


t.Run("with plan, shared and euAccess", func(t *testing.T) {
rule := parser.Parse("azure->S,EU")
t.Run("with plan and all output attributes - different positions", func(t *testing.T) {
rule, err := parser.Parse("azure->S,EU")
require.NoError(t, err)

require.NotNil(t, rule)
require.Equal(t, "azure", rule.Plan)
Expand All @@ -79,6 +105,78 @@ func ParserTest(t *testing.T, parser Parser) {

require.True(t, rule.EuAccess)
require.True(t, rule.Shared)

rule, err = parser.Parse("azure->EU,S")
require.NoError(t, err)

require.NotNil(t, rule)
require.Equal(t, "azure", rule.Plan)
require.Empty(t, rule.HyperscalerRegion)
require.Empty(t, rule.PlatformRegion)

require.True(t, rule.EuAccess)
require.True(t, rule.Shared)
})

t.Run("with plan and single output/input attributes", func(t *testing.T) {
rule, err := parser.Parse("azure(PR=westeurope)->EU")
require.NoError(t, err)

require.NotNil(t, rule)
require.Equal(t, "azure", rule.Plan)
require.Empty(t, rule.HyperscalerRegion)
require.Equal(t, "westeurope", rule.PlatformRegion)

require.True(t, rule.EuAccess)
require.False(t, rule.Shared)
})

t.Run("with plan and all input/output attributes", func(t *testing.T) {
rule, err := parser.Parse("azure(PR=westeurope, HR=easteurope)->EU,S")
require.NoError(t, err)

require.NotNil(t, rule)
require.Equal(t, "azure", rule.Plan)
require.Equal(t, "easteurope", rule.HyperscalerRegion)
require.Equal(t, "westeurope", rule.PlatformRegion)

require.True(t, rule.EuAccess)
require.True(t, rule.Shared)
})
}


func ParserValidationTest(t *testing.T, parser Parser) {

t.Run("with paranthesis only", func(t *testing.T) {
rule, err := parser.Parse("()")
require.Nil(t, rule)
require.Error(t, err)
})

t.Run("with arrow only", func(t *testing.T) {
rule, err := parser.Parse("->")
require.Nil(t, rule)
require.Error(t, err)
})

t.Run("with incorrect attributes list", func(t *testing.T) {
rule, err := parser.Parse("test(,)->,")
require.Nil(t, rule)
require.Error(t, err)

rule, err = parser.Parse("test(PR=west,HR=east)->,")
require.Nil(t, rule)
require.Error(t, err)
})

// t.Run("with duplicated input attribute", func(t *testing.T) {
// rule, err := parser.Parse("azure(PR=test,PR=test2)")
// require.Nil(t, rule)
// require.Error(t, err)

// rule, err = parser.Parse("test(PR=west,HR=east)->EU,EU")
// require.Nil(t, rule)
// require.Error(t, err)
// })
}
18 changes: 15 additions & 3 deletions common/hyperscaler/rules/simple_parser.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package rules

import (
"fmt"
"strings"
)

type SimpleParser struct{

}

func (g* SimpleParser) Parse(ruleEntry string) *Rule {
func (g* SimpleParser) Parse(ruleEntry string) (*Rule, error) {
outputRule := &Rule{}

outputInputPart := strings.Split(ruleEntry, "->")
Expand All @@ -18,13 +19,21 @@ func (g* SimpleParser) Parse(ruleEntry string) *Rule {
planAndInputAttr := strings.Split(inputPart, "(")

outputRule.Plan = planAndInputAttr[0]
if outputRule.Plan == "" {
return nil, fmt.Errorf("plan is empty")
}

if len(planAndInputAttr) > 1 {
inputPart := strings.TrimSuffix(planAndInputAttr[1], ")")

inputAttrs := strings.Split(inputPart, ",")

for _, inputAttr := range inputAttrs {

if inputAttr == "" {
return nil, fmt.Errorf("input attribute is empty")
}

if strings.Contains(inputAttr, "PR") {
outputRule.PlatformRegion = strings.Split(inputAttr, "=")[1]
}
Expand All @@ -33,13 +42,16 @@ func (g* SimpleParser) Parse(ruleEntry string) *Rule {
outputRule.HyperscalerRegion = strings.Split(inputAttr, "=")[1]
}
}

}

if len(outputInputPart) > 1 {
outputAttrs := strings.Split(outputInputPart[1], ",")

for _, outputAttr := range outputAttrs {
if outputAttr == "" {
return nil, fmt.Errorf("output attribute is empty")
}

if outputAttr == "S" {
outputRule.Shared = true
} else if outputAttr == "EU" {
Expand All @@ -48,5 +60,5 @@ func (g* SimpleParser) Parse(ruleEntry string) *Rule {
}
}

return outputRule
return outputRule, nil
}
5 changes: 2 additions & 3 deletions common/hyperscaler/rules/simple_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package rules
import "testing"

func TestParser(t *testing.T) {

ParserTest(t, &SimpleParser{})

ParserHappyPathTest(t, &SimpleParser{})
ParserValidationTest(t, &SimpleParser{})
}

0 comments on commit dadfbf0

Please sign in to comment.