/*
* Copyright (c) 2008-2014 MongoDB, Inc.
*
* 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.
*/
// JavaClientTest.java
package com.mongodb;
import com.mongodb.util.JSON;
import com.mongodb.util.TestCase;
import com.mongodb.util.Util;
import org.bson.BSON;
import org.bson.Transformer;
import org.bson.types.BSONTimestamp;
import org.bson.types.Binary;
import org.bson.types.Code;
import org.bson.types.CodeWScope;
import org.bson.types.MaxKey;
import org.bson.types.MinKey;
import org.bson.types.ObjectId;
import org.junit.Test;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
public class JavaClientTest extends TestCase {
@Test
public void test1()
throws MongoException {
DBCollection c = collection;
DBObject m = new BasicDBObject();
m.put( "name" , "eliot" );
m.put( "state" , "ny" );
c.save( m );
assert( m.containsField( "_id" ) );
Map out = (Map)(c.findOne( m.get( "_id" )));
assertEquals( "eliot" , out.get( "name" ) );
assertEquals( "ny" , out.get( "state" ) );
}
@Test
public void test2()
throws MongoException {
DBCollection c = collection;
DBObject m = new BasicDBObject();
m.put( "name" , "eliot" );
m.put( "state" , "ny" );
Map<String,Object> sub = new HashMap<String,Object>();
sub.put( "bar" , "1z" );
m.put( "foo" , sub );
c.save( m );
assert( m.containsField( "_id" ) );
Map out = (Map)(c.findOne( m.get( "_id" )));
assertEquals( "eliot" , out.get( "name" ) );
assertEquals( "ny" , out.get( "state" ) );
Map z = (Map)out.get( "foo" );
assertNotNull( z );
assertEquals( "1z" , z.get( "bar" ) );
}
@Test
public void testWhere1()
throws MongoException {
DBCollection c = collection;
assertNull( c.findOne() );
c.save( BasicDBObjectBuilder.start().add( "a" , 1 ).get() );
assertNotNull( c.findOne() != null );
assertNotNull( c.findOne( BasicDBObjectBuilder.start().add( "$where" , "this.a == 1" ).get() ) );
assertNull( c.findOne( BasicDBObjectBuilder.start().add( "$where" , "this.a == 2" ).get() ) );
}
@Test
public void testCodeWScope()
throws MongoException {
DBCollection c = collection;
assertNull( c.findOne() );
c.save( BasicDBObjectBuilder.start().add( "a" , 1 ).get() );
assertNotNull( c.findOne() != null );
assertNotNull( c.findOne( BasicDBObjectBuilder.start().add( "$where" , new CodeWScope( "this.a == x" , new BasicDBObject( "x" , 1 ) ) ).get() ) );
assertNull( c.findOne( BasicDBObjectBuilder.start().add( "$where" , new CodeWScope( "this.a == x" , new BasicDBObject( "x" , 2 ) ) ).get() ) );
c.drop();
BasicDBObject in = new BasicDBObject();
in.put( "_id" , 1 );
in.put( "a" , new Code("x=5") );
in.put( "b" , new CodeWScope( "x=5" , new BasicDBObject( "x" , 2 ) ) );
c.insert( in );
DBObject out = c.findOne();
assertEquals( in , out );
}
@Test
public void testCount()
throws MongoException {
DBCollection c = collection;;
c.drop();
assertNull(c.findOne());
assertTrue(c.getCount() == 0);
for (int i=0; i < 100; i++) {
c.insert(new BasicDBObject("i", i));
}
assertEquals( 100 , c.getCount() );
assertEquals( 100 , c.find().count() );
assertEquals( 100 , c.find().limit(10).count() );
assertEquals( 10 , c.find().limit(10).size() );
assertEquals( 90 , c.find().skip(10).size() );
}
@Test
public void testIndex()
throws MongoException {
DBCollection c = collection;
c.drop();
assertNull(c.findOne());
for (int i=0; i < 100; i++) {
c.insert(new BasicDBObject("i", i));
}
assertTrue(c.getCount() == 100);
c.createIndex(new BasicDBObject("i", 1));
List<DBObject> list = c.getIndexInfo();
assertTrue(list.size() == 2);
assertTrue(list.get(1).get("name").equals("i_1"));
}
@Test
public void testBinary()
throws MongoException {
DBCollection c = collection;
c.save( BasicDBObjectBuilder.start().add( "a" , "eliot".getBytes() ).get() );
DBObject out = c.findOne();
byte[] b = (byte[])(out.get( "a" ) );
assertEquals( "eliot" , new String( b ) );
{
byte[] raw = new byte[9];
ByteBuffer bb = ByteBuffer.wrap( raw );
bb.order( Bytes.ORDER );
bb.putInt( 5 );
bb.put( "eliot".getBytes() );
out.put( "a" , "eliot".getBytes() );
c.save( out );
out = c.findOne();
b = (byte[])(out.get( "a" ) );
assertEquals( "eliot" , new String( b ) );
out.put( "a" , new Binary( (byte)111 , raw ) );
c.save( out );
Binary blah = (Binary)c.findOne().get( "a" );
assertEquals( 111 , blah.getType() );
assertEquals( Util.toHex( raw ) , Util.toHex( blah.getData() ) );
}
}
@Test
public void testMinMaxKey()
throws MongoException {
DBCollection c = collection;
c.save( BasicDBObjectBuilder.start().add( "min" , new MinKey() ).add( "max" , new MaxKey() ).get() );
DBObject out = c.findOne();
MinKey min = (MinKey)(out.get( "min" ) );
MaxKey max = (MaxKey)(out.get( "max" ) );
assertTrue( JSON.serialize(min).contains("$minKey") );
assertTrue( JSON.serialize(max).contains("$maxKey") );
}
@Test
public void testBinaryOld()
throws MongoException {
DBCollection c = collection;
c.save( BasicDBObjectBuilder.start().add( "a" , "eliot".getBytes() ).get() );
DBObject out = c.findOne();
byte[] b = (byte[])(out.get( "a" ) );
assertEquals( "eliot" , new String( b ) );
{
byte[] raw = new byte[9];
ByteBuffer bb = ByteBuffer.wrap( raw );
bb.order( Bytes.ORDER );
bb.putInt( 5 );
bb.put( "eliot".getBytes() );
out.put( "a" , new Binary( BSON.B_BINARY , "eliot".getBytes() ) );
c.save( out );
// objects of subtype B_BINARY or B_GENERAL should becomes byte[]
out = c.findOne();
// Binary blah = (Binary)(out.get( "a" ) );
byte[] bytes = (byte[]) out.get("a");
assertEquals( "eliot" , new String( bytes ) );
out.put( "a" , new Binary( (byte)111 , raw ) );
c.save( out );
Binary blah = (Binary)c.findOne().get( "a" );
assertEquals( 111 , blah.getType() );
assertEquals( Util.toHex( raw ) , Util.toHex( blah.getData() ) );
}
}
@Test
public void testUUID()
throws MongoException {
DBCollection c = collection;
c.save( BasicDBObjectBuilder.start().add( "a" , new UUID(1,2)).add("x",5).get() );
DBObject out = c.findOne();
UUID b = (UUID)(out.get( "a" ) );
assertEquals( new UUID(1,2), b);
assertEquals( 5 , out.get("x" ) );
}
@Test
public void testEval()
throws MongoException {
assertEquals( 17 , ((Number)(getDatabase().eval( "return 17" ))).intValue() );
assertEquals( 18 , ((Number)(getDatabase().eval( "function(x){ return 17 + x; }" , 1 ))).intValue() );
}
@Test
public void testPartial1()
throws MongoException {
DBCollection c = collection;
c.save( BasicDBObjectBuilder.start().add( "a" , 1 ).add( "b" , 2 ).get() );
DBObject out = c.find().next();
assertEquals( 1 , out.get( "a" ) );
assertEquals( 2 , out.get( "b" ) );
out = c.find( new BasicDBObject() , BasicDBObjectBuilder.start().add( "a" , 1 ).get() ).next();
assertEquals( 1 , out.get( "a" ) );
assertNull( out.get( "b" ) );
out = c.find( null , BasicDBObjectBuilder.start().add( "a" , 1 ).get() ).next();
assertEquals( 1 , out.get( "a" ) );
assertNull( out.get( "b" ) );
// make sure can't insert back partial
try {
c.update(out, out);
assertTrue(false);
} catch (IllegalArgumentException ex) {
}
out = c.findOne( null , BasicDBObjectBuilder.start().add( "b" , 1 ).get() );
assertEquals( 2 , out.get( "b" ) );
assertNull( out.get( "a" ) );
// make sure can't insert back partial
try {
c.update(out, out);
assertTrue(false);
} catch (IllegalArgumentException ex) {
}
}
@Test
public void testGroup()
throws MongoException {
DBCollection c = collection;
c.save( BasicDBObjectBuilder.start().add( "x" , "a" ).get() );
c.save( BasicDBObjectBuilder.start().add( "x" , "a" ).get() );
c.save( BasicDBObjectBuilder.start().add( "x" , "a" ).get() );
c.save( BasicDBObjectBuilder.start().add( "x" , "b" ).get() );
DBObject g = c.group( new BasicDBObject( "x" , 1 ) , null , new BasicDBObject( "count" , 0 ) ,
"function( o , p ){ p.count++; }" );
List l = (List)g;
assertEquals( 2 , l.size() );
}
@Test
public void testSet()
throws MongoException {
DBCollection c = collection;
c.save( BasicDBObjectBuilder.start().add( "id" , 1 ).add( "x" , true ).get() );
assertEquals( Boolean.class , c.findOne().get( "x" ).getClass() );
c.update( new BasicDBObject( "id" , 1 ) ,
new BasicDBObject( "$set" ,
new BasicDBObject( "x" , 5.5 ) ) );
assertEquals( Double.class , c.findOne().get( "x" ).getClass() );
}
@Test
public void testKeys1()
throws MongoException {
DBCollection c = collection;
c.save( BasicDBObjectBuilder.start().push( "a" ).add( "x" , 1 ).get() );
assertEquals( 1, ((DBObject)c.findOne().get("a")).get("x" ) );
c.update( new BasicDBObject() , BasicDBObjectBuilder.start().push( "$set" ).add( "a.x" , 2 ).get() );
assertEquals( 1 , c.find().count() );
assertEquals( 2, ((DBObject)c.findOne().get("a")).get("x" ) );
}
@Test
public void testTimestamp()
throws MongoException {
DBCollection c = collection;
c.save( BasicDBObjectBuilder.start().add( "y" , new BSONTimestamp() ).get() );
BSONTimestamp t = (BSONTimestamp)c.findOne().get("y");
assert( t.getTime() > 0 );
assert( t.getInc() > 0 );
}
@Test
public void testStrictWriteSetInCollection(){
DBCollection c = collection;
c.setWriteConcern( WriteConcern.SAFE);
c.insert( new BasicDBObject( "_id" , 1 ) );
boolean gotError = false;
try {
c.insert( new BasicDBObject( "_id" , 1 ) );
}
catch ( MongoException.DuplicateKey e ){
gotError = true;
}
assertEquals( true , gotError );
assertEquals( 1 , c.find().count() );
}
@Test
public void testStrictWriteSetInMethod(){
DBCollection c = collection;
c.insert( new BasicDBObject( "_id" , 1 ));
boolean gotError = false;
try {
c.insert( new BasicDBObject( "_id" , 1 ) , WriteConcern.SAFE);
}
catch ( MongoException.DuplicateKey e ){
gotError = true;
}
assertEquals( true , gotError );
assertEquals( 1 , c.find().count() );
}
@Test
public void testPattern(){
DBCollection c = collection;
c.insert( new BasicDBObject( "x" , "a" ) );
c.insert( new BasicDBObject( "x" , "A" ) );
assertEquals( 1 , c.find( new BasicDBObject( "x" , Pattern.compile( "a" ) ) ).itcount() );
assertEquals( 1 , c.find( new BasicDBObject( "x" , Pattern.compile( "A" ) ) ).itcount() );
assertEquals( 2 , c.find( new BasicDBObject( "x" , Pattern.compile( "a" , Pattern.CASE_INSENSITIVE ) ) ).itcount() );
assertEquals( 2 , c.find( new BasicDBObject( "x" , Pattern.compile( "A" , Pattern.CASE_INSENSITIVE ) ) ).itcount() );
}
@Test
public void testDates(){
DBCollection c = collection;
DBObject in = new BasicDBObject( "x" , new java.util.Date() );
c.insert( in );
DBObject out = c.findOne();
assertEquals( java.util.Date.class , in.get("x").getClass() );
assertEquals( in.get( "x" ).getClass() , out.get( "x" ).getClass() );
}
@Test
public void testMapReduce(){
DBCollection c = collection;
c.save( new BasicDBObject( "x" , new String[]{ "a" , "b" } ) );
c.save( new BasicDBObject( "x" , new String[]{ "b" , "c" } ) );
c.save( new BasicDBObject( "x" , new String[]{ "c" , "d" } ) );
MapReduceOutput out =
c.mapReduce( "function(){ for ( var i=0; i<this.x.length; i++ ){ emit( this.x[i] , 1 ); } }" ,
"function(key,values){ var sum=0; for( var i=0; i<values.length; i++ ) sum += values[i]; return sum;}" ,
"jmr1_out" , null );
Map<String,Integer> m = new HashMap<String,Integer>();
for ( DBObject r : out.results() ){
m.put( r.get( "_id" ).toString() , ((Number)(r.get( "value" ))).intValue() );
}
assertEquals( 4 , m.size() );
assertEquals( 1 , m.get( "a" ).intValue() );
assertEquals( 2 , m.get( "b" ).intValue() );
assertEquals( 2 , m.get( "c" ).intValue() );
assertEquals( 1 , m.get( "d" ).intValue() );
}
@Test
public void testMapReduceInline(){
DBCollection c = collection;
c.save( new BasicDBObject( "x" , new String[]{ "a" , "b" } ) );
c.save( new BasicDBObject( "x" , new String[]{ "b" , "c" } ) );
c.save( new BasicDBObject( "x" , new String[]{ "c" , "d" } ) );
MapReduceOutput out =
c.mapReduce( "function(){ for ( var i=0; i<this.x.length; i++ ){ emit( this.x[i] , 1 ); } }" ,
"function(key,values){ var sum=0; for( var i=0; i<values.length; i++ ) sum += values[i]; return sum;}" ,
null, MapReduceCommand.OutputType.INLINE, null, ReadPreference.primaryPreferred());
Map<String,Integer> m = new HashMap<String,Integer>();
for ( DBObject r : out.results() ){
m.put( r.get( "_id" ).toString() , ((Number)(r.get( "value" ))).intValue() );
}
assertEquals( 4 , m.size() );
assertEquals( 1 , m.get( "a" ).intValue() );
assertEquals( 2 , m.get( "b" ).intValue() );
assertEquals( 2 , m.get( "c" ).intValue() );
assertEquals( 1 , m.get( "d" ).intValue() );
}
//If run against a replicaset this will verify that the inline map/reduce hits the secondary.
@Test
@SuppressWarnings("deprecation")
public void testMapReduceInlineSecondary() throws Exception {
if (!isReplicaSet(cleanupMongo)) {
return;
}
Mongo mongo = new MongoClient(getMongoClientURI());
mongo.setWriteConcern(WriteConcern.UNACKNOWLEDGED);
int size = getReplicaSetSize(mongo);
DBCollection c = mongo.getDB(getDatabase().getName()).getCollection( "imr2" );
//c.setReadPreference(ReadPreference.SECONDARY);
c.slaveOk();
c.drop();
c.save( new BasicDBObject( "x" , new String[]{ "a" , "b" } ) );
c.save(new BasicDBObject("x", new String[]{"b", "c"}));
WriteResult wr = c.save(new BasicDBObject("x", new String[]{"c", "d"}));
if (mongo.getReplicaSetStatus() != null && mongo.getReplicaSetStatus().getName() != null) {
wr.getLastError(new WriteConcern(size));
}
MapReduceOutput out =
c.mapReduce( "function(){ for ( var i=0; i<this.x.length; i++ ){ emit( this.x[i] , 1 ); } }" ,
"function(key,values){ var sum=0; for( var i=0; i<values.length; i++ ) sum += values[i]; return sum;}" , null, MapReduceCommand.OutputType.INLINE, null);
Map<String,Integer> m = new HashMap<String,Integer>();
for ( DBObject r : out.results() ){
m.put( r.get( "_id" ).toString() , ((Number)(r.get( "value" ))).intValue() );
}
assertEquals( 4 , m.size() );
assertEquals( 1 , m.get( "a" ).intValue() );
assertEquals( 2 , m.get( "b" ).intValue() );
assertEquals( 2 , m.get( "c" ).intValue() );
assertEquals( 1 , m.get( "d" ).intValue() );
ReplicaSetStatus replStatus = mongo.getReplicaSetStatus();
//if it is a replicaset, and there is no master, or master is not the secondary
// TODO
// if( replStatus!= null && replStatus.getName() != null && ((replStatus.getMaster() == null) || (replStatus.getMaster() != null && !replStatus.getMaster().equals(replStatus.getASecondary()))))
// assertTrue( !mongo.getReplicaSetStatus().isMaster( out.getCommandResult().getServerUsed() ),
// "Had a replicaset but didn't use secondary! replSetStatus : " + mongo.getReplicaSetStatus() + " \n Used: " + out.getCommandResult().getServerUsed() + " \n ");
}
@Test
public void testMapReduceInlineWScope(){
DBCollection c = collection;
c.save( new BasicDBObject( "x" , new String[]{ "a" , "b" } ) );
c.save(new BasicDBObject("x", new String[]{"b", "c"}));
c.save( new BasicDBObject( "x" , new String[]{ "c" , "d" } ) );
Map<String, Object> scope = new HashMap<String, Object>();
scope.put("exclude", "a");
MapReduceCommand mrc = new MapReduceCommand( c, "function(){ for ( var i=0; i<this.x.length; i++ ){ if(this.x[i] != exclude) emit( this.x[i] , 1 ); } }" ,
"function(key,values){ var sum=0; for( var i=0; i<values.length; i++ ) sum += values[i]; return sum;}" , null, MapReduceCommand.OutputType.INLINE, null);
mrc.setScope( scope );
MapReduceOutput out = c.mapReduce( mrc );
Map<String,Integer> m = new HashMap<String,Integer>();
for ( DBObject r : out.results() ){
m.put( r.get( "_id" ).toString() , ((Number)(r.get( "value" ))).intValue() );
}
assertEquals( 3 , m.size() );
assertEquals( 2 , m.get( "b" ).intValue() );
assertEquals( 2 , m.get( "c" ).intValue() );
assertEquals( 1 , m.get( "d" ).intValue() );
}
@Test
public void testMapReduceExecutionTimeout() {
assumeFalse(isSharded(getMongoClient()));
checkServerVersion(2.5);
String map = "function(){ for ( var i=0; i<this.x.length; i++ ){ emit( this.x[i] , 1 ); } }";
String reduce = "function(key,values){ var sum=0; for( var i=0; i<values.length; i++ ) sum += values[i]; return sum;}";
enableMaxTimeFailPoint();
DBCollection c = collection;
c.insert(new BasicDBObject("x", 1));
try {
final MapReduceCommand command = new MapReduceCommand(c, map, reduce, null, MapReduceCommand.OutputType.INLINE,
new BasicDBObject());
command.setMaxTime(1, TimeUnit.SECONDS);
c.mapReduce(command);
fail("Show have thrown");
} catch (MongoExecutionTimeoutException e) {
assertEquals(50, e.getCode());
} finally {
disableMaxTimeFailPoint();
}
}
@Test
public void testAggregation(){
if (!serverIsAtLeastVersion(2.1)) {
return;
}
DBCollection c = collection;
DBObject foo = new BasicDBObject( "name" , "foo" ) ;
DBObject bar = new BasicDBObject( "name" , "bar" ) ;
DBObject baz = new BasicDBObject( "name" , "foo" ) ;
foo.put( "count", 5 );
bar.put( "count", 2 );
baz.put( "count", 7 );
c.insert( foo );
c.insert( bar );
c.insert( baz );
DBObject projFields = new BasicDBObject( "name", 1 );
projFields.put("count", 1);
DBObject group = new BasicDBObject( );
group.put("_id", "$name" );
group.put( "docsPerName", new BasicDBObject( "$sum", 1 ));
group.put( "countPerName", new BasicDBObject( "$sum", "$count" ));
AggregationOutput out = c.aggregate( new BasicDBObject( "$project", projFields ), new BasicDBObject( "$group", group) );
Map<String, DBObject> results = new HashMap<String, DBObject>();
for(DBObject result : out.results())
results.put((String)result.get("_id"), result);
DBObject fooResult = results.get("foo");
assertNotNull(fooResult);
assertEquals(2, fooResult.get("docsPerName"));
assertEquals(12, fooResult.get("countPerName"));
DBObject barResult = results.get("bar");
assertNotNull(barResult);
assertEquals(1, barResult.get("docsPerName"));
assertEquals(2, barResult.get("countPerName"));
DBObject aggregationCommand = out.getCommand();
assertNotNull(aggregationCommand);
assertEquals(c.getName(), aggregationCommand.get("aggregate"));
assertNotNull(aggregationCommand.get("pipeline"));
}
String _testMulti( DBCollection c ){
String s = "";
for ( DBObject z : c.find().sort( new BasicDBObject( "_id" , 1 ) ) ){
if ( s.length() > 0 )
s += ",";
s += z.get( "x" );
}
return s;
}
@Test
public void testMulti(){
DBCollection c = collection;
c.insert( BasicDBObjectBuilder.start( "_id" , 1 ).add( "x" , 1 ).get() );
c.insert( BasicDBObjectBuilder.start( "_id" , 2 ).add( "x" , 5 ).get() );
assertEquals( "1,5" , _testMulti( c ) );
c.update( new BasicDBObject() , BasicDBObjectBuilder.start().push( "$inc" ).add( "x" , 1 ).get() );
assertEquals( "2,5" , _testMulti( c ) );
c.update( new BasicDBObject( "_id" , 2 ) , BasicDBObjectBuilder.start().push( "$inc" ).add( "x" , 1 ).get() );
assertEquals( "2,6" , _testMulti( c ) );
c.updateMulti( new BasicDBObject() , BasicDBObjectBuilder.start().push( "$inc" ).add( "x" , 1 ).get() );
assertEquals( "3,7" , _testMulti( c ) );
}
@Test
public void testAuthenticate() throws UnknownHostException {
assertEquals( "26e3d12bd197368526409177b3e8aab6" , getDatabase()._hash( "e" , "j".toCharArray() ) );
Mongo m = new MongoClient(getMongoClientURI());
DB db = m.getDB(getDatabase().getName());
try {
db.addUser("xx", "e".toCharArray());
assertEquals(false, db.authenticate( "xx" , "f".toCharArray() ) );
assertNull(db.getAuthenticationCredentials());
assertNull(m.getAuthority().getCredentialsStore().get(db.getName()));
assertEquals(true, db.authenticate("xx", "e".toCharArray()));
assertEquals(MongoCredential.createCredential("xx", db.getName(), "e".toCharArray()), db.getAuthenticationCredentials());
assertEquals(db.getAuthenticationCredentials(), m.getAuthority().getCredentialsStore().get(db.getName()));
assertEquals(true, db.authenticate( "xx" , "e".toCharArray() ) );
try {
db.authenticateCommand("xx", "f".toCharArray());
fail("can't auth with different credentials");
} catch (IllegalStateException e) {
// all good;
}
}
finally {
db.removeUser("xx");
m.close();
}
}
@Test
public void testAuthenticateCommand() throws UnknownHostException {
try {
getDatabase().addUser("xx", "e".toCharArray());
MongoClient m = new MongoClient();
try {
DB db = m.getDB(getDatabase().getName());
try {
db.authenticateCommand( "xx" , "f".toCharArray());
fail("Auth should have failed");
} catch (CommandFailureException e) {
// all good
}
assertTrue(db.authenticateCommand("xx", "e".toCharArray()).ok());
assertTrue(db.authenticateCommand("xx", "e".toCharArray()).ok());
try {
db.authenticateCommand("xx", "f".toCharArray());
fail("can't auth with different credentials");
} catch (IllegalStateException e) {
// all good;
}
} finally {
m.close();
}
}
finally {
getDatabase().removeUser("xx");
}
}
@Test
public void testAuthenticateWithCredentialsInURI() throws UnknownHostException {
getDatabase().addUser("xx", "e".toCharArray());
try {
MongoClient m = new MongoClient(new MongoClientURI("mongodb://xx:e@localhost/" + getDatabase().getName()));
try {
DB db = m.getDB(getDatabase().getName());
assertNotNull(db.getAuthenticationCredentials());
assertEquals(true, db.authenticate("xx", "e".toCharArray()) );
}
finally {
m.close();
}
} finally {
getDatabase().removeUser("xx");
}
}
@Test
public void testAuthenticateCommandWithCredentialsInURI() throws UnknownHostException {
getDatabase().addUser("xx", "e".toCharArray());
try {
MongoClient m = new MongoClient(new MongoClientURI("mongodb://xx:e@localhost/" + getDatabase().getName()));
try {
DB db = m.getDB(getDatabase().getName());
assertNotNull(db.getAuthenticationCredentials());
assertTrue(db.authenticateCommand("xx", "e".toCharArray()).ok());
} finally {
m.close();
}
}
finally {
getDatabase().removeUser("xx");
}
}
@Test
public void testTransformers(){
DBCollection c = collection;
c.save( BasicDBObjectBuilder.start( "_id" , 1 ).add( "x" , 1.1 ).get() );
assertEquals( Double.class , c.findOne().get( "x" ).getClass() );
Bytes.addEncodingHook( Double.class , new Transformer(){
public Object transform( Object o ){
return o.toString();
}
} );
c.save( BasicDBObjectBuilder.start( "_id" , 1 ).add( "x" , 1.1 ).get() );
assertEquals( String.class , c.findOne().get( "x" ).getClass() );
Bytes.clearAllHooks();
c.save( BasicDBObjectBuilder.start( "_id" , 1 ).add( "x" , 1.1 ).get() );
assertEquals( Double.class , c.findOne().get( "x" ).getClass() );
Bytes.addDecodingHook( Double.class , new Transformer(){
public Object transform( Object o ){
return o.toString();
}
} );
assertEquals( String.class , c.findOne().get( "x" ).getClass() );
Bytes.clearAllHooks();
assertEquals( Double.class , c.findOne().get( "x" ).getClass() );
}
@Test
public void testObjectIdCompat(){
DBCollection c = collection;
c.save( new BasicDBObject( "x" , 1 ) );
getDatabase().eval("return db." + collection.getName() + ".insert( { x : 2 } );");
List<DBObject> l = c.find().toArray();
assertEquals( 2 , l.size() );
ObjectId a = (ObjectId)(l.get(0).get("_id"));
ObjectId b = (ObjectId)(l.get(1).get("_id"));
assertTrue(Math.abs(a.getTime() - b.getTime()) < 10000);
}
@Test
public void testObjectIdCompat2(){
DBCollection c = collection;
c.save(new BasicDBObject("x", 1));
String o = (String) getDatabase().eval( "return db." + collection.getName() + ".findOne()._id.toString()" );
// printing on servers has changed in 2.1
if (o.startsWith("ObjectId"))
o = (String) getDatabase().eval( "return db." + collection.getName() + ".findOne()._id.valueOf()" );
String x = c.findOne().get( "_id" ).toString();
assertEquals( x , o );
}
@Test
public void testBatchInsertSplitting(){
int maxObjSize = getMongoClient().getMaxBsonObjectSize();
DBCollection c = collection;
c.drop();
String s = "asdasdasd";
while ( s.length() < 10000 )
s += s;
List<DBObject> l = new ArrayList<DBObject>();
final int num = 3 * ( maxObjSize / s.length() );
for ( int i=0; i<num; i++ ){
l.add( BasicDBObjectBuilder.start()
.add( "_id" , i )
.add( "x" , s )
.get() );
}
c.insert( l );
assertEquals(num, c.find().count());
}
@Test
public void testOversizedDocumentFailure() {
int maxObjSize = getMongoClient().getMaxBsonObjectSize();
DBCollection c = collection;
c.drop();
try {
c.save( new BasicDBObject( "foo" , new Binary(new byte[maxObjSize]) ) );
fail("Should not be able to save an object larger than maximum bson object size of " + maxObjSize);
}
catch ( MongoInternalException ie ) {
assertEquals(-3, ie.getCode());
}
assertEquals(0, c.find().count());
}
@Test
public void testUpdate5(){
DBCollection c = collection;
c.insert( new BasicDBObject( "x" , 5) );
assertEquals(Integer.class, c.findOne().get("x").getClass());
assertEquals(5, c.findOne().get("x"));
c.update(new BasicDBObject(), new BasicDBObject("$set", new BasicDBObject("x", 5.6D)));
assertEquals( Double.class , c.findOne().get("x").getClass() );
assertEquals( 5.6 , c.findOne().get("x") );
}
@Test
public void testIn(){
DBCollection c = collection;
c.insert( new BasicDBObject( "x" , 1 ) );
c.insert(new BasicDBObject("x", 2));
c.insert(new BasicDBObject("x", 3));
c.insert(new BasicDBObject("x", 4));
List<DBObject> a = c.find( new BasicDBObject( "x" , new BasicDBObject( "$in" , new Integer[]{ 2 , 3 } ) ) ).toArray();
assertEquals(2, a.size());
}
@Test
public void testWriteResultWithGetLastErrorWithDifferentConcerns(){
DBCollection c = collection;
c.insert( new BasicDBObject( "_id" , 1 ) );
WriteResult res = c.update( new BasicDBObject( "_id" , 1 ) , new BasicDBObject( "$inc" , new BasicDBObject( "x" , 1 ) ),
false, false, WriteConcern.UNACKNOWLEDGED);
assertEquals( 1 , res.getN() );
assertTrue(res.isLazy());
CommandResult cr = res.getLastError( WriteConcern.FSYNC_SAFE );
assertEquals( 1 , cr.getInt( "n" ) );
CommandResult cr2 = res.getLastError( WriteConcern.FSYNC_SAFE );
assertTrue( cr == cr2 );
CommandResult cr3 = res.getLastError( WriteConcern.NONE );
assertTrue( cr3 == cr );
}
@Test
public void testWriteResultOnUnacknowledgedUpdate(){
collection.insert(new BasicDBObject("_id", 1));
WriteResult res = collection.update(new BasicDBObject("_id", 1), new BasicDBObject("$inc", new BasicDBObject("x", 1)),
false, false, WriteConcern.UNACKNOWLEDGED);
assertEquals(1, res.getN());
assertTrue(res.isLazy());
}
@Test
public void testWriteResultOnInsert(){
WriteResult res = collection.insert(new BasicDBObject());
assertEquals(0, res.getN());
assertFalse(res.isUpdateOfExisting());
assertNull(res.getUpsertedId());
assertFalse(res.isLazy());
}
@Test
public void testWriteResultOnInsertList(){
WriteResult res = collection.insert(Arrays.<DBObject>asList(new BasicDBObject(), new BasicDBObject()));
assertEquals(0, res.getN());
assertFalse(res.isUpdateOfExisting());
assertNull(res.getUpsertedId());
assertFalse(res.isLazy());
}
@Test
public void testWriteResultOnUpdate(){
collection.insert(new BasicDBObject("_id", 1));
WriteResult res = collection.update(new BasicDBObject("_id", 1), new BasicDBObject("$inc", new BasicDBObject("x", 1)));
assertEquals(1, res.getN());
assertTrue(res.isUpdateOfExisting());
assertNull(res.getUpsertedId());
assertFalse(res.isLazy());
}
@Test
public void testWriteResultOnUpdateWhenNoDocumentsMatch(){
WriteResult res = collection.update(new BasicDBObject("_id", 1), new BasicDBObject("$inc", new BasicDBObject("x", 1)));
assertEquals(0, res.getN());
assertFalse(res.isUpdateOfExisting());
assertNull(res.getUpsertedId());
assertFalse(res.isLazy());
}
@Test
public void testWriteResultOnUpsert(){
ObjectId id = new ObjectId();
collection.insert(new BasicDBObject("_id", 1));
WriteResult res = collection.update(new BasicDBObject("_id", id), new BasicDBObject("$inc", new BasicDBObject("x", 1)), true, false);
assertEquals(1, res.getN());
assertFalse(res.isUpdateOfExisting());
assertEquals(id, res.getUpsertedId());
}
@Test
public void testWriteResultOnRemove() {
collection.insert(new BasicDBObject("_id", 1));
collection.insert(new BasicDBObject("_id", 2));
WriteResult res = collection.remove(new BasicDBObject());
assertEquals(2, res.getN());
assertFalse(res.isUpdateOfExisting());
assertNull(res.getUpsertedId());
}
@Test
public void testWriteResultMethodLevelWriteConcern(){
DBCollection c = collection;
c.insert( new BasicDBObject( "_id" , 1 ) );
WriteResult res = c.update( new BasicDBObject( "_id" , 1 ) , new BasicDBObject( "$inc" , new BasicDBObject( "x" , 1 ) ),
false, false, WriteConcern.UNACKNOWLEDGED);
assertEquals( 1 , res.getN() );
assertTrue(res.isLazy());
res = c.update( new BasicDBObject( "_id" , 1 ) , new BasicDBObject( "$inc" , new BasicDBObject( "x" , 1 ) ) , false , false , WriteConcern.SAFE);
assertEquals( 1 , res.getN() );
assertFalse(res.isLazy());
}
@Test
public void testWriteConcernValueOf() {
WriteConcern wc1 = WriteConcern.NORMAL;
WriteConcern wc2 = WriteConcern.valueOf( "normal" );
WriteConcern wc3 = WriteConcern.valueOf( "NORMAL" );
assertEquals( wc1, wc2 );
assertEquals( wc1, wc3 );
assertEquals( wc1.getW(), wc2.getW() );
assertEquals( wc1.getWObject(), wc2.getWObject() );
assertEquals( wc1.getW(), wc3.getW() );
assertEquals( wc1.getWObject(), wc3.getWObject() );
}
@Test
public void testWriteConcernMajority() {
WriteConcern wc1 = WriteConcern.MAJORITY;
WriteConcern wc2 = WriteConcern.valueOf( "majority" );
WriteConcern wc3 = WriteConcern.valueOf( "MAJORITY" );
assertEquals( wc1, wc2 );
assertEquals( wc1, wc3 );
assertEquals( wc1.getWString(), wc2.getWString() );
assertEquals( wc1.getWObject(), wc2.getWObject() );
assertEquals( wc1.getWString(), wc3.getWString() );
assertEquals( wc1.getWObject(), wc3.getWObject() );
}
@Test
public void testFindAndModify(){
DBCollection c = collection;
c.insert( new BasicDBObject( "_id" , 1 ) );
//return old one
DBObject dbObj = c.findAndModify( new BasicDBObject( "_id" , 1 ) , null, new BasicDBObject( "x", 1));
assertEquals( 1 , dbObj.keySet().size());
assertEquals( 1 , c.findOne(new BasicDBObject( "_id" , 1 ) ).get( "x" ));
//return new one
dbObj = c.findAndModify( new BasicDBObject( "_id" , 1 ) , null, null, false, new BasicDBObject( "x", 5), true, false);
assertEquals( 2 , dbObj.keySet().size());
assertEquals( 5 , dbObj.get( "x" ));
assertEquals( 5 , c.findOne(new BasicDBObject( "_id" , 1 ) ).get( "x" ));
//remove it, and return old one
dbObj = c.findAndRemove( new BasicDBObject( "_id" , 1 ) );
assertEquals( 2 , dbObj.keySet().size());
assertEquals( 5 , dbObj.get( "x" ));
assertNull( c.findOne(new BasicDBObject( "_id" , 1 ) ));
// create new one with upsert and return it
dbObj = c.findAndModify( new BasicDBObject( "_id" , 2 ) , null, null, false, new BasicDBObject("$set", new BasicDBObject("a", 6)), true, true);
assertEquals( 2 , dbObj.keySet().size());
assertEquals( 6 , dbObj.get( "a" ));
assertEquals( 6 , c.findOne(new BasicDBObject( "_id" , 2 ) ).get( "a" ));
// create new one with upsert and don't return it
dbObj = c.findAndModify( new BasicDBObject( "_id" , 3 ) , null, null, false, new BasicDBObject("$set", new BasicDBObject("b", 7)), false, true);
assertEquals( 7 , c.findOne(new BasicDBObject( "_id" , 3 ) ).get( "b" ));
if (serverIsAtLeastVersion(2.1)) {
assertNull(dbObj);
} else {
assertEquals(0, dbObj.keySet().size());
}
// test exception throwing
c.insert( new BasicDBObject( "a" , 1 ) );
try {
c.findAndModify( null, null );
fail("Exception not thrown when no update nor remove");
} catch (MongoException e) {
}
try {
dbObj = c.findAndModify( new BasicDBObject("a", "noexist"), null );
if (!serverIsAtLeastVersion(2.1)) {
assertNull(dbObj);
}
} catch (MongoException e) {
if (!serverIsAtLeastVersion(2.1)) {
fail("Exception thrown when matching record");
}
}
}
@Test
public void testGetCollectionFromString(){
DBCollection c = getDatabase().getCollectionFromString( "foo" );
assertEquals( "foo" , c.getName() );
c = getDatabase().getCollectionFromString( "foo.bar" );
assertEquals( "foo.bar" , c.getName() );
c = getDatabase().getCollectionFromString( "foo.bar.zoo" );
assertEquals( "foo.bar.zoo" , c.getName() );
c = getDatabase().getCollectionFromString( "foo.bar.zoo.dork" );
assertEquals( "foo.bar.zoo.dork" , c.getName() );
}
@Test
public void testBadKey(){
DBCollection c = getDatabase().getCollectionFromString( "foo" );
assertEquals( "foo" , c.getName() );
try {
c.insert(new BasicDBObject("a.b", 1));
fail("Bad key was accepted");
} catch (IllegalArgumentException e) {}
try {
Map<String, Integer> data = new HashMap<String, Integer>();
data.put("a.b", 1);
c.insert(new BasicDBObject("data", data));
fail("Bad key was accepted");
} catch (IllegalArgumentException e) {}
try {
c.insert(new BasicDBObject("$a", 1));
fail("Bad key was accepted");
} catch (IllegalArgumentException e) {}
try {
c.save(new BasicDBObject("a.b", 1));
fail("Bad key was accepted");
} catch (IllegalArgumentException e) {}
try {
c.save(new BasicDBObject("$a", 1));
fail("Bad key was accepted");
} catch (IllegalArgumentException e) {}
try {
final BasicDBList list = new BasicDBList();
list.add(new BasicDBObject("$a", 1));
c.save(new BasicDBObject("a", list));
fail("Bad key was accepted");
} catch (IllegalArgumentException e) {}
try {
final List<BasicDBObject> list = asList(new BasicDBObject("$a", 1));
c.save(new BasicDBObject("a", list));
fail("Bad key was accepted");
} catch (IllegalArgumentException e) {}
// try {
// c.save(new BasicDBObject("a", Arrays.asList(new BasicDBObject("$a", 1))));
// fail("Bad key was accepted");
// } catch (IllegalArgumentException e) {}
c.insert(new BasicDBObject("a", 1));
try {
c.update(new BasicDBObject("a", 1), new BasicDBObject("a.b", 1));
fail("Bad key was accepted");
} catch (IllegalArgumentException e) {}
// this should work because it's a query
c.update(new BasicDBObject("a", 1), new BasicDBObject("$set", new BasicDBObject("a.b", 1)), false, false,
WriteConcern.UNACKNOWLEDGED);
}
@Test
public void testAllTypes(){
DBCollection c = collection;
String json = "{ 'str' : 'asdfasd' , 'long' : 5 , 'float' : 0.4 , 'bool' : false , 'date' : { '$date' : '2011-05-18T18:56:00Z'} , 'pat' : { '$regex' : '.*' , '$options' : ''} , 'oid' : { '$oid' : '4d83ab3ea39562db9c1ae2ae'} , 'ref' : { '$ref' : 'test.test' , '$id' : { '$oid' : '4d83ab59a39562db9c1ae2af'}} , 'code' : { '$code' : 'asdfdsa'} , 'codews' : { '$code' : 'ggggg' , '$scope' : { }} , 'ts' : { '$ts' : 1300474885 , '$inc' : 10} , 'null' : null, 'uuid' : { '$uuid' : '60f65152-6d4a-4f11-9c9b-590b575da7b5' }}";
BasicDBObject a = (BasicDBObject) JSON.parse(json);
c.insert(a);
DBObject b = c.findOne();
assertTrue(a.equals(b));
}
@Test
@SuppressWarnings("deprecation")
public void testMongoHolder() throws MongoException, UnknownHostException {
Mongo m1 = Mongo.Holder.singleton().connect( new MongoURI( "mongodb://localhost" ) );
Mongo m2 = Mongo.Holder.singleton().connect( new MongoURI( "mongodb://localhost" ) );
assertEquals( m1, m2);
}
}