<commit_before>= Arquillian Cube

== What is this?

*Arquillian Cube* is an _Arquillian_ extension that can be used to manager _Docker_ containers from _Arquillian_.

Extension is named *Cube* for two reasons:

* Because Docker is like a cube
* Because http://en.memory-alpha.org/wiki/Borg_cube[Borg starship] is named *cube* and well because we are moving tests close to production we can say that "any resistance is futile, bugs will be assimilated".

With this extension you can start a _Docker_ container with a server installed, deploy the required deployable file within it and execute _Arquillian_ tests.

The key point here is that if _Docker_ is used as deployable platform in production, your tests are executed in a the same container as it will be in production, so your tests are even more real than before.

But also let you start a container with every required service like database, mail server, ... and instead of stubbing or using fake objects your tests can use real servers.

[WARNING]
====
This extension has been developed and tested in a Linux machine with _Docker_ server already installed.
It should work with *Boot2Docker* as well in _Windows_ and _MacOS_ machines, but some parameters like _host ip_ must be the _Boot2Docker_ server instead of _localhost_ (in case you have _Docker_ server installed inside your own machine).

One of the best resources to learn about why using _Boot2Docker_ is different from using _Docker_ in Linux can be read here http://viget.com/extend/how-to-use-docker-on-os-x-the-missing-guide
====

== Preliminaries

*Arquillian Cube* relies on https://github.com/docker-java/docker-java[docker-java] API.

To use *Arquillian Cube* you need a _Docker_ daemon running on a computer (it can be local or not), but probably it will be at local.

By default _Docker_ server is using UNIX sockets for communication with the _Docker_ client, however _docker-java_ client uses TCP/IP to connect to the Docker server, so you will need to make sure that your _Docker_ server is listening on TCP port.
To allow _Docker_ server to use TCP add the following line to +/etc/default/docker+:

+DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock"+

After restarting the _Docker_ daemon you need to make sure that _Docker_ is up and listening on TCP.

[source, terminal]
----
$ docker -H tcp://127.0.0.1:2375 version

Client version: 0.8.0
Go version (client): go1.2
Git commit (client): cc3a8c8
Server version: 1.2.0
Git commit (server): fa7b24f
Go version (server): go1.3.1
----

If you cannot see the client and server versions then means that something is wrong in _Docker_ installation.

== Basic Example

After having a _Docker_ server installed we can start using *Arquillian Cube*.
In this case we are going to use a very simple example using a _Docker_ image with an _Apache Tomcat_ and we are going to test a _Servlet_ on it.

[source, java]
.HelloWorldServlet.java
----
@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    PrintWriter writer = resp.getWriter();
    writer.println("Hello World");
  }
}
----

[source, java]
.HelloWorldServletTest.java
----
@RunWith(Arquillian.class)
public class HelloWorldServletTest {

  @Deployment(testable=false) //<1>
  public static WebArchive create() {
    return ShrinkWrap.create(WebArchive.class, "hello.war").addClass(HelloWorldServlet.class); //<2>
  }

