• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package com.google.caliper.runner;
16 
17 import com.google.caliper.bridge.LogMessage;
18 import com.google.caliper.bridge.LogMessageVisitor;
19 import com.google.caliper.bridge.OpenedSocket;
20 import com.google.caliper.config.CaliperConfig;
21 import com.google.caliper.config.InvalidConfigurationException;
22 import com.google.caliper.platform.Platform;
23 import com.google.caliper.platform.jvm.JvmPlatform;
24 import com.google.caliper.util.Util;
25 import com.google.common.annotations.VisibleForTesting;
26 import com.google.common.collect.ImmutableMap;
27 
28 import java.io.IOException;
29 import java.io.Serializable;
30 import java.net.InetAddress;
31 import java.net.Socket;
32 import java.util.Collections;
33 import java.util.List;
34 import java.util.concurrent.CountDownLatch;
35 
36 import javax.annotation.concurrent.GuardedBy;
37 
38 /**
39  * A collection of Simple java executables and a helper method for creating process builders for
40  * them.
41  */
42 final class FakeWorkers {
43 
44   @GuardedBy("FakeWorkers.class")
45   private static VirtualMachine jvm;
46 
47   /**
48    * Try to find the currently executing jvm binary, N.B. This isn't guaranteed to be cross
49    * platform.
50    */
init()51   private static synchronized VirtualMachine init() {
52     if (jvm == null) {
53       try {
54         Platform platform = new JvmPlatform();
55         jvm = new VirtualMachine("default",
56             new CaliperConfig(ImmutableMap.<String, String>of()).getDefaultVmConfig(platform));
57       } catch (InvalidConfigurationException e) {
58         throw new RuntimeException();
59       }
60     }
61     return jvm;
62   }
63 
64   /**
65    * Returns a ProcessBuilder that attempts to invoke the given class as main in a JVM configured
66    * with a classpath equivalent to the currently executing JVM.
67    */
createProcessBuilder(Class<?> mainClass, String ...mainArgs)68   static ProcessBuilder createProcessBuilder(Class<?> mainClass, String ...mainArgs) {
69     VirtualMachine jvm = init();
70     List<String> args;
71     try {
72       args = WorkerProcess.getJvmArgs(jvm, BenchmarkClass.forClass(mainClass));
73     } catch (InvalidBenchmarkException e) {
74       throw new RuntimeException(e);
75     }
76     args.add(mainClass.getName());
77     Collections.addAll(args, mainArgs);
78     return new ProcessBuilder().command(args);
79   }
80 
getVirtualMachine()81   public static VirtualMachine getVirtualMachine() {
82     return init();
83   }
84 
85   /**
86    * A simple main method that will sleep for the number of milliseconds specified in the first
87    * argument.
88    */
89   static final class Sleeper {
main(String[] args)90     public static void main(String[] args) throws NumberFormatException, InterruptedException {
91       Thread.sleep(Long.parseLong(args[0]));
92     }
93   }
94 
95   /**
96    * A simple main method that exits immediately with the code provided by the first argument
97    */
98   static final class Exit {
main(String[] args)99     public static void main(String[] args) {
100       System.exit(Integer.parseInt(args[0]));
101     }
102   }
103 
104   /**
105    * A simple main method that exits immediately with the code provided by the first argument
106    */
107   static final class CloseAndSleep {
main(String[] args)108     public static void main(String[] args) throws IOException, InterruptedException {
109       System.err.close();
110       System.in.close();
111       System.out.close();
112       new CountDownLatch(1).await();  // wait forever
113     }
114   }
115 
116   /**
117    * Prints alternating arguments to standard out and standard error.
118    */
119   static final class PrintClient {
main(String[] args)120     public static void main(String[] args)  {
121       for (int i = 0; i < args.length; i++) {
122         if (i % 2 == 0) {
123           System.out.println(args[i]);
124           System.out.flush();
125         } else {
126           System.err.println(args[i]);
127           System.err.flush();
128         }
129       }
130     }
131   }
132 
133   /**
134    * Prints alternating arguments to standard out and standard error.
135    */
136   @VisibleForTesting
137   static final class LoadBenchmarkClass {
138 
main(String[] args)139     public static void main(String[] args) throws ClassNotFoundException {
140         String benchmarkClassName = args[0];
141         Util.loadClass(benchmarkClassName);
142     }
143   }
144 
145   static final class DummyLogMessage extends LogMessage implements Serializable {
146     private final String content;
147 
DummyLogMessage(String content)148     DummyLogMessage(String content) {
149       this.content = content;
150     }
151 
accept(LogMessageVisitor visitor)152     @Override public void accept(LogMessageVisitor visitor) {}
153 
toString()154     @Override public String toString() {
155       return content;
156     }
157 
equals(Object obj)158     @Override public boolean equals(Object obj) {
159       return obj instanceof DummyLogMessage && ((DummyLogMessage) obj).content.equals(content);
160     }
161 
hashCode()162     @Override public int hashCode() {
163       return content.hashCode();
164     }
165   }
166 
167   /**
168    * Connects to a socket on localhost on the port provided as the first argument and echos all
169    * data.
170    *
171    * <p>Once the connection has been closed it prints the remaining args to stdout
172    */
173   static final class SocketEchoClient {
main(String[] args)174     public static void main(String[] args) throws Exception {
175       int port = Integer.parseInt(args[0]);
176       OpenedSocket openedSocket = OpenedSocket.fromSocket(
177           new Socket(InetAddress.getLocalHost(), port));
178       OpenedSocket.Reader reader = openedSocket.reader();
179       OpenedSocket.Writer writer = openedSocket.writer();
180       writer.write(new DummyLogMessage("start"));
181       writer.flush();
182       Serializable obj;
183       while ((obj = reader.read()) != null) {
184         writer.write(obj);
185         writer.flush();
186       }
187       writer.close();
188       reader.close();
189       for (int i = 1; i < args.length; i++) {
190         System.out.println(args[i]);
191         System.out.flush();
192       }
193     }
194   }
195 }
196