diff --git a/mongodb/pom.xml b/mongodb/pom.xml
index 0a81b248..3038e17d 100644
--- a/mongodb/pom.xml
+++ b/mongodb/pom.xml
@@ -1,87 +1,94 @@
-
- 4.0.0
-
- com.yahoo.ycsb
- root
- 0.2.0-SNAPSHOT
-
+
+ 4.0.0
+
+ com.yahoo.ycsb
+ root
+ 0.2.0-SNAPSHOT
+
- mongodb-binding
- MongoDB Binding
- jar
+ mongodb-binding
+ MongoDB Binding
+ jar
-
-
- org.mongodb
- mongo-java-driver
- ${mongodb.version}
-
-
- com.allanbank
- mongodb-async-driver
- ${mongodb.async.version}
-
-
- com.yahoo.ycsb
- core
- ${project.version}
-
-
- ch.qos.logback
- logback-classic
- 1.1.2
-
+
+
+ org.mongodb
+ mongo-java-driver
+ ${mongodb.version}
+
+
+ com.allanbank
+ mongodb-async-driver
+ ${mongodb.async.version}
+
+
+ com.yahoo.ycsb
+ core
+ ${project.version}
+
+
+ ch.qos.logback
+ logback-classic
+ 1.1.2
+
-
- junit
- junit
- 4.12
- test
-
-
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ de.flapdoodle.embed
+ de.flapdoodle.embed.mongo
+ 1.47.3
+ test
+
+
-
-
-
- org.apache.maven.plugins
- maven-assembly-plugin
- ${maven.assembly.version}
-
-
- jar-with-dependencies
-
- false
-
-
-
- package
-
- single
-
-
-
-
-
-
-
-
-
-
- true
- always
- warn
-
-
- false
- never
- fail
-
- allanbank
- Allanbank Releases
- http://www.allanbank.com/repo/
- default
-
-
-
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ ${maven.assembly.version}
+
+
+ jar-with-dependencies
+
+ false
+
+
+
+ package
+
+ single
+
+
+
+
+
+
+
+
+
+ true
+ always
+ warn
+
+
+ false
+ never
+ fail
+
+ allanbank
+ Allanbank Releases
+ http://www.allanbank.com/repo/
+ default
+
+
+
diff --git a/mongodb/src/main/java/com/yahoo/ycsb/db/MongoDbClient.java b/mongodb/src/main/java/com/yahoo/ycsb/db/MongoDbClient.java
index 511efda2..5163f05c 100644
--- a/mongodb/src/main/java/com/yahoo/ycsb/db/MongoDbClient.java
+++ b/mongodb/src/main/java/com/yahoo/ycsb/db/MongoDbClient.java
@@ -1,474 +1,476 @@
/**
* MongoDB client binding for YCSB.
*
* Submitted by Yen Pai on 5/11/2010.
*
* https://gist.github.com/000a66b8db2caf42467b#file_mongo_database.java
*
*/
package com.yahoo.ycsb.db;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;
import org.bson.Document;
+import org.bson.types.Binary;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.ReadPreference;
import com.mongodb.WriteConcern;
import com.mongodb.bulk.BulkWriteResult;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.BulkWriteOptions;
import com.mongodb.client.model.InsertOneModel;
import com.mongodb.client.model.UpdateOptions;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.yahoo.ycsb.ByteArrayByteIterator;
import com.yahoo.ycsb.ByteIterator;
import com.yahoo.ycsb.DB;
import com.yahoo.ycsb.DBException;
/**
* MongoDB client for YCSB framework.
*
* Properties to set:
*
* mongodatabase.url=mongodb://localhost:27017 mongodatabase.database=ycsb
* mongodatabase.writeConcern=acknowledged
*
* @author ypai
*/
public class MongoDbClient extends DB {
/** Update options to do an upsert. */
private static final UpdateOptions UPSERT = new UpdateOptions()
.upsert(true);
/** Used to include a field in a response. */
protected static final Integer INCLUDE = Integer.valueOf(1);
/** The database name to access. */
private static String databaseName;
/** The database name to access. */
private static MongoDatabase database;
/**
* Count the number of times initialized to teardown on the last
* {@link #cleanup()}.
*/
private static final AtomicInteger initCount = new AtomicInteger(0);
/** A singleton Mongo instance. */
private static MongoClient mongoClient;
/** The default read preference for the test */
private static ReadPreference readPreference;
/** The default write concern for the test. */
private static WriteConcern writeConcern;
/** The batch size to use for inserts. */
private static int batchSize;
/** The bulk inserts pending for the thread. */
private final List> bulkInserts = new ArrayList>();
/**
* Cleanup any state for this DB. Called once per DB instance; there is one
* DB instance per client thread.
*/
@Override
public void cleanup() throws DBException {
if (initCount.decrementAndGet() == 0) {
try {
mongoClient.close();
}
catch (Exception e1) {
System.err.println("Could not close MongoDB connection pool: "
+ e1.toString());
e1.printStackTrace();
return;
}
finally {
database = null;
mongoClient = null;
}
}
}
/**
* Delete a record from the database.
*
* @param table
* The name of the table
* @param key
* The record key of the record to delete.
* @return Zero on success, a non-zero error code on error. See the
* {@link DB} class's description for a discussion of error codes.
*/
@Override
public int delete(String table, String key) {
try {
MongoCollection collection = database
.getCollection(table);
Document query = new Document("_id", key);
DeleteResult result = collection.withWriteConcern(writeConcern)
.deleteOne(query);
if (result.getDeletedCount() == 0) {
System.err.println("Nothing deleted for key " + key);
return 1;
}
return 0;
}
catch (Exception e) {
System.err.println(e.toString());
return 1;
}
}
/**
* Initialize any state for this DB. Called once per DB instance; there is
* one DB instance per client thread.
*/
@Override
public void init() throws DBException {
initCount.incrementAndGet();
synchronized (INCLUDE) {
if (mongoClient != null) {
return;
}
Properties props = getProperties();
// Set insert batchsize, default 1 - to be YCSB-original equivalent
batchSize = Integer.parseInt(props.getProperty("batchsize", "1"));
// Just use the standard connection format URL
// http://docs.mongodatabase.org/manual/reference/connection-string/
// to configure the client.
//
// Support legacy options by updating the URL as appropriate.
String url = props.getProperty("mongodatabase.url", null);
boolean defaultedUrl = false;
if (url == null) {
defaultedUrl = true;
url = "mongodb://localhost:27017/ycsb?w=1";
}
url = OptionsSupport.updateUrl(url, props);
if (!url.startsWith("mongodb://")) {
System.err
.println("ERROR: Invalid URL: '"
+ url
+ "'. Must be of the form "
+ "'mongodb://:,:/database?options'. "
+ "See http://docs.mongodatabase.org/manual/reference/connection-string/.");
System.exit(1);
}
try {
MongoClientURI uri = new MongoClientURI(url);
String uriDb = uri.getDatabase();
if (!defaultedUrl && (uriDb != null) && !uriDb.isEmpty()
&& !"admin".equals(uriDb)) {
databaseName = uriDb;
}
else {
databaseName = props.getProperty("mongodatabase.database",
"ycsb");
}
if ((databaseName == null) || databaseName.isEmpty()) {
System.err
.println("ERROR: Invalid URL: '"
+ url
+ "'. Must provide a database name with the URI. "
+ "'mongodb://:,:/database");
System.exit(1);
}
readPreference = uri.getOptions().getReadPreference();
writeConcern = uri.getOptions().getWriteConcern();
mongoClient = new MongoClient(uri);
database = mongoClient.getDatabase(databaseName);
System.out.println("mongo client connection created with "
+ url);
}
catch (Exception e1) {
System.err
.println("Could not initialize MongoDB connection pool for Loader: "
+ e1.toString());
e1.printStackTrace();
return;
}
}
}
/**
* Insert a record in the database. Any field/value pairs in the specified
* values HashMap will be written into the record with the specified record
* key.
*
* @param table
* The name of the table
* @param key
* The record key of the record to insert.
* @param values
* A HashMap of field/value pairs to insert in the record
* @return Zero on success, a non-zero error code on error. See the
* {@link DB} class's description for a discussion of error codes.
*/
@Override
public int insert(String table, String key,
HashMap values) {
try {
MongoCollection collection = database
.getCollection(table);
Document criteria = new Document("_id", key);
Document toInsert = new Document("_id", key);
for (Map.Entry entry : values.entrySet()) {
toInsert.put(entry.getKey(), entry.getValue().toArray());
}
// Do a single upsert.
if (batchSize <= 1) {
UpdateResult result = collection.withWriteConcern(writeConcern)
- .updateOne(criteria, toInsert, UPSERT);
+ .replaceOne(criteria, toInsert, UPSERT);
if (result.getMatchedCount() > 0
- || result.getModifiedCount() > 0) {
+ || result.getModifiedCount() > 0
+ || result.getUpsertedId() != null) {
return 0;
}
System.err.println("Nothing inserted for key " + key);
return 1;
}
// Use a bulk insert.
try {
bulkInserts.add(new InsertOneModel(toInsert));
if (bulkInserts.size() < batchSize) {
return 0;
}
BulkWriteResult result = collection.withWriteConcern(
writeConcern).bulkWrite(bulkInserts,
new BulkWriteOptions().ordered(false));
if (result.getInsertedCount() == bulkInserts.size()) {
bulkInserts.clear();
return 0;
}
System.err
.println("Number of inserted documents doesn't match the number sent, "
+ result.getInsertedCount()
+ " inserted, sent " + bulkInserts.size());
bulkInserts.clear();
return 1;
}
catch (Exception e) {
System.err.println("Exception while trying bulk insert with "
+ bulkInserts.size());
e.printStackTrace();
return 1;
}
}
catch (Exception e) {
e.printStackTrace();
return 1;
}
}
/**
* Read a record from the database. Each field/value pair from the result
* will be stored in a HashMap.
*
* @param table
* The name of the table
* @param key
* The record key of the record to read.
* @param fields
* The list of fields to read, or null for all of them
* @param result
* A HashMap of field/value pairs for the result
* @return Zero on success, a non-zero error code on error or "not found".
*/
@Override
public int read(String table, String key, Set fields,
HashMap result) {
try {
MongoCollection collection = database
.getCollection(table);
Document query = new Document("_id", key);
Document fieldsToReturn = new Document();
Document queryResult = null;
if (fields != null) {
Iterator iter = fields.iterator();
while (iter.hasNext()) {
fieldsToReturn.put(iter.next(), INCLUDE);
}
queryResult = collection.withReadPreference(readPreference)
.find(query).projection(fieldsToReturn).first();
}
else {
queryResult = collection.withReadPreference(readPreference)
.find(query).first();
}
if (queryResult != null) {
fillMap(result, queryResult);
}
return queryResult != null ? 0 : 1;
}
catch (Exception e) {
System.err.println(e.toString());
return 1;
}
}
/**
* Perform a range scan for a set of records in the database. Each
* field/value pair from the result will be stored in a HashMap.
*
* @param table
* The name of the table
* @param startkey
* The record key of the first record to read.
* @param recordcount
* The number of records to read
* @param fields
* The list of fields to read, or null for all of them
* @param result
* A Vector of HashMaps, where each HashMap is a set field/value
* pairs for one record
* @return Zero on success, a non-zero error code on error. See the
* {@link DB} class's description for a discussion of error codes.
*/
@Override
public int scan(String table, String startkey, int recordcount,
Set fields, Vector> result) {
FindIterable cursor = null;
MongoCursor iter = null;
try {
MongoCollection collection = database
.getCollection(table);
Document scanRange = new Document("$gte", startkey);
Document query = new Document("_id", scanRange);
Document sort = new Document("_id", INCLUDE);
Document projection = null;
if (fields != null) {
projection = new Document();
for (String fieldName : fields) {
projection.put(fieldName, INCLUDE);
}
}
cursor = collection.withReadPreference(readPreference).find(query)
.projection(projection).sort(sort).limit(recordcount);
// Do the query.
iter = cursor.iterator();
if (!iter.hasNext()) {
System.err.println("Nothing found in scan for key " + startkey);
return 1;
}
while (iter.hasNext()) {
HashMap resultMap = new HashMap();
Document obj = iter.next();
fillMap(resultMap, obj);
result.add(resultMap);
}
return 0;
}
catch (Exception e) {
System.err.println(e.toString());
return 1;
}
finally {
if (iter != null) {
iter.close();
}
}
}
/**
* Update a record in the database. Any field/value pairs in the specified
* values HashMap will be written into the record with the specified record
* key, overwriting any existing values with the same field name.
*
* @param table
* The name of the table
* @param key
* The record key of the record to write.
* @param values
* A HashMap of field/value pairs to update in the record
* @return Zero on success, a non-zero error code on error. See this class's
* description for a discussion of error codes.
*/
@Override
public int update(String table, String key,
HashMap values) {
try {
MongoCollection collection = database
.getCollection(table);
Document query = new Document("_id", key);
Document fieldsToSet = new Document();
for (Map.Entry entry : values.entrySet()) {
fieldsToSet.put(entry.getKey(), entry.getValue().toArray());
}
Document update = new Document("$set", fieldsToSet);
UpdateResult result = collection.withWriteConcern(writeConcern)
.updateOne(query, update);
if (result.getMatchedCount() == 0) {
System.err.println("Nothing updated for key " + key);
return 1;
}
return 0;
}
catch (Exception e) {
System.err.println(e.toString());
return 1;
}
}
/**
* Fills the map with the values from the DBObject.
*
* @param resultMap
* The map to fill/
* @param obj
* The object to copy values from.
*/
protected void fillMap(HashMap resultMap, Document obj) {
for (Map.Entry entry : obj.entrySet()) {
- if (entry.getValue() instanceof byte[]) {
+ if (entry.getValue() instanceof Binary) {
resultMap.put(entry.getKey(), new ByteArrayByteIterator(
- (byte[]) entry.getValue()));
+ ((Binary) entry.getValue()).getData()));
}
}
}
}
diff --git a/mongodb/src/test/java/com/yahoo/ycsb/db/AbstractDBTestCases.java b/mongodb/src/test/java/com/yahoo/ycsb/db/AbstractDBTestCases.java
new file mode 100644
index 00000000..94d082b5
--- /dev/null
+++ b/mongodb/src/test/java/com/yahoo/ycsb/db/AbstractDBTestCases.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2014, Yahoo!, Inc. 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 static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.Vector;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.yahoo.ycsb.ByteArrayByteIterator;
+import com.yahoo.ycsb.ByteIterator;
+import com.yahoo.ycsb.DB;
+
+import de.flapdoodle.embed.mongo.Command;
+import de.flapdoodle.embed.mongo.MongodExecutable;
+import de.flapdoodle.embed.mongo.MongodProcess;
+import de.flapdoodle.embed.mongo.MongodStarter;
+import de.flapdoodle.embed.mongo.config.ArtifactStoreBuilder;
+import de.flapdoodle.embed.mongo.config.IMongodConfig;
+import de.flapdoodle.embed.mongo.config.MongodConfigBuilder;
+import de.flapdoodle.embed.mongo.config.Net;
+import de.flapdoodle.embed.mongo.config.RuntimeConfigBuilder;
+import de.flapdoodle.embed.mongo.distribution.Version;
+import de.flapdoodle.embed.process.io.directories.FixedPath;
+import de.flapdoodle.embed.process.runtime.Network;
+
+/**
+ * MongoDbClientTest provides runs the basic DB test cases.
+ */
+@SuppressWarnings("boxing")
+public abstract class AbstractDBTestCases {
+
+ /** The handle to the running server. */
+ private static MongodExecutable ourMongodExecutable = null;
+
+ /** The running Mongodb process. */
+ private static MongodProcess ourMongod = null;
+
+ /** The directory to download the MongoDB executables to. */
+ private static final File TMP_DIR = new File("target/mongodb");
+
+ /**
+ * Start a test mongd instance.
+ */
+ @BeforeClass
+ public static void setUpBeforeClass() {
+ TMP_DIR.mkdirs();
+
+ MongodStarter starter = MongodStarter
+ .getInstance(new RuntimeConfigBuilder()
+ .defaults(Command.MongoD)
+ .artifactStore(
+ new ArtifactStoreBuilder()
+ .defaults(Command.MongoD)
+ .useCache(false)
+ .tempDir(
+ new FixedPath(TMP_DIR
+ .getAbsolutePath())))
+ .build());
+ int port = 27017;
+
+ try {
+ IMongodConfig mongodConfig = new MongodConfigBuilder()
+ .version(Version.Main.PRODUCTION)
+ .net(new Net(port, Network.localhostIsIPv6())).build();
+
+ ourMongodExecutable = starter.prepare(mongodConfig);
+ ourMongod = ourMongodExecutable.start();
+ }
+ catch (IOException error) {
+ assumeNoException(error);
+ }
+ }
+
+ /**
+ * Stops the test server.
+ */
+ @AfterClass
+ public static void tearDownAfterClass() {
+ if (ourMongod != null) {
+ ourMongod.stop();
+ ourMongod = null;
+ }
+ if (ourMongodExecutable != null) {
+ ourMongodExecutable.stop();
+ ourMongodExecutable = null;
+ }
+ }
+
+ /**
+ * Test method for {@link MongoDbClient#insert}, {@link MongoDbClient#read},
+ * {@link com.yahoo.ycsb.db.MongoDbClient#delete}.
+ */
+ @Test
+ public void testInsertReadDelete() {
+ final DB client = getDB();
+
+ final String table = "test";
+ final String id = "delete";
+
+ HashMap inserted = new HashMap();
+ inserted.put("a", new ByteArrayByteIterator(new byte[] { 1, 2, 3, 4 }));
+ int result = client.insert(table, id, inserted);
+ assertThat("Insert did not return success (0).", result, is(0));
+
+ HashMap read = new HashMap();
+ Set keys = Collections.singleton("a");
+ result = client.read(table, id, keys, read);
+ assertThat("Read did not return success (0).", result, is(0));
+ for (String key : keys) {
+ ByteIterator iter = read.get(key);
+
+ assertThat("Did not read the inserted field: " + key, iter,
+ notNullValue());
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(), is(Byte.valueOf((byte) 1)));
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(), is(Byte.valueOf((byte) 2)));
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(), is(Byte.valueOf((byte) 3)));
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(), is(Byte.valueOf((byte) 4)));
+ assertFalse(iter.hasNext());
+ }
+
+ result = client.delete(table, id);
+ assertThat("Delete did not return success (0).", result, is(0));
+
+ read.clear();
+ result = client.read(table, id, null, read);
+ assertThat("Read, after delete, did not return not found (1).", result,
+ is(1));
+ assertThat("Found the deleted fields.", read.size(), is(0));
+
+ result = client.delete(table, id);
+ assertThat("Delete did not return not found (1).", result, is(1));
+ }
+
+ /**
+ * Test method for {@link MongoDbClient#scan} .
+ */
+ @Test
+ public void testScan() {
+ final DB client = getDB();
+
+ final String table = "test";
+
+ // Insert a bunch of documents.
+ for (int i = 0; i < 100; ++i) {
+ HashMap inserted = new HashMap();
+ inserted.put("a", new ByteArrayByteIterator(new byte[] {
+ (byte) (i & 0xFF), (byte) (i >> 8 & 0xFF),
+ (byte) (i >> 16 & 0xFF), (byte) (i >> 24 & 0xFF) }));
+ int result = client.insert(table, padded(i), inserted);
+ assertThat("Insert did not return success (0).", result, is(0));
+ }
+
+ Set keys = Collections.singleton("a");
+ Vector> results = new Vector>();
+ int result = client.scan(table, "00050", 5, null, results);
+ assertThat("Read did not return success (0).", result, is(0));
+ assertThat(results.size(), is(5));
+ for (int i = 0; i < 5; ++i) {
+ HashMap read = results.get(i);
+ for (String key : keys) {
+ ByteIterator iter = read.get(key);
+
+ assertThat("Did not read the inserted field: " + key, iter,
+ notNullValue());
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(),
+ is(Byte.valueOf((byte) ((i + 50) & 0xFF))));
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(),
+ is(Byte.valueOf((byte) ((i + 50) >> 8 & 0xFF))));
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(),
+ is(Byte.valueOf((byte) ((i + 50) >> 16 & 0xFF))));
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(),
+ is(Byte.valueOf((byte) ((i + 50) >> 24 & 0xFF))));
+ assertFalse(iter.hasNext());
+ }
+ }
+ }
+
+ /**
+ * Creates a zero padded integer.
+ *
+ * @param i
+ * The integer to padd.
+ * @return The padded integer.
+ */
+ private String padded(int i) {
+ String result = String.valueOf(i);
+ while (result.length() < 5) {
+ result = "0" + result;
+ }
+ return result;
+ }
+
+ /**
+ * Gets the test DB.
+ *
+ * @return The test DB.
+ */
+ protected abstract DB getDB();
+
+ /**
+ * Test method for
+ * {@link com.yahoo.ycsb.db.MongoDbClient#update(java.lang.String, java.lang.String, java.util.HashMap)}
+ * .
+ */
+ @Test
+ public void testInsertReadUpdate() {
+ DB client = getDB();
+
+ final String table = "test";
+ final String id = "update";
+
+ HashMap inserted = new HashMap();
+ inserted.put("a", new ByteArrayByteIterator(new byte[] { 1, 2, 3, 4 }));
+ int result = client.insert(table, id, inserted);
+ assertThat("Insert did not return success (0).", result, is(0));
+
+ HashMap read = new HashMap();
+ Set keys = Collections.singleton("a");
+ result = client.read(table, id, keys, read);
+ assertThat("Read did not return success (0).", result, is(0));
+ for (String key : keys) {
+ ByteIterator iter = read.get(key);
+
+ assertThat("Did not read the inserted field: " + key, iter,
+ notNullValue());
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(), is(Byte.valueOf((byte) 1)));
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(), is(Byte.valueOf((byte) 2)));
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(), is(Byte.valueOf((byte) 3)));
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(), is(Byte.valueOf((byte) 4)));
+ assertFalse(iter.hasNext());
+ }
+
+ HashMap updated = new HashMap();
+ updated.put("a", new ByteArrayByteIterator(new byte[] { 5, 6, 7, 8 }));
+ result = client.update(table, id, updated);
+ assertThat("Update did not return success (0).", result, is(0));
+
+ read.clear();
+ result = client.read(table, id, null, read);
+ assertThat("Read, after update, did not return success (0).", result,
+ is(0));
+ for (String key : keys) {
+ ByteIterator iter = read.get(key);
+
+ assertThat("Did not read the inserted field: " + key, iter,
+ notNullValue());
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(), is(Byte.valueOf((byte) 5)));
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(), is(Byte.valueOf((byte) 6)));
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(), is(Byte.valueOf((byte) 7)));
+ assertTrue(iter.hasNext());
+ assertThat(iter.nextByte(), is(Byte.valueOf((byte) 8)));
+ assertFalse(iter.hasNext());
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/mongodb/src/test/java/com/yahoo/ycsb/db/AsyncMongoDbClientTest.java b/mongodb/src/test/java/com/yahoo/ycsb/db/AsyncMongoDbClientTest.java
new file mode 100644
index 00000000..f5ee7b65
--- /dev/null
+++ b/mongodb/src/test/java/com/yahoo/ycsb/db/AsyncMongoDbClientTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014, Yahoo!, Inc. 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 static org.junit.Assume.assumeNoException;
+
+import java.util.Properties;
+
+import org.junit.After;
+import org.junit.Before;
+
+import com.yahoo.ycsb.DB;
+
+/**
+ * AsyncMongoDbClientTest provides runs the basic workload operations.
+ */
+public class AsyncMongoDbClientTest extends AbstractDBTestCases {
+
+ /** The client to use. */
+ private AsyncMongoDbClient myClient = null;
+
+ /**
+ * Start a test client.
+ */
+ @Before
+ public void setUp() {
+ myClient = new AsyncMongoDbClient();
+ myClient.setProperties(new Properties());
+ try {
+ myClient.init();
+ }
+ catch (Exception error) {
+ assumeNoException(error);
+ }
+ }
+
+ /**
+ * Stops the test client.
+ */
+ @After
+ public void tearDown() {
+ try {
+ myClient.cleanup();
+ }
+ catch (Exception error) {
+ // Ignore.
+ }
+ finally {
+ myClient = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Overriden to return the {@link AsyncMongoDbClient}.
+ *
+ */
+ @Override
+ protected DB getDB() {
+ return myClient;
+ }
+}
diff --git a/mongodb/src/test/java/com/yahoo/ycsb/db/MongoDbClientTest.java b/mongodb/src/test/java/com/yahoo/ycsb/db/MongoDbClientTest.java
new file mode 100644
index 00000000..515fb802
--- /dev/null
+++ b/mongodb/src/test/java/com/yahoo/ycsb/db/MongoDbClientTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014, Yahoo!, Inc. 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 static org.junit.Assume.assumeNoException;
+
+import java.util.Properties;
+
+import org.junit.After;
+import org.junit.Before;
+
+import com.yahoo.ycsb.DB;
+
+/**
+ * MongoDbClientTest provides runs the basic workload operations.
+ */
+public class MongoDbClientTest extends AbstractDBTestCases {
+
+ /** The client to use. */
+ private MongoDbClient myClient = null;
+
+ /**
+ * Start a test client.
+ */
+ @Before
+ public void setUp() {
+ myClient = new MongoDbClient();
+ myClient.setProperties(new Properties());
+ try {
+ myClient.init();
+ }
+ catch (Exception error) {
+ assumeNoException(error);
+ }
+ }
+
+ /**
+ * Stops the test client.
+ */
+ @After
+ public void tearDown() {
+ try {
+ myClient.cleanup();
+ }
+ catch (Exception error) {
+ // Ignore.
+ }
+ finally {
+ myClient = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Overriden to return the {@link MongoDbClient}.
+ *
+ */
+ @Override
+ protected DB getDB() {
+ return myClient;
+ }
+}
diff --git a/pom.xml b/pom.xml
index 9d430b7a..1b9f12cc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,124 +1,124 @@
4.0.0com.yahoo.ycsbroot0.2.0-SNAPSHOTpomYCSB Root
This is the top level project that builds, packages the core and all the DB bindings for YCSB infrastructure.
scm:git:git://github.com/brianfrankcooper/YCSB.gitmasterhttps://github.com/brianfrankcooper/YCSBcheckstylecheckstyle5.0org.jdomjdom1.1com.google.collectionsgoogle-collections1.0org.slf4jslf4j-api1.6.42.2.11.0.01.6.01.2.91.0.37.1.0.CR12.1.1
- 3.0.1
+ 3.0.22.0.11.0.12.0.00.81UTF-80.8.00.9.5.61.1.8cassandracorehbasehypertableaccumulodynamodbelasticsearchinfinispanjdbcmongodborientdbredisvoldemortdistributioncouchbaseorg.apache.maven.pluginsmaven-compiler-plugin2.3.21.6org.apache.maven.pluginsmaven-checkstyle-plugin2.6truecheckstyle.xmlvalidatevalidatecheckstyle