  @Test
  public void should_parse_and_load_configuration_file(@ArquillianResource URL resource) throws IOException { //<3>

    URL obj = new URL(resource, "HelloWorld");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");

    BufferedReader in = new BufferedReader(
            new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();

    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();

    assertThat(response.toString(), is("Hello World"));//<4>
  }
}
----
<1> In this case we are running test as a client. So in fact this test is executed against the container instead of inside the container.
<2> No changes in this part, we need to create a deployable file, and because it is a _Tomcat_, a _war_ file is created.
<3> Because test is run as client, we can use +@ArquillianResource+ to get the URL where file is deployed. Note that this will be the URL to access to _TomcaT_ that is running inside _Docker_ container.
<4> Typical jUnit assertion of servlet response.

Now this test could be run in any container, there is nothing that tights this to _Docker_.
Next step is adding some dependencies apart from the typical _Arquillian_ dependencies.

[source, xml]
.pom.xml
----
<dependency>
  <groupId>org.jboss.arquillian.extension</groupId>
  <artifactId>arquillian-cube-docker</artifactId> <!--1-->
  <version>${project.version}</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.jboss.arquillian.container</groupId>
  <artifactId>arquillian-tomcat-remote-7</artifactId> <!--2-->
  <version>1.0.0.CR7</version>
  <scope>test</scope>
</dependency>
----
<1> Adds *Arquillian Cube* dependency.
<2> From the point of view of _Arquillian_, _Tomcat_ is being executed in a remote host (in fact this is true because _Tomcat_ is running inside _Docker_ which is external to _Arquillian_), so we need to add the remote adapter.<commit_msg>Update arquillian-cube-docker groupId in README<commit_after>= Arquillian Cube

== What is this?

*Arquillian Cube* is an _Arquillian_ extension that can be used to manager _Docker_ containers from _Arquillian_.

Extension is named *Cube* for two reasons:

* Because Docker is like a cube
* Because http://en.memory-alpha.org/wiki/Borg_cube[Borg starship] is named *cube* and well because we are moving tests close to production we can say that "any resistance is futile, bugs will be assimilated".

With this extension you can start a _Docker_ container with a server installed, deploy the required deployable file within it and execute _Arquillian_ tests.

The key point here is that if _Docker_ is used as deployable platform in production, your tests are executed in a the same container as it will be in production, so your tests are even more real than before.

But also let you start a container with every required service like database, mail server, ... and instead of stubbing or using fake objects your tests can use real servers.

[WARNING]
====
This extension has been developed and tested in a Linux machine with _Docker_ server already installed.
It should work with *Boot2Docker* as well in _Windows_ and _MacOS_ machines, but some parameters like _host ip_ must be the _Boot2Docker_ server instead of _localhost_ (in case you have _Docker_ server installed inside your own machine).

One of the best resources to learn about why using _Boot2Docker_ is different from using _Docker_ in Linux can be read here http://viget.com/extend/how-to-use-docker-on-os-x-the-missing-guide
====

== Preliminaries

*Arquillian Cube* relies on https://github.com/docker-java/docker-java[docker-java] API.

To use *Arquillian Cube* you need a _Docker_ daemon running on a computer (it can be local or not), but probably it will be at local.

By default _Docker_ server is using UNIX sockets for communication with the _Docker_ client, however _docker-java_ client uses TCP/IP to connect to the Docker server, so you will need to make sure that your _Docker_ server is listening on TCP port.
To allow _Docker_ server to use TCP add the following line to +/etc/default/docker+:

+DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock"+

After restarting the _Docker_ daemon you need to make sure that _Docker_ is up and listening on TCP.

[source, terminal]
----
$ docker -H tcp://127.0.0.1:2375 version

Client version: 0.8.0
Go version (client): go1.2
Git commit (client): cc3a8c8
Server version: 1.2.0
Git commit (server): fa7b24f
Go version (server): go1.3.1
----

If you cannot see the client and server versions then means that something is wrong in _Docker_ installation.

== Basic Example

After having a _Docker_ server installed we can start using *Arquillian Cube*.
In this case we are going to use a very simple example using a _Docker_ image with an _Apache Tomcat_ and we are going to test a _Servlet_ on it.

[source, java]
.HelloWorldServlet.java
----
@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    PrintWriter writer = resp.getWriter();
    writer.println("Hello World");
  }
}
----

[source, java]
.HelloWorldServletTest.java
----
@RunWith(Arquillian.class)
public class HelloWorldServletTest {

  @Deployment(testable=false) //<1>
  public static WebArchive create() {
    return ShrinkWrap.create(WebArchive.class, "hello.war").addClass(HelloWorldServlet.class); //<2>
  }

  @Test
  public void should_parse_and_load_configuration_file(@ArquillianResource URL resource) throws IOException { //<3>

    URL obj = new URL(resource, "HelloWorld");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");

    BufferedReader in = new BufferedReader(
            new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();

    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();

    assertThat(response.toString(), is("Hello World"));//<4>
  }
}
----
<1> In this case we are running test as a client. So in fact this test is executed against the container instead of inside the container.
<2> No changes in this part, we need to create a deployable file, and because it is a _Tomcat_, a _war_ file is created.
<3> Because test is run as client, we can use +@ArquillianResource+ to get the URL where file is deployed. Note that this will be the URL to access to _TomcaT_ that is running inside _Docker_ container.
<4> Typical jUnit assertion of servlet response.

Now this test could be run in any container, there is nothing that tights this to _Docker_.
Next step is adding some dependencies apart from the typical _Arquillian_ dependencies.

[source, xml]
.pom.xml
----
<dependency>
  <groupId>org.arquillian.cube</groupId>
  <artifactId>arquillian-cube-docker</artifactId> <!--1-->
  <version>${project.version}</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.jboss.arquillian.container</groupId>
  <artifactId>arquillian-tomcat-remote-7</artifactId> <!--2-->
  <version>1.0.0.CR7</version>
  <scope>test</scope>
</dependency>
----
<1> Adds *Arquillian Cube* dependency.
<2> From the point of view of _Arquillian_, _Tomcat_ is being executed in a remote host (in fact this is true because _Tomcat_ is running inside _Docker_ which is external to _Arquillian_), so we need to add the remote adapter.
{'fraction_non_alphanumeric': 0.08528803810550913, 'fraction_numerical': 0.010245349150714478, 'mean_word_length': 4.278937381404175, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 67, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6903742', 'n_tokens_mistral': 3349, 'n_tokens_neox': 3196, 'n_words': 1397}