diff --git a/elasticsearch5/pom.xml b/elasticsearch5/pom.xml
index 3eb388084de5d63412f5a82085ba110bbd179bd4..5ceabfdbd291e80bf9f385111d98c6b79b9d7873 100644
--- a/elasticsearch5/pom.xml
+++ b/elasticsearch5/pom.xml
@@ -29,7 +29,143 @@ LICENSE file.
   <properties>
     <!-- Skip tests by default. will be activated by jdk8 profile -->
     <skipTests>true</skipTests>
+    <elasticsearch.groupid>org.elasticsearch.distribution.zip</elasticsearch.groupid>
+
+    <!-- For integration tests using ANT -->
+    <integ.http.port>9400</integ.http.port>
+    <integ.transport.port>9500</integ.transport.port>
   </properties>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.10</version>
+        <executions>
+          <execution>
+            <id>integ-setup-dependencies</id>
+            <phase>pre-integration-test</phase>
+            <goals>
+              <goal>copy</goal>
+            </goals>
+            <configuration>
+              <skip>${skipTests}</skip>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>${elasticsearch.groupid}</groupId>
+                  <artifactId>elasticsearch</artifactId>
+                  <version>${elasticsearch5-version}</version>
+                  <type>zip</type>
+                </artifactItem>
+              </artifactItems>
+              <useBaseVersion>true</useBaseVersion>
+              <outputDirectory>${project.build.directory}/integration-tests/binaries</outputDirectory>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <version>1.8</version>
+        <executions>
+          <!-- start up external cluster -->
+          <execution>
+            <id>integ-setup</id>
+            <phase>pre-integration-test</phase>
+            <goals>
+              <goal>run</goal>
+            </goals>
+            <configuration>
+              <skip>${skipTests}</skip>
+              <target>
+                <ant antfile="src/test/ant/integration-tests.xml" target="start-external-cluster"/>
+              </target>
+            </configuration>
+          </execution>
+          <!-- shut down external cluster -->
+          <execution>
+            <id>integ-teardown</id>
+            <phase>post-integration-test</phase>
+            <goals>
+              <goal>run</goal>
+            </goals>
+            <configuration>
+              <skip>${skipTests}</skip>
+              <target>
+                <ant antfile="src/test/ant/integration-tests.xml" target="stop-external-cluster"/>
+              </target>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.19</version>
+        <executions>
+          <execution>
+            <id>default-test</id>
+            <phase>none</phase>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>com.carrotsearch.randomizedtesting</groupId>
+        <artifactId>junit4-maven-plugin</artifactId>
+        <version>2.3.3</version>
+
+        <configuration>
+          <assertions enableSystemAssertions="false">
+            <enable/>
+          </assertions>
+
+          <listeners>
+            <report-text />
+          </listeners>
+        </configuration>
+
+        <executions>
+          <execution>
+            <id>unit-tests</id>
+            <phase>test</phase>
+            <goals>
+              <goal>junit4</goal>
+            </goals>
+            <inherited>true</inherited>
+            <configuration>
+              <skipTests>${skipTests}</skipTests>
+              <includes>
+                <include>**/*Test.class</include>
+              </includes>
+              <excludes>
+                <exclude>**/*$*</exclude>
+              </excludes>
+            </configuration>
+          </execution>
+          <execution>
+            <id>integration-tests</id>
+            <phase>integration-test</phase>
+            <goals>
+              <goal>junit4</goal>
+            </goals>
+            <inherited>true</inherited>
+            <configuration>
+              <skipTests>${skipTests}</skipTests>
+              <includes>
+                <include>**/*IT.class</include>
+              </includes>
+              <excludes>
+                <exclude>**/*$*</exclude>
+              </excludes>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
 
   <artifactId>elasticsearch5-binding</artifactId>
   <name>Elasticsearch 5.x Binding</name>
@@ -75,4 +211,19 @@ LICENSE file.
       <scope>test</scope>
     </dependency>
   </dependencies>
