1
1
package org .togetherjava .discord .server .execution ;
2
2
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 ;
9
8
10
9
import java .time .Duration ;
11
10
import java .util .List ;
12
11
import java .util .Properties ;
13
12
import java .util .concurrent .Executors ;
14
13
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 ;
17
24
18
25
class JShellWrapperTest {
19
26
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" );
32
57
}
58
+ }
33
59
34
- @ AfterAll
35
- static void cleanup () {
36
- wrapper .close ();
37
- }
60
+ @ Test
61
+ void correctlyComputesExpression () {
62
+ JShellWrapper .JShellResult result = wrapper .eval ("1+1" );
38
63
39
- @ Test
40
- void reportsCompileTimeError () {
41
- JShellWrapper .JShellResult result = wrapper .eval ("crazy stuff" );
64
+ assertEquals (result .getEvents ().size (), 1 , "Event count is not 1" );
42
65
43
- assertFalse ( result .getEvents ().isEmpty (), "Found no events" );
66
+ SnippetEvent snippetEvent = result .getEvents ().get ( 0 );
44
67
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" );
51
69
52
- @ Test
53
- void correctlyComputesExpression () {
54
- JShellWrapper .JShellResult result = wrapper .eval ("1+1" );
70
+ assertEquals ("2" , snippetEvent .value (), "Calculation was wrong" );
71
+ }
55
72
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" );
57
77
58
- SnippetEvent snippetEvent = result .getEvents ().get ( 0 );
78
+ assertEquals ( result .getEvents ().size (), 1 , "Event count is not 1" );
59
79
60
- assertNull ( snippetEvent . exception (), "An exception occurred" );
80
+ SnippetEvent snippetEvent = result . getEvents (). get ( 0 );
61
81
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
+ }
64
86
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
+ }
69
95
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()" );
71
104
72
- SnippetEvent snippetEvent = result .getEvents ().get (0 );
105
+ if (!allFailed (result )) {
106
+ printSnippetResult (result );
107
+ }
73
108
74
- assertNull (snippetEvent .exception (), "An exception occurred" );
109
+ assertTrue (
110
+ allFailed (result ),
111
+ "Not all snippets were rejected when accessing a file."
112
+ );
113
+ }
75
114
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 );
77
122
}
78
123
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
85
135
);
136
+ }
137
+
138
+ private void printSnippetResult (JShellResult result ) {
139
+ for (SnippetEvent event : result .getEvents ()) {
140
+ System .out .println (event );
86
141
}
142
+ }
87
143
}
0 commit comments