Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/share/options/package-info.java
41155 views
/*1* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/222324/**25* This framework allows one to automate parsing of the test command line26* arguments (it automatically sets the corresponding fields of the27* test class).28<p>29<h3>A simplified example</h3>30Suppose we want to to define a test Test with an option "iterations",31which can be run via32</p>33<pre> > java Test -iterations 10 </pre>34or via35<pre> java Test </pre>36in the last case iterations defaults to 100.37<p>38We want to achieve this by annotating fields of the Test class by39a special @Option annotation.40<p>41For simplicity suppose @Option is defined as follows:42<pre>43@interface Option44{ //here all the annotation fields are mandatory45String name();46String default();47String description();48}49</pre>50The test class uses an API like:51<pre>52public class OptionSupport {53public static void setup(Object test, String[] args);54}55</pre>56Now a simple example:57<pre>58public class Test {5960@Option( name="iterations",61default="100",62description="Number of iterations")63int iterations;64public void run() {65// ..do actual testing here..66}6768public static void main(String args) {69Test test = new Test();70OptionsSupport.setup(test, args); // instead of manually71// parsing arguments72// now test.iterations is set to 10 or 100.73test.run();74}75}76</pre>77This test can be also run via78<pre>79- java Test -help80</pre>81Then OptionSupport.setup() shows82help and exits (by throwing exception?):83<pre>84Supported options:85-iterations <number>86Number of iterations (mandatory)87</pre>88We also want to be able to apply this to fields of non-simple types (via89factories) and to other classes recursively (see @Options annotation90below).91<p>92Please, see {@link vm.share.options.test.SimpleExample}93for a working version of this.94* <h3> General description </h3>95Options are defined using annotations like this:96<pre>97public class StressOptions {98// [2]99@Option(name="stressTime",100default_value="30",101description="Stress time")102private long stressTime;103104...105}106</pre>107<p> we want to use command line like108<pre> java Test -stressTime 50 </pre>109here 50 is passed to the StressOptions.stressTime field.110see {@link vm.share.options.Options} below. </p>111<pre>112public class Test {113// [1]114@Options115StressOptions stressOptions = new StressOptions();116117// [2]118@Option(name="iterations",119default_value="100",120description="Number of iterations")121int iterations;122123// [3]124@Option(125name="garbageProducer",126default="byteArr",127description="Garbage producer",128factory="nsk.share.gc.gp.GarbageProducerFactory")129GarbageProducer garbageProducer;130...131132// [4]133@Option(name="logger",134description="Logger",135factory="nsk.share.log.LogFactory")136Log log;137138public void run() {139log.info("Start test");140log.info("Finish test");141}142143public static void main(String[] args) {144Test test = new Test();145OptionsSupport.setup(test, args);146test.run();147}148}149</pre>150<p> The API is invoked via a call to {@link vm.share.options.OptionSupport#setup(Object, String[])}).151Also there is {@link vm.share.options.OptionSupport#setup(Object, String[], OptionHandler)}) method.152It allows the caller to pass a handler which takes153care of the options not defined via @Option annotation.154</p>155156<h3>Requirements</h3>157<p>158- The following field types are supported out-of-box: [2]159<ul>160<li/>All basic (primitive) types (int, long, ...) and corresponding wrapper types.161<li/> In the case of a boolean type option user is allowed to skip second argument,162i.e. write '-option_name'163instead of '-option_name true'.164<li/> Strings.165<li/> One dimentional arrays of the above (comma-separated).166<li/> Classes if a factory is specified, see below.167<emph>NOTE: currently there is no way to pass some options to the instantiated objects.</emph>168</ul>169</p>170<p> All non-static fields (including private and protected) of class and171it's superclasses are scanned for annotations.172</p>173<p>174(Possibly) Same annotations for setter methods ? (NOT IMPLEMENTED)175</p>176<p>177It is possible to inherit options of the field type178through @Options annotations, see {@link vm.share.options.Options}, and [1] above.179</p>180<p>181Option.name defaults to the name of the field.182</p>183<p> Object options are supported using {@link vm.share.options.OptionObjectFactory}, see [3] above.184Please see {@link vm.share.options.OptionObjectFactory} interface, it should be185implemented by the user and specified in the Option.factory attribute.186</p>187<p>188As a shortcut we provide BasicOptionObjectFactory class, which allows user to189create a factory via @{@link vm.share.options.Factory} annotation:190<pre>191@Factory (192placeholder_text="garbage producer", //used for generating <..> in the help message193default_value="byteArr",194classlist={195@FClass(key="byteArr",196type="nsk.share.gc.gp.array.ByteArrayProducer",197description="byte array producer")198@FClass(key="charArr",199type="nsk.share.gc.gp.array.CharArrayProducer",200description="char array producer")201...202}203)204public class GarbageProducerFactory extends BasicOptionObjectFactory {205}206</pre>207<p> <emph> note: for subclasses of BasicOptionObjectFactory208factories can extend each other!!209so the check for @OptionObjectFactory is done recursively.210NOT SURE IF THIS IS IMPLEMENTED.211</emph></p>212<p> If there is no unknownOptionHandler then in case of unsupported213option, a Runtime exception is thrown.214</p>215<p>216If there is no 'default' annotation attribute and there is no default217for OptionObjectFactory, then option is mandatory and a Runtime exception is thrown if218it's missing.219</p>220<p> Both '-option value' and '-option=value' formats are supported.221</p>222<p> If main class is given '-help', OptionSupport.setup() shows223help and exits (by throwing a Runtime exception):224<pre>225Supported options:226-iterations <number>227Number of iterations (mandatory)228-stressTime <number>229Stress time (default 30)230-garbageProducer <garbage producer>231Garbage producer (default byteArr). Supported keys:232byteArr byte array producer233charArr char array producer234...235...236</pre>237238<p> <emph> NOT IMPLEMENTED: </emph>239Integer type boundaries are validated with RuntimeException with detailed240meaningful error message. Other validations that are possible are also done.241</p>242<p> <emph> NOT IMPLEMENTED: </emph>243Empty default ("") value for Object annotations [3] means null value.244</p>245<p> The object created via factory is also scanned for @Option annotations246(like in the @Options case), i.e. it inherits options from the Test class.247<emph> This is not implemented as it causes several problems, in particular, the248object must be instanciated in order to be scanned for options, hence no meaningful249help message could be generated for corresponding options.250One of the possible solutions251is to allow -object_opt_name.suboption syntax (or even with a colon), and to pass the252corresponding suboptions Map to the OptionObjectFactory, it could use OptionFramework253to take care of it. It is unclear, what other problems can arise.</emph>254</p>255*256*/257package vm.share.options;258259260