1/*
2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @summary The Serialization benchmark test. This java class is used to run the
27 *          test under JTREG.
28 * @library ../../
29 * @modules java.desktop
30 * @build bench.BenchInfo bench.HtmlReporter bench.Util bench.Benchmark
31 * @build bench.Reporter bench.XmlReporter bench.ConfigFormatException
32 * @build bench.Harness bench.TextReporter
33 * @build bench.serial.BooleanArrays bench.serial.Booleans
34 * @build bench.serial.ByteArrays bench.serial.Bytes bench.serial.CharArrays
35 * @build bench.serial.Chars bench.serial.ClassDesc bench.serial.Cons
36 * @build bench.serial.CustomDefaultObjTrees bench.serial.CustomObjTrees
37 * @build bench.serial.DoubleArrays bench.serial.Doubles
38 * @build bench.serial.ExternObjTrees bench.serial.FloatArrays
39 * @build bench.serial.Floats bench.serial.GetPutFieldTrees
40 * @build bench.serial.IntArrays bench.serial.Ints bench.serial.LongArrays
41 * @build bench.serial.Longs bench.serial.Main bench.serial.ObjArrays
42 * @build bench.serial.ObjTrees bench.serial.ProxyArrays
43 * @build bench.serial.ProxyClassDesc bench.serial.RepeatObjs
44 * @build bench.serial.ReplaceTrees bench.serial.ShortArrays
45 * @build bench.serial.Shorts bench.serial.SmallObjTrees
46 * @build bench.serial.StreamBuffer bench.serial.Strings
47 * @run main/othervm/timeout=1800 -Xss2m bench.serial.Main -c jtreg-config
48 * @author Mike Warres, Nigel Daley
49 */
50
51// The -Xss2m supplies additional stack space, as bench.serial.ClassDesc
52// consumes a considerable amount of stack.
53
54package bench.serial;
55
56import bench.ConfigFormatException;
57import bench.Harness;
58import bench.HtmlReporter;
59import bench.Reporter;
60import bench.TextReporter;
61import bench.XmlReporter;
62import java.io.File;
63import java.io.FileInputStream;
64import java.io.FileNotFoundException;
65import java.io.FileOutputStream;
66import java.io.InputStream;
67import java.io.IOException;
68import java.io.OutputStream;
69import java.io.PrintStream;
70import java.util.Timer;
71import java.util.TimerTask;
72
73/**
74 * Object serialization benchmark mainline.
75 */
76public class Main {
77
78    static final String CONFFILE = "config";
79    static final String VERSION = "1.3";
80    static final String TEST_SRC_PATH = System.getProperty("test.src") + File.separator;
81
82    static final int TEXT = 0;
83    static final int HTML = 1;
84    static final int XML = 2;
85
86    static boolean verbose;
87    static boolean list;
88    static boolean exitOnTimer;
89    static int testDurationSeconds;
90    static volatile boolean exitRequested;
91    static Timer timer;
92    static int format = TEXT;
93    static InputStream confstr;
94    static OutputStream repstr;
95    static Harness harness;
96    static Reporter reporter;
97
98    /**
99     * Print help message.
100     */
101    static void usage() {
102        PrintStream p = System.err;
103        p.println("\nUsage: java -jar serialbench.jar [-options]");
104        p.println("\nwhere options are:");
105        p.println("  -h              print this message");
106        p.println("  -v              verbose mode");
107        p.println("  -l              list configuration file");
108        p.println("  -t <num hours>  repeat benchmarks for specified number of hours");
109        p.println("  -o <file>       specify output file");
110        p.println("  -c <file>       specify (non-default) configuration file");
111        p.println("  -html           format output as html (default is text)");
112        p.println("  -xml            format output as xml");
113    }
114
115    /**
116     * Throw RuntimeException that wrap message.
117     *
118     * @param mesg a message will be wrapped in the RuntimeException.
119     */
120    static void die(String mesg) {
121        throw new RuntimeException(mesg);
122    }
123
124    /**
125     * Mainline parses command line, then hands off to benchmark harness.
126     *
127     * @param args
128     */
129    public static void main(String[] args) {
130        parseArgs(args);
131        setupStreams();
132        if (list) {
133            listConfig();
134        } else {
135            setupHarness();
136            setupReporter();
137            if (exitOnTimer) {
138                setupTimer(testDurationSeconds);
139                do {
140                    runBenchmarks();
141                } while (!exitRequested);
142            } else {
143                runBenchmarks();
144            }
145        }
146    }
147
148    /**
149     * Parse command-line arguments.
150     */
151    static void parseArgs(String[] args) {
152        for (int i = 0; i < args.length; i++) {
153            switch (args[i]) {
154                case "-h":
155                    usage();
156                    System.exit(0);
157                    break;
158                case "-v":
159                    verbose = true;
160                    break;
161                case "-l":
162                    list = true;
163                    break;
164                case "-t":
165                    if (++i >= args.length)
166                        die("Error: no timeout value specified");
167                    try {
168                        exitOnTimer = true;
169                        testDurationSeconds = Integer.parseInt(args[i]) * 3600;
170                    } catch (NumberFormatException e) {
171                        die("Error: unable to determine timeout value");
172                    }
173                    break;
174                case "-o":
175                    if (++i >= args.length)
176                        die("Error: no output file specified");
177                    try {
178                        repstr = new FileOutputStream(args[i]);
179                    } catch (FileNotFoundException e) {
180                        die("Error: unable to open \"" + args[i] + "\"");
181                    }
182                    break;
183                case "-c":
184                    if (++i >= args.length)
185                        die("Error: no config file specified");
186                    String confFileName = TEST_SRC_PATH + args[i];
187                    try {
188                        confstr = new FileInputStream(confFileName);
189                    } catch (FileNotFoundException e) {
190                        die("Error: unable to open \"" + confFileName + "\"");
191                    }
192                    break;
193                case "-html":
194                    if (format != TEXT)
195                        die("Error: conflicting formats");
196                    format = HTML;
197                    break;
198                case "-xml":
199                    if (format != TEXT)
200                        die("Error: conflicting formats");
201                    format = XML;
202                    break;
203                default:
204                    usage();
205                    die("Illegal option: \"" + args[i] + "\"");
206            }
207        }
208    }
209
210    /**
211     * Set up configuration file and report streams, if not set already.
212     */
213    static void setupStreams() {
214        if (repstr == null)
215            repstr = System.out;
216        if (confstr == null)
217            confstr = Main.class.getResourceAsStream(TEST_SRC_PATH + CONFFILE);
218        if (confstr == null)
219            die("Error: unable to find default config file");
220    }
221
222    /**
223     * Print contents of configuration file to selected output stream.
224     */
225    static void listConfig() {
226        try {
227            byte[] buf = new byte[256];
228            int len;
229            while ((len = confstr.read(buf)) != -1)
230                repstr.write(buf, 0, len);
231        } catch (IOException e) {
232            die("Error: failed to list config file");
233        }
234    }
235
236    /**
237     * Set up the timer to end the test.
238     *
239     * @param delay the amount of delay, in seconds, before requesting
240     * the process exit
241     */
242    static void setupTimer(int delay) {
243        timer = new Timer(true);
244        timer.schedule(
245            new TimerTask() {
246                @Override
247                public void run() {
248                    exitRequested = true;
249                }
250            },
251            delay * 1000);
252    }
253
254    /**
255     * Set up benchmark harness.
256     */
257    static void setupHarness() {
258        try {
259            harness = new Harness(confstr);
260        } catch (ConfigFormatException e) {
261            String errmsg = e.getMessage();
262            if (errmsg != null) {
263                die("Error parsing config file: " + errmsg);
264            } else {
265                die("Error: illegal config file syntax");
266            }
267        } catch (IOException e) {
268            die("Error: failed to read config file");
269        }
270    }
271
272    /**
273     * Setup benchmark reporter.
274     */
275    static void setupReporter() {
276        String title = "Object Serialization Benchmark, v" + VERSION;
277        switch (format) {
278            case TEXT:
279                reporter = new TextReporter(repstr, title);
280                break;
281
282            case HTML:
283                reporter = new HtmlReporter(repstr, title);
284                break;
285
286            case XML:
287                reporter = new XmlReporter(repstr, title);
288                break;
289
290            default:
291                die("Error: unrecognized format type");
292        }
293    }
294
295    /**
296     * Run benchmarks.
297     */
298    static void runBenchmarks() {
299        harness.runBenchmarks(reporter, verbose);
300    }
301}
302