diff --git a/pkg/yang/entry_test.go b/pkg/yang/entry_test.go index 1d60ef0..4d1c2b3 100644 --- a/pkg/yang/entry_test.go +++ b/pkg/yang/entry_test.go @@ -1804,13 +1804,15 @@ func getEntry(root *Entry, path []string) *Entry { func TestActionRPC(t *testing.T) { tests := []struct { - name string - inModule string - operationPath []string - wantNodeKind string - wantError string - noInput bool - noOutput bool + name string + inModule string + operationPath []string + wantNodeKind string + wantError string + noInput bool + noOutput bool + wantInputMust []string + wantOutputMust []string }{ { name: "test action in container", @@ -1987,6 +1989,29 @@ func TestActionRPC(t *testing.T) { // error: "operation" is not a valid sub-statement to "leaf-list" action operation; } +}`, + }, + { + name: "input-output rpc with must", + wantNodeKind: "rpc", + operationPath: []string{"operation"}, + wantInputMust: []string{"false()"}, + wantOutputMust: []string{"true()", "b"}, + inModule: `module test { + namespace "urn:test"; + prefix "test"; + rpc operation { + description "rpc"; + input { + must "false()" { + error-message "imposible"; + } + } + output { + must "true()"; + must "b"; + } + } }`, }, } @@ -2026,7 +2051,33 @@ func TestActionRPC(t *testing.T) { } else if !tt.noOutput && e.RPC.Output == nil { t.Errorf("%s: RPCEntry has nil Output, want: non-nil. Entry: %#v", tt.name, e.RPC) } + if e.RPC != nil { + if got := mustExprs(t, tt.name, e.RPC.Input); !reflect.DeepEqual(got, tt.wantInputMust) { + t.Errorf("%s: input must expressions: got %v, want %v", tt.name, got, tt.wantInputMust) + } + if got := mustExprs(t, tt.name, e.RPC.Output); !reflect.DeepEqual(got, tt.wantOutputMust) { + t.Errorf("%s: output must expressions: got %v, want %v", tt.name, got, tt.wantOutputMust) + } + } + + } +} + +func mustExprs(t *testing.T, name string, e *Entry) []string { + t.Helper() + if e == nil { + return nil + } + var exprs []string + for _, x := range e.Extra["must"] { + m, ok := x.(*Must) + if !ok { + t.Errorf("%s: Extra[\"must\"] contains %T, want *Must", name, x) + continue + } + exprs = append(exprs, m.Name) } + return exprs } var testIfFeatureModules = []struct { diff --git a/pkg/yang/yang.go b/pkg/yang/yang.go index efff44a..ae2e66a 100644 --- a/pkg/yang/yang.go +++ b/pkg/yang/yang.go @@ -689,7 +689,7 @@ func (s *RPC) Exts() []*Statement { return s.Extensions } func (s *RPC) Groupings() []*Grouping { return s.Grouping } func (s *RPC) Typedefs() []*Typedef { return s.Typedef } -// An Input is defined in: http://tools.ietf.org/html/rfc6020#section-7.13.2 +// An Input is defined in: http://tools.ietf.org/html/rfc7950#section-7.14.2 type Input struct { Name string `yang:"Name,nomerge"` Source *Statement `yang:"Statement,nomerge"` @@ -704,6 +704,7 @@ type Input struct { Leaf []*Leaf `yang:"leaf"` LeafList []*LeafList `yang:"leaf-list"` List []*List `yang:"list"` + Must []*Must `yang:"must"` Typedef []*Typedef `yang:"typedef"` Uses []*Uses `yang:"uses"` } @@ -716,7 +717,7 @@ func (s *Input) Exts() []*Statement { return s.Extensions } func (s *Input) Groupings() []*Grouping { return s.Grouping } func (s *Input) Typedefs() []*Typedef { return s.Typedef } -// An Output is defined in: http://tools.ietf.org/html/rfc6020#section-7.13.3 +// An Output is defined in: http://tools.ietf.org/html/rfc7950#section-7.14.3 type Output struct { Name string `yang:"Name,nomerge"` Source *Statement `yang:"Statement,nomerge"` @@ -731,6 +732,7 @@ type Output struct { Leaf []*Leaf `yang:"leaf"` LeafList []*LeafList `yang:"leaf-list"` List []*List `yang:"list"` + Must []*Must `yang:"must"` Typedef []*Typedef `yang:"typedef"` Uses []*Uses `yang:"uses"` }