Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: cdf0ea6e703e954d8a4e788f613b8d385c2f22b9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.eval;

import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.ServerSocket;

import org.eclipse.jdt.core.tests.runtime.LocalVirtualMachine;

import org.eclipse.jdt.core.tests.runtime.LocalVMLauncher;
import org.eclipse.jdt.core.tests.runtime.TargetException;
import org.eclipse.jdt.core.tests.runtime.TargetInterface;
import org.eclipse.jdt.core.tests.util.CompilerTestSetup;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.eval.EvaluationContext;

public class EvaluationSetup extends CompilerTestSetup {

	public static final String EVAL_DIRECTORY = Util.getOutputDirectory() + File.separator + "evaluation";
	public static final String JRE_PATH = Util.getJREDirectory();

	EvaluationContext context;
	TargetInterface target;
	LocalVirtualMachine launchedVM;
	INameEnvironment env;

	public EvaluationSetup(long complianceLevel) {
		super(complianceLevel);
	}

	protected void setUp() {
		if (this.context == null) { // non null if called from subclass
			try (ServerSocket server = new ServerSocket(0)) {
				// Launch VM in evaluation mode
				int evalPort = server.getLocalPort();
				try {
					LocalVMLauncher launcher = LocalVMLauncher.getLauncher();
					launcher.setVMPath(JRE_PATH);
					launcher.setEvalPort(evalPort);
					launcher.setEvalTargetPath(EVAL_DIRECTORY);
					this.launchedVM = launcher.launch();
				} catch (TargetException e) {
					e.printStackTrace();
					throw new Error(e.getMessage(), e);
				}

				// Thread that read the stout of the VM so that the VM doesn't block
				try {
					startReader("VM's stdout reader", this.launchedVM.getInputStream(), System.out);
				} catch (TargetException e) {
					e.printStackTrace();
				}

				// Thread that read the sterr of the VM so that the VM doesn't block
				try {
					startReader("VM's sterr reader", this.launchedVM.getErrorStream(), System.err);
				} catch (TargetException e) {
					e.printStackTrace();
				}

				// Create context
				this.context = new EvaluationContext();

				// Create target
				this.target = new TargetInterface();
				// allow 30s max to connect (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=188127)
				// Increased to 60 s for https://bugs.eclipse.org/bugs/show_bug.cgi?id=547417
				this.target.connect(server, 60000); 
				
				assertTrue("Failed to connect VM server", this.target.isConnected());

				System.out.println(getName() + ": connected to target");

				// Create name environment
				this.env = new FileSystem(Util.getJavaClassLibs(), new String[0], null);
			} catch (IOException e1) {
				e1.printStackTrace();
				throw new Error("Failed to open socket", e1);
			}
		}
		super.setUp();
	}

	protected void startReader(String name, final InputStream in, final PrintStream out) {
		(new Thread(name) {
			public void run() {
				int read = 0;
				while (read != -1) {
					try {
						read = in.read();
					} catch (java.io.IOException e) {
						read = -1;
					}
					if (read != -1) {
						out.print((char)read);
					}
				}
			}
		}).start();
	}

	final protected void tearDown() {
		if (this.context != null) {
			LocalVirtualMachine vm = this.launchedVM;
			if (vm != null) {
				try {
					if (this.target != null) {
						this.target.disconnect(); // Close the socket first so that the OS resource has a chance to be freed.
					}
					int retry = 0;
					while (vm.isRunning() && (++retry < 20)) {
						try {
							Thread.sleep(retry * 100);
						} catch (InterruptedException e) {
						}
					}
					if (vm.isRunning()) {
						vm.shutDown();
					}
					this.context = null;
				} catch (TargetException e) {
					e.printStackTrace();
					throw new Error(e.getMessage(), e);
				}
			}
		}
		if (this.env != null) {
			this.env.cleanup();
		}
	}
}

Back to the top