// Path: rx-docker-client/src/test/java/com/shekhargulati/reactivex/docker/client/junit/DockerContainerRule.java
// public class DockerContainerRule implements TestRule {
// 
//     private final RxDockerClient client;
//     private List<String> containerIds;
// 
//     public DockerContainerRule(RxDockerClient client) {
//         this.client = client;
//     }
// 
//     @Override
//     public Statement apply(Statement base, Description description) {
//         try {
//             CreateDockerContainer[] containerAnnotations = description.getTestClass().getDeclaredMethod(description.getMethodName()).getAnnotationsByType(CreateDockerContainer.class);
//             if (containerAnnotations != null && containerAnnotations.length > 0) {
//                 return new Statement() {
//                     @Override
//                     public void evaluate() throws Throwable {
//                         containerIds = createContainers(containerAnnotations);
//                         try {
//                             base.evaluate();
//                         } finally {
//                             containerIds.forEach(DockerContainerRule.this::removeContainer);
//                         }
//                     }
//                 };
//             }
//             return base;
//         } catch (NoSuchMethodException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
//     private List<String> createContainers(CreateDockerContainer[] containers) {
//         return Stream.of(containers).map(this::createAndStartContainer).map(DockerContainerResponse::getId).collect(toList());
//     }
// 
//     private DockerContainerResponse createAndStartContainer(CreateDockerContainer c) {
//         if (c.pullImage()) {
//             client.pullImage("registry");
//         }
//         final Map<String, List<PortBinding>> portBindings = new HashMap<>();
//         for (String hostPort : c.hostPorts()) {
//             List<PortBinding> hostPortBinding = new ArrayList<>();
//             hostPortBinding.add(PortBinding.of("0.0.0.0", hostPort));
//             portBindings.put(hostPort, hostPortBinding);
//         }
//         final HostConfig hostConfig = new HostConfigBuilder().setPortBindings(portBindings).createHostConfig();
// 
//         DockerContainerRequest request = new DockerContainerRequestBuilder()
//                 .setImage(c.image())
//                 .setCmd(Arrays.asList(c.command()))
//                 .setAttachStdin(c.attachStdin())
//                 .setTty(c.tty())
//                 .addExposedPort(c.exposedPorts())
//                 .setHostConfig(hostConfig)
//                 .createDockerContainerRequest();
// 
//         DockerContainerResponse response = client.createContainer(request, c.container());
//         if (c.start()) {
//             client.startContainer(response.getId());
//         }
//         return response;
//     }
// 
// 
//     private void removeContainer(String containerId) {
//         try {
//             client.removeContainer(containerId, false, true);
//         } catch (Exception e) {
//             // ignore as circle ci does not allow containers and images to be destroyed
//         }
//     }
// 
//     public List<String> containerIds() {
//         return containerIds;
//     }
// 
//     public String first() {
//         if (containerIds.isEmpty()) {
//             throw new NoSuchElementException("No container found");
//         }
//         return containerIds.get(0);
//     }
// }


