2 * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.rfc8819.parser;
10 import static org.hamcrest.CoreMatchers.startsWith;
11 import static org.hamcrest.MatcherAssert.assertThat;
12 import static org.junit.jupiter.api.Assertions.assertEquals;
13 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
14 import static org.junit.jupiter.api.Assertions.assertThrows;
16 import java.io.IOException;
17 import java.util.List;
18 import java.util.stream.Collectors;
19 import org.junit.jupiter.api.AfterAll;
20 import org.junit.jupiter.api.BeforeAll;
21 import org.junit.jupiter.api.Test;
22 import org.opendaylight.yangtools.rfc8819.model.api.ModuleTagEffectiveStatement;
23 import org.opendaylight.yangtools.rfc8819.model.api.Tag;
24 import org.opendaylight.yangtools.yang.model.spi.source.YangTextSource;
25 import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
26 import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException;
27 import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors;
28 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSource;
29 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
30 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
31 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
32 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
34 public class ModuleTagTest {
35 private static CrossSourceStatementReactor reactor;
38 public static void createReactor() {
39 reactor = RFC7950Reactors.vanillaReactorBuilder()
40 .addStatementSupport(ModelProcessingPhase.FULL_DECLARATION,
41 new ModuleTagStatementSupport(YangParserConfiguration.DEFAULT))
46 public static void freeReactor() {
51 public void testModuleTagSupportExtension() throws ReactorException {
52 final var moduleTags = reactor.newBuild()
54 moduleFromResources("/example-tag-module.yang"),
55 moduleFromResources("/ietf-module-tags.yang"),
56 moduleFromResources("/ietf-yang-types.yang"),
57 moduleFromResources("/ietf-module-tags-state.yang"))
59 .getModuleStatements().values().stream()
60 .flatMap(module -> module.streamEffectiveSubstatements(ModuleTagEffectiveStatement.class))
61 .map(ModuleTagEffectiveStatement::argument)
62 .collect(Collectors.toList());
65 new Tag("ietf:tag-outside-cntr"),
66 new Tag("ietf:some-other-tag"),
67 new Tag("ietf:network-element-class"),
68 new Tag("vendor:some-other-tag"),
69 new Tag("user:some-other-tag"),
70 new Tag("different:some-other-tag"),
71 new Tag("somestring"),
72 new Tag("sometag:somestring")), moduleTags);
76 public void throwExceptionWhenTagParentIsNotModuleOrSubmodule() {
77 final var action = reactor.newBuild()
79 moduleFromResources("/foo-tag-module.yang"),
80 moduleFromResources("/ietf-module-tags.yang"),
81 moduleFromResources("/ietf-yang-types.yang"),
82 moduleFromResources("/ietf-module-tags-state.yang"));
84 final var cause = assertThrows(ReactorException.class, action::buildEffective).getCause();
85 assertInstanceOf(SourceException.class, cause);
86 assertThat(cause.getMessage(),
87 startsWith("Tags may only be defined at root of either a module or a submodule [at "));
90 private static YangStatementStreamSource moduleFromResources(final String resourceName) {
92 return YangStatementStreamSource.create(YangTextSource.forResource(ModuleTagTest.class, resourceName));
93 } catch (final YangSyntaxErrorException | IOException e) {
94 throw new IllegalStateException("Failed to find resource " + resourceName, e);