17
17
import static com .github .tomakehurst .wiremock .client .WireMock .get ;
18
18
import static com .github .tomakehurst .wiremock .client .WireMock .getRequestedFor ;
19
19
import static com .github .tomakehurst .wiremock .client .WireMock .stubFor ;
20
- import static com .github .tomakehurst .wiremock .client .WireMock .urlEqualTo ;
21
20
import static com .github .tomakehurst .wiremock .client .WireMock .urlPathEqualTo ;
22
21
import static com .github .tomakehurst .wiremock .client .WireMock .verify ;
23
22
import static org .junit .Assert .assertEquals ;
24
23
25
24
import com .github .tomakehurst .wiremock .junit .WireMockRule ;
26
-
27
- import io .kubernetes .client .ApiException ;
25
+ import com .google .common .io .ByteStreams ;
26
+ import io .kubernetes .client .Exec .ExecProcess ;
27
+ import io .kubernetes .client .models .V1ObjectMeta ;
28
+ import io .kubernetes .client .models .V1Pod ;
28
29
import io .kubernetes .client .util .ClientBuilder ;
29
-
30
30
import java .io .ByteArrayInputStream ;
31
+ import java .io .ByteArrayOutputStream ;
31
32
import java .io .IOException ;
32
33
import java .io .InputStream ;
34
+ import java .io .OutputStream ;
33
35
import java .nio .charset .StandardCharsets ;
34
36
import org .junit .Before ;
35
37
import org .junit .Rule ;
@@ -45,6 +47,8 @@ public class ExecTest {
45
47
"{\" metadata\" :{},\" status\" :\" Failure\" ,\" message\" :\" command terminated with non-zero exit code: Error executing in Docker Container: 126\" ,\" reason\" :\" NonZeroExitCode\" ,\" details\" :{\" causes\" :[{\" reason\" :\" ExitCode\" ,\" message\" :\" 126\" }]}}" ;
46
48
private static final String BAD_OUTPUT_INCOMPLETE_MSG1 =
47
49
"{\" metadata\" :{},\" status\" :\" Failure\" ,\" message\" :\" command terminated with non-zero exit code: Error executing in Docker Container: 1\" ,\" reas" ;
50
+ private static final String OUTPUT_EXIT_BAD_INT =
51
+ "{\" metadata\" :{},\" status\" :\" Failure\" ,\" message\" :\" command terminated with non-zero exit code: Error executing in Docker Container: 126\" ,\" reason\" :\" NonZeroExitCode\" ,\" details\" :{\" causes\" :[{\" reason\" :\" ExitCode\" ,\" message\" :\" not a number\" }]}}" ;
48
52
49
53
private String namespace ;
50
54
private String podName ;
@@ -58,37 +62,97 @@ public class ExecTest {
58
62
@ Before
59
63
public void setup () throws IOException {
60
64
client = new ClientBuilder ().setBasePath ("http://localhost:" + PORT ).build ();
61
-
65
+
62
66
namespace = "default" ;
63
67
podName = "apod" ;
64
- // TODO: When WireMock supports multiple query params with the same name expand this
68
+ // TODO: When WireMock supports multiple query params with the same name expand
69
+ // this
65
70
// See: https://github.com/tomakehurst/wiremock/issues/398
66
71
cmd = new String [] {"cmd" };
67
72
}
68
73
74
+ public static InputStream makeStream (int streamNum , byte [] data ) {
75
+ return makeStream (new byte [] {(byte ) streamNum }, data );
76
+ }
77
+
78
+ public static InputStream makeStream (byte [] prefix , byte [] data ) {
79
+ byte [] out = new byte [prefix .length + data .length ];
80
+ System .arraycopy (prefix , 0 , out , 0 , prefix .length );
81
+ System .arraycopy (data , 0 , out , prefix .length , data .length );
82
+ return new ByteArrayInputStream (out );
83
+ }
84
+
85
+ public static Thread asyncCopy (final InputStream is , final OutputStream os ) {
86
+ Thread t =
87
+ new Thread (
88
+ new Runnable () {
89
+ public void run () {
90
+ try {
91
+ ByteStreams .copy (is , os );
92
+ } catch (IOException ex ) {
93
+ ex .printStackTrace ();
94
+ }
95
+ }
96
+ });
97
+ t .start ();
98
+ return t ;
99
+ }
100
+
101
+ @ Test
102
+ public void testExecProcess () throws IOException , InterruptedException {
103
+ final ExecProcess process = new ExecProcess (client );
104
+ process .getHandler ().open ("wss" , null );
105
+ String msgData = "This is the stdout message" ;
106
+ String errData = "This is the stderr message" ;
107
+
108
+ process .getHandler ().bytesMessage (makeStream (1 , msgData .getBytes (StandardCharsets .UTF_8 )));
109
+ process .getHandler ().bytesMessage (makeStream (2 , errData .getBytes (StandardCharsets .UTF_8 )));
110
+ process .getHandler ().bytesMessage (makeStream (3 , OUTPUT_EXIT0 .getBytes (StandardCharsets .UTF_8 )));
111
+
112
+ final ByteArrayOutputStream stdout = new ByteArrayOutputStream ();
113
+ final ByteArrayOutputStream stderr = new ByteArrayOutputStream ();
114
+
115
+ Thread t1 = asyncCopy (process .getInputStream (), stdout );
116
+ Thread t2 = asyncCopy (process .getErrorStream (), stderr );
117
+
118
+ // TODO: Fix this asap!
119
+ Thread .sleep (1000 );
120
+
121
+ process .destroy ();
122
+
123
+ assertEquals (msgData , stdout .toString ());
124
+ assertEquals (errData , stderr .toString ());
125
+ assertEquals (false , process .isAlive ());
126
+ assertEquals (0 , process .exitValue ());
127
+ }
128
+
69
129
@ Test
70
130
public void testUrl () throws IOException , ApiException , InterruptedException {
71
- Exec exec = new Exec (client );
131
+ Exec exec = new Exec (client );
132
+
133
+ V1Pod pod = new V1Pod ().metadata (new V1ObjectMeta ().name (podName ).namespace (namespace ));
72
134
73
- stubFor (
135
+ stubFor (
74
136
get (urlPathEqualTo ("/api/v1/namespaces/" + namespace + "/pods/" + podName + "/exec" ))
75
137
.willReturn (
76
138
aResponse ()
77
139
.withStatus (404 )
78
140
.withHeader ("Content-Type" , "application/json" )
79
141
.withBody ("{}" )));
80
142
81
- Process p = exec .exec (namespace , podName , cmd , false );
82
- p .waitFor ();
143
+ Process p = exec .exec (pod , cmd , true , false );
144
+ p .waitFor ();
83
145
84
- verify (getRequestedFor (urlPathEqualTo ("/api/v1/namespaces/" + namespace + "/pods/" + podName + "/exec" ))
85
- .withQueryParam ("stdin" , equalTo ("false" ))
86
- .withQueryParam ("stdout" , equalTo ("true" ))
87
- .withQueryParam ("stderr" , equalTo ("true" ))
88
- .withQueryParam ("tty" , equalTo ("false" ))
89
- .withQueryParam ("command" , equalTo ("cmd" )));
146
+ verify (
147
+ getRequestedFor (
148
+ urlPathEqualTo ("/api/v1/namespaces/" + namespace + "/pods/" + podName + "/exec" ))
149
+ .withQueryParam ("stdin" , equalTo ("true" ))
150
+ .withQueryParam ("stdout" , equalTo ("true" ))
151
+ .withQueryParam ("stderr" , equalTo ("true" ))
152
+ .withQueryParam ("tty" , equalTo ("false" ))
153
+ .withQueryParam ("command" , equalTo ("cmd" )));
90
154
91
- assertEquals (-1 , p .exitValue ());
155
+ assertEquals (-1 , p .exitValue ());
92
156
}
93
157
94
158
@ Test
@@ -122,4 +186,12 @@ public void testIncompleteData1() {
122
186
int exitCode = Exec .parseExitCode (client , inputStream );
123
187
assertEquals (-1 , exitCode );
124
188
}
189
+
190
+ @ Test
191
+ public void testNonZeroBadIntExit () {
192
+ InputStream inputStream =
193
+ new ByteArrayInputStream (OUTPUT_EXIT_BAD_INT .getBytes (StandardCharsets .UTF_8 ));
194
+ int exitCode = Exec .parseExitCode (client , inputStream );
195
+ assertEquals (-1 , exitCode );
196
+ }
125
197
}
0 commit comments