Skip to content

Commit

Permalink
Merge branch 'master' into fix-unmarshal-gnmi-empty-leaf
Browse files Browse the repository at this point in the history
  • Loading branch information
wenovus authored Nov 9, 2021
2 parents 4c90480 + ef8f2a1 commit be89046
Show file tree
Hide file tree
Showing 16 changed files with 84,360 additions and 73,344 deletions.
76,031 changes: 39,511 additions & 36,520 deletions exampleoc/oc.go

Large diffs are not rendered by default.

3,348 changes: 3,274 additions & 74 deletions exampleoc/ocpath.go

Large diffs are not rendered by default.

76,746 changes: 40,201 additions & 36,545 deletions exampleoc/opstateoc/oc.go

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions genutil/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ import (
const (
// GoDefaultYgotImportPath is the default import path used for the ygot library
// in the generated code.
GoDefaultYgotImportPath string = "github.com/openconfig/ygot/ygot"
GoDefaultYgotImportPath = "github.com/openconfig/ygot/ygot"
// GoDefaultYtypesImportPath is the default import path used for the ytypes library
// in the generated code.
GoDefaultYtypesImportPath string = "github.com/openconfig/ygot/ytypes"
GoDefaultYtypesImportPath = "github.com/openconfig/ygot/ytypes"
// GoDefaultGoyangImportPath is the default path for the goyang/pkg/yang library that
// is used in the generated code.
GoDefaultGoyangImportPath string = "github.com/openconfig/goyang/pkg/yang"
GoDefaultGoyangImportPath = "github.com/openconfig/goyang/pkg/yang"
// GoDefaultGNMIImportPath is the default import path that is used for the gNMI generated
// Go protobuf code in the generated output.
GoDefaultGNMIImportPath string = "github.com/openconfig/gnmi/proto/gnmi"
GoDefaultGNMIImportPath = "github.com/openconfig/gnmi/proto/gnmi"
)

// WriteIfNotEmpty writes the string s to b if it has a non-zero length.
Expand Down Expand Up @@ -374,6 +374,10 @@ func FindAllChildren(e *yang.Entry, compBehaviour CompressBehaviour) (map[string
// prioritized container, we must put the entry in the shadow list.
if prioNames[n.Name] {
childrenList = shadowChildren
if directChildren[n.Name].Annotation == nil {
directChildren[n.Name].Annotation = map[string]interface{}{}
}
directChildren[n.Name].Annotation[ygot.GoCompressedLeafAnnotation] = struct{}{}
}
errs = addNewChild(childrenList, n.Name, n, errs)
}
Expand Down
33 changes: 32 additions & 1 deletion util/gnmi.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func PathMatchesPrefix(path *gpb.Path, prefix []string) bool {
}

// PathElemsEqual replaces the proto.Equal() check for PathElems.
// If a.Key["foo"] == "*" and b.Key["foo"] == "bar" func returns false.
// This significantly improves comparison speed.
func PathElemsEqual(a, b *gpb.PathElem) bool {
// This check allows avoiding to deal with any null PathElems later on.
Expand All @@ -53,12 +54,13 @@ func PathElemsEqual(a, b *gpb.PathElem) bool {
if a.Name != b.Name {
return false
}

if len(a.Key) != len(b.Key) {
return false
}

for k, v := range a.Key {
if vo, ok := b.Key[k]; !ok || vo != v {
if vo, ok := b.Key[k]; !ok || v != vo {
return false
}
}
Expand All @@ -80,6 +82,9 @@ func PathElemSlicesEqual(a, b []*gpb.PathElem) bool {

// PathMatchesPathElemPrefix checks whether prefix is a prefix of path. Both paths
// must use the gNMI >=0.4.0 PathElem path format.
// Note: Paths must match exactly, that is if path has a wildcard key,
// then the same key must also be a wildcard in the prefix.
// See PathMatchesQuery for comparing paths with wildcards.
func PathMatchesPathElemPrefix(path, prefix *gpb.Path) bool {
if len(path.GetElem()) < len(prefix.GetElem()) || path.Origin != prefix.Origin {
return false
Expand All @@ -92,6 +97,32 @@ func PathMatchesPathElemPrefix(path, prefix *gpb.Path) bool {
return true
}

// PathMatchesQuery returns whether query is prefix of path.
// Only the query may contain wildcard name or keys.
// TODO: Multilevel wildcards ("...") not supported.
// If either path and query contain nil elements func returns false.
// Both paths must use the gNMI >=0.4.0 PathElem path format.
func PathMatchesQuery(path, query *gpb.Path) bool {
if len(path.GetElem()) < len(query.GetElem()) || path.Origin != query.Origin {
return false
}
for i, queryElem := range query.Elem {
pathElem := path.Elem[i]
if queryElem == nil || pathElem == nil {
return false
}
if queryElem.Name != "*" && queryElem.Name != pathElem.Name {
return false
}
for qk, qv := range queryElem.Key {
if pv, ok := pathElem.Key[qk]; !ok || (qv != "*" && qv != pv) {
return false
}
}
}
return true
}

// TrimGNMIPathPrefix returns path with the prefix trimmed. It returns the
// original path if the prefix does not fully match.
func TrimGNMIPathPrefix(path *gpb.Path, prefix []string) *gpb.Path {
Expand Down
194 changes: 194 additions & 0 deletions util/gnmi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,200 @@ func TestPathMatchesPathElemPrefix(t *testing.T) {
}
}

func TestPathMatchesQuery(t *testing.T) {
tests := []struct {
desc string
inPath *gpb.Path
inQuery *gpb.Path
want bool
}{{
desc: "valid query with no keys",
inPath: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "one",
}, {
Name: "two",
}},
},
inQuery: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "one",
}},
},
want: true,
}, {
desc: "valid query with wildcard name",
inPath: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "one",
}, {
Name: "two",
}},
},
inQuery: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "*",
}, {
Name: "two",
}},
},
want: true,
}, {
desc: "valid query with exact key match",
inPath: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "one",
Key: map[string]string{"two": "three"},
}, {
Name: "four",
}},
},
inQuery: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "one",
Key: map[string]string{"two": "three"},
}},
},
want: true,
}, {
desc: "valid query with wildcard keys",
inPath: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "one",
Key: map[string]string{"two": "three"},
}, {
Name: "four",
}},
},
inQuery: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "one",
Key: map[string]string{"two": "*"},
}},
},
want: true,
}, {
desc: "valid query with no keys and path with keys",
inPath: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "one",
Key: map[string]string{"two": "three"},
}, {
Name: "four",
}},
},
inQuery: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "one",
}},
},
want: true,
}, {
desc: "valid query with both missing and wildcard keys",
inPath: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "one",
Key: map[string]string{
"two": "three",
"four": "five",
},
}, {
Name: "four",
}},
},
inQuery: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "one",
Key: map[string]string{"four": "*"},
}},
},
want: true,
}, {
desc: "invalid nil elements",
inPath: &gpb.Path{
Elem: []*gpb.PathElem{
nil,
{
Name: "twelve",
}},
},
inQuery: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "three",
}},
},
}, {
desc: "invalid names not equal",
inPath: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "fourteen",
}, {
Name: "twelve",
}},
},
inQuery: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "three",
}},
},
}, {
desc: "invalid origin",
inPath: &gpb.Path{
Origin: "openconfig",
Elem: []*gpb.PathElem{{
Name: "one",
}, {
Name: "two",
}},
},
inQuery: &gpb.Path{
Origin: "google",
Elem: []*gpb.PathElem{{
Name: "one",
}},
},
}, {
desc: "invalid keys",
inPath: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "three",
Key: map[string]string{"four": "five"},
}, {
Name: "six",
}},
},
inQuery: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "three",
Key: map[string]string{"seven": "eight"},
}},
},
}, {
desc: "invalid missing wildcard keys",
inPath: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "three",
Key: map[string]string{"four": "five"},
}, {
Name: "six",
}},
},
inQuery: &gpb.Path{
Elem: []*gpb.PathElem{{
Name: "three",
Key: map[string]string{"seven": "*"},
}},
},
}}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
if got := PathMatchesQuery(tt.inPath, tt.inQuery); got != tt.want {
t.Fatalf("did not get expected result, got: %v, want: %v", got, tt.want)
}
})
}
}

func TestTrimGNMIPathElemPrefix(t *testing.T) {
tests := []struct {
desc string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@
}
}
]
},
"Annotation": {
"ygot-oc-compressed-leaf": {}
}
},
"peer-address": {
Expand Down Expand Up @@ -123,6 +126,9 @@
]
}
]
},
"Annotation": {
"ygot-oc-compressed-leaf": {}
}
}
},
Expand Down
Loading

0 comments on commit be89046

Please sign in to comment.