1717import static com .github .tomakehurst .wiremock .client .WireMock .get ;
1818import static com .github .tomakehurst .wiremock .client .WireMock .getRequestedFor ;
1919import static com .github .tomakehurst .wiremock .client .WireMock .stubFor ;
20- import static com .github .tomakehurst .wiremock .client .WireMock .urlEqualTo ;
2120import static com .github .tomakehurst .wiremock .client .WireMock .urlPathEqualTo ;
2221import static com .github .tomakehurst .wiremock .client .WireMock .verify ;
2322import static org .junit .Assert .assertEquals ;
2423
2524import 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 ;
2829import io .kubernetes .client .util .ClientBuilder ;
29-
3030import java .io .ByteArrayInputStream ;
31+ import java .io .ByteArrayOutputStream ;
3132import java .io .IOException ;
3233import java .io .InputStream ;
34+ import java .io .OutputStream ;
3335import java .nio .charset .StandardCharsets ;
3436import org .junit .Before ;
3537import org .junit .Rule ;
@@ -45,6 +47,8 @@ public class ExecTest {
4547 "{\" 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\" }]}}" ;
4648 private static final String BAD_OUTPUT_INCOMPLETE_MSG1 =
4749 "{\" 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\" }]}}" ;
4852
4953 private String namespace ;
5054 private String podName ;
@@ -58,37 +62,97 @@ public class ExecTest {
5862 @ Before
5963 public void setup () throws IOException {
6064 client = new ClientBuilder ().setBasePath ("http://localhost:" + PORT ).build ();
61-
65+
6266 namespace = "default" ;
6367 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
6570 // See: https://github.com/tomakehurst/wiremock/issues/398
6671 cmd = new String [] {"cmd" };
6772 }
6873
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+
69129 @ Test
70130 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 ));
72134
73- stubFor (
135+ stubFor (
74136 get (urlPathEqualTo ("/api/v1/namespaces/" + namespace + "/pods/" + podName + "/exec" ))
75137 .willReturn (
76138 aResponse ()
77139 .withStatus (404 )
78140 .withHeader ("Content-Type" , "application/json" )
79141 .withBody ("{}" )));
80142
81- Process p = exec .exec (namespace , podName , cmd , false );
82- p .waitFor ();
143+ Process p = exec .exec (pod , cmd , true , false );
144+ p .waitFor ();
83145
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" )));
90154
91- assertEquals (-1 , p .exitValue ());
155+ assertEquals (-1 , p .exitValue ());
92156 }
93157
94158 @ Test
@@ -122,4 +186,12 @@ public void testIncompleteData1() {
122186 int exitCode = Exec .parseExitCode (client , inputStream );
123187 assertEquals (-1 , exitCode );
124188 }
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+ }
125197}
0 commit comments