package com.github.dockerjava.core.command;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.model.Event;
import com.github.dockerjava.client.AbstractDockerClientTest;
/*
* NOTE: These tests may fail if there is a difference between local and daemon time
* (this is especially a problem when using boot2docker as time may not in sync
* with the virtualbox host system)
*/
@Test(groups = "integration")
public class EventsCmdImplTest extends AbstractDockerClientTest {
private static String getEpochTime() {
return String.valueOf(System.currentTimeMillis() / 1000);
}
@BeforeTest
public void beforeTest() throws Exception {
super.beforeTest();
}
@AfterTest
public void afterTest() {
super.afterTest();
}
@BeforeMethod
public void beforeMethod(Method method) {
super.beforeMethod(method);
}
@AfterMethod
public void afterMethod(ITestResult result) {
super.afterMethod(result);
}
@Test
public void testEventStreamTimeBound() throws Exception {
// Don't include other tests events
TimeUnit.SECONDS.sleep(1);
String startTime = getEpochTime();
int expectedEvents = generateEvents();
String endTime = getEpochTime();
EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents);
dockerClient.eventsCmd()
.withSince(startTime)
.withUntil(endTime)
.exec(eventCallback);
List<Event> events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES);
// we may receive more events as expected
assertTrue(events.size() >= expectedEvents, "Received events: " + events);
}
@Test
public void testEventStreaming() throws Exception {
// Don't include other tests events
TimeUnit.SECONDS.sleep(1);
String startTime = getEpochTime();
int expectedEvents = generateEvents();
EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents);
dockerClient.eventsCmd()
.withSince(startTime)
.exec(eventCallback);
generateEvents();
List<Event> events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES);
// we may receive more events as expected
assertTrue(events.size() >= expectedEvents, "Received events: " + events);
}
public void testEventStreamingWithFilter() throws Exception {
// Don't include other tests events
TimeUnit.SECONDS.sleep(1);
String startTime = getEpochTime();
int expectedEvents = 1;
EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents);
dockerClient.eventsCmd()
.withSince(startTime)
.withEventFilter("start")
.exec(eventCallback);
generateEvents();
List<Event> events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES);
// we should get exactly one "start" event here
assertEquals(events.size(), expectedEvents, "Received events: " + events);
}
/**
* This method generates some events and returns the number of events being generated
*/
private int generateEvents() throws Exception {
String testImage = "busybox:latest";
dockerClient.pullImageCmd(testImage).exec(new PullImageResultCallback()).awaitSuccess();
CreateContainerResponse container = dockerClient.createContainerCmd(testImage).withCmd("sleep", "9999").exec();
dockerClient.startContainerCmd(container.getId()).exec();
dockerClient.stopContainerCmd(container.getId()).withTimeout(1).exec();
// generates 5 events with remote api 1.24:
// Event[status=pull,id=busybox:latest,from=<null>,node=<null>,type=IMAGE,action=pull,actor=com.github.dockerjava.api.model.EventActor@417db6d7[id=busybox:latest,attributes={name=busybox}],time=1473455186,timeNano=1473455186436681587]
// Event[status=create,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=<null>,type=CONTAINER,action=create,actor=com.github.dockerjava.api.model.EventActor@40bcec[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport}],time=1473455186,timeNano=1473455186470713257]
// Event[status=<null>,id=<null>,from=<null>,node=<null>,type=NETWORK,action=connect,actor=com.github.dockerjava.api.model.EventActor@318a1b01[id=10870ceb13abb7cf841ea68868472da881b33c8ed08d2cde7dbb39d7c24d1d27,attributes={container=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c, name=bridge, type=bridge}],time=1473455186,timeNano=1473455186544318466]
// Event[status=start,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=<null>,type=CONTAINER,action=start,actor=com.github.dockerjava.api.model.EventActor@606f43a3[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport}],time=1473455186,timeNano=1473455186786163819]
// Event[status=kill,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=<null>,type=CONTAINER,action=kill,actor=com.github.dockerjava.api.model.EventActor@72a9ffcf[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport, signal=15}],time=1473455186,timeNano=1473455186792963392]
return 5;
}
private class EventsTestCallback extends EventsResultCallback {
private final CountDownLatch countDownLatch;
private final List<Event> events = new ArrayList<Event>();
public EventsTestCallback(int expextedEvents) {
this.countDownLatch = new CountDownLatch(expextedEvents);
}
public void onNext(Event event) {
LOG.info("Received event #{}: {}", countDownLatch.getCount(), event);
events.add(event);
countDownLatch.countDown();
}
public List<Event> awaitExpectedEvents(long timeout, TimeUnit unit ) {
try {
countDownLatch.await(timeout, unit);
close();
} catch (Exception e) {
throw new RuntimeException(e);
}
return new ArrayList<Event>(events);
}
}
}