mirror of
https://github.com/enso-org/enso.git
synced 2024-12-27 07:32:38 +03:00
Reducing memory leaks in runtime-integration-tests (#10793)
Inspired by the revert done in https://github.com/enso-org/enso/pull/10778, started looking into apparent memory leaks in `runtime-integration-tests`, written in Java. Initial state: ![Screenshot from 2024-08-09 14-36-29](https://github.com/user-attachments/assets/39abd48f-503b-49d8-af97-da051352c70d) After: ![Screenshot from 2024-08-12 16-33-40](https://github.com/user-attachments/assets/2bf4cc2d-7e0e-4d22-8810-c2e7e5c3b065) # Important Notes Some remaining issues: - [ ] [TCK tests](https://github.com/enso-org/enso/tree/develop/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/tck) appear to have some memory leaks but we are essentially enabling them via simple inheritance - [ ] [RuntimeManagementTest](https://github.com/enso-org/enso/blob/develop/engine/runtime-integration-tests/src/test/scala/org/enso/interpreter/test/semantic/RuntimeManagementTest.scala) appears to be broken as it doesn't seem to shutdown properly created threads: ![Screenshot from 2024-08-12 16-29-09](https://github.com/user-attachments/assets/d90aca62-0562-4287-88b7-6d4719e5cf50) Leaving this for now, as it will probably need to be taken care by initial authors of those tests, if possible. Plus this PR leaves tests in a much better state than before.
This commit is contained in:
parent
31e589e362
commit
ff7e31c237
@ -105,6 +105,7 @@ trait PackageRepository {
|
||||
context: CompilerContext
|
||||
): Option[IRModule]
|
||||
|
||||
def shutdown(): Unit
|
||||
}
|
||||
|
||||
object PackageRepository {
|
||||
|
@ -17,8 +17,8 @@ import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.PolyglotException;
|
||||
import org.graalvm.polyglot.Source;
|
||||
import org.graalvm.polyglot.io.IOAccess;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -45,7 +45,7 @@ public class ExecStrictCompilerTest {
|
||||
assertNotNull("Enso language is supported", ctx.getEngine().getLanguages().get("enso"));
|
||||
}
|
||||
|
||||
@Before
|
||||
@After
|
||||
public void cleanMessages() {
|
||||
MESSAGES.reset();
|
||||
}
|
||||
@ -53,6 +53,7 @@ public class ExecStrictCompilerTest {
|
||||
@AfterClass
|
||||
public static void closeEnsoContext() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -47,13 +47,14 @@ public class ExportedSymbolsTest {
|
||||
type A_Type
|
||||
""");
|
||||
ProjectUtils.createProject("Proj", Set.of(mainSrcMod), projDir);
|
||||
var ctx = createCtx(projDir);
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(1));
|
||||
assertThat(mainExportedSymbols.containsKey("A_Type"), is(true));
|
||||
assertThat(
|
||||
mainExportedSymbols.get("A_Type").get(0), instanceOf(BindingsMap.ResolvedType.class));
|
||||
try (var ctx = createCtx(projDir)) {
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(1));
|
||||
assertThat(mainExportedSymbols.containsKey("A_Type"), is(true));
|
||||
assertThat(
|
||||
mainExportedSymbols.get("A_Type").get(0), instanceOf(BindingsMap.ResolvedType.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -70,11 +71,12 @@ public class ExportedSymbolsTest {
|
||||
type B_Type
|
||||
""");
|
||||
ProjectUtils.createProject("Proj", Set.of(aMod, mainSrcMod), projDir);
|
||||
var ctx = createCtx(projDir);
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(2));
|
||||
assertThat(mainExportedSymbols.keySet(), containsInAnyOrder("A_Type", "B_Type"));
|
||||
try (var ctx = createCtx(projDir)) {
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(2));
|
||||
assertThat(mainExportedSymbols.keySet(), containsInAnyOrder("A_Type", "B_Type"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -91,11 +93,12 @@ public class ExportedSymbolsTest {
|
||||
type B_Type
|
||||
""");
|
||||
ProjectUtils.createProject("Proj", Set.of(mainMod, bMod), projDir);
|
||||
var ctx = createCtx(projDir);
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(2));
|
||||
assertThat(mainExportedSymbols.keySet(), containsInAnyOrder("A_Type", "B_Type"));
|
||||
try (var ctx = createCtx(projDir)) {
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(2));
|
||||
assertThat(mainExportedSymbols.keySet(), containsInAnyOrder("A_Type", "B_Type"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -111,11 +114,12 @@ public class ExportedSymbolsTest {
|
||||
export project.A_Module.A_Type as Foo
|
||||
""");
|
||||
ProjectUtils.createProject("Proj", Set.of(aMod, mainSrcMod), projDir);
|
||||
var ctx = createCtx(projDir);
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(1));
|
||||
assertThat(mainExportedSymbols.keySet(), containsInAnyOrder("Foo"));
|
||||
try (var ctx = createCtx(projDir)) {
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(1));
|
||||
assertThat(mainExportedSymbols.keySet(), containsInAnyOrder("Foo"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -133,13 +137,16 @@ public class ExportedSymbolsTest {
|
||||
import project.Synthetic_Module
|
||||
""");
|
||||
ProjectUtils.createProject("Proj", Set.of(aMod, mainMod), projDir);
|
||||
var ctx = createCtx(projDir);
|
||||
compile(ctx);
|
||||
var syntheticModExpSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Synthetic_Module");
|
||||
assertThat(
|
||||
"Just a A_Module submodule should be exported", syntheticModExpSymbols.size(), is(1));
|
||||
assertThat(
|
||||
"Just a A_Module submodule should be exported", syntheticModExpSymbols, hasKey("A_Module"));
|
||||
try (var ctx = createCtx(projDir)) {
|
||||
compile(ctx);
|
||||
var syntheticModExpSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Synthetic_Module");
|
||||
assertThat(
|
||||
"Just a A_Module submodule should be exported", syntheticModExpSymbols.size(), is(1));
|
||||
assertThat(
|
||||
"Just a A_Module submodule should be exported",
|
||||
syntheticModExpSymbols,
|
||||
hasKey("A_Module"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -156,14 +163,16 @@ public class ExportedSymbolsTest {
|
||||
export project.A_Module.A_Module
|
||||
""");
|
||||
ProjectUtils.createProject("Proj", Set.of(aMod, mainMod), projDir);
|
||||
var ctx = createCtx(projDir);
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(1));
|
||||
assertThat(mainExportedSymbols.keySet(), containsInAnyOrder("A_Module"));
|
||||
assertThat(mainExportedSymbols.get("A_Module").size(), is(1));
|
||||
assertThat(
|
||||
mainExportedSymbols.get("A_Module").get(0), is(instanceOf(BindingsMap.ResolvedType.class)));
|
||||
try (var ctx = createCtx(projDir)) {
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(1));
|
||||
assertThat(mainExportedSymbols.keySet(), containsInAnyOrder("A_Module"));
|
||||
assertThat(mainExportedSymbols.get("A_Module").size(), is(1));
|
||||
assertThat(
|
||||
mainExportedSymbols.get("A_Module").get(0),
|
||||
is(instanceOf(BindingsMap.ResolvedType.class)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -179,15 +188,16 @@ public class ExportedSymbolsTest {
|
||||
export project.A_Module
|
||||
""");
|
||||
ProjectUtils.createProject("Proj", Set.of(aMod, mainMod), projDir);
|
||||
var ctx = createCtx(projDir);
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(1));
|
||||
assertThat(mainExportedSymbols.keySet(), containsInAnyOrder("A_Module"));
|
||||
assertThat(mainExportedSymbols.get("A_Module").size(), is(1));
|
||||
assertThat(
|
||||
mainExportedSymbols.get("A_Module").get(0),
|
||||
is(instanceOf(BindingsMap.ResolvedModule.class)));
|
||||
try (var ctx = createCtx(projDir)) {
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(1));
|
||||
assertThat(mainExportedSymbols.keySet(), containsInAnyOrder("A_Module"));
|
||||
assertThat(mainExportedSymbols.get("A_Module").size(), is(1));
|
||||
assertThat(
|
||||
mainExportedSymbols.get("A_Module").get(0),
|
||||
is(instanceOf(BindingsMap.ResolvedModule.class)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -205,15 +215,16 @@ public class ExportedSymbolsTest {
|
||||
export project.Synthetic_Module
|
||||
""");
|
||||
ProjectUtils.createProject("Proj", Set.of(aMod, mainMod), projDir);
|
||||
var ctx = createCtx(projDir);
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(1));
|
||||
assertThat(mainExportedSymbols.keySet(), containsInAnyOrder("Synthetic_Module"));
|
||||
assertThat(mainExportedSymbols.get("Synthetic_Module").size(), is(1));
|
||||
assertThat(
|
||||
mainExportedSymbols.get("Synthetic_Module").get(0),
|
||||
is(instanceOf(BindingsMap.ResolvedModule.class)));
|
||||
try (var ctx = createCtx(projDir)) {
|
||||
compile(ctx);
|
||||
var mainExportedSymbols = getExportedSymbolsFromModule(ctx, "local.Proj.Main");
|
||||
assertThat(mainExportedSymbols.size(), is(1));
|
||||
assertThat(mainExportedSymbols.keySet(), containsInAnyOrder("Synthetic_Module"));
|
||||
assertThat(mainExportedSymbols.get("Synthetic_Module").size(), is(1));
|
||||
assertThat(
|
||||
mainExportedSymbols.get("Synthetic_Module").get(0),
|
||||
is(instanceOf(BindingsMap.ResolvedModule.class)));
|
||||
}
|
||||
}
|
||||
|
||||
private static Context createCtx(Path projDir) {
|
||||
|
@ -103,6 +103,7 @@ main = 42
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
private final Symbol symbol;
|
||||
|
@ -74,7 +74,7 @@ public class SerdeCompilerTest {
|
||||
var persisted = f.get(10, TimeUnit.SECONDS);
|
||||
assertEquals("Fib_Test library has been fully persisted", true, persisted);
|
||||
}
|
||||
old = module.getIr();
|
||||
old = module.getIr().duplicate(true, true, true, false);
|
||||
ctx.leave();
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ public class SerdeCompilerTest {
|
||||
var mainValue = ctx.asValue(main);
|
||||
assertEquals(42, mainValue.execute().asInt());
|
||||
|
||||
now = module.getIr();
|
||||
now = module.getIr().duplicate(true, true, true, false);
|
||||
|
||||
ctx.leave();
|
||||
}
|
||||
|
@ -28,11 +28,12 @@ public class SerializationManagerTest {
|
||||
|
||||
private static final long COMPILE_TIMEOUT_SECONDS = 20;
|
||||
|
||||
private final PackageManager<TruffleFile> packageManager;
|
||||
private final InterpreterContext interpreterContext;
|
||||
private final EnsoContext ensoContext;
|
||||
private PackageManager<TruffleFile> packageManager;
|
||||
private InterpreterContext interpreterContext;
|
||||
private EnsoContext ensoContext;
|
||||
|
||||
public SerializationManagerTest() {
|
||||
@Before
|
||||
public void setup() {
|
||||
packageManager = new PackageManager<>(new TruffleFileSystem());
|
||||
interpreterContext = new InterpreterContext(x -> x);
|
||||
ensoContext =
|
||||
@ -41,22 +42,20 @@ public class SerializationManagerTest {
|
||||
.getBindings(LanguageInfo.ID)
|
||||
.invokeMember(MethodNames.TopScope.LEAK_CONTEXT)
|
||||
.asHostObject();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
interpreterContext.ctx().initialize(LanguageInfo.ID);
|
||||
interpreterContext.ctx().enter();
|
||||
}
|
||||
|
||||
@After
|
||||
public void teardown() {
|
||||
interpreterContext.ctx().close();
|
||||
interpreterContext.close();
|
||||
ensoContext.shutdown();
|
||||
ensoContext = null;
|
||||
}
|
||||
|
||||
private Path getLibraryPath(LibraryName libraryName) {
|
||||
return Paths.get(
|
||||
interpreterContext.languageHome(),
|
||||
interpreterContext.languageHome().toFile().getAbsolutePath(),
|
||||
"..",
|
||||
"lib",
|
||||
libraryName.namespace(),
|
||||
|
@ -42,29 +42,29 @@ public class SerializerTest {
|
||||
var pkgPath = new File(getClass().getClassLoader().getResource(testName).getPath());
|
||||
var pkg = PackageManager.Default().fromDirectory(pkgPath).get();
|
||||
|
||||
var ctx = ensoContextForPackage(testName, pkgPath);
|
||||
var ensoContext =
|
||||
(EnsoContext)
|
||||
ctx.getBindings(LanguageInfo.ID)
|
||||
.invokeMember(MethodNames.TopScope.LEAK_CONTEXT)
|
||||
.asHostObject();
|
||||
var mainModuleOpt = ensoContext.getModuleForFile(pkg.mainFile());
|
||||
assertEquals(mainModuleOpt.isPresent(), true);
|
||||
try (var ctx = ensoContextForPackage(testName, pkgPath)) {
|
||||
var ensoContext =
|
||||
(EnsoContext)
|
||||
ctx.getBindings(LanguageInfo.ID)
|
||||
.invokeMember(MethodNames.TopScope.LEAK_CONTEXT)
|
||||
.asHostObject();
|
||||
var mainModuleOpt = ensoContext.getModuleForFile(pkg.mainFile());
|
||||
assertEquals(mainModuleOpt.isPresent(), true);
|
||||
|
||||
var compiler = ensoContext.getCompiler();
|
||||
var module = mainModuleOpt.get().asCompilerModule();
|
||||
var compiler = ensoContext.getCompiler();
|
||||
var module = mainModuleOpt.get().asCompilerModule();
|
||||
|
||||
ctx.enter();
|
||||
var result = compiler.run(module);
|
||||
assertEquals(result.compiledModules().exists(m -> m == module), true);
|
||||
var useThreadPool = compiler.context().isCreateThreadAllowed();
|
||||
var future = compiler.context().serializeModule(compiler, module, true, useThreadPool);
|
||||
var serialized = future.get(5, TimeUnit.SECONDS);
|
||||
assertEquals(serialized, true);
|
||||
var deserialized = compiler.context().deserializeModule(compiler, module);
|
||||
assertTrue("Deserialized", deserialized);
|
||||
compiler.context().shutdown(true);
|
||||
ctx.leave();
|
||||
ctx.close();
|
||||
ctx.enter();
|
||||
var result = compiler.run(module);
|
||||
assertEquals(result.compiledModules().exists(m -> m == module), true);
|
||||
var useThreadPool = compiler.context().isCreateThreadAllowed();
|
||||
var future = compiler.context().serializeModule(compiler, module, true, useThreadPool);
|
||||
var serialized = future.get(5, TimeUnit.SECONDS);
|
||||
assertEquals(serialized, true);
|
||||
var deserialized = compiler.context().deserializeModule(compiler, module);
|
||||
assertTrue("Deserialized", deserialized);
|
||||
compiler.context().shutdown(true);
|
||||
ctx.leave();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ public class VectorArraySignatureTest {
|
||||
@AfterClass
|
||||
public static void closeEnsoParser() throws Exception {
|
||||
ensoCompiler.close();
|
||||
ensoCompiler = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -19,8 +19,7 @@ public class IRDumpTest {
|
||||
System.setProperty(IRDumper.SYSTEM_PROP, "true");
|
||||
try (var ctx = ContextUtils.defaultContextBuilder().out(out).build()) {
|
||||
// Dumping is done in the compiler, so it is enough just to compile the module
|
||||
var moduleIr =
|
||||
ContextUtils.compileModule(ctx, """
|
||||
ContextUtils.compileModule(ctx, """
|
||||
main = 42
|
||||
""", "MyMainModule");
|
||||
assertThat(
|
||||
@ -39,6 +38,7 @@ public class IRDumpTest {
|
||||
} catch (IOException e) {
|
||||
// Ignore. The ir-dumps directory should be deleted eventually.
|
||||
}
|
||||
out.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.test.utils.ContextUtils;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.Source;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -30,6 +31,12 @@ public class ModuleCacheTest {
|
||||
.build();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void disposeContext() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareList() throws Exception {
|
||||
var ensoCtx =
|
||||
|
@ -27,6 +27,7 @@ public class PolyglotCallTypeTest {
|
||||
@AfterClass
|
||||
public static void closeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -66,6 +66,7 @@ public class TypeOfNodeTest {
|
||||
public static void disposeCtx() throws Exception {
|
||||
if (ctx != null) {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,7 @@ public class ModuleSourcesTest {
|
||||
public void cleanup() {
|
||||
f.delete();
|
||||
this.ctx.close();
|
||||
this.ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -50,6 +50,7 @@ public class ModuleTest {
|
||||
public void cleanup() {
|
||||
f.delete();
|
||||
this.ctx.close();
|
||||
this.ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -31,6 +31,7 @@ public class AtomConstructorTest {
|
||||
@AfterClass
|
||||
public static void closeContext() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -27,6 +27,7 @@ public class AtomInteropTest {
|
||||
@After
|
||||
public void disposeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -12,8 +12,8 @@ import org.enso.common.MethodNames;
|
||||
import org.enso.test.utils.ContextUtils;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.PolyglotException;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -28,7 +28,7 @@ public class AutoscopedConstructorTest {
|
||||
ctx = ContextUtils.createDefaultContext(out);
|
||||
}
|
||||
|
||||
@Before
|
||||
@After
|
||||
public void resetOut() {
|
||||
out.reset();
|
||||
}
|
||||
@ -36,6 +36,7 @@ public class AutoscopedConstructorTest {
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -28,6 +28,7 @@ public class BigNumberTest {
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -63,7 +63,9 @@ public class BinaryDispatchTest {
|
||||
|
||||
@AfterClass
|
||||
public static void closeCtx() {
|
||||
module = null;
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -89,6 +89,7 @@ public class BinaryOpFloatTest {
|
||||
@AfterClass
|
||||
public static void closeContext() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
private final String operation;
|
||||
|
@ -108,6 +108,7 @@ public class BinaryOpIntegerTest {
|
||||
@AfterClass
|
||||
public static void closeContext() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
private final String operation;
|
||||
|
@ -0,0 +1,27 @@
|
||||
package org.enso.interpreter.test;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import org.enso.test.utils.ContextUtils;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
public class ContextTest {
|
||||
|
||||
protected static Context ctx;
|
||||
|
||||
@BeforeClass
|
||||
public static void prepareCtx() {
|
||||
ctx =
|
||||
ContextUtils.defaultContextBuilder()
|
||||
.out(OutputStream.nullOutputStream())
|
||||
.err(OutputStream.nullOutputStream())
|
||||
.build();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
}
|
@ -10,8 +10,8 @@ import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.Value;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -28,9 +28,10 @@ public class ConversionMethodTests {
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Before
|
||||
@After
|
||||
public void resetOutput() {
|
||||
out.reset();
|
||||
}
|
||||
|
@ -79,7 +79,9 @@ public class DebuggingEnsoTest {
|
||||
@After
|
||||
public void disposeContext() {
|
||||
context.close();
|
||||
context = null;
|
||||
engine.close();
|
||||
engine = null;
|
||||
}
|
||||
|
||||
private static void expectStackFrame(
|
||||
|
@ -55,6 +55,7 @@ public class DiagnosticFormatterTest {
|
||||
@After
|
||||
public void closeCtx() throws IOException {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
output.close();
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ public class EqualsConversionsTest {
|
||||
@AfterClass
|
||||
public static void disposeContext() {
|
||||
context.close();
|
||||
context = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -61,6 +61,8 @@ public class EqualsTest {
|
||||
@AfterClass
|
||||
public static void disposeContext() {
|
||||
context.close();
|
||||
context = null;
|
||||
unwrappedValues = null;
|
||||
}
|
||||
|
||||
@DataPoints public static Object[] unwrappedValues;
|
||||
@ -90,6 +92,8 @@ public class EqualsTest {
|
||||
.toArray(new Object[] {});
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
} finally {
|
||||
valGenerator.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ public class FindExceptionMessageTest {
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -27,6 +27,7 @@ public class ForeignMethodInvokeTest {
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -53,6 +53,8 @@ public class HashCodeTest {
|
||||
@AfterClass
|
||||
public static void disposeContext() {
|
||||
context.close();
|
||||
context = null;
|
||||
unwrappedValues = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,7 +60,9 @@ public class InsightForEnsoTest {
|
||||
@After
|
||||
public void disposeContext() throws Exception {
|
||||
this.insightHandle.close();
|
||||
this.out.reset();
|
||||
this.ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -40,6 +40,7 @@ public class IntegerTest {
|
||||
@AfterClass
|
||||
public static void teardown() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
private static final EnsoBigInteger bigInt =
|
||||
|
@ -12,8 +12,8 @@ import org.enso.test.utils.ContextUtils;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.PolyglotException;
|
||||
import org.graalvm.polyglot.Value;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -30,9 +30,10 @@ public class JavaInteropTest {
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Before
|
||||
@After
|
||||
public void resetOutput() {
|
||||
out.reset();
|
||||
}
|
||||
|
@ -18,12 +18,13 @@ public class JsInteropTest {
|
||||
@Before
|
||||
public void initContext() {
|
||||
ctx = ContextUtils.createDefaultContext(out);
|
||||
out.reset();
|
||||
}
|
||||
|
||||
@After
|
||||
public void disposeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
out.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -64,7 +64,15 @@ public class ListTest {
|
||||
|
||||
@After
|
||||
public void disposeCtx() {
|
||||
generator = null;
|
||||
plusOne = null;
|
||||
evenOnes = null;
|
||||
taken = null;
|
||||
init = null;
|
||||
asVector = null;
|
||||
asText = null;
|
||||
this.ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -53,7 +53,10 @@ public class MetaIsATest {
|
||||
generator.dispose();
|
||||
generator = null;
|
||||
}
|
||||
isACheck = null;
|
||||
warningCheck = null;
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,6 +38,7 @@ public class NonStrictModeTests {
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
nonStrictCtx.close();
|
||||
nonStrictCtx = null;
|
||||
}
|
||||
|
||||
@Before
|
||||
|
@ -93,7 +93,9 @@ public class PolyglotErrorTest {
|
||||
|
||||
@After
|
||||
public void disposeCtx() {
|
||||
this.panic = null;
|
||||
this.ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -55,6 +55,8 @@ public class RootNamesTest {
|
||||
public void disposeContext() throws Exception {
|
||||
this.insightHandle.close();
|
||||
this.ctx.close();
|
||||
this.ctx = null;
|
||||
this.out.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -6,36 +6,16 @@ import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import org.enso.common.MethodNames;
|
||||
import org.enso.test.utils.ContextUtils;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.PolyglotException;
|
||||
import org.graalvm.polyglot.Source;
|
||||
import org.graalvm.polyglot.Value;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SignatureTest {
|
||||
private static Context ctx;
|
||||
|
||||
@BeforeClass
|
||||
public static void prepareCtx() {
|
||||
ctx =
|
||||
ContextUtils.defaultContextBuilder()
|
||||
.out(OutputStream.nullOutputStream())
|
||||
.err(OutputStream.nullOutputStream())
|
||||
.build();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close();
|
||||
}
|
||||
public class SignatureTest extends ContextTest {
|
||||
|
||||
@Test
|
||||
public void wrongFunctionSignature() throws Exception {
|
||||
|
@ -3,32 +3,12 @@ package org.enso.interpreter.test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import org.enso.common.MethodNames;
|
||||
import org.enso.test.utils.ContextUtils;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.Source;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SymbolResolutionTest {
|
||||
private static Context ctx;
|
||||
|
||||
@BeforeClass
|
||||
public static void prepareCtx() {
|
||||
ctx =
|
||||
ContextUtils.defaultContextBuilder()
|
||||
.out(OutputStream.nullOutputStream())
|
||||
.err(OutputStream.nullOutputStream())
|
||||
.build();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close();
|
||||
}
|
||||
public class SymbolResolutionTest extends ContextTest {
|
||||
|
||||
@Test
|
||||
public void resolvingLocalSymbol() throws Exception {
|
||||
|
@ -10,8 +10,8 @@ import org.enso.test.utils.ContextUtils;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.PolyglotException;
|
||||
import org.graalvm.polyglot.Source;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -34,7 +34,7 @@ public class TypeInferenceConsistencyTest {
|
||||
.build();
|
||||
}
|
||||
|
||||
@Before
|
||||
@After
|
||||
public void cleanMessages() {
|
||||
output.reset();
|
||||
}
|
||||
@ -46,6 +46,7 @@ public class TypeInferenceConsistencyTest {
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -28,6 +28,7 @@ public class TypeMembersTest {
|
||||
@After
|
||||
public void disposeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -47,12 +47,14 @@ public class VectorSortTest {
|
||||
values.addAll(valuesGenerator.booleans());
|
||||
values.addAll(valuesGenerator.durations());
|
||||
values.addAll(valuesGenerator.maps());
|
||||
valuesGenerator.dispose();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
values.clear();
|
||||
context.close();
|
||||
context = null;
|
||||
}
|
||||
|
||||
@DataPoints public static List<Value> values;
|
||||
|
@ -27,6 +27,7 @@ public class VectorTest {
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -48,8 +48,11 @@ public class WarningsTest {
|
||||
|
||||
@AfterClass
|
||||
public static void disposeContext() {
|
||||
ensoContext = null;
|
||||
generator.dispose();
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
ensoContext.shutdown();
|
||||
ensoContext = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -42,6 +42,7 @@ public class AssertionsTest {
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close(true);
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -27,6 +27,7 @@ public class DisabledAssertionsTest {
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close(true);
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -36,6 +36,7 @@ public class SuccessfulAssertionExpressionTest {
|
||||
@AfterClass
|
||||
public static void disposeCtx() {
|
||||
ctx.close(true);
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -44,7 +44,9 @@ public class AvoidIdInstrumentationTagTest {
|
||||
|
||||
@After
|
||||
public void disposeContext() {
|
||||
nodes = null;
|
||||
context.close();
|
||||
context = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -48,6 +48,7 @@ public class FunctionPointerTest {
|
||||
@After
|
||||
public void disposeContext() {
|
||||
context.close();
|
||||
context = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -68,7 +68,9 @@ public class IncrementalUpdatesTest {
|
||||
|
||||
@After
|
||||
public void teardownContext() {
|
||||
nodeCountingInstrument = null;
|
||||
context.close();
|
||||
context = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -62,7 +62,9 @@ public class WarningInstrumentationTest {
|
||||
|
||||
@After
|
||||
public void disposeContext() {
|
||||
instrument = null;
|
||||
context.close();
|
||||
context = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -16,7 +16,8 @@ import java.util.UUID
|
||||
|
||||
class IRUtilsTest extends AnyWordSpecLike with Matchers with OptionValues {
|
||||
private val ctx = new InterpreterContext()
|
||||
private val langCtx = ctx.ctx
|
||||
private val langCtx = ctx
|
||||
.ctx()
|
||||
.getBindings(LanguageInfo.ID)
|
||||
.invokeMember(MethodNames.TopScope.LEAK_CONTEXT)
|
||||
.asHostObject[EnsoContext]()
|
||||
|
@ -71,13 +71,15 @@ trait ModifiedTest
|
||||
.build()
|
||||
context.initialize(LanguageInfo.ID)
|
||||
val executionContext = new PolyglotContext(context)
|
||||
InterpreterException.rethrowPolyglot {
|
||||
val result = InterpreterException.rethrowPolyglot {
|
||||
val topScope = executionContext.getTopScope
|
||||
val mainModuleScope = topScope.getModule(mainModule.toString)
|
||||
val assocCons = mainModuleScope.getAssociatedType
|
||||
val mainFun = mainModuleScope.getMethod(assocCons, "main").get
|
||||
mainFun.execute()
|
||||
}
|
||||
context.close()
|
||||
result
|
||||
}
|
||||
|
||||
private def initialCopy(from: File, to: File): Unit = {
|
||||
|
@ -16,7 +16,8 @@ import java.util.UUID
|
||||
|
||||
class SuggestionBuilderTest extends AnyWordSpecLike with Matchers {
|
||||
private val ctx = new InterpreterContext()
|
||||
private val langCtx = ctx.ctx
|
||||
private val langCtx = ctx
|
||||
.ctx()
|
||||
.getBindings(LanguageInfo.ID)
|
||||
.invokeMember(MethodNames.TopScope.LEAK_CONTEXT)
|
||||
.asHostObject[EnsoContext]()
|
||||
|
@ -130,7 +130,8 @@ class TypeSignaturesTest
|
||||
with TypeMatchers {
|
||||
|
||||
private val ctx = new InterpreterContext()
|
||||
private val langCtx = ctx.ctx
|
||||
private val langCtx = ctx
|
||||
.ctx()
|
||||
.getBindings(LanguageInfo.ID)
|
||||
.invokeMember(MethodNames.TopScope.LEAK_CONTEXT)
|
||||
.asHostObject[EnsoContext]()
|
||||
|
@ -15,7 +15,6 @@ import org.enso.polyglot.debugger.{
|
||||
}
|
||||
import org.enso.common.LanguageInfo
|
||||
import org.enso.common.RuntimeOptions
|
||||
|
||||
import org.enso.polyglot.{Function, PolyglotContext}
|
||||
import org.graalvm.polyglot.{Context, Value}
|
||||
import org.scalatest.Assertions
|
||||
@ -28,7 +27,7 @@ import java.io.{
|
||||
PipedOutputStream,
|
||||
PrintStream
|
||||
}
|
||||
import java.nio.file.Paths
|
||||
import java.nio.file.{Path, Paths}
|
||||
import java.util.UUID
|
||||
import java.util.logging.Level
|
||||
|
||||
@ -104,43 +103,101 @@ class ReplaceableSessionManager extends SessionManager {
|
||||
class InterpreterContext(
|
||||
contextModifiers: Context#Builder => Context#Builder = bldr => bldr
|
||||
) {
|
||||
val output = new ByteArrayOutputStream()
|
||||
val err = new ByteArrayOutputStream()
|
||||
val inOut = new PipedOutputStream()
|
||||
val inOutPrinter = new PrintStream(inOut, true)
|
||||
val in = new PipedInputStream(inOut)
|
||||
val sessionManager = new ReplaceableSessionManager
|
||||
var _ctx: Context = _
|
||||
var _err: ByteArrayOutputStream = _
|
||||
var _output: ByteArrayOutputStream = new ByteArrayOutputStream()
|
||||
var _in: PipedInputStream = _
|
||||
var _inOut: PipedOutputStream = _
|
||||
var _inOutPrinter: PrintStream = _
|
||||
var _sessionManager: ReplaceableSessionManager = new ReplaceableSessionManager
|
||||
var _languageHome: Path = _
|
||||
val edition = "0.0.0-dev"
|
||||
def ctx(): Context = {
|
||||
if (_ctx == null) {
|
||||
_output = new ByteArrayOutputStream()
|
||||
_err = new ByteArrayOutputStream()
|
||||
_inOut = new PipedOutputStream()
|
||||
_inOutPrinter = new PrintStream(_inOut, true)
|
||||
_in = new PipedInputStream(_inOut)
|
||||
|
||||
val languageHome = Paths
|
||||
.get("../../test/micro-distribution/component")
|
||||
.toFile
|
||||
.getAbsolutePath
|
||||
val edition = "0.0.0-dev"
|
||||
_languageHome = Paths
|
||||
.get("../../test/micro-distribution/component")
|
||||
|
||||
val ctx = contextModifiers(
|
||||
Context
|
||||
.newBuilder(LanguageInfo.ID)
|
||||
.allowExperimentalOptions(true)
|
||||
.allowAllAccess(true)
|
||||
.allowCreateThread(false)
|
||||
.out(output)
|
||||
.err(err)
|
||||
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
|
||||
.option(RuntimeOptions.DISABLE_IR_CACHES, "true")
|
||||
.option(RuntimeOptions.STRICT_ERRORS, "false")
|
||||
.environment("NO_COLOR", "true")
|
||||
.logHandler(System.err)
|
||||
.in(in)
|
||||
.option(RuntimeOptions.LANGUAGE_HOME_OVERRIDE, languageHome)
|
||||
.option(RuntimeOptions.EDITION_OVERRIDE, edition)
|
||||
.option("engine.WarnInterpreterOnly", "false")
|
||||
.serverTransport { (uri, peer) =>
|
||||
if (uri.toString == DebugServerInfo.URI) {
|
||||
new DebuggerSessionManagerEndpoint(sessionManager, peer)
|
||||
} else null
|
||||
}
|
||||
).build()
|
||||
lazy val executionContext = new PolyglotContext(ctx)
|
||||
_ctx = contextModifiers(
|
||||
Context
|
||||
.newBuilder(LanguageInfo.ID)
|
||||
.allowExperimentalOptions(true)
|
||||
.allowAllAccess(true)
|
||||
.allowCreateThread(false)
|
||||
.out(_output)
|
||||
.err(_err)
|
||||
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
|
||||
.option(RuntimeOptions.DISABLE_IR_CACHES, "true")
|
||||
.option(RuntimeOptions.STRICT_ERRORS, "false")
|
||||
.environment("NO_COLOR", "true")
|
||||
.logHandler(System.err)
|
||||
.in(_in)
|
||||
.option(
|
||||
RuntimeOptions.LANGUAGE_HOME_OVERRIDE,
|
||||
_languageHome.toFile.getAbsolutePath
|
||||
)
|
||||
.option(RuntimeOptions.EDITION_OVERRIDE, edition)
|
||||
.option("engine.WarnInterpreterOnly", "false")
|
||||
.serverTransport { (uri, peer) =>
|
||||
if (uri.toString == DebugServerInfo.URI) {
|
||||
new DebuggerSessionManagerEndpoint(_sessionManager, peer)
|
||||
} else null
|
||||
}
|
||||
).build()
|
||||
}
|
||||
_ctx
|
||||
}
|
||||
|
||||
def err(): ByteArrayOutputStream = {
|
||||
assert(_ctx != null)
|
||||
_err
|
||||
}
|
||||
|
||||
def output(): ByteArrayOutputStream = {
|
||||
_output
|
||||
}
|
||||
|
||||
def in(): PipedInputStream = {
|
||||
assert(_ctx != null)
|
||||
_in
|
||||
}
|
||||
|
||||
def inOut(): PipedOutputStream = {
|
||||
assert(_ctx != null)
|
||||
_inOut;
|
||||
}
|
||||
|
||||
def inOutPrinter(): PrintStream = {
|
||||
assert(_ctx != null)
|
||||
_inOutPrinter
|
||||
}
|
||||
|
||||
def sessionManager(): ReplaceableSessionManager = {
|
||||
_sessionManager
|
||||
}
|
||||
|
||||
def languageHome(): Path = {
|
||||
assert(_ctx != null)
|
||||
_languageHome
|
||||
}
|
||||
|
||||
def close(): Unit = {
|
||||
if (_ctx != null) {
|
||||
_ctx.close()
|
||||
_ctx = null
|
||||
}
|
||||
|
||||
_output.reset()
|
||||
if (_err != null) _err.close()
|
||||
if (_in != null) _in.close()
|
||||
if (_inOut != null) _inOut.close()
|
||||
}
|
||||
lazy val executionContext = new PolyglotContext(ctx())
|
||||
}
|
||||
|
||||
trait InterpreterRunner {
|
||||
@ -154,7 +211,10 @@ trait InterpreterRunner {
|
||||
def withLocationsInstrumenter(
|
||||
test: LocationsInstrumenter => Unit
|
||||
)(implicit interpreterContext: InterpreterContext): Unit = {
|
||||
val instrument = interpreterContext.ctx.getEngine.getInstruments
|
||||
val instrument = interpreterContext
|
||||
.ctx()
|
||||
.getEngine
|
||||
.getInstruments
|
||||
.get(CodeLocationsTestInstrument.INSTRUMENT_ID)
|
||||
.lookup(classOf[CodeLocationsTestInstrument])
|
||||
val instrumenter = LocationsInstrumenter(instrument)
|
||||
@ -166,7 +226,10 @@ trait InterpreterRunner {
|
||||
def withIdsInstrumenter(
|
||||
test: IdsInstrumenter => Unit
|
||||
)(implicit interpreterContext: InterpreterContext): Unit = {
|
||||
val instrument = interpreterContext.ctx.getEngine.getInstruments
|
||||
val instrument = interpreterContext
|
||||
.ctx()
|
||||
.getEngine
|
||||
.getInstruments
|
||||
.get(CodeIdsTestInstrument.INSTRUMENT_ID)
|
||||
.lookup(classOf[CodeIdsTestInstrument])
|
||||
val instrumenter = IdsInstrumenter(instrument)
|
||||
@ -185,7 +248,7 @@ trait InterpreterRunner {
|
||||
def getMain(
|
||||
code: String
|
||||
)(implicit interpreterContext: InterpreterContext): MainMethod = {
|
||||
interpreterContext.output.reset()
|
||||
interpreterContext.output().reset()
|
||||
val module = InterpreterException.rethrowPolyglot(
|
||||
interpreterContext.executionContext.evalModule(code, "Test")
|
||||
)
|
||||
@ -206,52 +269,52 @@ trait InterpreterRunner {
|
||||
def consumeErr(implicit
|
||||
interpreterContext: InterpreterContext
|
||||
): List[String] = {
|
||||
val result = interpreterContext.err.toString
|
||||
interpreterContext.err.reset()
|
||||
val result = interpreterContext.err().toString
|
||||
interpreterContext.err().reset()
|
||||
result.linesIterator.toList
|
||||
}
|
||||
|
||||
def consumeErrBytes(implicit
|
||||
interpreterContext: InterpreterContext
|
||||
): Array[Byte] = {
|
||||
val result = interpreterContext.err.toByteArray
|
||||
interpreterContext.err.reset()
|
||||
val result = interpreterContext.err().toByteArray
|
||||
interpreterContext.err().reset()
|
||||
result
|
||||
}
|
||||
|
||||
def consumeOut(implicit
|
||||
interpreterContext: InterpreterContext
|
||||
): List[String] = {
|
||||
val result = interpreterContext.output.toString
|
||||
interpreterContext.output.reset()
|
||||
val result = interpreterContext.output().toString
|
||||
interpreterContext.output().reset()
|
||||
result.linesIterator.toList
|
||||
}
|
||||
|
||||
def consumeOutBytes(implicit
|
||||
interpreterContext: InterpreterContext
|
||||
): Array[Byte] = {
|
||||
val result = interpreterContext.output.toByteArray
|
||||
interpreterContext.output.reset()
|
||||
val result = interpreterContext.output().toByteArray
|
||||
interpreterContext.output().reset()
|
||||
result
|
||||
}
|
||||
|
||||
def feedInput(
|
||||
string: String
|
||||
)(implicit interpreterContext: InterpreterContext): Unit = {
|
||||
interpreterContext.inOutPrinter.println(string)
|
||||
interpreterContext.inOutPrinter().println(string)
|
||||
}
|
||||
|
||||
def feedBytes(
|
||||
input: Array[Byte]
|
||||
)(implicit interpreterContext: InterpreterContext): Unit = {
|
||||
interpreterContext.inOut.write(input)
|
||||
interpreterContext.inOut.flush()
|
||||
interpreterContext.inOut().write(input)
|
||||
interpreterContext.inOut().flush()
|
||||
}
|
||||
|
||||
def setSessionManager(
|
||||
manager: SessionManager
|
||||
)(implicit interpreterContext: InterpreterContext): Unit =
|
||||
interpreterContext.sessionManager.setSessionManager(manager)
|
||||
interpreterContext.sessionManager().setSessionManager(manager)
|
||||
|
||||
// For Enso raw text blocks inside scala multiline strings
|
||||
val rawTQ = "\"\"\""
|
||||
|
@ -36,7 +36,7 @@ class RuntimeServerTest
|
||||
|
||||
val out: ByteArrayOutputStream = new ByteArrayOutputStream()
|
||||
val logOut: ByteArrayOutputStream = new ByteArrayOutputStream()
|
||||
val context =
|
||||
protected val context =
|
||||
Context
|
||||
.newBuilder(LanguageInfo.ID)
|
||||
.allowExperimentalOptions(true)
|
||||
|
@ -15,7 +15,8 @@ class RuntimeManagementTest extends InterpreterTest {
|
||||
): Unit = {
|
||||
|
||||
"Interrupt threads through Thread#interrupt()" in {
|
||||
val langCtx = interpreterContext.ctx
|
||||
val langCtx = interpreterContext
|
||||
.ctx()
|
||||
.getBindings(LanguageInfo.ID)
|
||||
.invokeMember(MethodNames.TopScope.LEAK_CONTEXT)
|
||||
.asHostObject[EnsoContext]()
|
||||
|
@ -290,6 +290,10 @@ public final class EnsoContext {
|
||||
threadManager.shutdown();
|
||||
resourceManager.shutdown();
|
||||
compiler.shutdown(shouldWaitForPendingSerializationJobs);
|
||||
packageRepository.shutdown();
|
||||
guestJava = null;
|
||||
topScope = null;
|
||||
hostClassLoader.close();
|
||||
}
|
||||
|
||||
private boolean shouldAssertionsBeEnabled() {
|
||||
|
@ -17,7 +17,7 @@ import org.slf4j.LoggerFactory;
|
||||
* the classes that are loaded via this class loader are first searched inside those archives. If
|
||||
* not found, delegates to parent class loaders.
|
||||
*/
|
||||
final class HostClassLoader extends URLClassLoader {
|
||||
final class HostClassLoader extends URLClassLoader implements AutoCloseable {
|
||||
|
||||
private final Map<String, Class<?>> loadedClasses = new ConcurrentHashMap<>();
|
||||
private static final Logger logger = LoggerFactory.getLogger(HostClassLoader.class);
|
||||
@ -84,4 +84,9 @@ final class HostClassLoader extends URLClassLoader {
|
||||
return super.findResources(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
loadedClasses.clear();
|
||||
}
|
||||
}
|
||||
|
@ -121,6 +121,7 @@ final class SerializationPool {
|
||||
t.join();
|
||||
}
|
||||
context.logSerializationManager(Level.FINE, "Serialization manager has been shut down.");
|
||||
threads.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -610,6 +610,13 @@ private class DefaultPackageRepository(
|
||||
}
|
||||
else Failure(PackageManager.PackageNotFound())
|
||||
}
|
||||
|
||||
override def shutdown(): Unit = {
|
||||
loadedPackages.clear()
|
||||
loadedModules.clear()
|
||||
loadedComponents.clear()
|
||||
loadedLibraryBindings.clear()
|
||||
}
|
||||
}
|
||||
|
||||
private object DefaultPackageRepository {
|
||||
|
Loading…
Reference in New Issue
Block a user