Skip to content

Commit 2f3d104

Browse files
Морозов Евгений СергеевичМорозов Евгений Сергеевич
Морозов Евгений Сергеевич
authored and
Морозов Евгений Сергеевич
committed
169 add implementation of method exec for Container
1 parent 7996e81 commit 2f3d104

File tree

4 files changed

+155
-0
lines changed

4 files changed

+155
-0
lines changed

src/main/java/com/amihaiemil/docker/Container.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,13 @@ void remove(final boolean volumes, final boolean force, final boolean link)
164164
*/
165165
int waitOn(String state) throws IOException;
166166

167+
/**
168+
* Create a Exec.
169+
* @param config Exec configuration.
170+
* @see <a href="https://docs.docker.com/engine/api/v1.40/#operation/ContainerExec">Create Exec</a>
171+
* @return Exec created.
172+
* @throws IOException If something goes wrong.
173+
*/
174+
Exec exec(final JsonObject config) throws IOException;
175+
167176
}

src/main/java/com/amihaiemil/docker/RtContainer.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import org.apache.http.client.HttpClient;
3333
import org.apache.http.client.methods.HttpDelete;
3434
import org.apache.http.client.methods.HttpPost;
35+
import org.apache.http.entity.StringEntity;
36+
import org.apache.http.message.BasicHeader;
3537

3638
/**
3739
* Restful Container.
@@ -253,4 +255,25 @@ public int waitOn(final String state) throws IOException {
253255
waiter.releaseConnection();
254256
}
255257
}
258+
259+
@Override
260+
public Exec exec(final JsonObject config) throws IOException {
261+
final URI uri = new UncheckedUriBuilder(
262+
this.baseUri.toString() + "/exec")
263+
.build();
264+
final HttpPost post = new HttpPost(uri);
265+
try {
266+
post.setEntity(new StringEntity(config.toString()));
267+
post.setHeader(new BasicHeader("Content-Type", "application/json"));
268+
final JsonObject json = this.client.execute(
269+
post,
270+
new ReadJsonObject(
271+
new MatchStatus(post.getURI(), HttpStatus.SC_CREATED)
272+
)
273+
);
274+
return this.docker.execs().get(json.getString("Id"));
275+
} finally {
276+
post.releaseConnection();
277+
}
278+
}
256279
}

src/test/java/com/amihaiemil/docker/RtContainerITCase.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,37 @@ private boolean pausedState(final Container container) throws IOException {
206206
.getBoolean("Paused");
207207
}
208208

209+
210+
/**
211+
* {@link RtContainer} Can create Exec of Docker container it represents.
212+
* @throws Exception If something goes wrong.
213+
*/
214+
@Test
215+
public void execContainer() throws Exception {
216+
final Container container = new UnixDocker(
217+
new File("/var/run/docker.sock")
218+
).containers().create("TestStart", this.containerJsonObject());
219+
container.start();
220+
MatcherAssert.assertThat(
221+
this.runningState(container),
222+
new IsEqual<>(true)
223+
);
224+
final JsonObject json = Json.createObjectBuilder()
225+
.add("Cmd", Json.createArrayBuilder().add("date").build())
226+
.add("Tty", true)
227+
.add("AttachStdout", true)
228+
.build();
229+
Exec exec = container.exec(json);
230+
MatcherAssert.assertThat(
231+
container.inspect().getJsonArray("ExecIDs").size(),
232+
new IsEqual<>(1)
233+
);
234+
MatcherAssert.assertThat(
235+
container.inspect().getJsonArray("ExecIDs").getString(0),
236+
new IsEqual<>(exec.inspect().getString("ID"))
237+
);
238+
container.stop();
239+
container.remove();
240+
}
241+
209242
}

src/test/java/com/amihaiemil/docker/RtContainerTestCase.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@
3636
import org.mockito.Mockito;
3737
import javax.json.Json;
3838
import javax.json.JsonObject;
39+
import java.io.IOException;
3940
import java.net.URI;
4041
import static org.junit.Assert.assertEquals;
42+
import static org.mockito.Mockito.when;
4143

4244
/**
4345
* Unit tests for RtContainer.
@@ -706,4 +708,92 @@ public void waitWithServerError() throws Exception {
706708
Mockito.mock(Docker.class)
707709
).waitOn(null);
708710
}
711+
712+
/**
713+
* Can create Exec.
714+
* @throws Exception If something goes wrong.
715+
*/
716+
@Test
717+
public void createTest() throws Exception {
718+
final JsonObject json = Json.createObjectBuilder()
719+
.add("Cmd", Json.createArrayBuilder().add("date").build())
720+
.add("Tty", "true")
721+
.add("AttachStdin", "true")
722+
.build();
723+
724+
RtContainer rtContainer = new RtContainer(
725+
Json.createObjectBuilder().add("Id", "123").build(),
726+
new AssertRequest(
727+
new Response(
728+
HttpStatus.SC_CREATED,
729+
Json.createObjectBuilder()
730+
.add("Id", "01e1564097")
731+
.build().toString()
732+
),
733+
new Condition(
734+
"Method should be a POST",
735+
req -> req.getRequestLine().getMethod().equals("POST")
736+
),
737+
new Condition(
738+
"Resource path must be /123/exec",
739+
req -> req.getRequestLine().getUri().endsWith("/123/exec")
740+
)
741+
),
742+
URI.create("http://localhost:80/1.30/containers/123"),
743+
Mockito.mock(Docker.class)
744+
);
745+
when(rtContainer.docker().execs()).thenReturn(
746+
new RtExecs(
747+
new AssertRequest(
748+
new Response(
749+
HttpStatus.SC_OK,
750+
"{\"Id\": \"exec123\"}"
751+
),
752+
new Condition(
753+
"must send a GET request",
754+
req -> "GET".equals(req.getRequestLine().getMethod())
755+
),
756+
new Condition(
757+
"resource URL should end with '/exec123/json'",
758+
req -> req.getRequestLine()
759+
.getUri().endsWith("/exec123/json")
760+
)
761+
),
762+
URI.create("http://localhost/exec"),
763+
Mockito.mock(Docker.class)
764+
)
765+
);
766+
rtContainer.exec(json);
767+
}
768+
769+
/**
770+
* Must fail if docker responds with error code 500.
771+
* @throws IOException due to code 500
772+
*/
773+
@Test(expected = UnexpectedResponseException.class)
774+
public void execWithServerError() throws IOException {
775+
final JsonObject json = Json.createObjectBuilder()
776+
.add("Tty", "true")
777+
.add("AttachStdin", "true")
778+
.build();
779+
780+
new RtContainer(
781+
Json.createObjectBuilder().add("Id", "123").build(),
782+
new AssertRequest(
783+
new Response(
784+
HttpStatus.SC_INTERNAL_SERVER_ERROR
785+
),
786+
new Condition(
787+
"Method should be a POST",
788+
req -> req.getRequestLine().getMethod().equals("POST")
789+
),
790+
new Condition(
791+
"Resource path must be /123/exec",
792+
req -> req.getRequestLine().getUri().endsWith("/123/exec")
793+
)
794+
),
795+
URI.create("http://localhost:80/1.30/containers/123"),
796+
Mockito.mock(Docker.class)
797+
).exec(json);
798+
}
709799
}

0 commit comments

Comments
 (0)