2 * Copyright (c) 2016 Cisco Systems, Inc. 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.yang.validator;
10 import ch.qos.logback.classic.Level;
11 import com.google.common.base.Stopwatch;
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.Collection;
15 import java.util.HashSet;
16 import java.util.List;
17 import org.apache.commons.cli.BasicParser;
18 import org.apache.commons.cli.CommandLine;
19 import org.apache.commons.cli.CommandLineParser;
20 import org.apache.commons.cli.HelpFormatter;
21 import org.apache.commons.cli.Option;
22 import org.apache.commons.cli.Options;
23 import org.apache.commons.cli.ParseException;
24 import org.opendaylight.yangtools.yang.common.QName;
25 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * Main class of Yang parser system test.
33 * yang-system-test [-f features] [-h help] [-p path] [-v verbose] yangFiles...
34 * -f,--features <arg> features is a string in the form
35 * [feature(,feature)*] and feature is a string in the form
36 * [($namespace?revision=$revision)$local_name].
37 * This option is used to prune the data model by removing
38 * all nodes that are defined with a "if-feature".
39 * -h,--help print help message and exit.
40 * -p,--path <arg> path is a colon (:) separated list of directories
41 * to search for yang modules.
42 * -r, --recursive recursive search of directories specified by -p option
43 * -v,--verbose shows details about the results of test running.
47 private static final Logger LOG = LoggerFactory.getLogger(Main.class);
48 private static final int MB = 1024 * 1024;
50 private static Options createOptions() {
51 final Options options = new Options();
53 final Option help = new Option("h", "help", false, "print help message and exit.");
54 help.setRequired(false);
55 options.addOption(help);
57 final Option path = new Option("p", "path", true,
58 "path is a colon (:) separated list of directories to search for yang modules.");
59 path.setRequired(false);
60 options.addOption(path);
62 final Option recursiveSearch = new Option("r", "recursive", false,
63 "recursive search of directories specified by -p option.");
64 recursiveSearch.setRequired(false);
65 options.addOption(recursiveSearch);
67 final Option verbose = new Option("v", "verbose", false, "shows details about the results of test running.");
68 verbose.setRequired(false);
69 options.addOption(verbose);
71 final Option feature = new Option(
75 "features is a string in the form [feature(,feature)*] and feature is a string in the form "
76 + "[($namespace?revision=$revision)$local_name]. This option is used to prune the data model "
77 + "by removing all nodes that are defined with a \"if-feature\".");
78 feature.setRequired(false);
79 options.addOption(feature);
83 public static void main(final String[] args) {
84 final HelpFormatter formatter = new HelpFormatter();
85 final Options options = createOptions();
86 final CommandLine arguments = parseArguments(args, options, formatter);
88 if (arguments.hasOption("help")) {
89 printHelp(options, formatter);
93 if (arguments.hasOption("verbose")) {
94 setLoggingLevel(Level.DEBUG);
96 setLoggingLevel(Level.ERROR);
99 final List<String> yangLibDirs = initYangDirsPath(arguments);
100 final List<String> yangFiles = Arrays.asList(arguments.getArgs());
101 final HashSet<QName> supportedFeatures = initSupportedFeatures(arguments);
103 runSystemTest(yangLibDirs, yangFiles, supportedFeatures, arguments.hasOption("recursive"));
106 private static void setLoggingLevel(final Level level) {
107 ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(
108 ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
109 root.setLevel(level);
112 @SuppressWarnings("checkstyle:illegalCatch")
113 private static void runSystemTest(final List<String> yangLibDirs, final List<String> yangFiles,
114 final HashSet<QName> supportedFeatures, final boolean recursiveSearch) {
115 LOG.info("Yang model dirs: {} ", yangLibDirs);
116 LOG.info("Yang model files: {} ", yangFiles);
117 LOG.info("Supported features: {} ", supportedFeatures);
119 SchemaContext context = null;
121 printMemoryInfo("start");
122 final Stopwatch stopWatch = Stopwatch.createStarted();
125 context = SystemTestUtils.parseYangSources(yangLibDirs, yangFiles, supportedFeatures, recursiveSearch);
126 } catch (final Exception e) {
127 LOG.error("Failed to create SchemaContext.", e);
132 LOG.info("Elapsed time: {}", stopWatch);
133 printMemoryInfo("end");
134 LOG.info("SchemaContext resolved Successfully. {}", context);
135 Runtime.getRuntime().gc();
136 printMemoryInfo("after gc");
139 private static List<String> initYangDirsPath(final CommandLine arguments) {
140 final List<String> yangDirs = new ArrayList<>();
141 if (arguments.hasOption("path")) {
142 for (final String pathArg : arguments.getOptionValues("path")) {
143 yangDirs.addAll(Arrays.asList(pathArg.split(":")));
149 private static HashSet<QName> initSupportedFeatures(final CommandLine arguments) {
150 HashSet<QName> supportedFeatures = null;
151 if (arguments.hasOption("features")) {
152 supportedFeatures = new HashSet<>();
153 for (final String pathArg : arguments.getOptionValues("features")) {
154 supportedFeatures.addAll(createQNames(pathArg.split(",")));
157 return supportedFeatures;
160 private static Collection<? extends QName> createQNames(final String[] featuresArg) {
161 final HashSet<QName> qnames = new HashSet<>();
162 for (final String featureStr : featuresArg) {
163 qnames.add(QName.create(featureStr));
169 private static CommandLine parseArguments(final String[] args, final Options options,
170 final HelpFormatter formatter) {
171 final CommandLineParser parser = new BasicParser();
173 CommandLine cmd = null;
175 cmd = parser.parse(options, args);
176 } catch (final ParseException e) {
177 LOG.error("Failed to parse command line options.", e);
178 printHelp(options, formatter);
186 private static void printHelp(final Options options, final HelpFormatter formatter) {
187 formatter.printHelp("yang-system-test [-f features] [-h help] [-p path] [-v verbose] yangFiles...", options);
190 private static void printMemoryInfo(final String info) {
191 LOG.info("Memory INFO [{}]: free {}MB, used {}MB, total {}MB, max {}MB", info,
192 Runtime.getRuntime().freeMemory() / MB,
193 (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / MB,
194 Runtime.getRuntime().totalMemory() / MB, Runtime.getRuntime().maxMemory() / MB);