+
+  <profiles>
+    <!-- Requires JDK8 to run, so none of our tests
+         will work unless we're using jdk8.
+      -->
+    <profile>
+      <id>jdk8-tests</id>
+      <activation>
+        <jdk>1.8</jdk>
+      </activation>
+      <properties>
+        <skipTests>false</skipTests>
+      </properties>
+    </profile>
+  </profiles>
 </project>
diff --git a/elasticsearch5/src/main/java/com/yahoo/ycsb/db/elasticsearch5/ElasticsearchRestClient.java b/elasticsearch5/src/main/java/com/yahoo/ycsb/db/elasticsearch5/ElasticsearchRestClient.java
index e4f3c9e535740efec00ac52077f3e04049265b4a..55ddc5b4d8e6996f5c6df2b06708a18d54018be7 100644
--- a/elasticsearch5/src/main/java/com/yahoo/ycsb/db/elasticsearch5/ElasticsearchRestClient.java
+++ b/elasticsearch5/src/main/java/com/yahoo/ycsb/db/elasticsearch5/ElasticsearchRestClient.java
@@ -120,13 +120,11 @@ public class ElasticsearchRestClient extends DB {
           Collections.<String, String>emptyMap(),
           new NStringEntity(new ObjectMapper().writeValueAsString(data), ContentType.APPLICATION_JSON));
 
-      if(response.getStatusLine().getStatusCode() == 200) {
-        return Status.OK;
-      }
+      return Status.OK;
     } catch (Exception e) {
       e.printStackTrace();
+      return Status.ERROR;
     }
-    return Status.ERROR;
   }
 
   @Override
@@ -136,13 +134,11 @@ public class ElasticsearchRestClient extends DB {
           HttpDelete.METHOD_NAME,
           "/" + indexKey + "/" + table + "/" + key);
 
-      if(response.getStatusLine().getStatusCode() == 200) {
-        return Status.OK;
-      }
+      return Status.OK;
     } catch (Exception e) {
       e.printStackTrace();
+      return Status.ERROR;
     }
-    return Status.ERROR;
   }
 
   @Override
