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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
21 package org.oran.smo.yangtools.parser.test;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.assertFalse;
26 import java.io.ByteArrayOutputStream;
28 import java.io.FileInputStream;
29 import java.io.IOException;
30 import java.io.OutputStream;
31 import java.util.Arrays;
32 import java.util.List;
34 import org.junit.Test;
36 import org.oran.smo.yangtools.parser.findings.ParserFindingType;
37 import org.oran.smo.yangtools.parser.model.YangModel;
38 import org.oran.smo.yangtools.parser.model.statements.yang.CY;
39 import org.oran.smo.yangtools.parser.model.statements.yang.YAction;
40 import org.oran.smo.yangtools.parser.model.statements.yang.YContainer;
41 import org.oran.smo.yangtools.parser.model.statements.yang.YLeaf;
42 import org.oran.smo.yangtools.parser.model.statements.yang.YModule;
43 import org.oran.smo.yangtools.parser.model.yangdom.OriginalFileNameOutputFileNameResolver;
44 import org.oran.smo.yangtools.parser.model.yangdom.OutputFileNameResolver;
45 import org.oran.smo.yangtools.parser.model.yangdom.OutputStreamResolver;
46 import org.oran.smo.yangtools.parser.testutils.YangTestCommon;
48 public class YangDomWriteOutTest extends YangTestCommon {
50 private static final String OUT_DIR = "target/test-output/out-files";
53 public void testSimpleWriteOut() throws IOException {
55 parseAbsoluteImplementsYangModels(Arrays.asList("src/test/resources/basics/yangdom-write-out-test/module1.yang"));
57 final YModule module = getModule("module1");
58 assertTrue(module != null);
60 // write out with default resolver
62 createCleanTargetDir();
63 yangDeviceModel.getTopLevelSchema().writeOut(new File(OUT_DIR));
65 assertTrue(new File(OUT_DIR, "module1-2020-09-30.yang").exists());
67 // write out with file-name resolver
69 createCleanTargetDir();
70 yangDeviceModel.getTopLevelSchema().writeOut(new File(OUT_DIR), new OriginalFileNameOutputFileNameResolver());
72 assertTrue(new File(OUT_DIR, "module1.yang").exists());
74 // write out with custom resolver
76 yangDeviceModel.getTopLevelSchema().writeOut(new File(OUT_DIR), new OutputFileNameResolver() {
78 public String getOutputFileNameForYangInput(YangModel yangModelInput) {
79 return "out-module.yang";
83 assertTrue(new File(OUT_DIR, "out-module.yang").exists());
85 // read back in the module and make sure content is correct.
88 parseAbsoluteImplementsYangModels(Arrays.asList(new File(OUT_DIR, "out-module.yang").getAbsolutePath()));
90 final YModule module1 = getModule("module1");
91 assertTrue(module1 != null);
93 assertTrue(module1.getNamespace().getNamespace().equals("test:module1"));
94 assertTrue(module1.getRevisions().get(0).getValue().equals("2020-09-30"));
96 final YContainer cont1 = getContainer(module1, "cont1");
97 assertTrue(cont1 != null);
99 final YAction action11 = getChild(cont1, CY.ACTION, "action11");
100 assertTrue(action11 != null);
102 final YContainer cont112 = action11.getInput().getContainers().get(0);
103 assertTrue(cont112 != null);
107 public void testSimpleStreamOut() throws IOException {
109 parseAbsoluteImplementsYangModels(Arrays.asList("src/test/resources/basics/yangdom-write-out-test/module1.yang"));
111 final YModule module = getModule("module1");
112 assertTrue(module != null);
114 // write out to stream
116 final ByteArrayOutputStream os = new ByteArrayOutputStream();
117 final OutputStreamResolver resolver = new OutputStreamResolver() {
119 public OutputStream getOutputStreamForYangInput(YangModel yangModelInput) {
124 yangDeviceModel.getTopLevelSchema().writeOut(resolver);
126 final byte[] streamResult = os.toByteArray();
127 assertTrue(streamResult.length > 0);
129 // write out the module to file
131 createCleanTargetDir();
132 yangDeviceModel.getTopLevelSchema().writeOut(new File(OUT_DIR), new OriginalFileNameOutputFileNameResolver());
134 assertTrue(new File(OUT_DIR, "module1.yang").exists());
136 // contents of file and byte[] must match exactly
138 final FileInputStream fis = new FileInputStream(new File(OUT_DIR, "module1.yang"));
139 final ByteArrayOutputStream fileBuffer = new ByteArrayOutputStream();
142 byte[] data = new byte[100000];
144 while ((nRead = fis.read(data, 0, data.length)) != -1) {
145 fileBuffer.write(data, 0, nRead);
148 final byte[] fileContents = fileBuffer.toByteArray();
150 assertTrue(streamResult.length == fileContents.length);
154 public void testWriteOutToFileChangedOnly() throws IOException {
156 parseAbsoluteImplementsYangModels(Arrays.asList("src/test/resources/basics/yangdom-write-out-test/module1.yang"));
158 final YModule module = getModule("module1");
159 assertTrue(module != null);
161 final YContainer cont1 = module.getContainers().get(0);
162 cont1.getYangModelRoot().getDomDocumentRoot().setDomHasBeenModified();
164 createCleanTargetDir();
165 final List<YangModel> writeOutChanged = yangDeviceModel.getTopLevelSchema().writeOutChanged(new File(OUT_DIR),
166 new OriginalFileNameOutputFileNameResolver());
168 assertTrue(new File(OUT_DIR, "module1.yang").exists());
169 assertTrue(writeOutChanged.size() == 1);
173 public void testWriteOutToStreamChangedOnly() throws IOException {
175 parseAbsoluteImplementsYangModels(Arrays.asList("src/test/resources/basics/yangdom-write-out-test/module1.yang"));
177 final YModule module = getModule("module1");
178 assertTrue(module != null);
180 final YContainer cont1 = module.getContainers().get(0);
181 cont1.getYangModelRoot().getDomDocumentRoot().setDomHasBeenModified();
183 // write out to stream
185 final ByteArrayOutputStream os = new ByteArrayOutputStream();
186 final OutputStreamResolver resolver = new OutputStreamResolver() {
188 public OutputStream getOutputStreamForYangInput(YangModel yangModelInput) {
193 final List<YangModel> writeOutChanged = yangDeviceModel.getTopLevelSchema().writeOutChanged(resolver);
194 assertTrue(writeOutChanged.size() == 1);
196 final byte[] streamResult = os.toByteArray();
197 assertTrue(streamResult.length > 0);
201 public void testWriteOutChangedOnlyButModuleNotChanged() throws IOException {
203 parseAbsoluteImplementsYangModels(Arrays.asList("src/test/resources/basics/yangdom-write-out-test/module1.yang"));
205 final YModule module = getModule("module1");
206 assertTrue(module != null);
208 // Don't mark as modified, should not be written out.
210 // final YContainer cont1 = module.getContainers().get(0);
211 // cont1.getYangModelRoot().getDomDocumentRoot().setDomHasBeenModified();
213 createCleanTargetDir();
214 final List<YangModel> writeOutChanged = yangDeviceModel.getTopLevelSchema().writeOutChanged(new File(OUT_DIR),
215 new OriginalFileNameOutputFileNameResolver());
217 assertFalse(new File(OUT_DIR, "module1.yang").exists());
218 assertTrue(writeOutChanged.size() == 0);
222 public void testWeirdStringsAndCharactersWriteOut() throws IOException {
224 parseAbsoluteImplementsYangModels(Arrays.asList("src/test/resources/basics/yangdom-write-out-test/module1.yang"));
225 assertHasFindingOfType(ParserFindingType.P011_INVALID_CHARACTER_ESCAPING_IN_QUOTED_TEXT.toString());
226 assertHasFindingOfType(ParserFindingType.P101_EMPTY_DOCUMENTATION_VALUE.toString());
228 final YModule module = getModule("module1");
229 assertTrue(module != null);
231 checkDescriptions(module);
233 // write out with file-name resolver
235 createCleanTargetDir();
236 yangDeviceModel.getTopLevelSchema().writeOut(new File(OUT_DIR), new OriginalFileNameOutputFileNameResolver());
238 assertTrue(new File(OUT_DIR, "module1.yang").exists());
240 // read back in the module and make sure content is correct.
243 parseAbsoluteImplementsYangModels(Arrays.asList(new File(OUT_DIR, "module1.yang").getAbsolutePath()));
246 * The writing-out of the strings should have cleaned up any illegal escaping, so we shouldn't see this again.
248 assertHasFindingOfType(ParserFindingType.P101_EMPTY_DOCUMENTATION_VALUE.toString());
250 final YModule module1 = getModule("module1");
251 assertTrue(module1 != null);
253 checkDescriptions(module1);
256 private void checkDescriptions(final YModule module) {
257 final YContainer cont2 = getContainer(module, "cont2");
258 assertTrue(cont2 != null);
260 final YLeaf leaf21 = getLeaf(cont2, "leaf21");
261 assertTrue(leaf21.getDescription().getValue().equals("simple string with space character"));
263 final YLeaf leaf22 = getLeaf(cont2, "leaf22");
264 assertTrue(leaf22.getDescription().getValue().equals("simple string\twith tab character"));
266 final YLeaf leaf23 = getLeaf(cont2, "leaf23");
267 assertTrue(leaf23.getDescription().getValue().equals("simple string with \" escaped quote character"));
269 final YLeaf leaf24 = getLeaf(cont2, "leaf24");
270 assertTrue(leaf24.getDescription().getValue().equals("simple string with \\' escaped single-quote character"));
272 final YLeaf leaf25 = getLeaf(cont2, "leaf25");
273 assertTrue(leaf25.getDescription().getValue().equals("exact characters\ttab and quote \""));
275 final YLeaf leaf26 = getLeaf(cont2, "leaf26");
276 assertTrue(leaf26.getDescription().getValue().equals(
277 "exact characters stretching over\n multiple lines - note three spaces at start of line"));
279 final YLeaf leaf27 = getLeaf(cont2, "leaf27");
280 assertTrue(leaf27.getDescription().getValue().equals("+"));
282 final YLeaf leaf28 = getLeaf(cont2, "leaf28");
283 assertTrue(leaf28.getDescription().getValue().equals(";"));
285 final YLeaf leaf29 = getLeaf(cont2, "leaf29");
286 assertTrue(leaf29.getDescription().getValue().equals(";;"));
288 final YLeaf leaf30 = getLeaf(cont2, "leaf30");
289 assertTrue(leaf30.getDescription().getValue().equals("Hello+World!"));
291 final YLeaf leaf31 = getLeaf(cont2, "leaf31");
292 assertTrue(leaf31.getDescription().getValue().equals("on next line"));
294 final YLeaf leaf32 = getLeaf(cont2, "leaf32");
295 assertTrue(leaf32.getDescription().getValue().equals("some on this line some on the next line"));
297 final YLeaf leaf33 = getLeaf(cont2, "leaf33");
298 assertTrue(leaf33.getDescription().getValue().equals("First paragraph. \nSecond paragraph."));
300 final YLeaf leaf34 = getLeaf(cont2, "leaf34");
301 assertTrue(leaf34.getDescription().getValue().equals("this_is_//_not_a_comment"));
303 final YLeaf leaf35 = getLeaf(cont2, "leaf35");
304 assertTrue(leaf35.getDescription().getValue().equals("this_is_/*_not_a_comment"));
306 final YLeaf leaf36 = getLeaf(cont2, "leaf36");
307 assertTrue(leaf36.getDescription().getValue().equals("this_is_*/_not_a_comment"));
309 final YLeaf leaf37 = getLeaf(cont2, "leaf37");
310 assertTrue(leaf37.getDescription().getValue().equals(""));
312 final YLeaf leaf38 = getLeaf(cont2, "leaf38");
313 assertTrue(leaf38.getDescription().getValue().equals("{"));
315 final YLeaf leaf39 = getLeaf(cont2, "leaf39");
316 assertTrue(leaf39.getDescription().getValue().equals("}"));
318 final YLeaf leaf40 = getLeaf(cont2, "leaf40");
319 assertTrue(leaf40.getDescription().getValue().equals("\""));
322 private void createCleanTargetDir() {
324 final File dir = new File(OUT_DIR);
330 final File[] listFiles = dir.listFiles();
331 for (final File file : listFiles) {