94840bb0f75891cdeca9cdae7b5ef33026708a49
[yangtools.git] / yang / yang-system-test / src / main / java / org / opendaylight / yangtools / yang / parser / system / test / Main.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.parser.system.test;
9
10 import com.google.common.base.Stopwatch;
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Collection;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.logging.Level;
17 import java.util.logging.Logger;
18 import org.apache.commons.cli.BasicParser;
19 import org.apache.commons.cli.CommandLine;
20 import org.apache.commons.cli.CommandLineParser;
21 import org.apache.commons.cli.HelpFormatter;
22 import org.apache.commons.cli.Option;
23 import org.apache.commons.cli.Options;
24 import org.apache.commons.cli.ParseException;
25 import org.apache.log4j.BasicConfigurator;
26 import org.opendaylight.yangtools.yang.common.QName;
27 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
28
29 /**
30  * Main class of Yang parser system test.
31  *
32  * yang-system-test [-f features] [-h help] [-p path] [-v verbose] yangFiles...
33  *  -f,--features <arg>   features is a string in the form
34  *                        [feature(,feature)*] and feature is a string in the form
35  *                        [($namespace?revision=$revision)$local_name].
36  *                        This option is used to prune the data model by removing
37  *                        all nodes that are defined with a "if-feature".
38  *  -h,--help             print help message and exit.
39  *  -p,--path <arg>       path is a colon (:) separated list of directories
40  *                        to search for yang modules.
41  *  -v,--verbose          shows details about the results of test running.
42  *
43  */
44 public class Main {
45     private static final Logger LOG = Logger.getLogger(Main.class.getName());
46     private static final int MB = 1024 * 1024;
47
48     private static Options createOptions() {
49         final Options options = new Options();
50
51         final Option help = new Option("h", "help", false, "print help message and exit.");
52         help.setRequired(false);
53         options.addOption(help);
54
55         final Option path = new Option("p", "path", true,
56                 "path is a colon (:) separated list of directories to search for yang modules.");
57         path.setRequired(false);
58         options.addOption(path);
59
60         final Option verbose = new Option("v", "verbose", false, "shows details about the results of test running.");
61         verbose.setRequired(false);
62         options.addOption(verbose);
63
64         final Option feature = new Option(
65                 "f",
66                 "features",
67                 true,
68                 "features is a string in the form [feature(,feature)*] and feature is a string in the form "
69                         + "[($namespace?revision=$revision)$local_name]. This option is used to prune the data model by removing "
70                         + "all nodes that are defined with a \"if-feature\".");
71         feature.setRequired(false);
72         options.addOption(feature);
73         return options;
74     }
75
76     public static void main(final String[] args) {
77
78         BasicConfigurator.configure();
79
80         final HelpFormatter formatter = new HelpFormatter();
81         final Options options = createOptions();
82         final CommandLine arguments = parseArguments(args, options, formatter);
83
84         if (arguments.hasOption("help")) {
85             printHelp(options, formatter);
86             return;
87         }
88
89         if (arguments.hasOption("verbose")) {
90             LOG.setLevel(Level.CONFIG);
91         } else {
92             LOG.setLevel(Level.SEVERE);
93         }
94
95         final List<String> yangLibDirs = initYangDirsPath(arguments);
96         final List<String> yangFiles = Arrays.asList(arguments.getArgs());
97         final HashSet<QName> supportedFeatures = initSupportedFeatures(arguments);
98
99         runSystemTest(yangLibDirs, yangFiles, supportedFeatures);
100     }
101
102     private static void runSystemTest(final List<String> yangLibDirs, final List<String> yangFiles,
103             final HashSet<QName> supportedFeatures) {
104         LOG.log(Level.INFO, "Yang model dirs: {0} ", yangLibDirs);
105         LOG.log(Level.INFO, "Yang model files: {0} ", yangFiles);
106         LOG.log(Level.INFO, "Supported features: {0} ", supportedFeatures);
107
108         SchemaContext context = null;
109
110         printMemoryInfo("start");
111         final Stopwatch stopWatch = Stopwatch.createStarted();
112
113         try {
114             context = SystemTestUtils.parseYangSources(yangLibDirs, yangFiles, supportedFeatures);
115         } catch (final Exception e) {
116             LOG.log(Level.SEVERE, "Failed to create SchemaContext.", e);
117             System.exit(1);
118         }
119
120         stopWatch.stop();
121         LOG.log(Level.INFO, "Elapsed time: {0}", stopWatch);
122         printMemoryInfo("end");
123         LOG.log(Level.INFO, "SchemaContext resolved Successfully. {0}", context);
124         Runtime.getRuntime().gc();
125         printMemoryInfo("after gc");
126     }
127
128     private static List<String> initYangDirsPath(final CommandLine arguments) {
129         final List<String> yangDirs = new ArrayList<>();
130         if (arguments.hasOption("path")) {
131             for (final String pathArg : arguments.getOptionValues("path")) {
132                 yangDirs.addAll(Arrays.asList(pathArg.split(":")));
133             }
134         }
135         return yangDirs;
136     }
137
138     private static HashSet<QName> initSupportedFeatures(final CommandLine arguments) {
139         HashSet<QName> supportedFeatures = null;
140         if (arguments.hasOption("features")) {
141             supportedFeatures = new HashSet<>();
142             for (final String pathArg : arguments.getOptionValues("features")) {
143                 supportedFeatures.addAll(createQNames(pathArg.split(",")));
144             }
145         }
146         return supportedFeatures;
147     }
148
149     private static Collection<? extends QName> createQNames(final String[] featuresArg) {
150         final HashSet<QName> qnames = new HashSet<>();
151         for (final String featureStr : featuresArg) {
152             qnames.add(QName.create(featureStr));
153         }
154
155         return qnames;
156     }
157
158     private static CommandLine parseArguments(final String[] args, final Options options, final HelpFormatter formatter) {
159         final CommandLineParser parser = new BasicParser();
160
161         CommandLine cmd = null;
162         try {
163             cmd = parser.parse(options, args);
164         } catch (final ParseException e) {
165             LOG.log(Level.SEVERE, "Failed to parse command line options.", e);
166             printHelp(options, formatter);
167
168             System.exit(1);
169         }
170
171         return cmd;
172     }
173
174     private static void printHelp(final Options options, final HelpFormatter formatter) {
175         formatter.printHelp("yang-system-test [-f features] [-h help] [-p path] [-v verbose] yangFiles...", options);
176     }
177
178     private static void printMemoryInfo(final String info) {
179         LOG.log(Level.INFO, "Memory INFO [{0}]: free {1}MB, used {2}MB, total {3}MB, max {4}MB", new Object[] { info,
180                 Runtime.getRuntime().freeMemory() / MB,
181                 (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / MB,
182                 Runtime.getRuntime().totalMemory() / MB, Runtime.getRuntime().maxMemory() / MB });
183     }
184 }