github.com/openconfig/goyang@v1.4.5/pkg/yang/find_test.go (about)

     1  package yang
     2  
     3  import (
     4  	"testing"
     5  )
     6  
     7  func TestFindGrouping(t *testing.T) {
     8  	tests := []struct {
     9  		desc              string
    10  		inMods            map[string]string
    11  		inNode            func(*Modules) (Node, error)
    12  		inName            string
    13  		wantGroupNodePath string
    14  		// wantCannotFound indicates that the grouping cannot be found.
    15  		wantCannotFound bool
    16  	}{{
    17  		desc: "grouping within module",
    18  		inMods: map[string]string{
    19  			"dev": `
    20  				module dev {
    21  					prefix d;
    22  					namespace "urn:d";
    23  
    24  					revision 01-01-01 { description "the start of time"; }
    25  
    26  					grouping g { leaf a { type string; } }
    27  
    28  					container c { leaf b { type string; } }
    29  				}`,
    30  		},
    31  		inNode: func(ms *Modules) (Node, error) {
    32  			return FindNode(ms.Modules["dev"], "c")
    33  		},
    34  		inName:            "g",
    35  		wantGroupNodePath: "/dev/g",
    36  	}, {
    37  		desc: "nested grouping within module",
    38  		inMods: map[string]string{
    39  			"dev": `
    40  				module dev {
    41  					prefix d;
    42  					namespace "urn:d";
    43  
    44  					revision 01-01-01 { description "the start of time"; }
    45  
    46  					grouping g { grouping gg { leaf a { type string; } } uses gg; }
    47  
    48  					container c { leaf b { type string; } }
    49  				}`,
    50  		},
    51  		inNode: func(ms *Modules) (Node, error) {
    52  			return FindNode(ms.Modules["dev"], "g")
    53  		},
    54  		inName:            "gg",
    55  		wantGroupNodePath: "/dev/g/gg",
    56  	}, {
    57  		desc: "grouping that uses another grouping both within the same module",
    58  		inMods: map[string]string{
    59  			"dev": `
    60  				module dev {
    61  					prefix d;
    62  					namespace "urn:d";
    63  
    64  					revision 01-01-01 { description "the start of time"; }
    65  
    66  					grouping gg { leaf a { type string; } }
    67  
    68  					grouping g { uses gg; }
    69  
    70  					container c { leaf b { type string; } }
    71  				}`,
    72  		},
    73  		inNode: func(ms *Modules) (Node, error) {
    74  			return FindNode(ms.Modules["dev"], "g")
    75  		},
    76  		inName:            "gg",
    77  		wantGroupNodePath: "/dev/gg",
    78  	}, {
    79  		desc: "grouping in included submodule",
    80  		inMods: map[string]string{
    81  			"dev": `
    82  				module dev {
    83  					prefix d;
    84  					namespace "urn:d";
    85  					include sys;
    86  
    87  					container c { leaf b { type string; } }
    88  
    89  					revision 01-01-01 { description "the start of time"; }
    90  				}`,
    91  			"sys": `
    92  				submodule sys {
    93  					belongs-to dev {
    94  						prefix "d";
    95  					}
    96  
    97  					revision 01-01-01 { description "the start of time"; }
    98  
    99  					grouping g { leaf a { type string; } }
   100  				}`,
   101  		},
   102  		inNode: func(ms *Modules) (Node, error) {
   103  			return FindNode(ms.Modules["dev"], "c")
   104  		},
   105  		inName:            "g",
   106  		wantGroupNodePath: "/sys/g",
   107  	}, {
   108  		desc: "grouping in indirectly-included submodule",
   109  		inMods: map[string]string{
   110  			"dev": `
   111  				module dev {
   112  					prefix d;
   113  					namespace "urn:d";
   114  					include sys;
   115  
   116  					revision 01-01-01 { description "the start of time"; }
   117  
   118  					container c { leaf b { type string; } }
   119  				}`,
   120  			"sys": `
   121  				submodule sys {
   122  					belongs-to dev {
   123  						prefix "d";
   124  					}
   125  					include sysdb;
   126  
   127  					revision 01-01-01 { description "the start of time"; }
   128  				}`,
   129  			"sysdb": `
   130  				submodule sysdb {
   131  					belongs-to dev {
   132  						prefix "d";
   133  					}
   134  
   135  					revision 01-01-01 { description "the start of time"; }
   136  
   137  					grouping g { leaf a { type string; } }
   138  				}`,
   139  		},
   140  		inNode: func(ms *Modules) (Node, error) {
   141  			return FindNode(ms.Modules["dev"], "c")
   142  		},
   143  		inName:            "g",
   144  		wantGroupNodePath: "/sysdb/g",
   145  	}, {
   146  		desc: "grouping in indirectly-included submodule with node in submodule",
   147  		inMods: map[string]string{
   148  			"dev": `
   149  				module dev {
   150  					prefix d;
   151  					namespace "urn:d";
   152  					include sys;
   153  
   154  					revision 01-01-01 { description "the start of time"; }
   155  				}`,
   156  			"sys": `
   157  				submodule sys {
   158  					belongs-to dev {
   159  						prefix "d";
   160  					}
   161  					include sysdb;
   162  
   163  					revision 01-01-01 { description "the start of time"; }
   164  
   165  					container c { leaf b { type string; } }
   166  				}`,
   167  			"sysdb": `
   168  				submodule sysdb {
   169  					belongs-to dev {
   170  						prefix "d";
   171  					}
   172  
   173  					revision 01-01-01 { description "the start of time"; }
   174  
   175  					grouping g { leaf a { type string; } }
   176  				}`,
   177  		},
   178  		inNode: func(ms *Modules) (Node, error) {
   179  			return FindNode(ms.SubModules["sys"], "c")
   180  		},
   181  		inName:            "g",
   182  		wantGroupNodePath: "/sysdb/g",
   183  	}, {
   184  		desc: "grouping in submodule",
   185  		inMods: map[string]string{
   186  			"dev": `
   187  				module dev {
   188  					prefix d;
   189  					namespace "urn:d";
   190  					import sysdb { prefix "s"; }
   191  
   192  					revision 01-01-01 { description "the start of time"; }
   193  
   194  					container c { leaf b { type string; } uses s:g; }
   195  				}`,
   196  			"sysdb": `
   197  				module sysdb {
   198  					prefix sd;
   199  					namespace "urn:sd";
   200  
   201  					revision 01-01-01 { description "the start of time"; }
   202  
   203  					grouping g { leaf a { type string; } }
   204  				}`,
   205  		},
   206  		inNode: func(ms *Modules) (Node, error) {
   207  			return FindNode(ms.Modules["dev"], "c")
   208  		},
   209  		inName:            "s:g",
   210  		wantGroupNodePath: "/sysdb/g",
   211  	}, {
   212  		desc: "grouping that uses another grouping both in different modules",
   213  		inMods: map[string]string{
   214  			"dev": `
   215  				module dev {
   216  					prefix d;
   217  					namespace "urn:d";
   218  					import dev2 { prefix "de2"; }
   219  
   220  					revision 01-01-01 { description "the start of time"; }
   221  
   222  					container c { leaf l { type string; } uses de2:g; }
   223  				}`,
   224  			"dev2": `
   225  				module dev2 {
   226  					prefix d2;
   227  					namespace "urn:d2";
   228  					import dev3 { prefix "de3"; }
   229  
   230  					revision 01-01-01 { description "the start of time"; }
   231  
   232  					grouping g { leaf a { type string; } uses de3:gg; }
   233  				}`,
   234  			"dev3": `
   235  				module dev3 {
   236  					prefix d3;
   237  					namespace "urn:d3";
   238  
   239  					revision 01-01-01 { description "the start of time"; }
   240  
   241  					grouping gg { leaf b { type string; } }
   242  				}`,
   243  		},
   244  		inNode: func(ms *Modules) (Node, error) {
   245  			return FindNode(ms.Modules["dev2"], "g")
   246  		},
   247  		inName:            "de3:gg",
   248  		wantGroupNodePath: "/dev3/gg",
   249  	}, {
   250  		desc: "grouping that uses another grouping both in different modules but prefix is wrong",
   251  		inMods: map[string]string{
   252  			"dev": `
   253  				module dev {
   254  					prefix d;
   255  					namespace "urn:d";
   256  					import dev2 { prefix "de2"; }
   257  
   258  					revision 01-01-01 { description "the start of time"; }
   259  
   260  					container c { leaf l { type string; } uses de2:g; }
   261  				}`,
   262  			"dev2": `
   263  				module dev2 {
   264  					prefix d2;
   265  					namespace "urn:d2";
   266  					import dev3 { prefix "de3"; }
   267  
   268  					revision 01-01-01 { description "the start of time"; }
   269  
   270  					grouping g { leaf a { type string; } uses de3:gg; }
   271  				}`,
   272  			"dev3": `
   273  				module dev3 {
   274  					prefix dev3;
   275  					namespace "urn:dev3";
   276  
   277  					revision 01-01-01 { description "the start of time"; }
   278  
   279  					grouping gg { leaf b { type string; } }
   280  				}`,
   281  		},
   282  		inNode: func(ms *Modules) (Node, error) {
   283  			return FindNode(ms.Modules["dev2"], "g")
   284  		},
   285  		inName:          "d3:gg",
   286  		wantCannotFound: true,
   287  	}, {
   288  		desc: "grouping that uses another grouping both in different modules but uses wrong context node",
   289  		inMods: map[string]string{
   290  			"dev": `
   291  				module dev {
   292  					prefix d;
   293  					namespace "urn:d";
   294  					import dev2 { prefix "de2"; }
   295  
   296  					revision 01-01-01 { description "the start of time"; }
   297  
   298  					container c { leaf l { type string; } uses de2:g; }
   299  				}`,
   300  			"dev2": `
   301  				module dev2 {
   302  					prefix d2;
   303  					namespace "urn:d2";
   304  					import dev3 { prefix "dev3"; }
   305  
   306  					revision 01-01-01 { description "the start of time"; }
   307  
   308  					grouping g { leaf a { type string; } uses dev3:gg; }
   309  				}`,
   310  			"dev3": `
   311  				module dev3 {
   312  					prefix dev3;
   313  					namespace "urn:dev3";
   314  
   315  					revision 01-01-01 { description "the start of time"; }
   316  
   317  					grouping gg { leaf b { type string; } }
   318  				}`,
   319  		},
   320  		inNode: func(ms *Modules) (Node, error) {
   321  			return FindNode(ms.Modules["dev"], "c")
   322  		},
   323  		inName:          "dev3:gg",
   324  		wantCannotFound: true,
   325  	}}
   326  
   327  	for _, tt := range tests {
   328  		t.Run(tt.desc, func(t *testing.T) {
   329  			ms := NewModules()
   330  
   331  			for n, m := range tt.inMods {
   332  				if err := ms.Parse(m, n); err != nil {
   333  					t.Fatalf("cannot parse module %s, err: %v", n, err)
   334  				}
   335  			}
   336  
   337  			if errs := ms.Process(); errs != nil {
   338  				t.Fatalf("cannot process modules: %v", errs)
   339  			}
   340  
   341  			seen := map[string]bool{}
   342  			node, err := tt.inNode(ms)
   343  			if err != nil {
   344  				t.Fatalf("cannot find input node: %v", err)
   345  			}
   346  			g := FindGrouping(node, tt.inName, seen)
   347  			if got, want := g == nil, tt.wantCannotFound; got != want {
   348  				t.Fatalf("got grouping: %v, wantCannotFound: %v", got, want)
   349  			}
   350  			if tt.wantCannotFound {
   351  				return
   352  			}
   353  			if got, want := NodePath(g), tt.wantGroupNodePath; got != want {
   354  				t.Errorf("found grouping path doesn't match expected, got: %s, want: %s", got, want)
   355  			}
   356  		})
   357  	}
   358  }