Skip to content

Commit 34e81ce

Browse files
committed
Add regression tests for Together-Java#22
1 parent 3327c9a commit 34e81ce

File tree

2 files changed

+121
-58
lines changed

2 files changed

+121
-58
lines changed

pom.xml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
<properties>
1515
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16+
<junit-jupiter.version>5.3.2</junit-jupiter.version>
1617
</properties>
1718

1819
<build>
@@ -116,13 +117,19 @@
116117
<dependency>
117118
<groupId>org.junit.jupiter</groupId>
118119
<artifactId>junit-jupiter-api</artifactId>
119-
<version>5.3.1</version>
120+
<version>${junit-jupiter.version}</version>
120121
<scope>test</scope>
121122
</dependency>
122123
<dependency>
123124
<groupId>org.junit.jupiter</groupId>
124125
<artifactId>junit-jupiter-engine</artifactId>
125-
<version>5.3.1</version>
126+
<version>${junit-jupiter.version}</version>
127+
<scope>test</scope>
128+
</dependency>
129+
<dependency>
130+
<groupId>org.junit.jupiter</groupId>
131+
<artifactId>junit-jupiter-params</artifactId>
132+
<version>${junit-jupiter.version}</version>
126133
<scope>test</scope>
127134
</dependency>
128135
</dependencies>
Lines changed: 112 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,143 @@
11
package org.togetherjava.discord.server.execution;
22

3-
import jdk.jshell.Diag;
4-
import jdk.jshell.SnippetEvent;
5-
import org.junit.jupiter.api.AfterAll;
6-
import org.junit.jupiter.api.BeforeAll;
7-
import org.junit.jupiter.api.Test;
8-
import org.togetherjava.discord.server.Config;
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertFalse;
5+
import static org.junit.jupiter.api.Assertions.assertNull;
6+
import static org.junit.jupiter.api.Assertions.assertThrows;
7+
import static org.junit.jupiter.api.Assertions.assertTrue;
98

109
import java.time.Duration;
1110
import java.util.List;
1211
import java.util.Properties;
1312
import java.util.concurrent.Executors;
1413
import java.util.stream.Collectors;
15-
16-
import static org.junit.jupiter.api.Assertions.*;
14+
import jdk.jshell.Diag;
15+
import jdk.jshell.Snippet.Status;
16+
import jdk.jshell.SnippetEvent;
17+
import org.junit.jupiter.api.AfterAll;
18+
import org.junit.jupiter.api.BeforeAll;
19+
import org.junit.jupiter.api.Test;
20+
import org.junit.jupiter.params.ParameterizedTest;
21+
import org.junit.jupiter.params.provider.ValueSource;
22+
import org.togetherjava.discord.server.Config;
23+
import org.togetherjava.discord.server.execution.JShellWrapper.JShellResult;
1724

