diff --git a/orientdb/pom.xml b/orientdb/pom.xml
index 0613b0f8838df12088c8fe9fe81aca951dc5b539..3f10a675cb8259f50dfa19834f3e53224b7a5523 100644
--- a/orientdb/pom.xml
+++ b/orientdb/pom.xml
@@ -47,5 +47,11 @@ LICENSE file.
 			<artifactId>orientdb-core</artifactId>
 			<version>1.7.10</version>
 		</dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
 	</dependencies>
 </project>
diff --git a/orientdb/src/test/java/com/yahoo/ycsb/db/OrientDBClientTest.java b/orientdb/src/test/java/com/yahoo/ycsb/db/OrientDBClientTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..bd1f3fd73f57c041cad31edd887d0c807cc4b28b
--- /dev/null
+++ b/orientdb/src/test/java/com/yahoo/ycsb/db/OrientDBClientTest.java
@@ -0,0 +1,236 @@
+/**
+ * Copyright (c) 2015 YCSB contributors. All rights reserved.
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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;
+
+import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
+import com.orientechnologies.orient.core.dictionary.ODictionary;
+import com.orientechnologies.orient.core.record.ORecordInternal;
+import com.orientechnologies.orient.core.record.impl.ODocument;
+import com.yahoo.ycsb.ByteIterator;
+import com.yahoo.ycsb.DBException;
+import com.yahoo.ycsb.StringByteIterator;
+
+import org.junit.*;
+import java.util.*;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by kruthar on 12/29/15.
+ */
+public class OrientDBClientTest {
+  // TODO: This must be copied because it is private in OrientDBClient, but this should defer to table property.
+  private static final String CLASS = "usertable";
+  private static final int FIELD_LENGTH = 32;
+  private static final String FIELD_PREFIX = "FIELD";
+  private static final String KEY_PREFIX = "user";
+  private static final int NUM_FIELDS = 3;
+  private static final String TEST_DB_URL = "memory:test";
+
+  private static ODatabaseDocumentTx orientDBConnection = null;
+  private static ODictionary<ORecordInternal<?>> orientDBDictionary;
+  private static OrientDBClient orientDBClient = null;
+
+  @Before
+  public void setup() throws DBException {
+    orientDBClient = new OrientDBClient();
+
+    Properties p = new Properties();
+    // TODO: Extract the property names into final variables in OrientDBClient
+    p.setProperty("orientdb.url", TEST_DB_URL);
+
+    orientDBClient.setProperties(p);
+    orientDBClient.init();
+    orientDBConnection = new ODatabaseDocumentTx(TEST_DB_URL).open("admin","admin");
+    orientDBDictionary = orientDBConnection.getMetadata().getIndexManager().getDictionary();
+  }
+
+  @After
+  public void teardown() throws DBException {
+    if (orientDBConnection != null) {
+      orientDBConnection.close();
+    }
+
+    if (orientDBClient != null) {
+      orientDBClient.cleanup();
+    }
+  }
+
+  /*
+      This is a copy of buildDeterministicValue() from core:com.yahoo.ycsb.workloads.CoreWorkload.java.
+      That method is neither public nor static so we need a copy.
+   */
+  private String buildDeterministicValue(String key, String fieldkey) {
+    int size = FIELD_LENGTH;
+    StringBuilder sb = new StringBuilder(size);
+    sb.append(key);
+    sb.append(':');
+    sb.append(fieldkey);
+    while (sb.length() < size) {
+      sb.append(':');
+      sb.append(sb.toString().hashCode());
+    }
+    sb.setLength(size);
+
+    return sb.toString();
+  }
+
+  /*
+      Inserts a row of deterministic values for the given insertKey using the orientDBClient.
+   */
+  private Map<String, ByteIterator> insertRow(String insertKey) {
+    HashMap<String, ByteIterator> insertMap = new HashMap<>();
+    for (int i = 0; i < 3; i++) {
+      insertMap.put(FIELD_PREFIX + i, new StringByteIterator(buildDeterministicValue(insertKey, FIELD_PREFIX + i)));
+    }
+    orientDBClient.insert(CLASS, insertKey, insertMap);
+
+    return insertMap;
+  }
+
+  @Test
+  public void insertTest() {
+    String insertKey = "user0";
+    Map<String, ByteIterator> insertMap = insertRow(insertKey);
+
+    ODocument result = orientDBDictionary.get(insertKey);
+
+    assertTrue("Assert a row was inserted.", result != null);
+
+    for (int i = 0; i < NUM_FIELDS; i++) {
+      assertEquals("Assert all inserted columns have correct values.", result.field(FIELD_PREFIX + i), insertMap.get(FIELD_PREFIX + i).toString());
+    }
+  }
+
+  @Test
+  public void updateTest() {
+    String preupdateString = "preupdate";
+    String user0 = "user0";
+    String user1 = "user1";
+    String user2 = "user2";
+
+    // Manually insert three documents
+    for(String key: Arrays.asList(user0, user1, user2)) {
+      ODocument doc = new ODocument(CLASS);
+      for (int i = 0; i < NUM_FIELDS; i++) {
+        doc.field(FIELD_PREFIX + i, preupdateString);
+      }
+      doc.save();
+      orientDBDictionary.put(key, doc);
+    }
+
+    HashMap<String, ByteIterator> updateMap = new HashMap<>();
+    for (int i = 0; i < NUM_FIELDS; i++) {
+      updateMap.put(FIELD_PREFIX + i, new StringByteIterator(buildDeterministicValue(user1, FIELD_PREFIX + i)));
+    }
+
+    orientDBClient.update(CLASS, user1, updateMap);
+
+    // Ensure that user0 record was not changed
+    ODocument result = orientDBDictionary.get(user0);
+    for (int i = 0; i < NUM_FIELDS; i++) {
+      assertEquals("Assert first row fields contain preupdateString", result.field(FIELD_PREFIX + i), preupdateString);
+    }
+
+    // Check that all the columns have expected values for user1 record
+    result = orientDBDictionary.get(user1);
+    for (int i = 0; i < NUM_FIELDS; i++) {
+      assertEquals("Assert updated row fields are correct", result.field(FIELD_PREFIX + i), updateMap.get(FIELD_PREFIX + i).toString());
+    }
+
+    // Ensure that user2 record was not changed
+    result = orientDBDictionary.get(user2);
+    for (int i = 0; i < NUM_FIELDS; i++) {
+      assertEquals("Assert third row fields contain preupdateString", result.field(FIELD_PREFIX + i), preupdateString);
+    }
+  }
+
+  @Test
+  public void readTest() {
+    String insertKey = "user0";
+    Map<String, ByteIterator> insertMap = insertRow(insertKey);
+    HashSet<String> readFields = new HashSet<>();
+    HashMap<String, ByteIterator> readResultMap = new HashMap<>();
+
+    // Test reading a single field
+    readFields.add("FIELD0");
+    orientDBClient.read(CLASS, insertKey, readFields, readResultMap);
+    assertEquals("Assert that result has correct number of fields", readFields.size(), readResultMap.size());
+    for (String field: readFields) {
+      assertEquals("Assert " + field + " was read correctly", insertMap.get(field).toString(), readResultMap.get(field).toString());
+    }
+
+    readResultMap = new HashMap<>();
+
+    // Test reading all fields
+    readFields.add("FIELD1");
+    readFields.add("FIELD2");
+    orientDBClient.read(CLASS, insertKey, readFields, readResultMap);
+    assertEquals("Assert that result has correct number of fields", readFields.size(), readResultMap.size());
+    for (String field: readFields) {
+      assertEquals("Assert " + field + " was read correctly", insertMap.get(field).toString(), readResultMap.get(field).toString());
+    }
+  }
+
+  @Test
+  public void deleteTest() {
+    String user0 = "user0";
+    String user1 = "user1";
+    String user2 = "user2";
+
+    insertRow(user0);
+    insertRow(user1);
+    insertRow(user2);
+
+    orientDBClient.delete(CLASS, user1);
+
+    assertNotNull("Assert user0 still exists", orientDBDictionary.get(user0));
+    assertNull("Assert user1 does not exist", orientDBDictionary.get(user1));
+    assertNotNull("Assert user2 still exists", orientDBDictionary.get(user2));
+  }
+
+  @Test
+  public void scanTest() {
+    Map<String, Map<String, ByteIterator>> keyMap = new HashMap<>();
+    for (int i = 0; i < 5; i++) {
+      String insertKey = KEY_PREFIX + i;
+      keyMap.put(insertKey, insertRow(insertKey));
+    }
+
+    Set<String> fieldSet = new HashSet<>();
+    fieldSet.add("FIELD0");
+    fieldSet.add("FIELD1");
+    int startIndex = 1;
+    int resultRows = 3;
+
+    Vector<HashMap<String, ByteIterator>> resultVector = new Vector<>();
+    orientDBClient.scan(CLASS, KEY_PREFIX + startIndex, resultRows, fieldSet, resultVector);
+
+    // Check the resultVector is the correct size
+    assertEquals("Assert the correct number of results rows were returned", resultRows, resultVector.size());
+    // Check each vector row to make sure we have the correct fields
+    int testIndex = startIndex;
+    for (HashMap<String, ByteIterator> result: resultVector) {
+      assertEquals("Assert that this row has the correct number of fields", fieldSet.size(), result.size());
+      for (String field: fieldSet) {
+        assertEquals("Assert this field is correct in this row", keyMap.get(KEY_PREFIX + testIndex).get(field).toString(), result.get(field).toString());
+      }
+      testIndex++;
+    }
+  }
+}