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 }