Skip to content

Commit

Permalink
Merge pull request #11 from slankdev/xpath-util
Browse files Browse the repository at this point in the history
Improve and Refactor XPath Utilities
  • Loading branch information
slankdev committed May 1, 2024
2 parents af1e09b + d075bdb commit f0a6139
Show file tree
Hide file tree
Showing 13 changed files with 455 additions and 184 deletions.
18 changes: 12 additions & 6 deletions pkg/vtyang/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ func TestAgentXPathCli(t *testing.T) {
func TestAgentXPathCliFRR(t *testing.T) {
executeTestCase(t, &TestCase{
RuntimePath: "/tmp/run/vtyang",
LogFile: "/tmp/run/vtyang/vtyang.log",
YangPath: "./testdata/yang/frr_isisd_minimal",
OutputFile: "./testdata/frr_isisd_test1_output.json",
Inputs: []string{
Expand Down Expand Up @@ -99,21 +98,32 @@ func TestLoadDatabaseFromFile(t *testing.T) {
})
}

func TestAccountingConfigXpath01(t *testing.T) {
executeTestCase(t, &TestCase{
RuntimePath: "/tmp/run/vtyang",
YangPath: "./testdata/yang/accounting",
OutputFile: "./testdata/TestAccountingConfigXpath01.txt",
Inputs: []string{
"eval-xpath /account:users/account:user[name='eva']",
},
})
}

func TestXpathParse1(t *testing.T) {
executeTestCase(t, &TestCase{
RuntimePath: "/tmp/run/vtyang",
YangPath: "./testdata/yang/frr_mgmtd_minimal",
OutputFile: "./testdata/xpath_parse1_output.txt",
Inputs: []string{
"show-xpath lib interface dum0 description dum0-comment",
"eval-xpath /frr-interface:lib/interface[name='dum10']/description",
},
})
}

func TestXpathParse2(t *testing.T) {
executeTestCase(t, &TestCase{
RuntimePath: "/tmp/run/vtyang",
LogFile: "/tmp/run/vtyang/vtyang.log",
YangPath: "./testdata/yang/basic",
OutputFile: "./testdata/xpath_parse2_output.txt",
Inputs: []string{
Expand Down Expand Up @@ -214,7 +224,6 @@ func TestXpathParse2(t *testing.T) {
func TestXpathParse3(t *testing.T) {
executeTestCase(t, &TestCase{
RuntimePath: "/tmp/run/vtyang",
LogFile: "/tmp/run/vtyang/vtyang.log",
YangPath: "./testdata/yang/frr_mgmtd_minimal",
OutputFile: "./testdata/xpath_parse3_output.txt",
Inputs: []string{
Expand All @@ -233,7 +242,6 @@ func TestXpathParse3(t *testing.T) {
func TestXpathParse4(t *testing.T) {
executeTestCase(t, &TestCase{
RuntimePath: "/tmp/run/vtyang",
LogFile: "/tmp/run/vtyang/vtyang.log",
YangPath: "./testdata/yang/basic",
OutputFile: "./testdata/xpath_parse4_output.txt",
Inputs: []string{
Expand All @@ -253,7 +261,6 @@ func TestXpathParse4(t *testing.T) {
func TestChoiceCase1(t *testing.T) {
executeTestCase(t, &TestCase{
RuntimePath: "/tmp/run/vtyang",
LogFile: "/tmp/run/vtyang/vtyang.log",
YangPath: "./testdata/yang/choice_case",
OutputFile: "./testdata/choice_case_output1.json",
Inputs: []string{
Expand All @@ -265,7 +272,6 @@ func TestChoiceCase1(t *testing.T) {
func TestChoiceCase2(t *testing.T) {
executeTestCase(t, &TestCase{
RuntimePath: "/tmp/run/vtyang",
LogFile: "/tmp/run/vtyang/vtyang.log",
YangPath: "./testdata/yang/choice_case",
OutputFile: "./testdata/choice_case_output2.txt",
Inputs: []string{
Expand Down
20 changes: 20 additions & 0 deletions pkg/vtyang/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"time"

"github.com/openconfig/goyang/pkg/yang"
"github.com/pkg/errors"
)

type CliMode int
Expand Down Expand Up @@ -116,6 +117,25 @@ func installCommandsDefault(mode CliMode) {
}
fmt.Fprintf(stdout, "%s\n", string(out))
})

installCommandNoCompletion(mode, "eval-xpath", func(args []string) {
if len(args) != 2 {
err := errors.Errorf("Usage: %s <xpath>", args[0])
fmt.Fprintf(stdout, "Error: %s\n", err)
return
}
xp, err := ParseXPathString(dbm, args[1])
if err != nil {
fmt.Fprintf(stdout, "Error: %s\n", err)
return
}
out, err := json.MarshalIndent(xp, "", " ")
if err != nil {
fmt.Fprintf(stdout, "Error: %s\n", err.Error())
return
}
fmt.Fprintf(stdout, "%s\n", string(out))
})
}

func installCommandNoCompletion(mode CliMode, match string,
Expand Down
46 changes: 0 additions & 46 deletions pkg/vtyang/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,49 +70,3 @@ func TestInstallCompletionTree(t *testing.T) {
t.Errorf("missmatch")
}
}

func TestInterraction(t *testing.T) {
// CMD := func(l string) { GetCommandNodeCurrent().ExecuteCommand(l) }
// CMD("configure")
// CMD("delete users user hiroki age")
// CMD("commit")
// CMD("set users user hiroki age 20")
// CMD("commit")
// CMD("set users user hiroki age 30")
// CMD("commit")
// CMD("do show configuration commit list")
// ExecuteCommand("show running-config")
// pp.Println(dbm.SetNode(mod, x(mod, "/users/user['name'='hiroki']/age"), "10"))
// pp.Println(dbm.SetNode(mod, x(mod, "/users/user['name'='hiroki']/age"), "10"))
// ExecuteCommand("set account users user taro age 10")
// ExecuteCommand("show operational-data account users user taro")
// err := dbm.DeleteNode(mod, x(mod, "/users/user['name'='taro']/age"))
// ErrorOnDie(err)
// ExecuteCommand("show operational-data account users user taro")

// pp.Println(dbm.SetNode(mod, x(mod, "/users/user['name'='hoge']/age"), "10"))
// pp.Println(dbm.SetNode(mod, x(mod, "/users/user['name'='hiroki']/age"), "10"))
// pp.Println(dbm.SetNode(mod, x(mod, "/users/user['name'='yuta']/age"), "100"))
// pp.Println(dbm.SetNode(mod, x(mod,
// "/users/user['name'='hoge']/projects['name'='p1']/finished",
// ), "true"))

//dbm.SetNode("accounting", NewXPathOrDie("/users/user['name'='hoge']"), nil)
//ExecuteCommand("show operational-data account users user hoge")

//ExecuteCommand("show operational-data account users user hiroki")
//ExecuteCommand("set account users user hoge")
// ExecuteCommand("show operational-data account users user hoge")
// ExecuteCommand("show operational-data account users user hoge")
//ExecuteCommand("show operational-data account users user hiroki")
// ExecuteCommand("show operational-data account users user hiroki age")

// ExecuteCommand("set account users user hoge")
// ExecuteCommand("show operational-data account users user hoge")

// node, err := dbm.GetNode("account", "/users/user['name'='eva']")
// if err != nil {
// panic(err)
// }
// pp.Println(node)
}
9 changes: 9 additions & 0 deletions pkg/vtyang/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import (
"github.com/slankdev/vtyang/pkg/util"
)

const (
agentTestDefaultLogFile = "/tmp/run/vtyang/vtyang.log"
)

type TestCase struct {
YangPath string
RuntimePath string
Expand Down Expand Up @@ -38,6 +42,11 @@ func executeTestCase(t *testing.T, tc *TestCase) {
}
}

// NOTE(slankdev): set as default
if tc.LogFile == "" {
tc.LogFile = agentTestDefaultLogFile
}

// Initializing Agent
if err := InitAgent(tc.RuntimePath, tc.YangPath, tc.LogFile); err != nil {
t.Fatal(err)
Expand Down
12 changes: 8 additions & 4 deletions pkg/vtyang/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,10 @@ func (v *DBValue) ToYangNumber() (*yang.Number, error) {

func (v *DBValue) ToString() string {
switch v.Type {
case yang.Ystring:
case yang.Ystring,
yang.Yidentityref,
yang.Yleafref,
yang.Yenum:
return v.String
case yang.Yint8:
return fmt.Sprintf("%d", v.Int8)
Expand All @@ -800,14 +803,15 @@ func (v *DBValue) ToString() string {
return fmt.Sprintf("%v", v.Boolean)
case yang.Ydecimal64:
return fmt.Sprintf("%f", v.Decimal64)
case yang.Yunion:
vv := *v
vv.Type = vv.UnionType
return vv.ToString()
// case yang.Ybinary:
// case yang.Ybits:
// case yang.Yempty:
// case yang.Yenum:
// case yang.Yidentityref:
// case yang.YinstanceIdentifier:
// case yang.Yleafref:
// case yang.Yunion:
default:
panic(fmt.Sprintf("OKASHI (%s)", v.Type))
}
Expand Down
68 changes: 66 additions & 2 deletions pkg/vtyang/database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/google/go-cmp/cmp"
"github.com/k0kubun/pp"
"github.com/nsf/jsondiff"
"github.com/openconfig/goyang/pkg/yang"

"github.com/slankdev/vtyang/pkg/util"
Expand Down Expand Up @@ -90,7 +91,8 @@ func TestDBNodeGet(t *testing.T) {
}

for _, tc := range testcases {
xpath := NewXPathOrDie(dbm, tc.in)
xpath, err := ParseXPathString(dbm, tc.in)
ErrorOnDie(err)
node, err := dbm.GetNode(xpath)
ErrorOnDie(err)

Expand Down Expand Up @@ -150,7 +152,8 @@ func TestDBNodeCreate(t *testing.T) {
}

for _, tc := range testcases {
xpath := NewXPathOrDie(dbm, tc.in[0])
xpath, err := ParseXPathString(dbm, tc.in[0])
ErrorOnDie(err)
root, err := xpath.CreateDBNodeTree()
ErrorOnDie(err)

Expand Down Expand Up @@ -402,3 +405,64 @@ func Test_DBValue_ToAbsoluteNumber(t *testing.T) {
}
}
}

func Test_SetNode(t *testing.T) {
xpath := XPath{
Words: []XWord{
{
Module: "frr-interface",
Word: "lib",
Dbtype: Container,
},
{
Module: "frr-interface",
Word: "interface",
Dbtype: List,
Keys: map[string]DBValue{
"name": {
Type: yang.Ystring,
String: "dum0",
},
},
},
{
Module: "frr-interface",
Word: "description",
Dbtype: Leaf,
Dbvaluetype: yang.Ystring,
},
},
}
value := "hoge"
out, err := CraftDBNode([]YangData{
{
XPath: xpath,
Value: value,
},
})
if err != nil {
t.Fatal(err)
}

const expect = `{
"lib": {
"interface": [
{
"description": "hoge",
"name": "dum0"
}
]
}
}`

// Compare as json string
opts := jsondiff.DefaultConsoleOptions()
opts.Indent = " "
opt, diff := jsondiff.Compare([]byte(expect), []byte(out.String()), &opts)
if opt != jsondiff.FullMatch {
fmt.Printf("exp: \n%s\n", expect)
fmt.Printf("out: \n%s\n", out)
fmt.Printf("diff: \n%s\n", diff)
t.Fatal("unexpected output")
}
}
33 changes: 33 additions & 0 deletions pkg/vtyang/testdata/TestAccountingConfigXpath01.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"Words": [
{
"Module": "account",
"Word": "users",
"Keys": null,
"Dbtype": "container",
"Dbvaluetype": 0
},
{
"Module": "account",
"Word": "user",
"Keys": {
"name": {
"Type": 18,
"Int8": 0,
"Int16": 0,
"Int32": 0,
"Int64": 0,
"Uint8": 0,
"Uint16": 0,
"Uint32": 0,
"Uint64": 0,
"String": "eva",
"Boolean": false,
"Decimal64": 0
}
},
"Dbtype": "list",
"Dbvaluetype": 0
}
]
}
6 changes: 6 additions & 0 deletions pkg/vtyang/testdata/choice_case_output2.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
{
"Words": [
{
"Module": "main",
"Word": "values",
"Keys": null,
"Dbtype": "container",
"Dbvaluetype": 0
},
{
"Module": "main",
"Word": "transport-proto",
"Keys": null,
"Dbtype": "container",
"Dbvaluetype": 0
},
{
"Module": "main",
"Word": "tcp-app",
"Keys": null,
"Dbtype": "leaf",
Expand All @@ -23,12 +26,14 @@
{
"Words": [
{
"Module": "main",
"Word": "items",
"Keys": null,
"Dbtype": "container",
"Dbvaluetype": 0
},
{
"Module": "main",
"Word": "items",
"Keys": {
"name": {
Expand All @@ -50,6 +55,7 @@
"Dbvaluetype": 0
},
{
"Module": "main",
"Word": "ipv4-proto",
"Keys": null,
"Dbtype": "leaf",
Expand Down
Loading

0 comments on commit f0a6139

Please sign in to comment.