< prev index next >

test/jdk/jshell/UserJDIUserRemoteTest.java

Print this page
rev 3613 : imported patch 8131023


  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24  /*
  25  * @test
  26  * @bug 8160128 8159935
  27  * @summary Tests for Aux channel, custom remote agents, custom JDI implementations.
  28  * @build KullaTesting ExecutionControlTestBase
  29  * @run testng UserJDIUserRemoteTest
  30  */
  31 import java.io.ByteArrayOutputStream;
  32 import org.testng.annotations.Test;
  33 import org.testng.annotations.BeforeMethod;
  34 import jdk.jshell.Snippet;
  35 import static jdk.jshell.Snippet.Status.OVERWRITTEN;
  36 import static jdk.jshell.Snippet.Status.VALID;
  37 import java.io.IOException;
  38 import java.io.ObjectInput;
  39 import java.io.ObjectOutput;
  40 import java.io.ObjectOutputStream;
  41 import java.net.ServerSocket;
  42 import java.util.ArrayList;
  43 import java.util.List;
  44 import com.sun.jdi.VMDisconnectedException;
  45 import com.sun.jdi.VirtualMachine;
  46 import jdk.jshell.VarSnippet;
  47 import jdk.jshell.execution.DirectExecutionControl;
  48 import jdk.jshell.execution.JDIExecutionControl;
  49 import jdk.jshell.execution.JDIInitiator;
  50 import jdk.jshell.execution.Util;
  51 import java.io.InputStream;
  52 import java.io.OutputStream;
  53 import java.io.PrintStream;
  54 import java.net.Socket;
  55 
  56 import java.util.HashMap;
  57 import java.util.Map;
  58 import java.util.function.Consumer;
  59 import jdk.jshell.spi.ExecutionControl;
  60 import jdk.jshell.spi.ExecutionControl.ExecutionControlException;
  61 import jdk.jshell.spi.ExecutionEnv;
  62 import static org.testng.Assert.assertEquals;
  63 import static org.testng.Assert.fail;
  64 import static jdk.jshell.execution.Util.forwardExecutionControlAndIO;
  65 import static jdk.jshell.execution.Util.remoteInput;
  66 
  67 @Test
  68 public class UserJDIUserRemoteTest extends ExecutionControlTestBase {
  69 
  70     ExecutionControl currentEC;
  71     ByteArrayOutputStream auxStream;
  72 
  73     @BeforeMethod
  74     @Override
  75     public void setUp() {
  76         auxStream = new ByteArrayOutputStream();
  77         setUp(builder -> builder.executionEngine(MyExecutionControl.create(this)));
  78     }
  79 
  80     public void testVarValue() {
  81         VarSnippet dv = varKey(assertEval("double aDouble = 1.5;"));
  82         String vd = getState().varValue(dv);
  83         assertEquals(vd, "1.5");
  84         assertEquals(auxStream.toString(), "aDouble");
  85     }


 129      *
 130      * @return the generator
 131      */
 132     public static ExecutionControl.Generator create(UserJDIUserRemoteTest test) {
 133         return env -> make(env, test);
 134     }
 135 
 136     /**
 137      * Creates an ExecutionControl instance based on a JDI
 138      * {@code ListeningConnector} or {@code LaunchingConnector}.
 139      *
 140      * Initialize JDI and use it to launch the remote JVM. Set-up a socket for
 141      * commands and results. This socket also transports the user
 142      * input/output/error.
 143      *
 144      * @param env the context passed by
 145          * {@link jdk.jshell.spi.ExecutionControl#start(jdk.jshell.spi.ExecutionEnv) }
 146      * @return the channel
 147      * @throws IOException if there are errors in set-up
 148      */
 149     static MyExecutionControl make(ExecutionEnv env, UserJDIUserRemoteTest test) throws IOException {
 150         try (final ServerSocket listener = new ServerSocket(0)) {
 151             // timeout after 60 seconds
 152             listener.setSoTimeout(60000);
 153             int port = listener.getLocalPort();
 154 
 155             // Set-up the JDI connection
 156             List<String> opts = new ArrayList<>(env.extraRemoteVMOptions());
 157             opts.add("-classpath");
 158             opts.add(System.getProperty("java.class.path")
 159                     + System.getProperty("path.separator")
 160                     + System.getProperty("user.dir"));
 161             JDIInitiator jdii = new JDIInitiator(port,
 162                     opts, REMOTE_AGENT, true);
 163             VirtualMachine vm = jdii.vm();
 164             Process process = jdii.process();
 165 
 166             List<Consumer<String>> deathListeners = new ArrayList<>();
 167             deathListeners.add(s -> env.closeDown());
 168             Util.detectJDIExitEvent(vm, s -> {
 169                 for (Consumer<String> h : deathListeners) {
 170                     h.accept(s);
 171                 }
 172             });
 173 
 174             // Set-up the commands/reslts on the socket.  Piggy-back snippet
 175             // output.
 176             Socket socket = listener.accept();
 177             // out before in -- match remote creation so we don't hang
 178             ObjectOutput cmdout = new ObjectOutputStream(socket.getOutputStream());
 179             Map<String, OutputStream> io = new HashMap<>();
 180             io.put("out", env.userOut());
 181             io.put("err", env.userErr());
 182             io.put("aux", test.auxStream);
 183             ObjectInput cmdin = remoteInput(socket.getInputStream(), io);
 184             MyExecutionControl myec = new MyExecutionControl(cmdout, cmdin, vm, process, deathListeners);

 185             test.currentEC = myec;
 186             return myec;
 187         }
 188     }
 189 
 190     /**
 191      * Create an instance.
 192      *
 193      * @param out the output for commands
 194      * @param in the input for responses
 195      */
 196     private MyExecutionControl(ObjectOutput out, ObjectInput in,
 197             VirtualMachine vm, Process process,
 198             List<Consumer<String>> deathListeners) {
 199         super(out, in);
 200         this.vm = vm;
 201         this.process = process;
 202         deathListeners.add(s -> disposeVM());
 203     }
 204 


 238 }
 239 
 240 class MyRemoteExecutionControl extends DirectExecutionControl implements ExecutionControl {
 241 
 242     static PrintStream auxPrint;
 243 
 244     /**
 245      * Launch the agent, connecting to the JShell-core over the socket specified
 246      * in the command-line argument.
 247      *
 248      * @param args standard command-line arguments, expectation is the socket
 249      * number is the only argument
 250      * @throws Exception any unexpected exception
 251      */
 252     public static void main(String[] args) throws Exception {
 253         try {
 254             String loopBack = null;
 255             Socket socket = new Socket(loopBack, Integer.parseInt(args[0]));
 256             InputStream inStream = socket.getInputStream();
 257             OutputStream outStream = socket.getOutputStream();
 258             Map<String, Consumer<OutputStream>> chans = new HashMap<>();
 259             chans.put("out", st -> System.setOut(new PrintStream(st, true)));
 260             chans.put("err", st -> System.setErr(new PrintStream(st, true)));
 261             chans.put("aux", st -> { auxPrint = new PrintStream(st, true); });
 262             forwardExecutionControlAndIO(new MyRemoteExecutionControl(), inStream, outStream, chans);


 263         } catch (Throwable ex) {
 264             throw ex;
 265         }
 266     }
 267 
 268     @Override
 269     public String varValue(String className, String varName)
 270             throws RunException, EngineTerminationException, InternalException {
 271         auxPrint.print(varName);
 272         return super.varValue(className, varName);
 273     }
 274 
 275     @Override
 276     public Object extensionCommand(String className, Object arg)
 277             throws RunException, EngineTerminationException, InternalException {
 278         if (!arg.equals("test")) {
 279             throw new InternalException("expected extensionCommand arg to be 'test' got: " + arg);
 280         }
 281         return "ribbit";
 282     }


  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24  /*
  25  * @test
  26  * @bug 8160128 8159935
  27  * @summary Tests for Aux channel, custom remote agents, custom JDI implementations.
  28  * @build KullaTesting ExecutionControlTestBase
  29  * @run testng UserJDIUserRemoteTest
  30  */
  31 import java.io.ByteArrayOutputStream;
  32 import org.testng.annotations.Test;
  33 import org.testng.annotations.BeforeMethod;
  34 import jdk.jshell.Snippet;
  35 import static jdk.jshell.Snippet.Status.OVERWRITTEN;
  36 import static jdk.jshell.Snippet.Status.VALID;
  37 import java.io.IOException;
  38 import java.io.ObjectInput;
  39 import java.io.ObjectOutput;

  40 import java.net.ServerSocket;
  41 import java.util.ArrayList;
  42 import java.util.List;
  43 import com.sun.jdi.VMDisconnectedException;
  44 import com.sun.jdi.VirtualMachine;
  45 import jdk.jshell.VarSnippet;
  46 import jdk.jshell.execution.DirectExecutionControl;
  47 import jdk.jshell.execution.JDIExecutionControl;
  48 import jdk.jshell.execution.JDIInitiator;
  49 import jdk.jshell.execution.Util;
  50 import java.io.InputStream;
  51 import java.io.OutputStream;
  52 import java.io.PrintStream;
  53 import java.net.Socket;
  54 
  55 import java.util.HashMap;
  56 import java.util.Map;
  57 import java.util.function.Consumer;
  58 import jdk.jshell.spi.ExecutionControl;
  59 import jdk.jshell.spi.ExecutionControl.ExecutionControlException;
  60 import jdk.jshell.spi.ExecutionEnv;
  61 import static org.testng.Assert.assertEquals;
  62 import static org.testng.Assert.fail;
  63 import static jdk.jshell.execution.Util.forwardExecutionControlAndIO;
  64 import static jdk.jshell.execution.Util.remoteInputOutput;
  65 
  66 @Test
  67 public class UserJDIUserRemoteTest extends ExecutionControlTestBase {
  68 
  69     ExecutionControl currentEC;
  70     ByteArrayOutputStream auxStream;
  71 
  72     @BeforeMethod
  73     @Override
  74     public void setUp() {
  75         auxStream = new ByteArrayOutputStream();
  76         setUp(builder -> builder.executionEngine(MyExecutionControl.create(this)));
  77     }
  78 
  79     public void testVarValue() {
  80         VarSnippet dv = varKey(assertEval("double aDouble = 1.5;"));
  81         String vd = getState().varValue(dv);
  82         assertEquals(vd, "1.5");
  83         assertEquals(auxStream.toString(), "aDouble");
  84     }


 128      *
 129      * @return the generator
 130      */
 131     public static ExecutionControl.Generator create(UserJDIUserRemoteTest test) {
 132         return env -> make(env, test);
 133     }
 134 
 135     /**
 136      * Creates an ExecutionControl instance based on a JDI
 137      * {@code ListeningConnector} or {@code LaunchingConnector}.
 138      *
 139      * Initialize JDI and use it to launch the remote JVM. Set-up a socket for
 140      * commands and results. This socket also transports the user
 141      * input/output/error.
 142      *
 143      * @param env the context passed by
 144          * {@link jdk.jshell.spi.ExecutionControl#start(jdk.jshell.spi.ExecutionEnv) }
 145      * @return the channel
 146      * @throws IOException if there are errors in set-up
 147      */
 148     static ExecutionControl make(ExecutionEnv env, UserJDIUserRemoteTest test) throws IOException {
 149         try (final ServerSocket listener = new ServerSocket(0)) {
 150             // timeout after 60 seconds
 151             listener.setSoTimeout(60000);
 152             int port = listener.getLocalPort();
 153 
 154             // Set-up the JDI connection
 155             List<String> opts = new ArrayList<>(env.extraRemoteVMOptions());
 156             opts.add("-classpath");
 157             opts.add(System.getProperty("java.class.path")
 158                     + System.getProperty("path.separator")
 159                     + System.getProperty("user.dir"));
 160             JDIInitiator jdii = new JDIInitiator(port,
 161                     opts, REMOTE_AGENT, true);
 162             VirtualMachine vm = jdii.vm();
 163             Process process = jdii.process();
 164 
 165             List<Consumer<String>> deathListeners = new ArrayList<>();
 166             deathListeners.add(s -> env.closeDown());
 167             Util.detectJDIExitEvent(vm, s -> {
 168                 for (Consumer<String> h : deathListeners) {
 169                     h.accept(s);
 170                 }
 171             });
 172 
 173             // Set-up the commands/reslts on the socket.  Piggy-back snippet
 174             // output.
 175             Socket socket = listener.accept();
 176             // out before in -- match remote creation so we don't hang
 177             OutputStream out = socket.getOutputStream();
 178             Map<String, OutputStream> outputs = new HashMap<>();
 179             outputs.put("out", env.userOut());
 180             outputs.put("err", env.userErr());
 181             outputs.put("aux", test.auxStream);
 182             Map<String, InputStream> input = new HashMap<>();
 183             input.put("in", env.userIn());
 184             ExecutionControl myec = remoteInputOutput(socket.getInputStream(), out, outputs, input, (objIn, objOut) -> new MyExecutionControl(objOut, objIn, vm, process, deathListeners));
 185             test.currentEC = myec;
 186             return myec;
 187         }
 188     }
 189 
 190     /**
 191      * Create an instance.
 192      *
 193      * @param out the output for commands
 194      * @param in the input for responses
 195      */
 196     private MyExecutionControl(ObjectOutput out, ObjectInput in,
 197             VirtualMachine vm, Process process,
 198             List<Consumer<String>> deathListeners) {
 199         super(out, in);
 200         this.vm = vm;
 201         this.process = process;
 202         deathListeners.add(s -> disposeVM());
 203     }
 204 


 238 }
 239 
 240 class MyRemoteExecutionControl extends DirectExecutionControl implements ExecutionControl {
 241 
 242     static PrintStream auxPrint;
 243 
 244     /**
 245      * Launch the agent, connecting to the JShell-core over the socket specified
 246      * in the command-line argument.
 247      *
 248      * @param args standard command-line arguments, expectation is the socket
 249      * number is the only argument
 250      * @throws Exception any unexpected exception
 251      */
 252     public static void main(String[] args) throws Exception {
 253         try {
 254             String loopBack = null;
 255             Socket socket = new Socket(loopBack, Integer.parseInt(args[0]));
 256             InputStream inStream = socket.getInputStream();
 257             OutputStream outStream = socket.getOutputStream();
 258             Map<String, Consumer<OutputStream>> outputs = new HashMap<>();
 259             outputs.put("out", st -> System.setOut(new PrintStream(st, true)));
 260             outputs.put("err", st -> System.setErr(new PrintStream(st, true)));
 261             outputs.put("aux", st -> { auxPrint = new PrintStream(st, true); });
 262             Map<String, Consumer<InputStream>> input = new HashMap<>();
 263             input.put("in", st -> System.setIn(st));
 264             forwardExecutionControlAndIO(new MyRemoteExecutionControl(), inStream, outStream, outputs, input);
 265         } catch (Throwable ex) {
 266             throw ex;
 267         }
 268     }
 269 
 270     @Override
 271     public String varValue(String className, String varName)
 272             throws RunException, EngineTerminationException, InternalException {
 273         auxPrint.print(varName);
 274         return super.varValue(className, varName);
 275     }
 276 
 277     @Override
 278     public Object extensionCommand(String className, Object arg)
 279             throws RunException, EngineTerminationException, InternalException {
 280         if (!arg.equals("test")) {
 281             throw new InternalException("expected extensionCommand arg to be 'test' got: " + arg);
 282         }
 283         return "ribbit";
 284     }
< prev index next >