Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;

Expand Down Expand Up @@ -47,7 +49,7 @@ public abstract class ContainerizedKernelCase {
}

@BeforeAll
static void compileSources() throws IOException, InterruptedException {
static void setUp() throws IOException, InterruptedException {
String source = "$(find " + CONTAINER_RESOURCES + "/src -name '*.java')";
Container.ExecResult compileResult = executeInContainer("javac -d " + TEST_CLASSPATH + " " + source);

Expand All @@ -68,9 +70,29 @@ protected static Container.ExecResult executeInKernel(String snippet) throws IOE
}

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", "echo \"" + snippet64 + "\" | base64 -d | " + jupyterCommand};
long snippetLines = snippet.lines().count();
String snippetEscaped = snippet.replace("\\", "\\\\").replace("\"", "\\\"");
String snippetFeeding = Arrays.stream(snippetEscaped.split("\n"))
.flatMap(line -> Stream.of(
"p.expect(r'In \\[\\d+\\]:')",
"p.sendline(\"" + line + "\")"
))
.collect(Collectors.joining("\n"));

String pexpectScript = String.join("\n",
"import pexpect, sys, os, time",
"env = os.environ.copy()",
"env['PROMPT_TOOLKIT_NO_CPR'] = '1'",
"env['TERM'] = 'dumb'",
"p=pexpect.spawn('" + venvCommand("jupyter") + "', "
+ "['console', '--kernel=java', '--no-confirm-exit'], "
+ "env=env, timeout=60, encoding='utf-8')",
"p.logfile_read = sys.stdout",
snippetFeeding,
"p.expect(r'In \\[" + (snippetLines + 1) + "\\]:')",
"p.close(force=True)"
);
String[] containerCommand = new String[]{venvCommand("python"), "-c", pexpectScript};
Container.ExecResult execResult = container.execInContainer(ExecConfig.builder()
.envVars(env)
.command(containerCommand)
Expand All @@ -80,17 +102,17 @@ protected static Container.ExecResult executeInKernel(String snippet, Map<String
LOGGER.info("env = {}", env);
LOGGER.info("snippet = {}", snippet);
LOGGER.info("exitCode = {}", execResult.getExitCode());
LOGGER.debug("stderr = {}", execResult.getStderr());
LOGGER.debug("stdout = {}", execResult.getStdout());
LOGGER.debug("stderr = {}", execResult.getStderr());
return execResult;
}

private static String getStartupCommand() {
return String.join(" && ",
"apt-get update",
"apt-get install --no-install-recommends -y python3 python3-pip python3-venv",
"apt-get install --no-install-recommends -y python3 python3-pip python3-venv curl",
"python3 -m venv ./venv",
venvCommand("pip install jupyter-console --progress-bar off"),
venvCommand("pip install jupyter-console pexpect --progress-bar off"),
"tail -f /dev/null"
);
}
Expand Down
37 changes: 23 additions & 14 deletions jjava-distro/src/test/java/org/dflib/jjava/distro/KernelEnvIT.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package org.dflib.jjava.distro;

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;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class KernelEnvIT extends ContainerizedKernelCase {

Expand All @@ -18,7 +19,8 @@ public void compilerOpts() throws Exception {
String snippet = "var value = 1;";
Container.ExecResult snippetResult = executeInKernel(snippet, env);

assertThat(snippetResult.getStderr(), CoreMatchers.allOf(
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), allOf(
containsString("| var value = 1;"),
containsString(Runtime.version().feature() == 11
? "'var' is a restricted local variable type"
Expand All @@ -32,7 +34,8 @@ public void timeout() throws Exception {
String snippet = "Thread.sleep(5000);";
Container.ExecResult snippetResult = executeInKernel(snippet, env);

assertThat(snippetResult.getStderr(), CoreMatchers.allOf(
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), allOf(
containsString("| " + snippet),
containsString("Evaluation timed out after 3000 milliseconds.")
));
Expand All @@ -43,21 +46,23 @@ public 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()"
"\"className = \" + Dummy.class.getName();"
);
Container.ExecResult snippetResult = executeInKernel(snippet, env);

assertThat(snippetResult.getStderr(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString("org.dflib.jjava.Dummy"));
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString("className = org.dflib.jjava.Dummy"));
}

@Test
public void startUpScriptsPath() throws Exception {
Map<String, String> env = Map.of(Env.JJAVA_STARTUP_SCRIPTS_PATH, CONTAINER_RESOURCES + "/test-ping.jshell");
Map<String, String> env = Map.of(Env.JJAVA_STARTUP_SCRIPTS_PATH, CONTAINER_RESOURCES + "/test-ping.jshell");
String snippet = "ping()";
Container.ExecResult snippetResult = executeInKernel(snippet, env);

assertThat(snippetResult.getStderr(), not(containsString("|")));
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString("pong!"));
}

Expand All @@ -67,7 +72,8 @@ public void startUpScript() throws Exception {
String snippet = "ping()";
Container.ExecResult snippetResult = executeInKernel(snippet, env);

assertThat(snippetResult.getStderr(), not(containsString("|")));
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString("pong!"));
}

Expand All @@ -76,7 +82,8 @@ public void loadExtensions_Default() throws Exception {
String snippet = "printf(\"Hello, %s!\", \"world\");";
Container.ExecResult snippetResult = executeInKernel(snippet);

assertThat(snippetResult.getStderr(), not(containsString("|")));
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString("Hello, world!"));
}

Expand All @@ -86,7 +93,8 @@ public void loadExtensions_Disable() throws Exception {
String snippet = "printf(\"Hello, %s!\", \"world\");";
Container.ExecResult snippetResult = executeInKernel(snippet, env);

assertThat(snippetResult.getStderr(), CoreMatchers.allOf(
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), allOf(
containsString("| " + snippet),
containsString("cannot find symbol")
));
Expand All @@ -98,7 +106,8 @@ public void jvmOpts() throws Exception {
String snippet = "Runtime.getRuntime().maxMemory()";
Container.ExecResult snippetResult = executeInKernel(snippet, env);

assertThat(snippetResult.getStderr(), not(containsString("|")));
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString(String.valueOf(300 * (int) Math.pow(1024, 2))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
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.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class KernelMagicIT extends ContainerizedKernelCase {
Expand All @@ -19,7 +19,7 @@ public void jars() throws Exception {
"https://repo1.maven.org/maven2/jakarta/annotation/jakarta.annotation-api/3.0.0/jakarta.annotation-api-3.0.0.jar",
"-o", jar
);
assertEquals("", fetchResult.getStderr());
assertEquals(0, fetchResult.getExitCode(), fetchResult.getStdout());

String snippet = String.join("\n",
"%jars " + jar,
Expand All @@ -28,7 +28,8 @@ public void jars() throws Exception {
);
Container.ExecResult snippetResult = executeInKernel(snippet);

assertThat(snippetResult.getStderr(), not(containsString("|")));
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString("jakarta.annotation.Nullable"));
}

Expand All @@ -37,12 +38,13 @@ public void classpath() throws Exception {
String snippet = String.join("\n",
"%classpath " + TEST_CLASSPATH,
"import org.dflib.jjava.Dummy;",
"Dummy.class.getName()"
"\"className = \" + Dummy.class.getName();"
);
Container.ExecResult snippetResult = executeInKernel(snippet);

assertThat(snippetResult.getStderr(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString("org.dflib.jjava.Dummy"));
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString("className = org.dflib.jjava.Dummy"));
}

@Test
Expand All @@ -53,7 +55,8 @@ public void maven() throws Exception {
);
Container.ExecResult snippetResult = executeInKernel(snippet);

assertThat(snippetResult.getStderr(), not(containsString("|")));
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString("dflib-jupyter-1.0.0-RC1.jar"));
}

Expand All @@ -67,7 +70,8 @@ public void mavenIvySyntax() throws Exception {

Container.ExecResult snippetResult = executeInKernel(snippet);

assertThat(snippetResult.getStderr(), not(containsString("|")));
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString("jakarta.annotation-api-3.0.0.jar"));
}

Expand All @@ -80,7 +84,8 @@ public void load() throws Exception {
);
Container.ExecResult snippetResult = executeInKernel(snippet);

assertThat(snippetResult.getStderr(), not(containsString("|")));
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString("pong!"));
}