import com.shekhargulati.reactivex.docker.client.junit.CreateDockerContainer;
import com.shekhargulati.reactivex.docker.client.junit.DockerContainerRule;
import com.shekhargulati.reactivex.docker.client.representations.*;
import com.shekhargulati.reactivex.rxokhttp.HttpStatus;
import com.shekhargulati.reactivex.rxokhttp.QueryParameter;
import com.shekhargulati.reactivex.rxokhttp.StreamResponseException;
import org.junit.*;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rx.Observable;
import rx.Subscriber;
import rx.schedulers.Schedulers;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.AbstractMap.SimpleEntry;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import static java.util.Collections.emptyMap;
import static java.util.stream.Collectors.toMap;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeTrue;

    }

    @Test
    public void shouldCreateImageFromTar() throws Exception {
        HttpStatus httpStatus = client.createImage("test_rx_docker/docker_hello-world", Paths.get("src", "test", "resources", "images", "hello-world-image.tar"));
        assertThat(httpStatus, is(equalTo(HttpStatus.OK)));
    }

    @Test
    @CreateDockerContainer(container = "registry", command = {}, image = "registry", start = true, pullImage = true, exposedPorts = {"5000/tcp"}, hostPorts = {"5000/tcp"})
    public void shouldPullImageFromLocalRegistry() throws Exception {
        assumeTrue(System.getenv("CIRCLE_USERNAME") == null);
        client.tagImageObs("busybox", ImageTagQueryParameters.with("localhost:5000/busybox", "latest"))
                .subscribe(System.out::println, System.out::println, System.out::println);

        Observable.timer(15, TimeUnit.SECONDS, Schedulers.immediate()).subscribe();

        client.pushImageObs("localhost:5000/busybox", AuthConfig.authConfig("test", "test", "test").withServerAddress("http://localhost:5000"))
                .subscribe(System.out::println, System.out::println, System.out::println);

        HttpStatus httpStatus = client.pullImageFromRegistry("busybox", "localhost:5000");
        assertThat(httpStatus, is(equalTo(HttpStatus.OK)));
    }

    private DockerContainerResponse createContainer(String containerName) {
        DockerContainerRequest request = new DockerContainerRequestBuilder()
                .setImage("ubuntu")
                .setCmd(Collections.singletonList("/bin/bash"))
                .setAttachStdin(true)
// Path: rx-docker-client/src/test/java/com/shekhargulati/reactivex/docker/client/junit/DockerContainerRule.java
// public class DockerContainerRule implements TestRule {
// 
//     private final RxDockerClient client;
//     private List<String> containerIds;
// 
//     public DockerContainerRule(RxDockerClient client) {
//         this.client = client;
//     }
// 
//     @Override
//     public Statement apply(Statement base, Description description) {
//         try {
//             CreateDockerContainer[] containerAnnotations = description.getTestClass().getDeclaredMethod(description.getMethodName()).getAnnotationsByType(CreateDockerContainer.class);
//             if (containerAnnotations != null && containerAnnotations.length > 0) {
//                 return new Statement() {
//                     @Override
//                     public void evaluate() throws Throwable {
//                         containerIds = createContainers(containerAnnotations);
//                         try {
//                             base.evaluate();
//                         } finally {
//                             containerIds.forEach(DockerContainerRule.this::removeContainer);
//                         }
//                     }
//                 };
//             }
//             return base;
//         } catch (NoSuchMethodException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
//     private List<String> createContainers(CreateDockerContainer[] containers) {
//         return Stream.of(containers).map(this::createAndStartContainer).map(DockerContainerResponse::getId).collect(toList());
//     }
// 
//     private DockerContainerResponse createAndStartContainer(CreateDockerContainer c) {
//         if (c.pullImage()) {
//             client.pullImage("registry");
//         }
//         final Map<String, List<PortBinding>> portBindings = new HashMap<>();
//         for (String hostPort : c.hostPorts()) {
//             List<PortBinding> hostPortBinding = new ArrayList<>();
//             hostPortBinding.add(PortBinding.of("0.0.0.0", hostPort));
//             portBindings.put(hostPort, hostPortBinding);
//         }
//         final HostConfig hostConfig = new HostConfigBuilder().setPortBindings(portBindings).createHostConfig();
// 
//         DockerContainerRequest request = new DockerContainerRequestBuilder()
//                 .setImage(c.image())
//                 .setCmd(Arrays.asList(c.command()))
//                 .setAttachStdin(c.attachStdin())
//                 .setTty(c.tty())
//                 .addExposedPort(c.exposedPorts())
//                 .setHostConfig(hostConfig)
//                 .createDockerContainerRequest();
// 
//         DockerContainerResponse response = client.createContainer(request, c.container());
//         if (c.start()) {
//             client.startContainer(response.getId());
//         }
//         return response;
//     }
// 
// 
//     private void removeContainer(String containerId) {
//         try {
//             client.removeContainer(containerId, false, true);
//         } catch (Exception e) {
//             // ignore as circle ci does not allow containers and images to be destroyed
//         }
//     }
// 
//     public List<String> containerIds() {
//         return containerIds;
//     }
// 
//     public String first() {
//         if (containerIds.isEmpty()) {
//             throw new NoSuchElementException("No container found");
//         }
//         return containerIds.get(0);
//     }
// }


// Path: rx-docker-client/src/test/java/com/shekhargulati/reactivex/docker/client/DefaultRxDockerClientTest.java
import com.shekhargulati.reactivex.docker.client.junit.CreateDockerContainer;
import com.shekhargulati.reactivex.docker.client.junit.DockerContainerRule;
import com.shekhargulati.reactivex.docker.client.representations.*;
import com.shekhargulati.reactivex.rxokhttp.HttpStatus;
import com.shekhargulati.reactivex.rxokhttp.QueryParameter;
import com.shekhargulati.reactivex.rxokhttp.StreamResponseException;
import org.junit.*;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rx.Observable;
import rx.Subscriber;
import rx.schedulers.Schedulers;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.AbstractMap.SimpleEntry;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import static java.util.Collections.emptyMap;
import static java.util.stream.Collectors.toMap;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeTrue;


    }

    @Test
    public void shouldCreateImageFromTar() throws Exception {
        HttpStatus httpStatus = client.createImage("test_rx_docker/docker_hello-world", Paths.get("src", "test", "resources", "images", "hello-world-image.tar"));
        assertThat(httpStatus, is(equalTo(HttpStatus.OK)));
    }

    @Test
    @CreateDockerContainer(container = "registry", command = {}, image = "registry", start = true, pullImage = true, exposedPorts = {"5000/tcp"}, hostPorts = {"5000/tcp"})
    public void shouldPullImageFromLocalRegistry() throws Exception {
        assumeTrue(System.getenv("CIRCLE_USERNAME") == null);
        client.tagImageObs("busybox", ImageTagQueryParameters.with("localhost:5000/busybox", "latest"))
                .subscribe(System.out::println, System.out::println, System.out::println);

        Observable.timer(15, TimeUnit.SECONDS, Schedulers.immediate()).subscribe();

        client.pushImageObs("localhost:5000/busybox", AuthConfig.authConfig("test", "test", "test").withServerAddress("http://localhost:5000"))
                .subscribe(System.out::println, System.out::println, System.out::println);

        HttpStatus httpStatus = client.pullImageFromRegistry("busybox", "localhost:5000");
        assertThat(httpStatus, is(equalTo(HttpStatus.OK)));
    }

    private DockerContainerResponse createContainer(String containerName) {
        DockerContainerRequest request = new DockerContainerRequestBuilder()
                .setImage("ubuntu")
                .setCmd(Collections.singletonList("/bin/bash"))
                .setAttachStdin(true)
                .setTty(true)