-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6ceefe7
commit b47eac0
Showing
8 changed files
with
227 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
jjava/src/test/java/org/dflib/jjava/jupyter/kernel/ContainerizedKernelCase.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package org.dflib.jjava.jupyter.kernel; | ||
|
||
import org.junit.jupiter.api.BeforeAll; | ||
import org.testcontainers.containers.Container; | ||
import org.testcontainers.containers.ExecConfig; | ||
import org.testcontainers.containers.GenericContainer; | ||
import org.testcontainers.containers.wait.strategy.Wait; | ||
import org.testcontainers.utility.MountableFile; | ||
|
||
import java.io.IOException; | ||
import java.time.Duration; | ||
import java.util.ArrayList; | ||
import java.util.Base64; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
public abstract class ContainerizedKernelCase { | ||
|
||
protected static final GenericContainer<?> container; | ||
protected static final String WORKING_DIRECTORY = "/test"; | ||
protected static final String CONTAINER_KERNELSPEC = "/usr/share/jupyter/kernels/java"; | ||
protected static final String CONTAINER_RESOURCES = WORKING_DIRECTORY + "/resources"; | ||
protected static final String TEST_CLASSPATH = CONTAINER_RESOURCES + "/classes"; | ||
|
||
private static final String BASE_IMAGE = String.format("eclipse-temurin:%s", Runtime.version().version().get(0)); | ||
private static final String FS_KERNELSPEC = "../kernelspec/java"; | ||
private static final String FS_RESOURCES = "src/test/resources"; | ||
|
||
static { | ||
container = new GenericContainer<>(BASE_IMAGE) | ||
.withWorkingDirectory(WORKING_DIRECTORY) | ||
.withCopyToContainer(MountableFile.forHostPath(FS_KERNELSPEC), CONTAINER_KERNELSPEC) | ||
.withCopyToContainer(MountableFile.forHostPath(FS_RESOURCES), CONTAINER_RESOURCES) | ||
.withCommand("bash", "-c", getStartupCommand()) | ||
.waitingFor(Wait.forSuccessfulCommand(getSuccessfulCommand())) | ||
.withStartupTimeout(Duration.ofMinutes(5)); | ||
container.start(); | ||
} | ||
|
||
@BeforeAll | ||
static void compileSources() throws IOException, InterruptedException { | ||
String source = "$(find " + CONTAINER_RESOURCES + "/src -name '*.java')"; | ||
Container.ExecResult compileResult = executeInContainer("javac -d " + TEST_CLASSPATH + " " + source); | ||
|
||
assertEquals("", compileResult.getStdout()); | ||
assertEquals("", compileResult.getStderr()); | ||
} | ||
|
||
protected static Container.ExecResult executeInContainer(String... commands) throws IOException, InterruptedException { | ||
List<String> wrappedCommands = new ArrayList<>(); | ||
wrappedCommands.add("bash"); | ||
wrappedCommands.add("-c"); | ||
wrappedCommands.addAll(List.of(commands)); | ||
return container.execInContainer(wrappedCommands.toArray(new String[]{})); | ||
} | ||
|
||
protected static Container.ExecResult executeInKernel(String snippet) throws IOException, InterruptedException { | ||
return executeInKernel(snippet, Collections.emptyMap()); | ||
} | ||
|
||
protected static Container.ExecResult executeInKernel(String snippet, Map<String, String> env) throws IOException, InterruptedException { | ||
String snippet64 = Base64.getEncoder().encodeToString(snippet.getBytes()); | ||
String jupyterCommand = venvCommand("jupyter console --kernel=java --simple-prompt"); | ||
String[] containerCommand = new String[]{"bash", "-c", "base64 -d <<< " + snippet64 + " | " + jupyterCommand}; | ||
return container.execInContainer(ExecConfig.builder() | ||
.envVars(env) | ||
.command(containerCommand) | ||
.build() | ||
); | ||
} | ||
|
||
private static String getStartupCommand() { | ||
return String.join(" && ", | ||
"apt-get update", | ||
"apt-get install --no-install-recommends -y python3 python3-pip python3-venv", | ||
"python3 -m venv ./venv", | ||
venvCommand("pip install jupyter-console --progress-bar off"), | ||
"tail -f /dev/null" | ||
); | ||
} | ||
|
||
private static String getSuccessfulCommand() { | ||
return venvCommand("jupyter kernelspec list") | ||
+ " | grep ' java ' && " | ||
+ venvCommand("jupyter console --version"); | ||
} | ||
|
||
private static String venvCommand(String command) { | ||
return WORKING_DIRECTORY + "/venv/bin/" + command; | ||
} | ||
} |
103 changes: 103 additions & 0 deletions
103
jjava/src/test/java/org/dflib/jjava/jupyter/kernel/KernelEnvIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package org.dflib.jjava.jupyter.kernel; | ||
|
||
import org.dflib.jjava.Env; | ||
import org.hamcrest.CoreMatchers; | ||
import org.junit.jupiter.api.Test; | ||
import org.testcontainers.containers.Container; | ||
|
||
import java.util.Map; | ||
|
||
import static org.hamcrest.CoreMatchers.containsString; | ||
import static org.hamcrest.CoreMatchers.not; | ||
import static org.hamcrest.MatcherAssert.assertThat; | ||
|
||
class KernelEnvIT extends ContainerizedKernelCase { | ||
|
||
@Test | ||
void compilerOpts() throws Exception { | ||
Map<String, String> env = Map.of(Env.JJAVA_COMPILER_OPTS, "-source 9"); | ||
String snippet = "var value = 1"; | ||
Container.ExecResult snippetResult = executeInKernel(snippet, env); | ||
|
||
assertThat(snippetResult.getStderr(), CoreMatchers.allOf( | ||
containsString("| var value = 1;"), | ||
containsString("'var' is a restricted local variable type") | ||
)); | ||
} | ||
|
||
@Test | ||
void timeout() throws Exception { | ||
Map<String, String> env = Map.of(Env.JJAVA_TIMEOUT, "3000"); | ||
String snippet = "Thread.sleep(5000);"; | ||
Container.ExecResult snippetResult = executeInKernel(snippet, env); | ||
|
||
assertThat(snippetResult.getStderr(), CoreMatchers.allOf( | ||
containsString("| " + snippet), | ||
containsString("Evaluation timed out after 3000 milliseconds.") | ||
)); | ||
} | ||
|
||
@Test | ||
void classpath() throws Exception { | ||
Map<String, String> env = Map.of(Env.JJAVA_CLASSPATH, TEST_CLASSPATH); | ||
String snippet = String.join("\n", | ||
"import org.dflib.jjava.Dummy;", | ||
"Dummy.class.getName()" | ||
); | ||
Container.ExecResult snippetResult = executeInKernel(snippet, env); | ||
|
||
assertThat(snippetResult.getStderr(), not(containsString("|"))); | ||
assertThat(snippetResult.getStdout(), containsString("org.dflib.jjava.Dummy")); | ||
} | ||
|
||
@Test | ||
void startUpScriptsPath() throws Exception { | ||
Map<String, String> env = Map.of(Env.JJAVA_STARTUP_SCRIPTS_PATH, CONTAINER_RESOURCES + "/test-init.jshell"); | ||
String snippet = "ping()"; | ||
Container.ExecResult snippetResult = executeInKernel(snippet, env); | ||
|
||
assertThat(snippetResult.getStderr(), not(containsString("|"))); | ||
assertThat(snippetResult.getStdout(), containsString("pong!")); | ||
} | ||
|
||
@Test | ||
void startUpScript() throws Exception { | ||
Map<String, String> env = Map.of(Env.JJAVA_STARTUP_SCRIPT, "public String ping() { return \"pong!\"; }"); | ||
String snippet = "ping()"; | ||
Container.ExecResult snippetResult = executeInKernel(snippet, env); | ||
|
||
assertThat(snippetResult.getStderr(), not(containsString("|"))); | ||
assertThat(snippetResult.getStdout(), containsString("pong!")); | ||
} | ||
|
||
@Test | ||
void loadExtensions_Default() throws Exception { | ||
String snippet = "printf(\"Hello, %s!\", \"world\");"; | ||
Container.ExecResult snippetResult = executeInKernel(snippet); | ||
|
||
assertThat(snippetResult.getStderr(), not(containsString("|"))); | ||
assertThat(snippetResult.getStdout(), containsString("Hello, world!")); | ||
} | ||
|
||
@Test | ||
void loadExtensions_Disable() throws Exception { | ||
Map<String, String> env = Map.of(Env.JJAVA_LOAD_EXTENSIONS, "0"); | ||
String snippet = "printf(\"Hello, %s!\", \"world\");"; | ||
Container.ExecResult snippetResult = executeInKernel(snippet, env); | ||
|
||
assertThat(snippetResult.getStderr(), CoreMatchers.allOf( | ||
containsString("| " + snippet), | ||
containsString("cannot find symbol") | ||
)); | ||
} | ||
|
||
@Test | ||
void jvmOpts() throws Exception { | ||
Map<String, String> env = Map.of(Env.JJAVA_JVM_OPTS, "-Xmx300m"); | ||
String snippet = "Runtime.getRuntime().maxMemory()"; | ||
Container.ExecResult snippetResult = executeInKernel(snippet, env); | ||
|
||
assertThat(snippetResult.getStderr(), not(containsString("|"))); | ||
assertThat(snippetResult.getStdout(), containsString(String.valueOf(300 * (int) Math.pow(1024, 2)))); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
jjava/src/test/java/org/dflib/jjava/jupyter/kernel/KernelStartupIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package org.dflib.jjava.jupyter.kernel; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.testcontainers.containers.Container; | ||
|
||
import static org.hamcrest.CoreMatchers.containsString; | ||
import static org.hamcrest.CoreMatchers.not; | ||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
class KernelStartupIT extends ContainerizedKernelCase { | ||
|
||
@Test | ||
void startUp() throws Exception { | ||
String snippet = "1000d + 1"; | ||
Container.ExecResult snippetResult = executeInKernel(snippet); | ||
|
||
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStderr()); | ||
assertThat(snippetResult.getStderr(), not(containsString("|"))); | ||
assertThat(snippetResult.getStdout(), containsString("1001.0")); | ||
} | ||
} |
57 changes: 0 additions & 57 deletions
57
jjava/src/test/java/org/dflib/jjava/jupyter/kernel/testcontainers/KernelIT.java
This file was deleted.
Oops, something went wrong.
18 changes: 0 additions & 18 deletions
18
jjava/src/test/java/org/dflib/jjava/jupyter/kernel/testcontainers/KernelStartupTestIT.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package org.dflib.jjava; | ||
|
||
public class Dummy { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
public String ping() { | ||
return "pong!"; | ||
} |