Main.java revision 2362:00cd9dc3c2b5
11541Srgrimes/*
21541Srgrimes * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
31541Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
41541Srgrimes *
551138Salfred * This code is free software; you can redistribute it and/or modify it
6181905Sed * under the terms of the GNU General Public License version 2 only, as
71541Srgrimes * published by the Free Software Foundation.
81541Srgrimes *
9106149Sdwmalone * This code is distributed in the hope that it will be useful, but WITHOUT
101541Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1164002Speter * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
121541Srgrimes * version 2 for more details (a copy is included in the LICENSE file that
131541Srgrimes * accompanied this code).
141541Srgrimes *
151541Srgrimes * You should have received a copy of the GNU General Public License version
161541Srgrimes * 2 along with this work; if not, write to the Free Software Foundation,
171541Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18171210Speter *
191541Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
201541Srgrimes * or visit www.oracle.com if you need additional information or have any
211541Srgrimes * questions.
221541Srgrimes */
231541Srgrimes
241541Srgrimes/*
251541Srgrimes *
261541Srgrimes */
271541Srgrimes
28171210Speterpackage bench.rmi;
29171210Speter
301541Srgrimesimport bench.ConfigFormatException;
311541Srgrimesimport bench.Harness;
321541Srgrimesimport bench.HtmlReporter;
331541Srgrimesimport bench.Reporter;
341541Srgrimesimport bench.TextReporter;
351541Srgrimesimport bench.XmlReporter;
361541Srgrimesimport java.io.FileInputStream;
371541Srgrimesimport java.io.FileOutputStream;
381541Srgrimesimport java.io.InputStream;
391541Srgrimesimport java.io.IOException;
401541Srgrimesimport java.io.OutputStream;
411541Srgrimesimport java.io.PrintStream;
421541Srgrimesimport java.rmi.RemoteException;
431541Srgrimesimport java.rmi.RMISecurityManager;
441541Srgrimesimport java.rmi.registry.LocateRegistry;
451541Srgrimesimport java.rmi.registry.Registry;
461541Srgrimesimport java.rmi.server.RemoteObject;
471541Srgrimesimport java.util.Timer;
48171210Speterimport java.util.TimerTask;
491541Srgrimes
50171210Speter/*
511541Srgrimes * RMI/Serialization benchmark tests.
521541Srgrimes */
531541Srgrimespublic class Main {
541541Srgrimes
551541Srgrimes    /**
56171210Speter     * RMI-specific benchmark harness.
571541Srgrimes     */
58171210Speter    static class RMIHarness extends Harness {
591541Srgrimes        /**
601541Srgrimes         * Construct new RMI benchmark harness.
611541Srgrimes         */
62171210Speter        RMIHarness(InputStream in) throws IOException, ConfigFormatException {
631541Srgrimes            super(in);
641541Srgrimes        }
651541Srgrimes
661541Srgrimes        /**
671541Srgrimes         * Cleanup both client and server side in between each benchmark.
681541Srgrimes         */
691541Srgrimes        protected void cleanup() {
701541Srgrimes            System.gc();
711541Srgrimes            if (Main.runmode == CLIENT) {
72171210Speter                try {
73171210Speter                    Main.server.gc();
74171210Speter                } catch (Exception e) {
751541Srgrimes                    System.err.println("Warning: server gc failed: " + e);
761541Srgrimes                }
771541Srgrimes            }
781541Srgrimes        }
791541Srgrimes    }
801541Srgrimes
81171210Speter    static final String CONFFILE = "/bench/rmi/config";
821541Srgrimes    static final String VERSION = "1.3";
831541Srgrimes    static final String REGNAME = "server";
841541Srgrimes
851541Srgrimes    static final int SAMEVM = 0;
861541Srgrimes    static final int CLIENT = 1;
871541Srgrimes    static final int SERVER = 2;
881541Srgrimes
891541Srgrimes    static final int TEXT = 0;
901541Srgrimes    static final int HTML = 1;
911541Srgrimes    static final int XML = 2;
921541Srgrimes
931541Srgrimes    static boolean verbose;
94171210Speter    static boolean list;
951541Srgrimes    static boolean exitOnTimer;
961541Srgrimes    static int testDurationSeconds;
97171210Speter    static volatile boolean exitRequested;
98171210Speter    static Timer timer;
991541Srgrimes    static int format = TEXT;
1001541Srgrimes    static int runmode;
1011541Srgrimes    static InputStream confstr;
1021541Srgrimes    static OutputStream repstr;
1031541Srgrimes    static String host;
1041541Srgrimes    static int port;
1051541Srgrimes    static RMIHarness harness;
1061541Srgrimes    static Reporter reporter;
1071541Srgrimes    static BenchServer server;
1081541Srgrimes    static BenchServerImpl serverImpl;
109171210Speter
1101541Srgrimes    /**
111171210Speter     * Returns reference to benchmark server.
112171210Speter     */
113171210Speter    public static BenchServer getBenchServer() {
1141541Srgrimes        return server;
1151541Srgrimes    }
1161541Srgrimes
1171541Srgrimes    /**
118171210Speter     * Prints help message.
119171210Speter     */
120171210Speter    static void usage() {
121171210Speter        PrintStream p = System.err;
122171210Speter        p.println("\nUsage: java -jar rmibench.jar [-options]");
123171210Speter        p.println("\nwhere options are:");
124171210Speter        p.println("  -h                   print this message");
1251541Srgrimes        p.println("  -v                   verbose mode");
1261541Srgrimes        p.println("  -l                   list configuration file");
1271541Srgrimes        p.println("  -t <num hours>       repeat benchmarks for specified number of hours");
1281541Srgrimes        p.println("  -o <file>            specify output file");
12914220Speter        p.println("  -c <file>            specify (non-default) " +
1301541Srgrimes                "configuration file");
1311541Srgrimes        p.println("  -html                format output as html " +
1321541Srgrimes                "(default is text)");
1331541Srgrimes        p.println("  -xml                 format output as xml");
1341541Srgrimes        p.println("  -client <host:port>  run benchmark client using server " +
135171210Speter                "on specified host/port");
1368019Sache        p.println("  -server <port>       run benchmark server on given port");
1378019Sache    }
1381541Srgrimes
139171210Speter    /**
140171210Speter     * Print error message and exit.
1411541Srgrimes     */
1421541Srgrimes    static void die(String mesg) {
1431541Srgrimes        System.err.println(mesg);
1441541Srgrimes        System.exit(1);
1451541Srgrimes    }
1461541Srgrimes
1471541Srgrimes    /**
1481541Srgrimes     * Stop server and exit.
1491541Srgrimes     */
1501541Srgrimes    public static void exit() {
151171210Speter        switch (runmode) {
152171210Speter            case CLIENT:
153171210Speter                if (server != null) {
154171210Speter                    try {
155171210Speter                        server.terminate(0);
156171210Speter                    } catch (RemoteException re) {
1571541Srgrimes                        // ignore
1581541Srgrimes                    }
159171210Speter                }
160171210Speter            default:
16114220Speter                System.exit(0);
16214220Speter        }
16314220Speter    }
164177634Sdfr
1651541Srgrimes    /**
166171210Speter     * Benchmark mainline.
167171210Speter     */
168171210Speter    public static void main(String[] args) {
1691541Srgrimes        setupSecurity();
170127891Sdfr        parseArgs(args);
1711541Srgrimes        setupStreams();
1721549Srgrimes        if (list) {
1731549Srgrimes            listConfig();
1741549Srgrimes        } else {
1751549Srgrimes            setupServer();
1762442Sdg            if (runmode != SERVER) {
1771541Srgrimes                setupHarness();
1781541Srgrimes                setupReporter();
1792729Sdfr                if (exitOnTimer) {
1802729Sdfr                    setupTimer(testDurationSeconds);
1811541Srgrimes                    while (true) {
1821541Srgrimes                        runBenchmarks();
183171210Speter                        if (exitRequested) {
184171210Speter                            exit();
185178888Sjulian                        }
1862297Swollman                    }
18714220Speter                } else {
18814220Speter                    runBenchmarks();
18914220Speter                    exit();
1901541Srgrimes                }
1911541Srgrimes            }
1921541Srgrimes        }
1931541Srgrimes    }
19432889Sphk
19532889Sphk    /**
19632889Sphk     * Parse command-line arguments.
19732889Sphk     */
1981541Srgrimes    static void parseArgs(String[] args) {
1991541Srgrimes        for (int i = 0; i < args.length; i++) {
2001541Srgrimes            if (args[i].equals("-h")) {
2011541Srgrimes                usage();
2021541Srgrimes                System.exit(0);
2031541Srgrimes            } else if (args[i].equals("-v")) {
2041541Srgrimes                verbose = true;
2051541Srgrimes            } else if (args[i].equals("-l")) {
2061541Srgrimes                list = true;
207171210Speter            } else if (args[i].equals("-t")) {
2081541Srgrimes                if (++i >= args.length)
209171210Speter                    die("Error: no timeout value specified");
210171210Speter                try {
211171210Speter                    exitOnTimer = true;
2121541Srgrimes                    testDurationSeconds = Integer.parseInt(args[i]) * 3600;
2131541Srgrimes                } catch (Exception e) {
2141541Srgrimes                    die("Error: unable to determine timeout value");
21535938Sdyson                }
21635938Sdyson            } else if (args[i].equals("-o")) {
21728400Speter                if (++i >= args.length)
21825582Speter                    die("Error: no output file specified");
21929349Speter                try {
2202124Sdg                    repstr = new FileOutputStream(args[i]);
2212124Sdg                } catch (IOException e) {
2222124Sdg                    die("Error: unable to open \"" + args[i] + "\"");
2232124Sdg                }
2242124Sdg            } else if (args[i].equals("-c")) {
2252124Sdg                if (++i >= args.length)
2262124Sdg                    die("Error: no config file specified");
2272124Sdg                try {
2282124Sdg                    confstr = new FileInputStream(args[i]);
2292124Sdg                } catch (IOException e) {
23012865Speter                    die("Error: unable to open \"" + args[i] + "\"");
23112865Speter                }
23212865Speter            } else if (args[i].equals("-html")) {
23359829Speter                if (format != TEXT)
23412865Speter                    die("Error: conflicting formats");
23512865Speter                format = HTML;
23612865Speter            } else if (args[i].equals("-xml")) {
23712865Speter                if (format != TEXT)
23812865Speter                    die("Error: conflicting formats");
23912865Speter                format = XML;
24012865Speter            } else if (args[i].equals("-client")) {
24112865Speter                if (runmode == CLIENT)
24225582Speter                    die("Error: multiple -client options");
24325582Speter                if (runmode == SERVER)
24425582Speter                    die("Error: -client and -server options conflict");
245156138Sdavidxu                if (++i >= args.length)
246156138Sdavidxu                    die("Error: -client missing host/port");
247156138Sdavidxu                try {
248156138Sdavidxu                    int sepi = args[i].indexOf(':');
249156138Sdavidxu                    host = args[i].substring(0, sepi);
25025582Speter                    port = Integer.parseInt(args[i].substring(sepi + 1));
25114220Speter                } catch (Exception e) {
25214220Speter                    die("Error: illegal host/port specified for -client");
25314220Speter                }
25414220Speter                runmode = CLIENT;
25514220Speter            } else if (args[i].equals("-server")) {
25614220Speter                if (runmode == CLIENT)
25714220Speter                    die("Error: -client and -server options conflict");
258137875Smarks                if (runmode == SERVER)
25914220Speter                    die("Error: multiple -server options");
26014220Speter                if (++i >= args.length)
26114220Speter                    die("Error: -server missing port");
26229349Speter                try {
26324452Speter                    port = Integer.parseInt(args[i]);
26424440Speter                } catch (Exception e) {
265151868Sdavidxu                    die("Error: illegal port specified for -server");
266151868Sdavidxu                }
267151868Sdavidxu                runmode = SERVER;
268152846Sdavidxu            } else {
269152846Sdavidxu                System.err.println("Illegal option: \"" + args[i] + "\"");
270152846Sdavidxu                usage();
271152846Sdavidxu                System.exit(1);
272152846Sdavidxu            }
273152846Sdavidxu        }
27425537Sdfr    }
27525537Sdfr
27625537Sdfr    /**
27725537Sdfr     * Set up security manager and policy, if not set already.
27825537Sdfr     */
27925537Sdfr    static void setupSecurity() {
28025537Sdfr        if (System.getSecurityManager() != null)
28125537Sdfr            return;
28235938Sdyson
28325537Sdfr        /* As of 1.4, it is too late to set the security policy
28435938Sdyson         * file at this point so these line have been commented out.
28535938Sdyson         */
28635938Sdyson        //System.setProperty("java.security.policy",
28735938Sdyson        //      Main.class.getResource("/bench/rmi/policy.all").toString());
28835938Sdyson        System.setSecurityManager(new RMISecurityManager());
28935938Sdyson    }
29035938Sdyson
29125537Sdfr    /**
29225537Sdfr     * Set up configuration file and report streams, if not set already.
29325537Sdfr     */
29425537Sdfr    static void setupStreams() {
29525537Sdfr        if (repstr == null)
29625537Sdfr            repstr = System.out;
29725537Sdfr        if (confstr == null)
29825537Sdfr            confstr = (new Main()).getClass().getResourceAsStream(CONFFILE);
299147814Sjhb        if (confstr == null)
300147814Sjhb            die("Error: unable to find default config file");
30125537Sdfr    }
30225537Sdfr
30325537Sdfr    /**
30425537Sdfr     * Print contents of configuration file to selected output stream.
30525537Sdfr     */
30625537Sdfr    static void listConfig() {
307171210Speter        try {
30851138Salfred            byte[] buf = new byte[256];
30951138Salfred            int len;
31025537Sdfr            while ((len = confstr.read(buf)) != -1)
31125537Sdfr                repstr.write(buf, 0, len);
31225537Sdfr        } catch (IOException e) {
31325537Sdfr            die("Error: failed to list config file");
31425537Sdfr        }
31525537Sdfr    }
31625537Sdfr
31725537Sdfr    /**
31825537Sdfr     * Setup benchmark server.
31925537Sdfr     */
32028400Speter    static void setupServer() {
32156115Speter        switch (runmode) {
32256115Speter            case SAMEVM:
32336034Speter                try {
32426671Sdyson                    serverImpl = new BenchServerImpl();
32526671Sdyson                    server = (BenchServer) RemoteObject.toStub(serverImpl);
32626671Sdyson                } catch (Exception e) {
32726671Sdyson                    die("Error: failed to create local server: " + e);
328151868Sdavidxu                }
329151868Sdavidxu                if (verbose)
330151868Sdavidxu                    System.out.println("Benchmark server created locally");
33126671Sdyson                break;
33269514Sjake
33369514Sjake            case CLIENT:
33426671Sdyson                try {
33526671Sdyson                    Registry reg = LocateRegistry.getRegistry(host, port);
33629391Sphk                    server = (BenchServer) reg.lookup(REGNAME);
33734925Sdufault                } catch (Exception e) {
33834925Sdufault                    die("Error: failed to connect to server: " + e);
33934925Sdufault                }
34034925Sdufault                if (server == null) {
34134925Sdufault                    die("Error: server not found");
34234925Sdufault                }
34334925Sdufault                if (verbose) {
34434925Sdufault                    System.out.println("Connected to benchmark server on " +
34535938Sdyson                            host + ":" + port);
346171210Speter                }
34741089Speter                break;
34846155Sphk
34949420Sjkh            case SERVER:
35051791Smarcel                try {
35151791Smarcel                    Registry reg = LocateRegistry.createRegistry(port);
352171210Speter                    serverImpl = new BenchServerImpl();
35351791Smarcel                    reg.bind(REGNAME, serverImpl);
354171210Speter                } catch (Exception e) {
355112895Sjeff                    die("Error: failed to initialize server: " + e);
356112895Sjeff                }
35756271Srwatson                if (verbose) {
35856271Srwatson                    System.out.println("Benchmark server started on port " +
35956271Srwatson                            port);
36056271Srwatson                }
36156271Srwatson                break;
36256271Srwatson
36356271Srwatson            default:
36456271Srwatson                throw new InternalError("illegal runmode");
36554803Srwatson        }
36654803Srwatson    }
36754803Srwatson
36854803Srwatson    /**
36955943Sjasone     * Set up the timer to end the test.
37056115Speter     *
37156115Speter     * @param delay the amount of delay, in seconds, before requesting
37259288Sjlemon     * the process exit
37359288Sjlemon     */
37498198Srwatson    static void setupTimer(int delay) {
37598198Srwatson        timer = new Timer(true);
37698198Srwatson        timer.schedule(
37798198Srwatson            new TimerTask() {
37898198Srwatson                public void run() {
37998198Srwatson                    exitRequested = true;
38069449Salfred                }
38175039Srwatson            },
38275039Srwatson            delay * 1000);
38375039Srwatson    }
38475427Srwatson
38583652Speter    /**
38683796Srwatson     * Set up benchmark harness.
38784884Srwatson     */
38885891Sphk    static void setupHarness() {
389177091Sjeff        try {
390177091Sjeff            harness = new RMIHarness(confstr);
391177091Sjeff        } catch (ConfigFormatException e) {
392177091Sjeff            String errmsg = e.getMessage();
393177091Sjeff            if (errmsg != null) {
394100897Srwatson                die("Error parsing config file: " + errmsg);
395100897Srwatson            } else {
396100897Srwatson                die("Error: illegal config file syntax");
397100897Srwatson            }
398100897Srwatson        } catch (IOException e) {
399100897Srwatson            die("Error: failed to read config file");
40094936Smux        }
40196084Smux    }
40297372Smarcel
40399856Salfred    /**
404101426Srwatson     * Setup benchmark reporter.
405122540Smckusick     */
406122540Smckusick    static void setupReporter() {
407122540Smckusick        String title = "RMI Benchmark, v" + VERSION;
408122540Smckusick        switch (format) {
409103575Salfred            case TEXT:
410103575Salfred                reporter = new TextReporter(repstr, title);
411103575Salfred                break;
412103575Salfred
413103575Salfred            case HTML:
414103575Salfred                reporter = new HtmlReporter(repstr, title);
415103575Salfred                break;
416103575Salfred
417103575Salfred            case XML:
418103575Salfred                reporter = new XmlReporter(repstr, title);
419105692Srwatson                break;
420105692Srwatson
421105692Srwatson            default:
422104731Srwatson                die("Error: unrecognized format type");
423104731Srwatson        }
424104731Srwatson    }
425106467Srwatson
426105950Speter    /**
427105950Speter     * Run benchmarks.
428105692Srwatson     */
429105692Srwatson    static void runBenchmarks() {
430105692Srwatson        harness.runBenchmarks(reporter, verbose);
431106978Sdeischen    }
432106978Sdeischen}
433106978Sdeischen