1825
class JShellWrapperTest {
1926

20-
private static JShellWrapper wrapper;
21-
22-
@BeforeAll
23-
static void setupWrapper() {
24-
Properties properties = new Properties();
25-
properties.setProperty("blocked.packages", "java.time");
26-
Config config = new Config(properties);
27-
TimeWatchdog timeWatchdog = new TimeWatchdog(
28-
Executors.newScheduledThreadPool(1),
29-
Duration.ofMinutes(20)
30-
);
31-
wrapper = new JShellWrapper(config, timeWatchdog);
27+
private static JShellWrapper wrapper;
28+
29+
@BeforeAll
30+
static void setupWrapper() {
31+
Properties properties = new Properties();
32+
properties.setProperty("blocked.packages", "java.time");
33+
Config config = new Config(properties);
34+
TimeWatchdog timeWatchdog = new TimeWatchdog(
35+
Executors.newScheduledThreadPool(1),
36+
Duration.ofMinutes(20)
37+
);
38+
wrapper = new JShellWrapper(config, timeWatchdog);
39+
}
40+
41+
@AfterAll
42+
static void cleanup() {
43+
wrapper.close();
44+
}
45+
46+
@Test
47+
void reportsCompileTimeError() {
48+
JShellWrapper.JShellResult result = wrapper.eval("crazy stuff");
49+
50+
assertFalse(result.getEvents().isEmpty(), "Found no events");
51+
52+
for (SnippetEvent snippetEvent : result.getEvents()) {
53+
List<Diag> diags = wrapper.getSnippetDiagnostics(snippetEvent.snippet())
54+
.collect(Collectors.toList());
55+
assertFalse(diags.isEmpty(), "Has no diagnostics");
56+
assertTrue(diags.get(0).isError(), "Diagnostic is no error");
3257
}
58+
}
3359

34-
@AfterAll
35-
static void cleanup() {
36-
wrapper.close();
37-
}
60+
@Test
61+
void correctlyComputesExpression() {
62+
JShellWrapper.JShellResult result = wrapper.eval("1+1");
3863

39-
@Test
40-
void reportsCompileTimeError() {
41-
JShellWrapper.JShellResult result = wrapper.eval("crazy stuff");
64+
assertEquals(result.getEvents().size(), 1, "Event count is not 1");
4265

43-
assertFalse(result.getEvents().isEmpty(), "Found no events");
66+
SnippetEvent snippetEvent = result.getEvents().get(0);
4467

45-
for (SnippetEvent snippetEvent : result.getEvents()) {
46-
List<Diag> diags = wrapper.getSnippetDiagnostics(snippetEvent.snippet()).collect(Collectors.toList());
47-
assertFalse(diags.isEmpty(), "Has no diagnostics");
48-
assertTrue(diags.get(0).isError(), "Diagnostic is no error");
49-
}
50-
}
68+
assertNull(snippetEvent.exception(), "An exception occurred");
5169

52-
@Test
53-
void correctlyComputesExpression() {
54-
JShellWrapper.JShellResult result = wrapper.eval("1+1");
70+
assertEquals("2", snippetEvent.value(), "Calculation was wrong");
71+
}
5572

56-
assertEquals(result.getEvents().size(), 1, "Event count is not 1");
73+
@Test
74+
void savesHistory() {
75+
wrapper.eval("int test = 1+1;");
76+
JShellWrapper.JShellResult result = wrapper.eval("test");
5777

58-
SnippetEvent snippetEvent = result.getEvents().get(0);
78+
assertEquals(result.getEvents().size(), 1, "Event count is not 1");
5979

60-
assertNull(snippetEvent.exception(), "An exception occurred");
80+
SnippetEvent snippetEvent = result.getEvents().get(0);
6181

62-
assertEquals("2", snippetEvent.value(), "Calculation was wrong");
63-
}
82+
assertNull(snippetEvent.exception(), "An exception occurred");
83+
84+
assertEquals("2", snippetEvent.value(), "Calculation was wrong");
85+
}
6486

65-
@Test
66-
void savesHistory() {
67-
wrapper.eval("int test = 1+1;");
68-
JShellWrapper.JShellResult result = wrapper.eval("test");
87+
@Test
88+
void blocksPackage() {
89+
assertThrows(
90+
UnsupportedOperationException.class,
91+
() -> wrapper.eval("java.time.LocalDateTime.now()"),
92+
"No exception was thrown when accessing a blocked package."
93+
);
94+
}
6995

70-
assertEquals(result.getEvents().size(), 1, "Event count is not 1");
96+
@ParameterizedTest(name = "Accessing \"{0}\" should fail")
97+
@ValueSource(strings = {
98+
"/opt",
99+
"~",
100+
"/tmp/"
101+
})
102+
void blocksFileAccess(String fileName) {
103+
JShellResult result = wrapper.eval("new java.io.File(\"" + fileName + "\").listFiles()");
71104

72-
SnippetEvent snippetEvent = result.getEvents().get(0);
105+
if (!allFailed(result)) {
106+
printSnippetResult(result);
107+
}
73108

74-
assertNull(snippetEvent.exception(), "An exception occurred");
109+
assertTrue(
110+
allFailed(result),
111+
"Not all snippets were rejected when accessing a file."
112+
);
113+
}
75114

76-
assertEquals("2", snippetEvent.value(), "Calculation was wrong");
115+
@Test
116+
void blocksNetworkIo() {
117+
JShellResult result = wrapper
118+
.eval("new java.net.URL(\"https://duckduckgo.com\").openConnection().connect()");
119+
120+
if (!allFailed(result)) {
121+
printSnippetResult(result);
77122
}
78123

79-
@Test
80-
void blocksPackage() {
81-
assertThrows(
82-
UnsupportedOperationException.class,
83-
() -> wrapper.eval("java.time.LocalDateTime.now()"),
84-
"No exception was thrown when accessing a blocked package."
124+
assertTrue(
125+
allFailed(result),
126+
"Not all snippets were rejected when doing network I/O."
127+
);
128+
}
129+
130+
private boolean allFailed(JShellResult result) {
131+
return result.getEvents().stream()
132+
.allMatch(snippetEvent ->
133+
snippetEvent.status() == Status.REJECTED
134+
|| snippetEvent.exception() != null
85135
);
136+
}
137+
138+
private void printSnippetResult(JShellResult result) {
139+
for (SnippetEvent event : result.getEvents()) {
140+
System.out.println(event);
86141
}
142+
}
87143
}

0 commit comments

Comments
 (0)