21 * questions.
22 */
23
24 package compiler.compilercontrol.share.scenario;
25
26 import compiler.compilercontrol.share.actions.BaseAction;
27 import jdk.test.lib.Asserts;
28 import jdk.test.lib.OutputAnalyzer;
29 import jdk.test.lib.ProcessTools;
30 import jdk.test.lib.dcmd.CommandExecutor;
31 import jdk.test.lib.dcmd.PidJcmdExecutor;
32
33 import java.io.BufferedReader;
34 import java.io.IOException;
35 import java.io.InputStreamReader;
36 import java.io.PrintWriter;
37 import java.lang.reflect.Executable;
38 import java.net.ServerSocket;
39 import java.net.Socket;
40 import java.util.ArrayList;
41 import java.util.List;
42 import java.util.Map;
43
44 public class Executor {
45 private final boolean isValid;
46 private final List<String> vmOptions;
47 private final Map<Executable, State> states;
48 private final List<String> jcmdCommands;
49
50 /**
51 * Constructor
52 *
53 * @param isValid shows that the input given to the VM is valid and
54 * VM shouldn't fail
55 * @param vmOptions a list of VM input options
56 * @param states a state map, or null for the non-checking execution
57 * @param jcmdCommands a list of diagnostic commands to be preformed
58 * on test VM
59 */
60 public Executor(boolean isValid, List<String> vmOptions,
61 Map<Executable, State> states, List<String> jcmdCommands) {
62 this.isValid = isValid;
63 if (vmOptions == null) {
64 this.vmOptions = new ArrayList<>();
65 } else {
66 this.vmOptions = vmOptions;
67 }
68 this.states = states;
69 this.jcmdCommands = jcmdCommands;
70 }
71
72 /**
73 * Executes separate VM a gets an OutputAnalyzer instance with the results
74 * of execution
75 */
76 public OutputAnalyzer execute() {
77 // Add class name that would be executed in a separate VM
78 String classCmd = BaseAction.class.getName();
79 vmOptions.add(classCmd);
80 OutputAnalyzer output;
81 try (ServerSocket serverSocket = new ServerSocket(0)) {
82 if (isValid) {
83 // Get port test VM will connect to
84 int port = serverSocket.getLocalPort();
85 if (port == -1) {
86 throw new Error("Socket is not bound: " + port);
87 }
88 vmOptions.add(String.valueOf(port));
89 if (states != null) {
90 // add flag to show that there should be state map passed
91 vmOptions.add("states");
92 }
93 // Start separate thread to connect with test VM
94 new Thread(() -> connectTestVM(serverSocket)).start();
95 }
96 // Start test VM
97 output = ProcessTools.executeTestJvmAllArgs(
98 vmOptions.toArray(new String[vmOptions.size()]));
99 } catch (Throwable thr) {
100 throw new Error("Execution failed: " + thr.getMessage(), thr);
101 }
102 return output;
103 }
104
105 /*
106 * Performs connection with a test VM, sends method states and performs
107 * JCMD operations on a test VM.
108 */
109 private void connectTestVM(ServerSocket serverSocket) {
110 /*
111 * There are no way to prove that accept was invoked before we started
112 * test VM that connects to this serverSocket. Connection timeout is
113 * enough
114 */
115 try (
116 Socket socket = serverSocket.accept();
117 PrintWriter pw = new PrintWriter(socket.getOutputStream(),
118 true);
119 BufferedReader in = new BufferedReader(new InputStreamReader(
120 socket.getInputStream()))) {
121 // Get pid of the executed process
122 int pid = Integer.parseInt(in.readLine());
123 Asserts.assertNE(pid, 0, "Got incorrect pid");
124 executeJCMD(pid);
125 if (states != null) {
126 // serialize and send state map
127 states.forEach((executable, state) -> {
128 pw.println("{");
129 pw.println(executable.toGenericString());
130 pw.println(state.toString());
131 pw.println("}");
132 });
133 } else {
134 pw.println();
135 }
136 } catch (IOException e) {
137 throw new Error("Failed to write data: " + e.getMessage(), e);
138 }
139 }
140
141 // Executes all diagnostic commands
142 protected void executeJCMD(int pid) {
143 CommandExecutor jcmdExecutor = new PidJcmdExecutor(String.valueOf(pid));
144 for (String command : jcmdCommands) {
145 jcmdExecutor.execute(command);
146 }
147 }
148 }
|
21 * questions.
22 */
23
24 package compiler.compilercontrol.share.scenario;
25
26 import compiler.compilercontrol.share.actions.BaseAction;
27 import jdk.test.lib.Asserts;
28 import jdk.test.lib.OutputAnalyzer;
29 import jdk.test.lib.ProcessTools;
30 import jdk.test.lib.dcmd.CommandExecutor;
31 import jdk.test.lib.dcmd.PidJcmdExecutor;
32
33 import java.io.BufferedReader;
34 import java.io.IOException;
35 import java.io.InputStreamReader;
36 import java.io.PrintWriter;
37 import java.lang.reflect.Executable;
38 import java.net.ServerSocket;
39 import java.net.Socket;
40 import java.util.ArrayList;
41 import java.util.Collections;
42 import java.util.List;
43 import java.util.Map;
44
45 public class Executor {
46 private final boolean isValid;
47 private final List<String> vmOptions;
48 private final Map<Executable, State> states;
49 private final List<String> jcmdCommands;
50 private OutputAnalyzer[] jcmdOutputAnalyzers;
51
52 /**
53 * Constructor
54 *
55 * @param isValid shows that the input given to the VM is valid and
56 * VM shouldn't fail
57 * @param vmOptions a list of VM input options
58 * @param states a state map, or null for the non-checking execution
59 * @param jcmdCommands a list of diagnostic commands to be preformed
60 * on test VM
61 */
62 public Executor(boolean isValid, List<String> vmOptions,
63 Map<Executable, State> states, List<String> jcmdCommands) {
64 this.isValid = isValid;
65 if (vmOptions == null) {
66 this.vmOptions = new ArrayList<>();
67 } else {
68 this.vmOptions = vmOptions;
69 }
70 this.states = states;
71 this.jcmdCommands = jcmdCommands;
72 }
73
74 /**
75 * Executes separate VM a gets an OutputAnalyzer instance with the results
76 * of execution
77 */
78 public List<OutputAnalyzer> execute() {
79 // Add class name that would be executed in a separate VM
80 String classCmd = BaseAction.class.getName();
81 vmOptions.add(classCmd);
82 OutputAnalyzer output;
83 try (ServerSocket serverSocket = new ServerSocket(0)) {
84 if (isValid) {
85 // Get port test VM will connect to
86 int port = serverSocket.getLocalPort();
87 if (port == -1) {
88 throw new Error("Socket is not bound: " + port);
89 }
90 vmOptions.add(String.valueOf(port));
91 if (states != null) {
92 // add flag to show that there should be state map passed
93 vmOptions.add("states");
94 }
95 // Start separate thread to connect with test VM
96 new Thread(() -> connectTestVM(serverSocket)).start();
97 }
98 // Start test VM
99 output = ProcessTools.executeTestJvmAllArgs(
100 vmOptions.toArray(new String[vmOptions.size()]));
101 } catch (Throwable thr) {
102 throw new Error("Execution failed: " + thr.getMessage(), thr);
103 }
104
105 List<OutputAnalyzer> outputList = new ArrayList<>();
106 outputList.add(output);
107 if (jcmdOutputAnalyzers != null) {
108 Collections.addAll(outputList, jcmdOutputAnalyzers);
109 }
110 return outputList;
111 }
112
113 /*
114 * Performs connection with a test VM, sends method states and performs
115 * JCMD operations on a test VM.
116 */
117 private void connectTestVM(ServerSocket serverSocket) {
118 /*
119 * There are no way to prove that accept was invoked before we started
120 * test VM that connects to this serverSocket. Connection timeout is
121 * enough
122 */
123 try (
124 Socket socket = serverSocket.accept();
125 PrintWriter pw = new PrintWriter(socket.getOutputStream(),
126 true);
127 BufferedReader in = new BufferedReader(new InputStreamReader(
128 socket.getInputStream()))) {
129 // Get pid of the executed process
130 int pid = Integer.parseInt(in.readLine());
131 Asserts.assertNE(pid, 0, "Got incorrect pid");
132 jcmdOutputAnalyzers = executeJCMD(pid);
133 if (states != null) {
134 // serialize and send state map
135 states.forEach((executable, state) -> {
136 pw.println("{");
137 pw.println(executable.toGenericString());
138 pw.println(state.toString());
139 pw.println("}");
140 });
141 } else {
142 pw.println();
143 }
144 } catch (IOException e) {
145 throw new Error("Failed to write data: " + e.getMessage(), e);
146 }
147 }
148
149 // Executes all diagnostic commands
150 protected OutputAnalyzer[] executeJCMD(int pid) {
151 int size = jcmdCommands.size();
152 OutputAnalyzer[] outputArray = new OutputAnalyzer[size];
153 CommandExecutor jcmdExecutor = new PidJcmdExecutor(String.valueOf(pid));
154 for (int i = 0; i < size; i++) {
155 outputArray[i] = jcmdExecutor.execute(jcmdCommands.get(i));
156 }
157 return outputArray;
158 }
159 }
|