Expand All @@ -94,7 +99,8 @@ public void loadFromPOM() throws Exception {
);
Container.ExecResult snippetResult = executeInKernel(snippet);

assertThat(snippetResult.getStderr(), not(containsString("|")));
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString("jakarta.annotation.Nullable"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

import java.util.Map;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.matchesPattern;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class KernelStartupIT extends ContainerizedKernelCase {

Expand All @@ -17,12 +18,13 @@ public void startUp() throws Exception {
String snippet = "1000d + 1";
Container.ExecResult snippetResult = executeInKernel(snippet);

assertThat(snippetResult.getStderr(), not(containsString("|")));
assertEquals(0, snippetResult.getExitCode(), snippetResult.getStdout());
assertThat(snippetResult.getStdout(), not(containsString("|")));
assertThat(snippetResult.getStdout(), containsString("1001.0"));
}

@Test
void startUp_scriptRequiresClasspath() throws Exception {
public void startUp_scriptRequiresClasspath() throws Exception {
Map<String, String> env = Map.of(
Env.JJAVA_CLASSPATH, TEST_CLASSPATH,
Env.JJAVA_STARTUP_SCRIPT, "var obj = new org.dflib.jjava.Dummy()"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
import org.dflib.jjava.jupyter.kernel.display.common.Url;
import org.dflib.jjava.jupyter.kernel.history.HistoryEntry;
import org.dflib.jjava.jupyter.kernel.history.HistoryManager;
import org.dflib.jjava.jupyter.kernel.magic.MagicsResolver;
import org.dflib.jjava.jupyter.kernel.magic.MagicsRegistry;
import org.dflib.jjava.jupyter.kernel.magic.MagicsResolver;
import org.dflib.jjava.jupyter.kernel.util.PathsHandler;
import org.dflib.jjava.jupyter.kernel.util.StringStyler;
import org.dflib.jjava.jupyter.messages.Header;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import org.dflib.jjava.jupyter.kernel.history.HistoryManager;
import org.dflib.jjava.jupyter.kernel.magic.CellMagic;
import org.dflib.jjava.jupyter.kernel.magic.LineMagic;
import org.dflib.jjava.jupyter.kernel.magic.MagicsResolver;
import org.dflib.jjava.jupyter.kernel.magic.MagicTranspiler;
import org.dflib.jjava.jupyter.kernel.magic.MagicsRegistry;
import org.dflib.jjava.jupyter.kernel.magic.MagicsResolver;
import org.dflib.jjava.jupyter.kernel.util.StringStyler;
import org.dflib.jjava.jupyter.kernel.util.TextColor;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.dflib.jjava.jupyter.messages;

import org.dflib.jjava.jupyter.channels.JupyterSocket;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
import org.dflib.jjava.jupyter.kernel.display.DisplayData;
import org.dflib.jjava.jupyter.kernel.display.Renderer;
import org.dflib.jjava.jupyter.kernel.history.HistoryManager;
import org.dflib.jjava.jupyter.kernel.magic.MagicsResolver;
import org.dflib.jjava.jupyter.kernel.magic.MagicTranspiler;
import org.dflib.jjava.jupyter.kernel.magic.MagicsRegistry;
import org.dflib.jjava.jupyter.kernel.magic.MagicsResolver;
import org.dflib.jjava.jupyter.kernel.util.CharPredicate;
import org.dflib.jjava.jupyter.kernel.util.PathsHandler;
import org.dflib.jjava.jupyter.kernel.util.StringStyler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import jdk.jshell.JShell;
import org.dflib.jjava.jupyter.kernel.BaseKernelBuilder;
import org.dflib.jjava.jupyter.kernel.LanguageInfo;
import org.dflib.jjava.jupyter.kernel.magic.MagicsResolver;
import org.dflib.jjava.jupyter.kernel.magic.MagicTranspiler;
import org.dflib.jjava.jupyter.kernel.magic.MagicsResolver;
import org.dflib.jjava.kernel.execution.CodeEvaluator;
import org.dflib.jjava.kernel.execution.JJavaExecutionControlProvider;

Expand Down Expand Up @@ -96,4 +96,4 @@ protected JJavaExecutionControlProvider buildJShellExecControlProvider(String na
? jShellExecControlProvider
: new JJavaExecutionControlProvider(name);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonReader;
import org.dflib.jjava.kernel.JavaKernel;
import org.dflib.jjava.jupyter.kernel.magic.LineMagic;
import org.dflib.jjava.jupyter.kernel.magic.MagicsArgs;
import org.dflib.jjava.kernel.JavaKernel;

import java.io.FileNotFoundException;
import java.io.Reader;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import java.nio.file.Path;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

public class JavaKernelExtensionsLifecycleTest {

Expand Down
Loading