Skip to content

Commit

Permalink
169 add implementation of method exec for Container
Browse files Browse the repository at this point in the history
  • Loading branch information
Морозов Евгений Сергеевич authored and Морозов Евгений Сергеевич committed Apr 20, 2020
1 parent 7996e81 commit 2f3d104
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/main/java/com/amihaiemil/docker/Container.java
Expand Up @@ -164,4 +164,13 @@ void remove(final boolean volumes, final boolean force, final boolean link)
*/
int waitOn(String state) throws IOException;

/**
* Create a Exec.
* @param config Exec configuration.
* @see <a href="https://docs.docker.com/engine/api/v1.40/#operation/ContainerExec">Create Exec</a>
* @return Exec created.
* @throws IOException If something goes wrong.
*/
Exec exec(final JsonObject config) throws IOException;

}
23 changes: 23 additions & 0 deletions src/main/java/com/amihaiemil/docker/RtContainer.java
Expand Up @@ -32,6 +32,8 @@
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;

/**
* Restful Container.
Expand Down Expand Up @@ -253,4 +255,25 @@ public int waitOn(final String state) throws IOException {
waiter.releaseConnection();
}
}

@Override
public Exec exec(final JsonObject config) throws IOException {
final URI uri = new UncheckedUriBuilder(
this.baseUri.toString() + "/exec")
.build();
final HttpPost post = new HttpPost(uri);
try {
post.setEntity(new StringEntity(config.toString()));
post.setHeader(new BasicHeader("Content-Type", "application/json"));
final JsonObject json = this.client.execute(
post,
new ReadJsonObject(
new MatchStatus(post.getURI(), HttpStatus.SC_CREATED)
)
);
return this.docker.execs().get(json.getString("Id"));
} finally {
post.releaseConnection();
}
}
}
33 changes: 33 additions & 0 deletions src/test/java/com/amihaiemil/docker/RtContainerITCase.java
Expand Up @@ -206,4 +206,37 @@ private boolean pausedState(final Container container) throws IOException {
.getBoolean("Paused");
}


/**
* {@link RtContainer} Can create Exec of Docker container it represents.
* @throws Exception If something goes wrong.
*/
@Test
public void execContainer() throws Exception {
final Container container = new UnixDocker(
new File("/var/run/docker.sock")
).containers().create("TestStart", this.containerJsonObject());
container.start();
MatcherAssert.assertThat(
this.runningState(container),
new IsEqual<>(true)
);
final JsonObject json = Json.createObjectBuilder()
.add("Cmd", Json.createArrayBuilder().add("date").build())
.add("Tty", true)
.add("AttachStdout", true)
.build();
Exec exec = container.exec(json);
MatcherAssert.assertThat(
container.inspect().getJsonArray("ExecIDs").size(),
new IsEqual<>(1)
);
MatcherAssert.assertThat(
container.inspect().getJsonArray("ExecIDs").getString(0),
new IsEqual<>(exec.inspect().getString("ID"))
);
container.stop();
container.remove();
}

}
90 changes: 90 additions & 0 deletions src/test/java/com/amihaiemil/docker/RtContainerTestCase.java
Expand Up @@ -36,8 +36,10 @@
import org.mockito.Mockito;
import javax.json.Json;
import javax.json.JsonObject;
import java.io.IOException;
import java.net.URI;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;

/**
* Unit tests for RtContainer.
Expand Down Expand Up @@ -706,4 +708,92 @@ public void waitWithServerError() throws Exception {
Mockito.mock(Docker.class)
).waitOn(null);
}

/**
* Can create Exec.
* @throws Exception If something goes wrong.
*/
@Test
public void createTest() throws Exception {
final JsonObject json = Json.createObjectBuilder()
.add("Cmd", Json.createArrayBuilder().add("date").build())
.add("Tty", "true")
.add("AttachStdin", "true")
.build();

RtContainer rtContainer = new RtContainer(
Json.createObjectBuilder().add("Id", "123").build(),
new AssertRequest(
new Response(
HttpStatus.SC_CREATED,
Json.createObjectBuilder()
.add("Id", "01e1564097")
.build().toString()
),
new Condition(
"Method should be a POST",
req -> req.getRequestLine().getMethod().equals("POST")
),
new Condition(
"Resource path must be /123/exec",
req -> req.getRequestLine().getUri().endsWith("/123/exec")
)
),
URI.create("http://localhost:80/1.30/containers/123"),
Mockito.mock(Docker.class)
);
when(rtContainer.docker().execs()).thenReturn(
new RtExecs(
new AssertRequest(
new Response(
HttpStatus.SC_OK,
"{\"Id\": \"exec123\"}"
),
new Condition(
"must send a GET request",
req -> "GET".equals(req.getRequestLine().getMethod())
),
new Condition(
"resource URL should end with '/exec123/json'",
req -> req.getRequestLine()
.getUri().endsWith("/exec123/json")
)
),
URI.create("http://localhost/exec"),
Mockito.mock(Docker.class)
)
);
rtContainer.exec(json);
}

/**
* Must fail if docker responds with error code 500.
* @throws IOException due to code 500
*/
@Test(expected = UnexpectedResponseException.class)
public void execWithServerError() throws IOException {
final JsonObject json = Json.createObjectBuilder()
.add("Tty", "true")
.add("AttachStdin", "true")
.build();

new RtContainer(
Json.createObjectBuilder().add("Id", "123").build(),
new AssertRequest(
new Response(
HttpStatus.SC_INTERNAL_SERVER_ERROR
),
new Condition(
"Method should be a POST",
req -> req.getRequestLine().getMethod().equals("POST")
),
new Condition(
"Resource path must be /123/exec",
req -> req.getRequestLine().getUri().endsWith("/123/exec")
)
),
URI.create("http://localhost:80/1.30/containers/123"),
Mockito.mock(Docker.class)
).exec(json);
}
}

0 comments on commit 2f3d104

Please sign in to comment.