fdedeb8e57281d04bc2143db42d1ab878d81d760
[smo/teiv.git] /
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2024 Ericsson
4  *  Modifications Copyright (C) 2024 OpenInfra Foundation Europe
5  *  ================================================================================
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  *  SPDX-License-Identifier: Apache-2.0
19  *  ============LICENSE_END=========================================================
20  */
21 package org.oran.smo.yangtools.parser.testutils;
22
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25
26 import java.io.File;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Map.Entry;
33 import java.util.Optional;
34 import java.util.Set;
35 import java.util.stream.Collectors;
36
37 import org.junit.Before;
38
39 import org.oran.smo.yangtools.parser.ParserExecutionContext;
40 import org.oran.smo.yangtools.parser.YangDeviceModel;
41 import org.oran.smo.yangtools.parser.data.dom.YangDataDomNode;
42 import org.oran.smo.yangtools.parser.data.dom.YangDataDomNodeAnnotationValue;
43 import org.oran.smo.yangtools.parser.data.instance.AbstractStructureInstance;
44 import org.oran.smo.yangtools.parser.data.instance.AnyDataInstance;
45 import org.oran.smo.yangtools.parser.data.instance.AnyXmlInstance;
46 import org.oran.smo.yangtools.parser.data.instance.ContainerInstance;
47 import org.oran.smo.yangtools.parser.data.instance.DataTreeBuilderPredicate;
48 import org.oran.smo.yangtools.parser.data.instance.LeafInstance;
49 import org.oran.smo.yangtools.parser.data.instance.LeafListInstance;
50 import org.oran.smo.yangtools.parser.data.instance.ListInstance;
51 import org.oran.smo.yangtools.parser.data.parser.JsonParser.JsonObject;
52 import org.oran.smo.yangtools.parser.data.parser.JsonParser.JsonObjectMemberName;
53 import org.oran.smo.yangtools.parser.data.parser.JsonParser.JsonValue;
54 import org.oran.smo.yangtools.parser.findings.Finding;
55 import org.oran.smo.yangtools.parser.findings.FindingFilterPredicate;
56 import org.oran.smo.yangtools.parser.findings.FindingsManager;
57 import org.oran.smo.yangtools.parser.findings.ModifyableFindingSeverityCalculator;
58 import org.oran.smo.yangtools.parser.findings.ModuleAndFindingTypeAndSchemaNodePathFilterPredicate;
59 import org.oran.smo.yangtools.parser.findings.ParserFindingType;
60 import org.oran.smo.yangtools.parser.input.FileBasedYangInput;
61 import org.oran.smo.yangtools.parser.input.FileBasedYangInputResolver;
62 import org.oran.smo.yangtools.parser.model.ConformanceType;
63 import org.oran.smo.yangtools.parser.model.ModuleIdentity;
64 import org.oran.smo.yangtools.parser.model.YangModel;
65 import org.oran.smo.yangtools.parser.model.schema.ModuleRegistry;
66 import org.oran.smo.yangtools.parser.model.statements.AbstractStatement;
67 import org.oran.smo.yangtools.parser.model.statements.ExtensionStatement;
68 import org.oran.smo.yangtools.parser.model.statements.StatementModuleAndName;
69 import org.oran.smo.yangtools.parser.model.statements.YangModelRoot;
70 import org.oran.smo.yangtools.parser.model.statements.ietf.IetfExtensionsClassSupplier;
71 import org.oran.smo.yangtools.parser.model.statements.oran.OranExtensionsClassSupplier;
72 import org.oran.smo.yangtools.parser.model.statements.threegpp.ThreeGppExtensionsClassSupplier;
73 import org.oran.smo.yangtools.parser.model.statements.yang.CY;
74 import org.oran.smo.yangtools.parser.model.statements.yang.YAction;
75 import org.oran.smo.yangtools.parser.model.statements.yang.YAugment;
76 import org.oran.smo.yangtools.parser.model.statements.yang.YCase;
77 import org.oran.smo.yangtools.parser.model.statements.yang.YChoice;
78 import org.oran.smo.yangtools.parser.model.statements.yang.YContainer;
79 import org.oran.smo.yangtools.parser.model.statements.yang.YDeviation;
80 import org.oran.smo.yangtools.parser.model.statements.yang.YFeature;
81 import org.oran.smo.yangtools.parser.model.statements.yang.YGrouping;
82 import org.oran.smo.yangtools.parser.model.statements.yang.YLeaf;
83 import org.oran.smo.yangtools.parser.model.statements.yang.YLeafList;
84 import org.oran.smo.yangtools.parser.model.statements.yang.YList;
85 import org.oran.smo.yangtools.parser.model.statements.yang.YModule;
86 import org.oran.smo.yangtools.parser.model.statements.yang.YNotification;
87 import org.oran.smo.yangtools.parser.model.statements.yang.YRpc;
88 import org.oran.smo.yangtools.parser.model.statements.yang.YSubmodule;
89 import org.oran.smo.yangtools.parser.model.statements.yang.YType;
90 import org.oran.smo.yangtools.parser.model.statements.yang.YTypedef;
91 import org.oran.smo.yangtools.parser.model.yangdom.YangDomElement;
92
93 public class YangTestCommon {
94
95     public static final String YANG_FILE_EXTENSION = ".yang";
96
97     protected static final String TARGET_DIR = "target/test-output";
98
99     private static final String YANG_TEST_FILES = "src/test/resources/model-statements-yang/";
100
101     protected static final String ORIG_MODULES_PATH = "src/test/resources/_orig-modules/";
102
103     protected static final String THREEGPP_YANG_EXT_PATH = ORIG_MODULES_PATH + "_3gpp-common-yang-extensions-2022-10-20.yang";
104     protected static final String YANG_METADATA_PATH = ORIG_MODULES_PATH + "ietf-yang-metadata-2016-08-05.yang";
105     protected static final String YANG_ORIGIN_PATH = ORIG_MODULES_PATH + "ietf-origin-2018-02-14.yang";
106     protected static final String NETCONF_ACM_PATH = ORIG_MODULES_PATH + "ietf-netconf-acm-2018-02-14.yang";
107
108     protected YangDeviceModel yangDeviceModel;
109     protected ModifyableFindingSeverityCalculator severityCalculator;
110     protected FindingsManager findingsManager;
111     protected ParserExecutionContext context;
112
113     @Before
114     public void setUp() {
115         yangDeviceModel = new YangDeviceModel("Yang Parser JAR Test Device Model");
116
117         severityCalculator = new ModifyableFindingSeverityCalculator();
118
119         findingsManager = new FindingsManager(severityCalculator);
120         findingsManager.addFilterPredicate(ModuleAndFindingTypeAndSchemaNodePathFilterPredicate.fromString(
121                 "ietf*,iana*;*;*"));
122
123         createContext();
124
125         context.setFailFast(false);
126         context.setSuppressFindingsOnUnusedSchemaNodes(true);
127     }
128
129     protected void createContext() {
130
131         final ThreeGppExtensionsClassSupplier threeGppStatementFactory = new ThreeGppExtensionsClassSupplier();
132         final IetfExtensionsClassSupplier ietfStatementFactory = new IetfExtensionsClassSupplier();
133         final OranExtensionsClassSupplier oranStatementFactory = new OranExtensionsClassSupplier();
134
135         context = new ParserExecutionContext(findingsManager, Arrays.asList(threeGppStatementFactory, oranStatementFactory,
136                 ietfStatementFactory));
137     }
138
139     protected void suppressAllExcept(final String findingType) {
140         suppressAllExcept(Collections.singletonList(findingType));
141     }
142
143     protected void suppressAllExcept(final List<String> findingTypes) {
144
145         final FindingFilterPredicate predicate = new FindingFilterPredicate() {
146             @Override
147             public boolean test(Finding t) {
148                 return !findingTypes.contains(t.getFindingType());
149             }
150         };
151
152         findingsManager.addFilterPredicate(predicate);
153     }
154
155     protected void parseAbsoluteImplementsYangModels(final List<String> absoluteImplementsFilePaths) {
156         parseImplementsYangModels(Collections.<String> emptyList(), absoluteImplementsFilePaths);
157     }
158
159     protected void parseRelativeImplementsYangModels(final List<String> relativeImplementsFilePaths) {
160         parseImplementsYangModels(relativeImplementsFilePaths, Collections.<String> emptyList());
161     }
162
163     protected void parseImplementsYangModels(final List<String> relativeImplementsFilePaths,
164             final List<String> absoluteImplementsFilePaths) {
165         parseYangModels(relativeImplementsFilePaths, absoluteImplementsFilePaths, Collections.<String> emptyList(),
166                 Collections.<String> emptyList());
167     }
168
169     protected void parseRelativeYangModels(final List<String> relativeImplementsFilePaths,
170             final List<String> relativeImportFilePaths) {
171         parseYangModels(relativeImplementsFilePaths, Collections.<String> emptyList(), relativeImportFilePaths, Collections
172                 .<String> emptyList());
173     }
174
175     protected void parseAbsoluteYangModels(final List<String> absoluteImplementsFilePaths,
176             final List<String> absoluteImportFilePaths) {
177         parseYangModels(Collections.<String> emptyList(), absoluteImplementsFilePaths, Collections.<String> emptyList(),
178                 absoluteImportFilePaths);
179     }
180
181     protected void parseYangModels(final List<String> relativeImplementsFilePaths,
182             final List<String> absoluteImplementsFilePaths, final List<String> relativeImportsFilePaths,
183             final List<String> absoluteImportsFilePaths) {
184
185         final List<YangModel> yangFiles = new ArrayList<>();
186
187         for (final String relativeImplementsFilePath : relativeImplementsFilePaths) {
188             yangFiles.add(new YangModel(new FileBasedYangInput(new File(YANG_TEST_FILES + relativeImplementsFilePath)),
189                     ConformanceType.IMPLEMENT));
190         }
191         for (final String absoluteImplementsFilePath : absoluteImplementsFilePaths) {
192             yangFiles.add(new YangModel(new FileBasedYangInput(new File(absoluteImplementsFilePath)),
193                     ConformanceType.IMPLEMENT));
194         }
195
196         for (final String relativeImportsFilePath : relativeImportsFilePaths) {
197             yangFiles.add(new YangModel(new FileBasedYangInput(new File(YANG_TEST_FILES + relativeImportsFilePath)),
198                     ConformanceType.IMPORT));
199         }
200         for (final String absoluteImportsFilePath : absoluteImportsFilePaths) {
201             yangFiles.add(new YangModel(new FileBasedYangInput(new File(absoluteImportsFilePath)), ConformanceType.IMPORT));
202         }
203
204         yangDeviceModel.parseIntoYangModels(context, yangFiles);
205
206         /*
207          * There should NEVER be a P000 finding, this would indicate a null objects wasn't handled somewhere.
208          */
209         assertHasNotFindingOfType(ParserFindingType.P000_UNSPECIFIED_ERROR.toString());
210     }
211
212     protected void parseRelativeYangData(final List<String> relativeFilePaths) {
213         final List<File> collect = relativeFilePaths.stream().map(relpath -> new File(YANG_TEST_FILES + relpath)).collect(
214                 Collectors.toList());
215         yangDeviceModel.parseYangData(context, new FileBasedYangInputResolver(collect), new DataTreeBuilderPredicate());
216     }
217
218     protected void parseAbsoluteYangData(final List<String> absoluteFilePaths) {
219         final List<File> collect = absoluteFilePaths.stream().map(abspath -> new File(abspath)).collect(Collectors
220                 .toList());
221         yangDeviceModel.parseYangData(context, new FileBasedYangInputResolver(collect), new DataTreeBuilderPredicate());
222     }
223
224     /**
225      * Get module from yangDeviceModel
226      */
227     public YModule getModule(final String moduleName) {
228         final ModuleRegistry moduleRegistry = yangDeviceModel.getModuleRegistry();
229
230         for (final YangModel yangModelFile : moduleRegistry.getAllYangModels()) {
231             final YangModelRoot yangModelRoot = yangModelFile.getYangModelRoot();
232             final YModule yModule = yangModelRoot.getModule();
233             if ((yModule != null) && (yModule.getModuleName().equals(moduleName))) {
234                 return yModule;
235             }
236         }
237         return null;
238     }
239
240     /**
241      * Get sub-module from yangDeviceModel
242      */
243     public YSubmodule getSubModule(final String subModuleName) {
244
245         final ModuleRegistry moduleRegistry = yangDeviceModel.getModuleRegistry();
246         for (final YangModel yangModelFile : moduleRegistry.getAllYangModels()) {
247             final YangModelRoot yangModelRoot = yangModelFile.getYangModelRoot();
248             final YSubmodule ySubModule = yangModelRoot.getSubmodule();
249             if (ySubModule != null && ySubModule.getSubmoduleName().equals(subModuleName)) {
250                 return ySubModule;
251             }
252         }
253         return null;
254     }
255
256     public static YRpc getRpc(final AbstractStatement parent, final String rpcName) {
257         return getChild(parent, CY.RPC, rpcName);
258     }
259
260     public static YContainer getContainer(final AbstractStatement parent, final String containerName) {
261         return getChild(parent, CY.CONTAINER, containerName);
262     }
263
264     public static YList getList(final AbstractStatement parent, final String listName) {
265         return getChild(parent, CY.LIST, listName);
266     }
267
268     public static YNotification getNotification(final AbstractStatement parent, final String notificationName) {
269         return getChild(parent, CY.NOTIFICATION, notificationName);
270     }
271
272     public static YChoice getChoice(final AbstractStatement parent, final String choiceName) {
273         return getChild(parent, CY.CHOICE, choiceName);
274     }
275
276     public static YCase getCase(final YChoice parent, final String caseName) {
277         return getChild(parent, CY.CASE, caseName);
278     }
279
280     public static YGrouping getGrouping(final YModule module, final String groupingName) {
281         return getChild(module, CY.GROUPING, groupingName);
282     }
283
284     public static YLeaf getLeaf(final AbstractStatement parent, final String leafName) {
285         return getChild(parent, CY.LEAF, leafName);
286     }
287
288     public static YAction getAction(final AbstractStatement parent, final String actionName) {
289         return getChild(parent, CY.ACTION, actionName);
290     }
291
292     public static YLeafList getLeafList(final AbstractStatement parent, final String leafListName) {
293         return getChild(parent, CY.LEAF_LIST, leafListName);
294     }
295
296     public YTypedef getTypedefForModule(final String moduleName, final String typedefName) {
297         final YModule module = getModule(moduleName);
298         return (YTypedef) (module == null ? null : getChild(module, CY.TYPEDEF, typedefName));
299     }
300
301     public static YTypedef getTypedef(final AbstractStatement parent, final String typedefName) {
302         return getChild(parent, CY.TYPEDEF, typedefName);
303     }
304
305     public static YAugment getAugment(final AbstractStatement parent, final String path) {
306         return getChild(parent, CY.AUGMENT, path);
307     }
308
309     public static YFeature getFeature(final AbstractStatement parent, final String featureName) {
310         return getChild(parent, CY.FEATURE, featureName);
311     }
312
313     public static YDeviation getDeviation(final AbstractStatement parent, final String path) {
314         return (YDeviation) parent.getChildStatements().stream().filter(stmt -> stmt.is(CY.STMT_DEVIATION)).filter(
315                 stmt -> stmt.getDomElement().getValue().equals(path)).findAny().orElse(null);
316     }
317
318     public ExtensionStatement getExtension(final AbstractStatement parent, final String owningModuleName,
319             final String extensionName, final String argument) {
320         for (final ExtensionStatement extensionStatement : parent.getExtensionChildStatements()) {
321             final String prefix = extensionStatement.getExtensionModulePrefix();
322             final ModuleIdentity owningModule = extensionStatement.getPrefixResolver().getModuleForPrefix(prefix);
323             if (owningModuleName.equals(owningModule.getModuleName()) && extensionStatement.getExtensionStatementName()
324                     .equals(extensionName)) {
325                 if (argument == null || (argument.equals(extensionStatement.getValue()))) {
326                     return extensionStatement;
327                 }
328             }
329         }
330         return null;
331     }
332
333     public YContainer getContainerUnderContainer(final AbstractStatement parent, final String containerName1,
334             final String containerName2) {
335         final YContainer cont1 = getContainer(parent, containerName1);
336         return cont1 == null ? null : getContainer(cont1, containerName2);
337     }
338
339     public YLeafList getLeafListUnderContainer(final AbstractStatement parent, final String containerName,
340             final String leafListName) {
341         final YContainer cont1 = getContainer(parent, containerName);
342         return cont1 == null ? null : getLeafList(cont1, leafListName);
343     }
344
345     public YLeafList getLeafListUnderList(final AbstractStatement parent, final String listName,
346             final String leafListName) {
347         final YList list1 = getList(parent, listName);
348         return list1 == null ? null : getLeafList(list1, leafListName);
349     }
350
351     public YLeaf getLeafUnderContainer(final AbstractStatement parent, final String containerName, final String leafName) {
352         final YContainer cont1 = getContainer(parent, containerName);
353         return cont1 == null ? null : getLeaf(cont1, leafName);
354     }
355
356     public YLeaf getLeafUnderList(final AbstractStatement parent, final String listName, final String leafName) {
357         final YList list = getList(parent, listName);
358         return list == null ? null : getLeaf(list, leafName);
359     }
360
361     public YList getListUnderContainer(final AbstractStatement parent, final String containerName, final String listName) {
362         final YContainer cont1 = getContainer(parent, containerName);
363         return cont1 == null ? null : getList(cont1, listName);
364     }
365
366     /**
367      * Get leaflist from container (container-list-leaflist)
368      */
369     public YLeafList getLeafListFromContainerList(final YModule yModule, final String containerName,
370             final String leafListName) {
371
372         for (final YContainer container : yModule.getContainers()) {
373             if (container.getContainerName().equals(containerName)) {
374                 for (final YList list : container.getLists()) {
375                     for (final YLeafList leafList : list.getLeafLists()) {
376                         if (leafList.getLeafListName().equals(leafListName)) {
377                             return leafList;
378                         }
379                     }
380                 }
381             }
382         }
383         return null;
384     }
385
386     /**
387      *
388      * Get leaf from container within another container (container-container-leaf)
389      */
390     public YLeaf getLeafFromContainerContainer(final YModule yModule, final String containerName1,
391             final String containerName2, final String leafName) {
392         for (final YContainer container : yModule.getContainers()) {
393             if (container.getContainerName().equals(containerName1)) {
394                 for (final YContainer innerContainer : container.getContainers()) {
395                     if (innerContainer.getContainerName().equals(containerName2)) {
396                         return getLeaf(innerContainer, leafName);
397                     }
398                 }
399             }
400         }
401         return null;
402     }
403
404     /**
405      * Get leaf from List within a container (container-list-leaf)
406      */
407     public YLeaf getLeafFromContainerList(final YModule yModule, final String containerName, final String listName,
408             final String leafName) {
409         final YList yList = getListUnderContainer(yModule, containerName, listName);
410         for (final YLeaf leaf : yList.getLeafs()) {
411             if (leaf.getLeafName().equals(leafName)) {
412                 return leaf;
413             }
414         }
415         return null;
416     }
417
418     @SuppressWarnings("unchecked")
419     public <T extends AbstractStatement> T getChild(final AbstractStatement parent, final String childType) {
420
421         if (parent == null) {
422             return null;
423         }
424
425         for (final AbstractStatement child : parent.getChildStatements()) {
426             if (child.getDomElement().getName().equals(childType)) {
427                 return (T) child;
428             }
429         }
430
431         return null;
432     }
433
434     @SuppressWarnings("unchecked")
435     public static <T extends AbstractStatement> T getChild(final AbstractStatement parent, final String childType,
436             final String childName) {
437
438         if (parent == null) {
439             return null;
440         }
441
442         for (final AbstractStatement child : parent.getChildStatements()) {
443             if (child.getDomElement().getName().equals(childType)) {
444                 if (childName == null && child.getDomElement().getValue() == null) {
445                     return (T) child;
446                 } else if (childName != null && childName.equals(child.getDomElement().getValue())) {
447                     return (T) child;
448                 }
449             }
450         }
451
452         return null;
453     }
454
455     @SuppressWarnings("unchecked")
456     public <T extends AbstractStatement> T getExtensionChild(final AbstractStatement parent, final String module,
457             final String extName) {
458
459         if (parent == null) {
460             return null;
461         }
462
463         for (final ExtensionStatement child : parent.getExtensionChildStatements()) {
464             final StatementModuleAndName childSman = child.getStatementModuleAndName();
465             if (childSman.getModuleName().equals(module) && childSman.getStatementName().equals(extName)) {
466                 return (T) child;
467             }
468         }
469
470         return null;
471     }
472
473     public YangDomElement getDomChild(final YangDomElement domParent, final String domChildName,
474             final String domChildValue) {
475
476         if (domParent == null) {
477             return null;
478         }
479
480         for (final YangDomElement domChild : domParent.getChildren()) {
481             if (domChild.getName().equals(domChildName) && domChild.getValue().equals(domChildValue)) {
482                 return domChild;
483             }
484         }
485
486         return null;
487     }
488
489     public YangDomElement getDomChild(final YangDomElement domParent, final String domChildName) {
490
491         if (domParent == null) {
492             return null;
493         }
494
495         for (final YangDomElement domChild : domParent.getChildren()) {
496             if (domChild.getName().equals(domChildName)) {
497                 return domChild;
498             }
499         }
500
501         return null;
502     }
503
504     /**
505      * Get identityref type from leaf (leaf-type)
506      */
507     public YType getIdentityType(final YLeaf leaf) {
508         for (final YType type : leaf.getType().getTypes()) {
509             if (type.getDataType().equals("identityref")) {
510                 return type;
511             }
512         }
513         return null;
514     }
515
516     /**
517      * Get a leaf from container by passing type.
518      */
519     public YLeaf getLeafOfTypeFromContainer(final YContainer container, final String type) {
520         for (final YLeaf yleaf : container.getLeafs()) {
521             if ((yleaf.getType().getDataType()).equals(type)) {
522                 return yleaf;
523             }
524         }
525         return null;
526     }
527
528     /**
529      * Get container from container (container-container)
530      */
531
532     /**
533      * Get case from choice within a container (container-choice-case)
534      */
535     public YCase getCaseFromChoiceContainer(final YModule yModule, final String containerName, final String choiceName,
536             final String caseName) {
537         final YChoice choice = getChoiceFromContainer(yModule, containerName, choiceName);
538         for (final YCase ycase : choice.getCases()) {
539             if (ycase.getCaseName().equals(caseName)) {
540                 return ycase;
541             }
542         }
543         return null;
544     }
545
546     /**
547      * Get choice from a container
548      */
549     public YChoice getChoiceFromContainer(final YModule yModule, final String containerName, final String choiceName) {
550         final YContainer container = getContainer(yModule, containerName);
551         for (final YChoice choice : container.getChoices()) {
552             if (choice.getChoiceName().equals(choiceName)) {
553                 return choice;
554             }
555         }
556         return null;
557     }
558
559     protected LeafInstance getLeafInstance(final AbstractStructureInstance parent, final String namespace,
560             final String name) {
561         return parent.getLeafInstance(namespace, name);
562     }
563
564     protected ContainerInstance getContainerInstance(final AbstractStructureInstance parent, final String namespace,
565             final String name) {
566         return parent.getContainerInstance(namespace, name);
567     }
568
569     protected List<LeafListInstance> getLeafListInstances(final AbstractStructureInstance parent, final String namespace,
570             final String name) {
571         if (!parent.hasLeafListInstance(namespace, name)) {
572             return Collections.<LeafListInstance> emptyList();
573         }
574         return parent.getLeafListInstances(namespace, name);
575     }
576
577     protected List<Object> getLeafListValues(final AbstractStructureInstance parent, final String namespace,
578             final String name) {
579         return parent.getLeafListValues(namespace, name);
580     }
581
582     protected AnyDataInstance getAnyDataInstance(final AbstractStructureInstance parent, final String namespace,
583             final String name) {
584         return parent.getAnyDataInstance(namespace, name);
585     }
586
587     protected AnyXmlInstance getAnyXmlInstance(final AbstractStructureInstance parent, final String namespace,
588             final String name) {
589         return parent.getAnyXmlInstance(namespace, name);
590     }
591
592     protected ListInstance getListInstanceData(AbstractStructureInstance parent, String ns, String name,
593             Map<String, String> keyValues) {
594
595         if (!parent.hasListInstance(ns, name)) {
596             return null;
597         }
598
599         return (ListInstance) parent.getListInstances(ns, name).stream().filter(inst -> keyValues.equals(
600                 ((ListInstance) inst).getKeyValues())).findAny().orElse(null);
601     }
602
603     protected static YangDataDomNode getChildDataDomNode(final YangDataDomNode parent, final String name) {
604         return parent.getChildren().stream().filter(child -> name.equals(child.getName())).findAny().orElse(null);
605     }
606
607     protected static YangDataDomNode getChildDataDomNode(final YangDataDomNode parent, final String name,
608             final String value) {
609         return parent.getChildren().stream().filter(child -> name.equals(child.getName()) && value.equals(child.getValue()))
610                 .findAny().orElse(null);
611     }
612
613     protected static YangDataDomNode getChildDataDomNode(final YangDataDomNode parent, final String name, final int index) {
614         final List<YangDataDomNode> collect = parent.getChildren().stream().filter(child -> name.equals(child.getName()))
615                 .collect(Collectors.toList());
616         return index < collect.size() ? collect.get(index) : null;
617     }
618
619     protected static YangDataDomNodeAnnotationValue getDataDomNodeAnnotation(final YangDataDomNode domNode,
620             final String name) {
621         return domNode.getAnnotations().stream().filter(anno -> name.equals(anno.getName())).findAny().orElse(null);
622     }
623
624     /**
625      * Check no findings found other than input argument
626      */
627     public boolean hasFindingsOfTypeOtherThan(final String findingType) {
628         for (final Finding finding : context.getFindingsManager().getAllFindings()) {
629             if (!finding.getFindingType().equals(findingType)) {
630                 return true;
631             }
632         }
633         return false;
634     }
635
636     public void assertSubTreeNoFindings(final AbstractStatement statement) {
637         assertNoFindingsOnStatement(statement);
638         for (final AbstractStatement child : statement.getChildStatements()) {
639             assertSubTreeNoFindings(child);
640         }
641     }
642
643     public void assertNoFindings() {
644         assertNoFindings(findingsManager.getAllFindings());
645     }
646
647     public void assertNoFindingsOnStatement(final AbstractStatement statement) {
648         assertNoFindings(statement.getFindings());
649     }
650
651     public void assertNoFindings(final Set<Finding> findings) {
652         if (findings.isEmpty()) {
653             return;
654         }
655
656         System.err.println("Findings count is " + findings.size() + ", not empty as expected.");
657         printFindings(findings);
658         fail();
659     }
660
661     public void assertOneFindingOnly() {
662         assertFindingCount(1);
663     }
664
665     public void assertOneFindingOnlyOnStatement(final AbstractStatement statement) {
666         assertFindingCountOnStatement(statement, 1);
667     }
668
669     public void assertOneFindingOnly(final Set<Finding> findings) {
670         assertFindingCount(findings, 1);
671     }
672
673     public void assertFindingCount(final int count) {
674         assertFindingCount(findingsManager.getAllFindings(), count);
675     }
676
677     public void assertFindingCountOnStatement(final AbstractStatement statement, final int count) {
678         assertFindingCount(statement.getFindings(), count);
679     }
680
681     public void assertFindingCount(final Set<Finding> findings, final int count) {
682         if (findings.size() == count) {
683             return;
684         }
685
686         System.err.println("Findings count is " + findings.size() + ", not as expected " + count);
687         printFindings(findings);
688         fail();
689     }
690
691     public void assertOneFindingOnly(final String findingType) {
692         assertSingleFindingOfType(findingsManager.getAllFindings(), findingType);
693     }
694
695     public void assertStatementHasSingleFindingOfType(final AbstractStatement statement, final String findingType) {
696         assertSingleFindingOfType(statement.getFindings(), findingType);
697     }
698
699     public void assertSingleFindingOfType(final Set<Finding> findings, final String findingType) {
700         assertFindingCount(findings, 1);
701         assertHasFindingOfType(findings, findingType);
702     }
703
704     public void assertHasFinding(final YangModel yangModelFile, final int lineNumber, final String findingType) {
705         for (final Finding finding : context.getFindingsManager().getAllFindings()) {
706             if (finding.getLineNumber() == lineNumber && finding.getFindingType().equals(findingType) && finding
707                     .getYangModel() == yangModelFile) {
708                 return;
709             }
710         }
711         fail();
712     }
713
714     public void assertHasFindingOfType(final String findingType) {
715         assertHasFindingOfType(context.getFindingsManager().getAllFindings(), findingType);
716     }
717
718     public void assertHasNotFindingOfType(final String findingType) {
719         assertHasNotFindingOfType(context.getFindingsManager().getAllFindings(), findingType);
720     }
721
722     public void assertStatementHasFindingOfType(final AbstractStatement statement, final String findingType) {
723         assertHasFindingOfType(statement.getFindings(), findingType);
724     }
725
726     public void assertStatementHasNotFindingOfType(final AbstractStatement statement, final String findingType) {
727         assertHasNotFindingOfType(statement.getFindings(), findingType);
728     }
729
730     public void assertDomElementHasFindingOfType(final YangDomElement domElement, final String findingType) {
731         final Set<Finding> filtered = context.getFindingsManager().getAllFindings().stream().filter(finding -> domElement
732                 .getYangModel() == finding.getYangModel() && domElement.getLineNumber() == finding.getLineNumber()).collect(
733                         Collectors.toSet());
734
735         assertHasFindingOfType(filtered, findingType);
736     }
737
738     public void assertDomElementHasNotFindingOfType(final YangDomElement domElement, final String findingType) {
739         final Set<Finding> filtered = context.getFindingsManager().getAllFindings().stream().filter(finding -> domElement
740                 .getYangModel() == finding.getYangModel() && domElement.getLineNumber() == finding.getLineNumber()).collect(
741                         Collectors.toSet());
742
743         assertHasNotFindingOfType(filtered, findingType);
744     }
745
746     public void assertDomElementHasNoFindings(final YangDomElement domElement) {
747         Set<Finding> filtered = context.getFindingsManager().getAllFindings().stream().filter(finding -> domElement
748                 .getYangModel() == finding.getYangModel() && domElement.getLineNumber() == finding.getLineNumber()).collect(
749                         Collectors.toSet());
750
751         assertNoFindings(filtered);
752     }
753
754     public void assertHasFindingOfTypeAndContainsMessage(final String findingType, final String message) {
755
756         final Optional<Finding> findAny = context.getFindingsManager().getAllFindings().stream().filter(finding -> finding
757                 .getFindingType().equals(findingType)).filter(finding -> finding.getMessage().contains(message)).findAny();
758
759         if (!findAny.isPresent()) {
760             System.err.println("Does not have finding of type " + findingType + " containing message " + message);
761             printFindings(context.getFindingsManager().getAllFindings());
762             fail();
763         }
764     }
765
766     public void assertHasFindingOfType(final Set<Finding> findings, final String findingType) {
767         if (hasFindingOfType(findings, findingType)) {
768             return;
769         }
770
771         System.err.println("Does not have finding of type " + findingType);
772         printFindings(findings);
773         fail();
774     }
775
776     public void assertHasNotFindingOfType(final Set<Finding> findings, final String findingType) {
777
778         if (!hasFindingOfType(findings, findingType)) {
779             return;
780         }
781
782         System.err.println("Has finding of type " + findingType);
783         printFindings(findings);
784         fail();
785     }
786
787     public void assertContextHasFindingOfType(final String findingType) {
788         assertTrue(contextHasFindingsOfTypes(Collections.singletonList(findingType)));
789     }
790
791     public void assertContextHasFindingsOfTypes(final List<String> findingTypes) {
792         assertTrue(contextHasFindingsOfTypes(findingTypes));
793     }
794
795     public void assertStatementHasFindingsOfTypes(final AbstractStatement statement, final List<String> findingTypes) {
796         assertTrue(statementHasFindingsOfTypes(statement, findingTypes));
797     }
798
799     public void assertHasFindingsOfTypes(final Set<Finding> findings, final List<String> findingTypes) {
800         assertTrue(hasFindingsOfTypes(findings, findingTypes));
801     }
802
803     public boolean contextHasFindingOfType(final String findingType) {
804         return hasFindingOfType(context.getFindingsManager().getAllFindings(), findingType);
805     }
806
807     public boolean statementHasFindingOfType(final AbstractStatement statement, final String findingType) {
808         return hasFindingOfType(statement.getFindings(), findingType);
809
810     }
811
812     public boolean hasFindingOfType(final Set<Finding> findings, final String findingType) {
813         for (final Finding finding : findings) {
814             if (finding.getFindingType().equals(findingType)) {
815                 return true;
816             }
817         }
818         return false;
819     }
820
821     public boolean contextHasFindingsOfTypes(final List<String> findingTypes) {
822         return hasFindingsOfTypes(context.getFindingsManager().getAllFindings(), findingTypes);
823     }
824
825     public boolean statementHasFindingsOfTypes(final AbstractStatement statement, final List<String> findingTypes) {
826         return hasFindingsOfTypes(statement.getFindings(), findingTypes);
827
828     }
829
830     public boolean hasFindingsOfTypes(final Set<Finding> findings, final List<String> findingTypes) {
831
832         for (final String findingType : findingTypes) {
833             if (!hasFindingOfType(findings, findingType)) {
834                 return false;
835             }
836         }
837         return true;
838     }
839
840     public void printFindings() {
841         printFindings(findingsManager.getAllFindings());
842     }
843
844     public void printFindingsForStatement(final AbstractStatement statement) {
845         printFindings(statement.getFindings());
846     }
847
848     public void printFindings(final Set<Finding> findings) {
849
850         final List<String> collect = findings.stream().map(Finding::toString).collect(Collectors.toList());
851         Collections.sort(collect);
852         collect.forEach(System.err::println);
853     }
854
855     // ================================== JSON stuff =======================================
856
857     protected static JsonValue getJsonObjectMemberValue(final JsonObject jsonObject, final String memberName) {
858
859         final Set<Entry<JsonObjectMemberName, JsonValue>> entrySet = jsonObject.getValuesByMember().entrySet();
860         for (final Entry<JsonObjectMemberName, JsonValue> entry : entrySet) {
861
862             if (memberName.equals(entry.getKey().getMemberName())) {
863                 return entry.getValue();
864             }
865         }
866
867         return null;
868     }
869
870 }