@@ -150,13 +146,11 @@ public class ElasticsearchRestClient extends DB {
     try {
       Response response = restClient.performRequest(HttpGet.METHOD_NAME, "/");
 
-      if(response.getStatusLine().getStatusCode() == 200) {
-        return Status.OK;
-      }
+      return Status.OK;
     } catch (Exception e) {
       e.printStackTrace();
+      return Status.ERROR;
     }
-    return Status.ERROR;
 
 //    try {
 //      final GetResponse response = client.prepareGet(indexKey, table, key).execute().actionGet();
diff --git a/elasticsearch5/src/test/ant/integration-tests.xml b/elasticsearch5/src/test/ant/integration-tests.xml
new file mode 100644
index 0000000000000000000000000000000000000000..59675ccebc08a8d296237000b7a8f6f2f8d046d8
--- /dev/null
+++ b/elasticsearch5/src/test/ant/integration-tests.xml
@@ -0,0 +1,282 @@
+<?xml version="1.0"?>
+<project name="integration-tests" xmlns:if="ant:if" xmlns:unless="ant:unless">
+  <!-- our pid file for easy cleanup -->
+  <property name="integ.pidfile" location="${project.build.directory}/integration-tests/run/es.pid"/>
+
+  <!-- if this exists, ES is running (maybe) -->
+  <available property="integ.pidfile.exists" file="${integ.pidfile}"/>
+
+  <!-- name of our cluster, maybe needs changing -->
+  <property name="integ.cluster.name" value="elasticsearch_integration"/>
+
+  <!-- runs an OS script -->
+  <macrodef name="run-script">
+    <attribute name="script"/>
+    <attribute name="spawn" default="false"/>
+    <element name="nested" optional="true"/>
+    <sequential>
+      <local name="failonerror"/>
+      <condition property="failonerror">
+        <isfalse value="@{spawn}"/>
+      </condition>
+
+      <!-- create a temp CWD, to enforce that commands don't rely on CWD -->
+      <local name="temp.cwd"/>
+      <tempfile property="temp.cwd" destDir="${project.build.directory}/integration-tests/run/tmp" deleteonexit="true"/>
+      <mkdir dir="${temp.cwd}"/>
+
+      <!-- print commands we run -->
+      <local name="script.base"/>
+      <basename file="@{script}" property="script.base"/>
+      <!-- crappy way to output, but we need it. make it nice later -->
+      <echoxml><exec script="${script.base}"><nested/></exec></echoxml>
+      <exec executable="cmd" osfamily="winnt" dir="${temp.cwd}" failonerror="${failonerror}" spawn="@{spawn}" taskname="${script.base}">
+        <arg value="/c"/>
+        <arg value="&quot;"/>
+        <arg value="@{script}.bat"/>
+        <nested/>
+        <arg value="&quot;"/>
+      </exec>
+
+      <exec executable="bash" osfamily="unix" dir="${temp.cwd}" failonerror="${failonerror}" spawn="@{spawn}" taskname="${script.base}">
+        <arg value="@{script}"/>
+        <nested/>
+      </exec>
+    </sequential>
+  </macrodef>
+
+  <!-- extracts PID from file -->
+  <macrodef name="extract-pid">
+    <attribute name="file"/>
+    <attribute name="property"/>
+    <sequential>
+      <loadfile srcFile="@{file}" property="@{property}">
+        <filterchain>
+          <striplinebreaks/>
+        </filterchain>
+      </loadfile>
+    </sequential>
+  </macrodef>
+
+  <!-- applies transformations to src and stores in dst -->
+  <macrodef name="filter-property">
+    <attribute name="src"/>
+    <attribute name="dest"/>
+    <element name="chain"/>
+    <sequential>
+      <loadresource property="@{dest}">
+        <propertyresource name="@{src}"/>
+        <filterchain>
+          <tokenfilter>
+            <chain/>
+          </tokenfilter>
+        </filterchain>
+      </loadresource>
+    </sequential>
+  </macrodef>
+
+  <!-- waits for elasticsearch to start -->
+  <macrodef name="waitfor-elasticsearch">
+    <attribute name="port"/>
+    <attribute name="timeoutproperty"/>
+    <sequential>
+      <echo>Waiting for elasticsearch to become available on port @{port}...</echo>
+      <waitfor maxwait="30" maxwaitunit="second"
+               checkevery="500" checkeveryunit="millisecond"
+               timeoutproperty="@{timeoutproperty}">
+        <http url="http://localhost:@{port}"/>
+      </waitfor>
+    </sequential>
+  </macrodef>
+
+  <scriptdef name="isGreater" language="javascript">
+    <attribute name="v1"/>
+    <attribute name="v2"/>
+    <![CDATA[
+
+            var i, l, d, s = false;
+
+            a = attributes.get("v1").split('.');
+            b = attributes.get("v2").split('.');
+            l = Math.min(a.length, b.length);
+
+            for (i=0; i<l; i++) {
+                d = parseInt(a[i], 10) - parseInt(b[i], 10);
+                if (d !== 0) {
+                    project.setProperty("compare-result", d > 0);
+                    s = true;
+                    break;
+                }
+            }
+
+            if(!s){
+                d = a.length - b.length;
+                project.setProperty("compare-result", d >= 0);
+            }
+
+            ]]>
+  </scriptdef>
+
+  <!-- start elasticsearch and wait until its ready -->
+  <macrodef name="startup-elasticsearch">
+    <attribute name="home" default="${project.build.directory}/integration-tests/run/elasticsearch-${elasticsearch5-version}"/>
+    <attribute name="spawn" default="true"/>
+    <attribute name="es.cluster.name" default="${integ.cluster.name}"/>
+    <attribute name="es.http.port" default="${integ.http.port}"/>
+    <attribute name="es.transport.tcp.port" default="${integ.transport.port}"/>
+    <attribute name="es.pidfile" default="${integ.pidfile}"/>
+    <element name="additional-args" optional="true"/>
+    <sequential>
+      <!-- make sure no elasticsearch instance is currently running and listening on the port we need -->
+      <fail message="This test expects port @{es.http.port} to be free but an elasticsearch instance is already running and listening on that port.
+      Maybe the last test run did not manage to shut down the node correctly?
+      You must kill it before tests can run.">
+        <condition>
+          <socket server="localhost" port="@{es.http.port}"></socket>
+        </condition>
+      </fail>
+      <!-- run bin/elasticsearch with args -->
+      <echo>Starting up external cluster...</echo>
+      <isGreater v1="${elasticsearch5-version}" v2="5.0.0" />
+
+      <echo if:true="${compare-result}">running Elasticsearch 5.0.0 or superior</echo>
+      <echo unless:true="${compare-result}">running Elasticsearch &lt; 5.0.0</echo>
+
+      <run-script script="@{home}/bin/elasticsearch"
+                  spawn="@{spawn}">
+        <nested>
+          <arg value="-Des.pidfile=@{es.pidfile}" unless:true="${compare-result}"/>
+          <arg value="-Des.cluster.name=@{es.cluster.name}" unless:true="${compare-result}"/>
+          <arg value="-Des.http.port=@{es.http.port}" unless:true="${compare-result}"/>
+          <arg value="-Des.transport.tcp.port=@{es.transport.tcp.port}" unless:true="${compare-result}"/>
+          <arg value="-Des.network.host=127.0.0.1" unless:true="${compare-result}"/>
+          <arg value="-Epidfile=@{es.pidfile}" if:true="${compare-result}"/>
+          <arg value="-Ecluster.name=@{es.cluster.name}" if:true="${compare-result}"/>
+          <arg value="-Ehttp.port=@{es.http.port}" if:true="${compare-result}"/>
+          <arg value="-Etransport.tcp.port=@{es.transport.tcp.port}" if:true="${compare-result}"/>
+          <arg value="-Enetwork.host=127.0.0.1" if:true="${compare-result}"/>
+          <additional-args/>
+        </nested>
+      </run-script>
+
+      <!-- wait for startup -->
+      <local name="failed.to.start"/>
+      <waitfor-elasticsearch port="@{es.http.port}"
+                             timeoutproperty="failed.to.start"/>
+
+      <!-- best effort, print console log. useful if it fails especially -->
+      <local name="log.contents"/>
+      <loadfile srcFile="@{home}/logs/@{es.cluster.name}.log"
+                property="log.contents"
+                failonerror="false"/>
+      <echo message="${log.contents}" taskname="elasticsearch"/>
+
+      <fail message="ES instance did not start" if="failed.to.start"/>
+
+      <local name="integ.pid"/>
+      <extract-pid file="@{es.pidfile}" property="integ.pid"/>
+      <echo>External node started PID ${integ.pid}</echo>
+    </sequential>
+  </macrodef>
+
+  <macrodef name="stop-node">
+    <attribute name="es.pidfile" default="${integ.pidfile}"/>
+    <sequential>
+      <local name="integ.pid"/>
+
+      <extract-pid file="@{es.pidfile}" property="integ.pid"/>
+      <echo>Shutting down external node PID ${integ.pid}</echo>
+      <!-- verify with jps that this actually is the correct pid.
+      See if we can find the line "pid org.elasticsearch.bootstrap.Elasticsearch" in the output of jps -l.-->
+      <local name="jps.pidline"/>
+      <local name="jps.executable"/>
+      <local name="environment"/>
+      <property environment="environment"/>
+      <property name="jps.executable" location="${environment.JAVA_HOME}/bin/jps"/>
+      <exec executable="${jps.executable}" failonerror="true">
+        <arg value="-l"/>
+        <redirector outputproperty="jps.pidline">
+          <outputfilterchain>
+            <linecontains>
+              <contains value="${integ.pid} org.elasticsearch.bootstrap.Elasticsearch"/>
+            </linecontains>
+          </outputfilterchain>
+        </redirector>
+      </exec>
+      <fail
+          message="pid file at @{es.pidfile} is ${integ.pid} but jps -l did not report any process with org.elasticsearch.bootstrap.Elasticsearch and this pid.
+          Did you run mvn clean? Maybe an old pid file is still lying around.">
+        <condition>
+          <equals arg1="${jps.pidline}" arg2=""/>
+        </condition>
+      </fail>
+
+      <exec executable="taskkill" failonerror="true" osfamily="winnt">
+        <arg value="/F"/>
+        <arg value="/PID"/>
+        <arg value="${integ.pid}"/>
+      </exec>
+      <exec executable="kill" failonerror="true" osfamily="unix">
+        <arg value="-9"/>
+        <arg value="${integ.pid}"/>
+      </exec>
+      <delete file="@{es.pidfile}"/>
+    </sequential>
+  </macrodef>
+
+  <target name="stop-external-cluster" if="integ.pidfile.exists">
+    <stop-node/>
+  </target>
+
+  <target name="setup-workspace" depends="stop-external-cluster">
+    <sequential>
+      <delete dir="${project.build.directory}/integration-tests/run"/>
+      <unzip src="${project.build.directory}/integration-tests/binaries/elasticsearch-${elasticsearch5-version}.zip"
+             dest="${project.build.directory}/integration-tests/run"/>
+    </sequential>
+  </target>
+
+  <target name="start-external-cluster" depends="setup-workspace">
+    <startup-elasticsearch/>
+  </target>
+
+  <!-- unzip integ test artifact, install plugin, then start ES -->
+  <target name="start-external-cluster-with-plugin" depends="setup-workspace">
+    <install-plugin name="${project.artifactId}" file="${project.build.directory}/releases/${project.artifactId}-${project.version}.zip"/>
+    <startup-elasticsearch/>
+  </target>
+
+  <!-- installs a plugin into elasticsearch -->
+  <macrodef name="install-plugin">
+    <attribute name="home" default="${project.build.directory}/integration-tests/run/elasticsearch-${elasticsearch5-version}"/>
+    <attribute name="name"/>
+    <attribute name="file"/>
+    <sequential>
+      <local name="url"/>
+      <makeurl property="url" file="@{file}"/>
+
+      <isGreater v1="${elasticsearch5-version}" v2="5.0.0" />
+      <property name="commandline" value="@{home}/bin/plugin" unless:true="${compare-result}"/>
+      <property name="commandline" value="@{home}/bin/elasticsearch-plugin" if:true="${compare-result}"/>
+
+      <!-- install plugin -->
+      <echo>Installing plugin @{name}...</echo>
+      <run-script script="${commandline}">
+        <nested>
+          <arg value="install"/>
+          <arg value="${url}"/>
+        </nested>
+      </run-script>
+
+      <fail message="did not find plugin installed as @{name}">
+        <condition>
+          <not>
+            <resourceexists>
+              <file file="@{home}/plugins/@{name}"/>
+            </resourceexists>
+          </not>
+        </condition>
+      </fail>
+    </sequential>
+  </macrodef>
+</project>
\ No newline at end of file
diff --git a/elasticsearch5/src/test/java/com/yahoo/ycsb/db/elasticsearch5/ElasticsearchRestClientTestIT.java b/elasticsearch5/src/test/java/com/yahoo/ycsb/db/elasticsearch5/ElasticsearchRestClientTestIT.java
new file mode 100644
index 0000000000000000000000000000000000000000..fac85fd7ba26e1eb74a64d15a059fe9f31dfbed9
--- /dev/null
+++ b/elasticsearch5/src/test/java/com/yahoo/ycsb/db/elasticsearch5/ElasticsearchRestClientTestIT.java
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2017 YCSB contributors. All rights reserved.
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); you
+ * may not use this file except in compliance with the License. You
+ * may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License. See accompanying
+ * LICENSE file.
+ */
+
+package com.yahoo.ycsb.db.elasticsearch5;
+
+import com.yahoo.ycsb.ByteIterator;
+import com.yahoo.ycsb.DBException;
+import com.yahoo.ycsb.Status;
+import com.yahoo.ycsb.StringByteIterator;
+import org.junit.*;
+
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+
+import static org.junit.Assert.assertEquals;
+
+public class ElasticsearchRestClientTestIT {
+  private final static String TEST_HOST = "localhost:9400";
+  private final static ElasticsearchRestClient instance = new ElasticsearchRestClient();
+  private final static HashMap<String, ByteIterator> MOCK_DATA;
+  private final static String MOCK_TABLE = "MOCK_TABLE";
+  private final static String MOCK_KEY0 = "0";
+  private final static String MOCK_KEY1 = "1";
+  private final static String MOCK_KEY2 = "2";
+
+  static {
+    MOCK_DATA = new HashMap<>(10);
+    for (int i = 1; i <= 10; i++) {
+      MOCK_DATA.put("field" + i, new StringByteIterator("value" + i));
+    }
+  }
+
+  @BeforeClass
+  public static void setUpClass() throws DBException {
+    final Properties props = new Properties();
+    props.setProperty("es.hosts.list", TEST_HOST);
+    instance.setProperties(props);
+    instance.init();
+  }
+
+  @AfterClass
+  public static void tearDownClass() throws DBException {
+    instance.cleanup();
+  }
+
+  @Before
+  public void setUp() {
+    instance.insert(MOCK_TABLE, MOCK_KEY1, MOCK_DATA);
+    instance.insert(MOCK_TABLE, MOCK_KEY2, MOCK_DATA);
+  }
+
+  @After
+  public void tearDown() {
+    instance.delete(MOCK_TABLE, MOCK_KEY1);
+    instance.delete(MOCK_TABLE, MOCK_KEY2);
+  }
+
+  @Test
+  public void testInsert() {
+    Status result = instance.insert(MOCK_TABLE, MOCK_KEY0, MOCK_DATA);
+    assertEquals(Status.OK, result);
+  }
+
+  @Test
+  public void testDelete() {
+    Status result = instance.delete(MOCK_TABLE, MOCK_KEY1);
+    assertEquals(Status.OK, result);
+  }
+
+  @Test
+  public void testRead() {
+    Set<String> fields = MOCK_DATA.keySet();
+    HashMap<String, ByteIterator> resultParam = new HashMap<>(10);
+    Status result = instance.read(MOCK_TABLE, MOCK_KEY1, fields, resultParam);
+    assertEquals(Status.OK, result);
+  }
+
+  @Test
+  public void testUpdate() {
+    int i;
+    HashMap<String, ByteIterator> newValues = new HashMap<>(10);
+
+    for (i = 1; i <= 10; i++) {
+      newValues.put("field" + i, new StringByteIterator("newvalue" + i));
+    }
+
+    Status result = instance.update(MOCK_TABLE, MOCK_KEY1, newValues);
+    assertEquals(Status.OK, result);
+
+    //validate that the values changed
+    HashMap<String, ByteIterator> resultParam = new HashMap<>(10);
+    instance.read(MOCK_TABLE, MOCK_KEY1, MOCK_DATA.keySet(), resultParam);
+
+    for (i = 1; i <= 10; i++) {
+      assertEquals("newvalue" + i, resultParam.get("field" + i).toString());
+    }
+
+  }
+  
+  @Test
+  public void testScan() {
+    int recordcount = 10;
+    Set<String> fields = MOCK_DATA.keySet();
+    Vector<HashMap<String, ByteIterator>> resultParam = new Vector<>(10);
+    Status result = instance.scan(MOCK_TABLE, MOCK_KEY1, recordcount, fields, resultParam);
+    assertEquals(Status.NOT_IMPLEMENTED, result);
+  }
+}