2009-01-17 08:57:27 -05:00
// jsobjtests.cpp - Tests for jsobj.{h,cpp} code
2008-12-11 19:16:06 -05:00
//
/**
* Copyright ( C ) 2008 10 gen Inc .
2008-12-28 20:28:49 -05:00
*
2008-12-11 19:16:06 -05:00
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License , version 3 ,
* as published by the Free Software Foundation .
2008-12-28 20:28:49 -05:00
*
2008-12-11 19:16:06 -05:00
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
2008-12-28 20:28:49 -05:00
*
2008-12-11 19:16:06 -05:00
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2010-04-27 15:27:52 -04:00
# include "pch.h"
2011-05-10 12:40:01 -04:00
# include "../bson/util/builder.h"
2008-12-11 19:16:06 -05:00
# include "../db/jsobj.h"
2009-02-27 17:18:56 -05:00
# include "../db/jsobjmanipulator.h"
2009-01-06 13:02:09 -05:00
# include "../db/json.h"
2009-02-27 17:18:56 -05:00
# include "../db/repl.h"
2009-09-16 15:26:18 -04:00
# include "../db/extsort.h"
2008-12-11 19:16:06 -05:00
# include "dbtests.h"
2010-07-29 01:08:20 -04:00
# include "../util/mongoutils/checksum.h"
2011-04-11 18:21:48 -04:00
# include "../db/key.h"
2011-04-20 15:45:32 -04:00
# include "../db/btree.h"
2008-12-11 19:16:06 -05:00
namespace JsobjTests {
2011-04-11 18:21:48 -04:00
2011-06-16 16:35:07 -04:00
IndexInterface & indexInterfaceForTheseTests = ( time ( 0 ) % 2 ) ? * IndexDetails : : iis [ 0 ] : * IndexDetails : : iis [ 1 ] ;
2011-05-05 14:09:07 -04:00
void keyTest ( const BSONObj & o , bool mustBeCompact = false ) {
2011-04-12 17:09:08 -04:00
static KeyV1Owned * kLast ;
static BSONObj last ;
KeyV1Owned * key = new KeyV1Owned ( o ) ;
KeyV1Owned & k = * key ;
2011-05-05 14:09:07 -04:00
ASSERT ( ! mustBeCompact | | k . isCompactFormat ( ) ) ;
2011-04-12 17:09:08 -04:00
BSONObj x = k . toBson ( ) ;
2011-04-20 12:07:08 -04:00
int res = o . woCompare ( x , BSONObj ( ) , /*considerfieldname*/ false ) ;
if ( res ) {
2011-06-01 14:57:40 -04:00
cout < < o . toString ( ) < < endl ;
2011-04-20 12:07:08 -04:00
k . toBson ( ) ;
2011-06-01 14:57:40 -04:00
cout < < x . toString ( ) < < endl ;
2011-04-20 12:07:08 -04:00
o . woCompare ( x , BSONObj ( ) , /*considerfieldname*/ false ) ;
ASSERT ( res = = 0 ) ;
}
2011-04-12 17:09:08 -04:00
ASSERT ( k . woEqual ( k ) ) ;
ASSERT ( ! k . isCompactFormat ( ) | | k . dataSize ( ) < o . objsize ( ) ) ;
2011-06-01 09:35:42 -04:00
{
// check BSONObj::equal. this part not a KeyV1 test.
int res = o . woCompare ( last ) ;
ASSERT ( ( res = = 0 ) = = o . equal ( last ) ) ;
}
2011-04-12 17:09:08 -04:00
if ( kLast ) {
int r1 = o . woCompare ( last , BSONObj ( ) , false ) ;
int r2 = k . woCompare ( * kLast , Ordering : : make ( BSONObj ( ) ) ) ;
bool ok = ( r1 < 0 & & r2 < 0 ) | | ( r1 > 0 & & r2 > 0 ) | | r1 = = r2 ;
if ( ! ok ) {
2011-04-20 12:07:08 -04:00
cout < < " r1r2 " < < r1 < < ' ' < < r2 < < endl ;
cout < < " o: " < < o . toString ( ) < < endl ;
cout < < " last: " < < last . toString ( ) < < endl ;
cout < < " k: " < < k . toString ( ) < < endl ;
cout < < " kLast: " < < kLast - > toString ( ) < < endl ;
2011-04-12 17:09:08 -04:00
int r3 = k . woCompare ( * kLast , Ordering : : make ( BSONObj ( ) ) ) ;
cout < < r3 < < endl ;
}
ASSERT ( ok ) ;
2011-05-14 22:30:18 -04:00
if ( k . isCompactFormat ( ) & & kLast - > isCompactFormat ( ) ) { // only check if not bson as bson woEqual is broken! (or was may2011)
if ( k . woEqual ( * kLast ) ! = ( r2 = = 0 ) ) { // check woEqual matches
cout < < r2 < < endl ;
cout < < k . toString ( ) < < endl ;
cout < < kLast - > toString ( ) < < endl ;
k . woEqual ( * kLast ) ;
ASSERT ( false ) ;
}
}
2011-04-12 17:09:08 -04:00
}
delete kLast ;
kLast = key ;
last = o . getOwned ( ) ;
2011-04-11 18:21:48 -04:00
}
2009-03-25 18:24:22 -04:00
class BufBuilderBasic {
public :
void run ( ) {
2011-05-10 12:40:01 -04:00
{
BufBuilder b ( 0 ) ;
b . appendStr ( " foo " ) ;
ASSERT_EQUALS ( 4 , b . len ( ) ) ;
ASSERT ( strcmp ( " foo " , b . buf ( ) ) = = 0 ) ;
}
{
mongo : : StackBufBuilder b ;
b . appendStr ( " foo " ) ;
ASSERT_EQUALS ( 4 , b . len ( ) ) ;
ASSERT ( strcmp ( " foo " , b . buf ( ) ) = = 0 ) ;
}
2009-03-25 18:24:22 -04:00
}
} ;
2009-09-18 14:25:23 -04:00
2009-03-24 14:32:13 -04:00
class BSONElementBasic {
public :
void run ( ) {
ASSERT_EQUALS ( 1 , BSONElement ( ) . size ( ) ) ;
2011-05-11 10:28:28 -04:00
BSONObj x ;
ASSERT_EQUALS ( 1 , x . firstElement ( ) . size ( ) ) ;
2009-03-24 14:32:13 -04:00
}
} ;
2009-09-18 14:25:23 -04:00
2009-01-15 10:17:11 -05:00
namespace BSONObjTests {
class Create {
public :
void run ( ) {
BSONObj b ;
ASSERT_EQUALS ( 0 , b . nFields ( ) ) ;
}
} ;
class Base {
protected :
static BSONObj basic ( const char * name , int val ) {
BSONObjBuilder b ;
2009-02-09 15:38:26 -05:00
b . append ( name , val ) ;
2009-02-09 13:04:32 -05:00
return b . obj ( ) ;
2009-01-15 10:17:11 -05:00
}
static BSONObj basic ( const char * name , vector < int > val ) {
BSONObjBuilder b ;
2009-02-09 15:38:26 -05:00
b . append ( name , val ) ;
2009-02-09 13:04:32 -05:00
return b . obj ( ) ;
2009-01-15 10:17:11 -05:00
}
template < class T >
static BSONObj basic ( const char * name , T val ) {
BSONObjBuilder b ;
b . append ( name , val ) ;
2009-02-09 13:04:32 -05:00
return b . obj ( ) ;
2009-01-15 10:17:11 -05:00
}
} ;
class WoCompareBasic : public Base {
public :
void run ( ) {
ASSERT ( basic ( " a " , 1 ) . woCompare ( basic ( " a " , 1 ) ) = = 0 ) ;
ASSERT ( basic ( " a " , 2 ) . woCompare ( basic ( " a " , 1 ) ) > 0 ) ;
ASSERT ( basic ( " a " , 1 ) . woCompare ( basic ( " a " , 2 ) ) < 0 ) ;
// field name comparison
ASSERT ( basic ( " a " , 1 ) . woCompare ( basic ( " b " , 1 ) ) < 0 ) ;
}
} ;
class NumericCompareBasic : public Base {
public :
void run ( ) {
ASSERT ( basic ( " a " , 1 ) . woCompare ( basic ( " a " , 1.0 ) ) = = 0 ) ;
}
} ;
class WoCompareEmbeddedObject : public Base {
public :
void run ( ) {
ASSERT ( basic ( " a " , basic ( " b " , 1 ) ) . woCompare
( basic ( " a " , basic ( " b " , 1.0 ) ) ) = = 0 ) ;
ASSERT ( basic ( " a " , basic ( " b " , 1 ) ) . woCompare
( basic ( " a " , basic ( " b " , 2 ) ) ) < 0 ) ;
}
} ;
class WoCompareEmbeddedArray : public Base {
public :
void run ( ) {
vector < int > i ;
i . push_back ( 1 ) ;
i . push_back ( 2 ) ;
vector < double > d ;
d . push_back ( 1 ) ;
d . push_back ( 2 ) ;
ASSERT ( basic ( " a " , i ) . woCompare ( basic ( " a " , d ) ) = = 0 ) ;
vector < int > j ;
j . push_back ( 1 ) ;
j . push_back ( 3 ) ;
ASSERT ( basic ( " a " , i ) . woCompare ( basic ( " a " , j ) ) < 0 ) ;
}
} ;
class WoCompareOrdered : public Base {
public :
void run ( ) {
ASSERT ( basic ( " a " , 1 ) . woCompare ( basic ( " a " , 1 ) , basic ( " a " , 1 ) ) = = 0 ) ;
ASSERT ( basic ( " a " , 2 ) . woCompare ( basic ( " a " , 1 ) , basic ( " a " , 1 ) ) > 0 ) ;
ASSERT ( basic ( " a " , 1 ) . woCompare ( basic ( " a " , 2 ) , basic ( " a " , 1 ) ) < 0 ) ;
ASSERT ( basic ( " a " , 1 ) . woCompare ( basic ( " a " , 1 ) , basic ( " a " , - 1 ) ) = = 0 ) ;
ASSERT ( basic ( " a " , 2 ) . woCompare ( basic ( " a " , 1 ) , basic ( " a " , - 1 ) ) < 0 ) ;
ASSERT ( basic ( " a " , 1 ) . woCompare ( basic ( " a " , 2 ) , basic ( " a " , - 1 ) ) > 0 ) ;
}
} ;
2009-09-18 14:25:23 -04:00
2009-02-26 11:20:19 -05:00
class WoCompareDifferentLength : public Base {
public :
void run ( ) {
ASSERT ( BSON ( " a " < < 1 ) . woCompare ( BSON ( " a " < < 1 < < " b " < < 1 ) ) < 0 ) ;
ASSERT ( BSON ( " a " < < 1 < < " b " < < 1 ) . woCompare ( BSON ( " a " < < 1 ) ) > 0 ) ;
}
} ;
2009-09-18 14:25:23 -04:00
2009-02-24 18:53:34 -05:00
class WoSortOrder : public Base {
public :
void run ( ) {
ASSERT ( BSON ( " a " < < 1 ) . woSortOrder ( BSON ( " a " < < 2 ) , BSON ( " b " < < 1 < < " a " < < 1 ) ) < 0 ) ;
ASSERT ( fromjson ( " {a:null} " ) . woSortOrder ( BSON ( " b " < < 1 ) , BSON ( " a " < < 1 ) ) = = 0 ) ;
}
} ;
2009-09-18 14:25:23 -04:00
2009-09-09 09:48:37 -04:00
class MultiKeySortOrder : public Base {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-09-09 09:48:37 -04:00
ASSERT ( BSON ( " x " < < " a " ) . woCompare ( BSON ( " x " < < " b " ) ) < 0 ) ;
ASSERT ( BSON ( " x " < < " b " ) . woCompare ( BSON ( " x " < < " a " ) ) > 0 ) ;
ASSERT ( BSON ( " x " < < " a " < < " y " < < " a " ) . woCompare ( BSON ( " x " < < " a " < < " y " < < " b " ) ) < 0 ) ;
ASSERT ( BSON ( " x " < < " a " < < " y " < < " a " ) . woCompare ( BSON ( " x " < < " b " < < " y " < < " a " ) ) < 0 ) ;
ASSERT ( BSON ( " x " < < " a " < < " y " < < " a " ) . woCompare ( BSON ( " x " < < " b " ) ) < 0 ) ;
ASSERT ( BSON ( " x " < < " c " ) . woCompare ( BSON ( " x " < < " b " < < " y " < < " h " ) ) > 0 ) ;
ASSERT ( BSON ( " x " < < " b " < < " y " < < " b " ) . woCompare ( BSON ( " x " < < " c " ) ) < 0 ) ;
BSONObj key = BSON ( " x " < < 1 < < " y " < < 1 ) ;
2009-09-18 14:25:23 -04:00
2009-09-09 09:48:37 -04:00
ASSERT ( BSON ( " x " < < " c " ) . woSortOrder ( BSON ( " x " < < " b " < < " y " < < " h " ) , key ) > 0 ) ;
ASSERT ( BSON ( " x " < < " b " < < " y " < < " b " ) . woCompare ( BSON ( " x " < < " c " ) , key ) < 0 ) ;
key = BSON ( " " < < 1 < < " " < < 1 ) ;
ASSERT ( BSON ( " " < < " c " ) . woSortOrder ( BSON ( " " < < " b " < < " " < < " h " ) , key ) > 0 ) ;
ASSERT ( BSON ( " " < < " b " < < " " < < " b " ) . woCompare ( BSON ( " " < < " c " ) , key ) < 0 ) ;
2009-09-18 14:25:23 -04:00
2011-07-01 12:39:50 -04:00
{
// test a big key
string x ( 2000 , ' z ' ) ;
BSONObj o = BSON ( " q " < < x ) ;
keyTest ( o , false ) ;
}
{
string y ( 200 , ' w ' ) ;
BSONObjBuilder b ;
for ( int i = 0 ; i < 10 ; i + + ) {
b . append ( " x " , y ) ;
}
keyTest ( b . obj ( ) , true ) ;
}
2011-07-05 11:17:05 -04:00
{
double nan = numeric_limits < double > : : quiet_NaN ( ) ;
BSONObj o = BSON ( " y " < < nan ) ;
keyTest ( o ) ;
}
2011-07-01 12:39:50 -04:00
2009-09-09 09:48:37 -04:00
{
BSONObjBuilder b ;
b . append ( " " , " c " ) ;
b . appendNull ( " " ) ;
BSONObj o = b . obj ( ) ;
2011-04-12 17:09:08 -04:00
keyTest ( o ) ;
2009-09-09 09:48:37 -04:00
ASSERT ( o . woSortOrder ( BSON ( " " < < " b " < < " " < < " h " ) , key ) > 0 ) ;
ASSERT ( BSON ( " " < < " b " < < " " < < " h " ) . woSortOrder ( o , key ) < 0 ) ;
2009-09-18 14:25:23 -04:00
2009-09-09 09:48:37 -04:00
}
2009-09-18 14:25:23 -04:00
2009-09-09 09:48:37 -04:00
ASSERT ( BSON ( " " < < " a " ) . woCompare ( BSON ( " " < < " a " < < " " < < " c " ) ) < 0 ) ;
{
BSONObjBuilder b ;
b . append ( " " , " a " ) ;
b . appendNull ( " " ) ;
2009-09-09 11:51:23 -04:00
ASSERT ( b . obj ( ) . woCompare ( BSON ( " " < < " a " < < " " < < " c " ) ) < 0 ) ; // SERVER-282
2009-09-09 09:48:37 -04:00
}
2009-09-18 14:25:23 -04:00
2009-09-09 09:48:37 -04:00
}
} ;
2009-09-18 14:25:23 -04:00
2009-02-27 18:14:45 -05:00
class TimestampTest : public Base {
2009-02-27 17:18:56 -05:00
public :
void run ( ) {
2011-05-14 20:16:24 -04:00
Client * c = currentClient . get ( ) ;
if ( c = = 0 ) {
Client : : initThread ( " pretouchN " ) ;
c = & cc ( ) ;
}
writelock lk ( " " ) ; // for initTimestamp
2009-02-27 17:18:56 -05:00
BSONObjBuilder b ;
2009-02-27 18:14:45 -05:00
b . appendTimestamp ( " a " ) ;
2009-02-27 17:18:56 -05:00
BSONObj o = b . done ( ) ;
o . toString ( ) ;
ASSERT ( o . valid ( ) ) ;
2009-02-27 18:14:45 -05:00
ASSERT_EQUALS ( Timestamp , o . getField ( " a " ) . type ( ) ) ;
2009-02-27 17:18:56 -05:00
BSONObjIterator i ( o ) ;
2009-06-09 11:43:04 -04:00
ASSERT ( i . moreWithEOO ( ) ) ;
2009-06-09 12:32:04 -04:00
ASSERT ( i . more ( ) ) ;
2009-06-09 11:43:04 -04:00
2009-02-27 17:18:56 -05:00
BSONElement e = i . next ( ) ;
2009-02-27 18:14:45 -05:00
ASSERT_EQUALS ( Timestamp , e . type ( ) ) ;
2009-06-09 11:43:04 -04:00
ASSERT ( i . moreWithEOO ( ) ) ;
2009-06-09 12:32:04 -04:00
ASSERT ( ! i . more ( ) ) ;
2009-09-18 14:25:23 -04:00
2009-02-27 17:18:56 -05:00
e = i . next ( ) ;
ASSERT ( e . eoo ( ) ) ;
2009-09-18 14:25:23 -04:00
2009-02-27 17:18:56 -05:00
OpTime before = OpTime : : now ( ) ;
2009-02-27 18:14:45 -05:00
BSONElementManipulator ( o . firstElement ( ) ) . initTimestamp ( ) ;
2009-02-27 17:18:56 -05:00
OpTime after = OpTime : : now ( ) ;
2009-09-18 14:25:23 -04:00
2009-02-27 17:18:56 -05:00
OpTime test = OpTime ( o . firstElement ( ) . date ( ) ) ;
2009-02-27 18:14:45 -05:00
ASSERT ( before < test & & test < after ) ;
2009-09-18 14:25:23 -04:00
2009-02-27 18:14:45 -05:00
BSONElementManipulator ( o . firstElement ( ) ) . initTimestamp ( ) ;
test = OpTime ( o . firstElement ( ) . date ( ) ) ;
2009-09-18 14:25:23 -04:00
ASSERT ( before < test & & test < after ) ;
2010-07-26 16:25:23 -04:00
OpTime x ( 123 , 456 ) ;
ASSERT_EQUALS ( 528280977864LL , x . asLL ( ) ) ;
2009-02-27 17:18:56 -05:00
}
} ;
2009-09-18 14:25:23 -04:00
2009-04-07 17:58:25 -04:00
class Nan : public Base {
public :
void run ( ) {
double inf = numeric_limits < double > : : infinity ( ) ;
double nan = numeric_limits < double > : : quiet_NaN ( ) ;
double nan2 = numeric_limits < double > : : signaling_NaN ( ) ;
2011-07-05 11:17:05 -04:00
ASSERT ( isNaN ( nan ) ) ;
ASSERT ( isNaN ( nan2 ) ) ;
ASSERT ( ! isNaN ( inf ) ) ;
2009-04-07 17:58:25 -04:00
ASSERT ( BSON ( " a " < < inf ) . woCompare ( BSON ( " a " < < inf ) ) = = 0 ) ;
2011-07-05 11:17:05 -04:00
ASSERT ( BSON ( " a " < < inf ) . woCompare ( BSON ( " a " < < 1 ) ) > 0 ) ;
ASSERT ( BSON ( " a " < < 1 ) . woCompare ( BSON ( " a " < < inf ) ) < 0 ) ;
2009-09-18 14:25:23 -04:00
2009-04-07 17:58:25 -04:00
ASSERT ( BSON ( " a " < < nan ) . woCompare ( BSON ( " a " < < nan ) ) = = 0 ) ;
ASSERT ( BSON ( " a " < < nan ) . woCompare ( BSON ( " a " < < 1 ) ) < 0 ) ;
2011-07-05 11:17:05 -04:00
ASSERT ( BSON ( " a " < < nan ) . woCompare ( BSON ( " a " < < 5000000000LL ) ) < 0 ) ;
{
KeyV1Owned a ( BSON ( " a " < < nan ) ) ;
KeyV1Owned b ( BSON ( " a " < < 1 ) ) ;
Ordering o = Ordering : : make ( BSON ( " a " < < 1 ) ) ;
ASSERT ( a . woCompare ( b , o ) < 0 ) ;
}
2009-04-07 17:58:25 -04:00
ASSERT ( BSON ( " a " < < 1 ) . woCompare ( BSON ( " a " < < nan ) ) > 0 ) ;
ASSERT ( BSON ( " a " < < nan2 ) . woCompare ( BSON ( " a " < < nan2 ) ) = = 0 ) ;
ASSERT ( BSON ( " a " < < nan2 ) . woCompare ( BSON ( " a " < < 1 ) ) < 0 ) ;
ASSERT ( BSON ( " a " < < 1 ) . woCompare ( BSON ( " a " < < nan2 ) ) > 0 ) ;
2009-09-18 14:25:23 -04:00
2011-07-05 11:17:05 -04:00
ASSERT ( BSON ( " a " < < inf ) . woCompare ( BSON ( " a " < < nan ) ) > 0 ) ;
ASSERT ( BSON ( " a " < < inf ) . woCompare ( BSON ( " a " < < nan2 ) ) > 0 ) ;
2009-04-07 17:58:25 -04:00
ASSERT ( BSON ( " a " < < nan ) . woCompare ( BSON ( " a " < < nan2 ) ) = = 0 ) ;
}
} ;
2009-09-18 14:25:23 -04:00
2011-01-04 00:40:41 -05:00
class AsTempObj {
2010-01-28 14:24:45 -05:00
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-01-28 14:24:45 -05:00
{
BSONObjBuilder bb ;
bb < < " a " < < 1 ;
BSONObj tmp = bb . asTempObj ( ) ;
ASSERT ( tmp . objsize ( ) = = 4 + ( 1 + 2 + 4 ) + 1 ) ;
ASSERT ( tmp . valid ( ) ) ;
ASSERT ( tmp . hasField ( " a " ) ) ;
ASSERT ( ! tmp . hasField ( " b " ) ) ;
ASSERT ( tmp = = BSON ( " a " < < 1 ) ) ;
2011-01-04 00:40:41 -05:00
2010-01-28 14:24:45 -05:00
bb < < " b " < < 2 ;
BSONObj obj = bb . obj ( ) ;
2010-06-10 16:00:37 -04:00
ASSERT_EQUALS ( obj . objsize ( ) , 4 + ( 1 + 2 + 4 ) + ( 1 + 2 + 4 ) + 1 ) ;
2010-01-28 14:24:45 -05:00
ASSERT ( obj . valid ( ) ) ;
ASSERT ( obj . hasField ( " a " ) ) ;
ASSERT ( obj . hasField ( " b " ) ) ;
ASSERT ( obj = = BSON ( " a " < < 1 < < " b " < < 2 ) ) ;
}
{
BSONObjBuilder bb ;
bb < < " a " < < GT < < 1 ;
BSONObj tmp = bb . asTempObj ( ) ;
ASSERT ( tmp . objsize ( ) = = 4 + ( 1 + 2 + ( 4 + 1 + 4 + 4 + 1 ) ) + 1 ) ;
ASSERT ( tmp . valid ( ) ) ;
ASSERT ( tmp . hasField ( " a " ) ) ;
ASSERT ( ! tmp . hasField ( " b " ) ) ;
ASSERT ( tmp = = BSON ( " a " < < BSON ( " $gt " < < 1 ) ) ) ;
2011-01-04 00:40:41 -05:00
2010-01-28 14:24:45 -05:00
bb < < " b " < < LT < < 2 ;
BSONObj obj = bb . obj ( ) ;
ASSERT ( obj . objsize ( ) = = 4 + ( 1 + 2 + ( 4 + 1 + 4 + 4 + 1 ) ) + ( 1 + 2 + ( 4 + 1 + 4 + 4 + 1 ) ) + 1 ) ;
ASSERT ( obj . valid ( ) ) ;
ASSERT ( obj . hasField ( " a " ) ) ;
ASSERT ( obj . hasField ( " b " ) ) ;
ASSERT ( obj = = BSON ( " a " < < BSON ( " $gt " < < 1 )
2011-01-04 00:40:41 -05:00
< < " b " < < BSON ( " $lt " < < 2 ) ) ) ;
2010-01-28 14:24:45 -05:00
}
{
BSONObjBuilder bb ( 32 ) ;
bb < < " a " < < 1 ;
BSONObj tmp = bb . asTempObj ( ) ;
ASSERT ( tmp . objsize ( ) = = 4 + ( 1 + 2 + 4 ) + 1 ) ;
ASSERT ( tmp . valid ( ) ) ;
ASSERT ( tmp . hasField ( " a " ) ) ;
ASSERT ( ! tmp . hasField ( " b " ) ) ;
ASSERT ( tmp = = BSON ( " a " < < 1 ) ) ;
2011-01-04 00:40:41 -05:00
2010-01-28 14:24:45 -05:00
//force a realloc
BSONArrayBuilder arr ;
2011-01-04 00:40:41 -05:00
for ( int i = 0 ; i < 10000 ; i + + ) {
2010-01-28 14:24:45 -05:00
arr < < i ;
}
bb < < " b " < < arr . arr ( ) ;
BSONObj obj = bb . obj ( ) ;
ASSERT ( obj . valid ( ) ) ;
ASSERT ( obj . hasField ( " a " ) ) ;
ASSERT ( obj . hasField ( " b " ) ) ;
}
}
} ;
2011-01-04 00:40:41 -05:00
struct AppendIntOrLL {
void run ( ) {
2010-02-02 21:34:21 -05:00
const long long billion = 1000 * 1000 * 1000 ;
2011-04-12 17:09:08 -04:00
2011-10-04 10:06:47 -04:00
long long n = 0x3333111122224444LL ;
2011-09-06 16:23:19 -04:00
{
2011-10-03 14:32:27 -04:00
double d = ( double ) n ;
2011-09-06 16:23:19 -04:00
BSONObj a = BSON ( " x " < < n ) ;
BSONObj b = BSON ( " x " < < d ) ;
long long back = ( long long ) d ;
2011-10-03 22:31:33 -04:00
//3717
////// int res = a.woCompare(b);
2011-09-06 16:23:19 -04:00
ASSERT ( n > back ) ;
//ASSERT( res > 0 ); // SERVER-3717
keyTest ( a , false ) ;
KeyV1Owned A ( a ) ;
KeyV1Owned B ( b ) ;
2011-10-03 22:31:33 -04:00
//3717
////// int res2 = A.woCompare(B, Ordering::make(BSONObj()));
2011-09-06 16:23:19 -04:00
// ASSERT( res2 > 0 ); // SERVER-3717
// fixing requires an index v# change.
cout < < " todo fix SERVER-3717 and uncomment test in AppendIntOrLL " < < endl ;
n + + ;
}
2011-04-12 17:09:08 -04:00
{
BSONObjBuilder b ;
b . appendIntOrLL ( " L4 " , - 4 * billion ) ;
keyTest ( b . obj ( ) ) ;
keyTest ( BSON ( " " < < billion ) ) ;
}
2010-02-02 21:34:21 -05:00
BSONObjBuilder b ;
b . appendIntOrLL ( " i1 " , 1 ) ;
b . appendIntOrLL ( " i2 " , - 1 ) ;
b . appendIntOrLL ( " i3 " , 1 * billion ) ;
b . appendIntOrLL ( " i4 " , - 1 * billion ) ;
b . appendIntOrLL ( " L1 " , 2 * billion ) ;
b . appendIntOrLL ( " L2 " , - 2 * billion ) ;
b . appendIntOrLL ( " L3 " , 4 * billion ) ;
b . appendIntOrLL ( " L4 " , - 4 * billion ) ;
b . appendIntOrLL ( " L5 " , 16 * billion ) ;
b . appendIntOrLL ( " L6 " , - 16 * billion ) ;
BSONObj o = b . obj ( ) ;
2011-04-11 18:21:48 -04:00
keyTest ( o ) ;
2010-02-02 21:34:21 -05:00
ASSERT ( o [ " i1 " ] . type ( ) = = NumberInt ) ;
ASSERT ( o [ " i1 " ] . number ( ) = = 1 ) ;
ASSERT ( o [ " i2 " ] . type ( ) = = NumberInt ) ;
ASSERT ( o [ " i2 " ] . number ( ) = = - 1 ) ;
ASSERT ( o [ " i3 " ] . type ( ) = = NumberInt ) ;
ASSERT ( o [ " i3 " ] . number ( ) = = 1 * billion ) ;
ASSERT ( o [ " i4 " ] . type ( ) = = NumberInt ) ;
ASSERT ( o [ " i4 " ] . number ( ) = = - 1 * billion ) ;
ASSERT ( o [ " L1 " ] . type ( ) = = NumberLong ) ;
ASSERT ( o [ " L1 " ] . number ( ) = = 2 * billion ) ;
ASSERT ( o [ " L2 " ] . type ( ) = = NumberLong ) ;
ASSERT ( o [ " L2 " ] . number ( ) = = - 2 * billion ) ;
ASSERT ( o [ " L3 " ] . type ( ) = = NumberLong ) ;
ASSERT ( o [ " L3 " ] . number ( ) = = 4 * billion ) ;
ASSERT ( o [ " L4 " ] . type ( ) = = NumberLong ) ;
ASSERT ( o [ " L4 " ] . number ( ) = = - 4 * billion ) ;
ASSERT ( o [ " L5 " ] . type ( ) = = NumberLong ) ;
ASSERT ( o [ " L5 " ] . number ( ) = = 16 * billion ) ;
ASSERT ( o [ " L6 " ] . type ( ) = = NumberLong ) ;
ASSERT ( o [ " L6 " ] . number ( ) = = - 16 * billion ) ;
}
} ;
2010-03-01 17:14:23 -05:00
struct AppendNumber {
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-03-01 17:14:23 -05:00
BSONObjBuilder b ;
b . appendNumber ( " a " , 5 ) ;
b . appendNumber ( " b " , 5.5 ) ;
b . appendNumber ( " c " , ( 1024LL * 1024 * 1024 ) - 1 ) ;
b . appendNumber ( " d " , ( 1024LL * 1024 * 1024 * 1024 ) - 1 ) ;
b . appendNumber ( " e " , 1024LL * 1024 * 1024 * 1024 * 1024 * 1024 ) ;
2011-01-04 00:40:41 -05:00
2010-03-01 17:14:23 -05:00
BSONObj o = b . obj ( ) ;
2011-04-12 17:09:08 -04:00
keyTest ( o ) ;
2011-01-04 00:40:41 -05:00
2010-03-01 17:14:23 -05:00
ASSERT ( o [ " a " ] . type ( ) = = NumberInt ) ;
ASSERT ( o [ " b " ] . type ( ) = = NumberDouble ) ;
ASSERT ( o [ " c " ] . type ( ) = = NumberInt ) ;
ASSERT ( o [ " d " ] . type ( ) = = NumberDouble ) ;
ASSERT ( o [ " e " ] . type ( ) = = NumberLong ) ;
}
} ;
2011-01-04 00:40:41 -05:00
2010-04-05 23:48:09 -07:00
class ToStringArray {
public :
void run ( ) {
string spec = " { a: [ \" a \" , \" b \" ] } " ;
ASSERT_EQUALS ( spec , fromjson ( spec ) . toString ( ) ) ;
2011-04-19 13:36:21 -04:00
BSONObj x = BSON ( " a " < < " astring " < < " b " < < " str " ) ;
keyTest ( x ) ;
keyTest ( x ) ;
BSONObj y = BSON ( " a " < < " astring " < < " b " < < " stra " ) ;
keyTest ( y ) ;
y = BSON ( " a " < < " " ) ;
keyTest ( y ) ;
keyTest ( BSON ( " abc " < < true ) ) ;
keyTest ( BSON ( " abc " < < false ) ) ;
keyTest ( BSON ( " abc " < < false < < " b " < < true ) ) ;
2011-04-20 09:23:39 -04:00
Date_t now = jsTime ( ) ;
keyTest ( BSON ( " " < < now < < " " < < 3 < < " " < < jstNULL < < " " < < true ) ) ;
keyTest ( BSON ( " " < < now < < " " < < 3 < < " " < < BSONObj ( ) < < " " < < true ) ) ;
2011-05-15 11:10:38 -04:00
{
2011-06-06 08:17:55 -04:00
{
// check signed dates with new key format
KeyV1Owned a ( BSONObjBuilder ( ) . appendDate ( " " , - 50 ) . obj ( ) ) ;
KeyV1Owned b ( BSONObjBuilder ( ) . appendDate ( " " , 50 ) . obj ( ) ) ;
ASSERT ( a . woCompare ( b , Ordering : : make ( BSONObj ( ) ) ) < 0 ) ;
}
{
// backward compatibility
KeyBson a ( BSONObjBuilder ( ) . appendDate ( " " , - 50 ) . obj ( ) ) ;
KeyBson b ( BSONObjBuilder ( ) . appendDate ( " " , 50 ) . obj ( ) ) ;
ASSERT ( a . woCompare ( b , Ordering : : make ( BSONObj ( ) ) ) > 0 ) ;
}
{
// this is an uncompactible key:
BSONObj uc1 = BSONObjBuilder ( ) . appendDate ( " " , - 50 ) . appendCode ( " " , " abc " ) . obj ( ) ;
BSONObj uc2 = BSONObjBuilder ( ) . appendDate ( " " , 55 ) . appendCode ( " " , " abc " ) . obj ( ) ;
ASSERT ( uc1 . woCompare ( uc2 , Ordering : : make ( BSONObj ( ) ) ) < 0 ) ;
{
KeyV1Owned a ( uc1 ) ;
KeyV1Owned b ( uc2 ) ;
ASSERT ( ! a . isCompactFormat ( ) ) ;
ASSERT ( a . woCompare ( b , Ordering : : make ( BSONObj ( ) ) ) < 0 ) ;
}
{
KeyBson a ( uc1 ) ;
KeyBson b ( uc2 ) ;
ASSERT ( ! a . isCompactFormat ( ) ) ;
ASSERT ( a . woCompare ( b , Ordering : : make ( BSONObj ( ) ) ) > 0 ) ;
}
}
2011-05-15 11:10:38 -04:00
}
2011-05-05 14:09:07 -04:00
{
BSONObjBuilder b ;
b . appendBinData ( " f " , 8 , ( BinDataType ) 1 , " aaaabbbb " ) ;
b . appendBinData ( " e " , 3 , ( BinDataType ) 1 , " aaa " ) ;
b . appendBinData ( " b " , 1 , ( BinDataType ) 1 , " x " ) ;
BSONObj o = b . obj ( ) ;
keyTest ( o , true ) ;
}
2011-09-06 11:58:17 -04:00
{
// check (non)equality
BSONObj a = BSONObjBuilder ( ) . appendBinData ( " " , 8 , ( BinDataType ) 1 , " abcdefgh " ) . obj ( ) ;
BSONObj b = BSONObjBuilder ( ) . appendBinData ( " " , 8 , ( BinDataType ) 1 , " abcdefgj " ) . obj ( ) ;
ASSERT ( ! a . equal ( b ) ) ;
int res_ab = a . woCompare ( b ) ;
ASSERT ( res_ab ! = 0 ) ;
keyTest ( a , true ) ;
keyTest ( b , true ) ;
// check subtypes do not equal
BSONObj c = BSONObjBuilder ( ) . appendBinData ( " " , 8 , ( BinDataType ) 4 , " abcdefgh " ) . obj ( ) ;
BSONObj d = BSONObjBuilder ( ) . appendBinData ( " " , 8 , ( BinDataType ) 0x81 , " abcdefgh " ) . obj ( ) ;
ASSERT ( ! a . equal ( c ) ) ;
int res_ac = a . woCompare ( c ) ;
ASSERT ( res_ac ! = 0 ) ;
keyTest ( c , true ) ;
ASSERT ( ! a . equal ( d ) ) ;
int res_ad = a . woCompare ( d ) ;
ASSERT ( res_ad ! = 0 ) ;
keyTest ( d , true ) ;
KeyV1Owned A ( a ) ;
KeyV1Owned B ( b ) ;
KeyV1Owned C ( c ) ;
KeyV1Owned D ( d ) ;
ASSERT ( ! A . woEqual ( B ) ) ;
2011-09-09 13:44:03 -04:00
ASSERT ( A . woCompare ( B , Ordering : : make ( BSONObj ( ) ) ) < 0 & & res_ab < 0 ) ;
2011-09-06 11:58:17 -04:00
ASSERT ( ! A . woEqual ( C ) ) ;
ASSERT ( A . woCompare ( C , Ordering : : make ( BSONObj ( ) ) ) < 0 & & res_ac < 0 ) ;
ASSERT ( ! A . woEqual ( D ) ) ;
ASSERT ( A . woCompare ( D , Ordering : : make ( BSONObj ( ) ) ) < 0 & & res_ad < 0 ) ;
}
2011-08-04 19:01:22 -04:00
{
BSONObjBuilder b ;
b . appendBinData ( " f " , 33 , ( BinDataType ) 1 , " 123456789012345678901234567890123 " ) ;
BSONObj o = b . obj ( ) ;
keyTest ( o , false ) ;
}
2011-05-05 14:09:07 -04:00
{
for ( int i = 1 ; i < = 3 ; i + + ) {
for ( int j = 1 ; j < = 3 ; j + + ) {
BSONObjBuilder b ;
b . appendBinData ( " f " , i , ( BinDataType ) j , " abc " ) ;
BSONObj o = b . obj ( ) ;
keyTest ( o , j ! = ByteArrayDeprecated ) ;
}
}
}
{
BSONObjBuilder b ;
b . appendBinData ( " f " , 1 , ( BinDataType ) 133 , " a " ) ;
BSONObj o = b . obj ( ) ;
keyTest ( o , true ) ;
}
{
BSONObjBuilder b ;
b . append ( " AA " , 3 ) ;
b . appendBinData ( " f " , 0 , ( BinDataType ) 0 , " " ) ;
b . appendBinData ( " e " , 3 , ( BinDataType ) 7 , " aaa " ) ;
b . appendBinData ( " b " , 1 , ( BinDataType ) 128 , " x " ) ;
b . append ( " z " , 3 ) ;
b . appendBinData ( " bb " , 0 , ( BinDataType ) 129 , " x " ) ;
BSONObj o = b . obj ( ) ;
keyTest ( o , true ) ;
}
{
// 9 is not supported in compact format. so test a non-compact case here.
BSONObjBuilder b ;
b . appendBinData ( " f " , 9 , ( BinDataType ) 0 , " aaaabbbbc " ) ;
BSONObj o = b . obj ( ) ;
keyTest ( o ) ;
}
2011-04-19 13:36:21 -04:00
}
2010-04-05 23:48:09 -07:00
} ;
2010-03-01 17:14:23 -05:00
2010-08-08 23:39:09 -04:00
class ToStringNumber {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-08-08 23:39:09 -04:00
BSONObjBuilder b ;
b . append ( " a " , ( int ) 4 ) ;
b . append ( " b " , ( double ) 5 ) ;
b . append ( " c " , ( long long ) 6 ) ;
2011-01-04 00:40:41 -05:00
2010-08-08 23:39:09 -04:00
b . append ( " d " , 123.456789123456789123456789123456789 ) ;
b . append ( " e " , 123456789.123456789123456789123456789 ) ;
b . append ( " f " , 1234567891234567891234.56789123456789 ) ;
b . append ( " g " , - 123.456 ) ;
2011-01-04 00:40:41 -05:00
2010-08-08 23:39:09 -04:00
BSONObj x = b . obj ( ) ;
2011-04-12 17:09:08 -04:00
keyTest ( x ) ;
2010-08-08 23:39:09 -04:00
ASSERT_EQUALS ( " 4 " , x [ " a " ] . toString ( false , true ) ) ;
ASSERT_EQUALS ( " 5.0 " , x [ " b " ] . toString ( false , true ) ) ;
2011-01-04 00:40:41 -05:00
ASSERT_EQUALS ( " 6 " , x [ " c " ] . toString ( false , true ) ) ;
2010-08-08 23:39:09 -04:00
ASSERT_EQUALS ( " 123.4567891234568 " , x [ " d " ] . toString ( false , true ) ) ;
ASSERT_EQUALS ( " 123456789.1234568 " , x [ " e " ] . toString ( false , true ) ) ;
2010-08-09 00:28:06 -04:00
// ASSERT_EQUALS( "1.234567891234568e+21" , x["f"].toString( false , true ) ); // windows and *nix are different - TODO, work around for test or not bother?
2011-01-04 00:40:41 -05:00
2010-08-08 23:39:09 -04:00
ASSERT_EQUALS ( " -123.456 " , x [ " g " ] . toString ( false , true ) ) ;
}
} ;
2010-06-25 17:32:12 -04:00
class NullString {
public :
void run ( ) {
2011-06-01 14:57:40 -04:00
{
BSONObjBuilder b ;
const char x [ ] = { ' a ' , 0 , ' b ' , 0 } ;
b . append ( " field " , x , 4 ) ;
b . append ( " z " , true ) ;
BSONObj B = b . obj ( ) ;
2011-06-06 18:38:30 -04:00
//cout << B.toString() << endl;
2011-06-01 14:57:40 -04:00
BSONObjBuilder a ;
const char xx [ ] = { ' a ' , 0 , ' c ' , 0 } ;
a . append ( " field " , xx , 4 ) ;
a . append ( " z " , true ) ;
BSONObj A = a . obj ( ) ;
BSONObjBuilder c ;
const char xxx [ ] = { ' a ' , 0 , ' c ' , 0 , 0 } ;
c . append ( " field " , xxx , 5 ) ;
c . append ( " z " , true ) ;
BSONObj C = c . obj ( ) ;
// test that nulls are ok within bson strings
ASSERT ( ! ( A = = B ) ) ;
ASSERT ( A > B ) ;
ASSERT ( ! ( B = = C ) ) ;
ASSERT ( C > B ) ;
// check iteration is ok
ASSERT ( B [ " z " ] . Bool ( ) & & A [ " z " ] . Bool ( ) & & C [ " z " ] . Bool ( ) ) ;
}
2010-06-25 17:32:12 -04:00
BSONObjBuilder b ;
b . append ( " a " , " a \0 b " , 4 ) ;
2011-06-01 14:57:40 -04:00
string z ( " a \0 b " , 3 ) ;
b . append ( " b " , z ) ;
2010-06-25 17:32:12 -04:00
b . appendAs ( b . asTempObj ( ) [ " a " ] , " c " ) ;
BSONObj o = b . obj ( ) ;
2011-04-12 17:09:08 -04:00
keyTest ( o ) ;
2010-06-25 17:32:12 -04:00
stringstream ss ;
ss < < ' a ' < < ' \0 ' < < ' b ' ;
ASSERT_EQUALS ( o [ " a " ] . valuestrsize ( ) , 3 + 1 ) ;
ASSERT_EQUALS ( o [ " a " ] . str ( ) , ss . str ( ) ) ;
ASSERT_EQUALS ( o [ " b " ] . valuestrsize ( ) , 3 + 1 ) ;
ASSERT_EQUALS ( o [ " b " ] . str ( ) , ss . str ( ) ) ;
ASSERT_EQUALS ( o [ " c " ] . valuestrsize ( ) , 3 + 1 ) ;
ASSERT_EQUALS ( o [ " c " ] . str ( ) , ss . str ( ) ) ;
2011-06-01 14:57:40 -04:00
2010-06-25 17:32:12 -04:00
}
} ;
2011-01-04 00:40:41 -05:00
2010-10-01 17:42:35 -07:00
class AppendAs {
public :
void run ( ) {
BSONObjBuilder b ;
{
BSONObj foo = BSON ( " foo " < < 1 ) ;
2010-10-10 15:09:13 -07:00
b . appendAs ( foo . firstElement ( ) , " bar " ) ;
2010-10-01 17:42:35 -07:00
}
2010-10-10 15:09:13 -07:00
ASSERT_EQUALS ( BSON ( " bar " < < 1 ) , b . done ( ) ) ;
2010-10-01 17:42:35 -07:00
}
} ;
2010-06-25 17:32:12 -04:00
2010-10-01 17:42:35 -07:00
class ArrayAppendAs {
public :
void run ( ) {
BSONArrayBuilder b ;
{
BSONObj foo = BSON ( " foo " < < 1 ) ;
2010-10-10 15:09:13 -07:00
b . appendAs ( foo . firstElement ( ) , " 3 " ) ;
2010-10-01 17:42:35 -07:00
}
2010-10-10 15:09:13 -07:00
BSONArray a = b . arr ( ) ;
2010-10-01 17:42:35 -07:00
BSONObj expected = BSON ( " 3 " < < 1 ) ;
2010-10-10 15:09:13 -07:00
ASSERT_EQUALS ( expected . firstElement ( ) , a [ 3 ] ) ;
ASSERT_EQUALS ( 4 , a . nFields ( ) ) ;
2010-10-01 17:42:35 -07:00
}
} ;
2011-01-04 00:40:41 -05:00
2011-01-17 15:31:22 -05:00
class GetField {
public :
void run ( ) {
BSONObj o = BSON ( " a " < < 1 < <
" b " < < BSON ( " a " < < 2 ) < <
" c " < < BSON_ARRAY ( BSON ( " a " < < 3 ) < < BSON ( " a " < < 4 ) ) ) ;
ASSERT_EQUALS ( 1 , o . getFieldDotted ( " a " ) . numberInt ( ) ) ;
ASSERT_EQUALS ( 2 , o . getFieldDotted ( " b.a " ) . numberInt ( ) ) ;
ASSERT_EQUALS ( 3 , o . getFieldDotted ( " c.0.a " ) . numberInt ( ) ) ;
ASSERT_EQUALS ( 4 , o . getFieldDotted ( " c.1.a " ) . numberInt ( ) ) ;
2011-04-12 17:09:08 -04:00
keyTest ( o ) ;
2011-01-17 15:31:22 -05:00
}
} ;
2009-01-16 15:13:46 -05:00
namespace Validation {
2009-09-18 14:25:23 -04:00
2009-01-16 15:13:46 -05:00
class Base {
public :
2009-02-18 13:42:32 -05:00
virtual ~ Base ( ) { }
2009-01-16 15:13:46 -05:00
void run ( ) {
ASSERT ( valid ( ) . valid ( ) ) ;
ASSERT ( ! invalid ( ) . valid ( ) ) ;
}
protected :
2009-03-19 16:23:04 -04:00
virtual BSONObj valid ( ) const { return BSONObj ( ) ; }
virtual BSONObj invalid ( ) const { return BSONObj ( ) ; }
2009-01-16 15:13:46 -05:00
static char get ( const BSONObj & o , int i ) {
return o . objdata ( ) [ i ] ;
}
static void set ( BSONObj & o , int i , char c ) {
const_cast < char * > ( o . objdata ( ) ) [ i ] = c ;
}
} ;
2009-09-18 14:25:23 -04:00
2009-01-16 15:13:46 -05:00
class BadType : public Base {
BSONObj valid ( ) const {
return fromjson ( " { \" a \" :1} " ) ;
}
BSONObj invalid ( ) const {
BSONObj ret = valid ( ) ;
set ( ret , 4 , 50 ) ;
return ret ;
}
} ;
class EooBeforeEnd : public Base {
BSONObj valid ( ) const {
return fromjson ( " { \" a \" :1} " ) ;
}
BSONObj invalid ( ) const {
BSONObj ret = valid ( ) ;
// (first byte of size)++
set ( ret , 0 , get ( ret , 0 ) + 1 ) ;
// re-read size for BSONObj::details
return ret . copy ( ) ;
}
} ;
2009-02-03 13:27:46 -05:00
class Undefined : public Base {
public :
void run ( ) {
BSONObjBuilder b ;
b . appendNull ( " a " ) ;
BSONObj o = b . done ( ) ;
set ( o , 4 , mongo : : Undefined ) ;
ASSERT ( o . valid ( ) ) ;
}
} ;
2009-09-18 14:25:23 -04:00
2009-01-16 15:13:46 -05:00
class TotalSizeTooSmall : public Base {
BSONObj valid ( ) const {
return fromjson ( " { \" a \" :1} " ) ;
}
BSONObj invalid ( ) const {
BSONObj ret = valid ( ) ;
// (first byte of size)--
set ( ret , 0 , get ( ret , 0 ) - 1 ) ;
// re-read size for BSONObj::details
2009-09-18 14:25:23 -04:00
return ret . copy ( ) ;
2009-01-16 15:13:46 -05:00
}
} ;
class EooMissing : public Base {
BSONObj valid ( ) const {
return fromjson ( " { \" a \" :1} " ) ;
}
BSONObj invalid ( ) const {
BSONObj ret = valid ( ) ;
2009-10-13 12:55:23 -04:00
set ( ret , ret . objsize ( ) - 1 , ( char ) 0xff ) ;
2009-01-16 15:13:46 -05:00
// (first byte of size)--
set ( ret , 0 , get ( ret , 0 ) - 1 ) ;
// re-read size for BSONObj::details
2009-09-18 14:25:23 -04:00
return ret . copy ( ) ;
2009-01-16 15:13:46 -05:00
}
} ;
2009-09-18 14:25:23 -04:00
2009-01-16 15:13:46 -05:00
class WrongStringSize : public Base {
BSONObj valid ( ) const {
return fromjson ( " { \" a \" : \" b \" } " ) ;
}
BSONObj invalid ( ) const {
BSONObj ret = valid ( ) ;
2010-03-06 16:55:26 -05:00
ASSERT_EQUALS ( ret . firstElement ( ) . valuestr ( ) [ 0 ] , ' b ' ) ;
ASSERT_EQUALS ( ret . firstElement ( ) . valuestr ( ) [ 1 ] , 0 ) ;
( ( char * ) ret . firstElement ( ) . valuestr ( ) ) [ 1 ] = 1 ;
2009-09-18 14:25:23 -04:00
return ret . copy ( ) ;
2009-01-16 15:13:46 -05:00
}
} ;
2009-01-18 13:11:43 -05:00
class ZeroStringSize : public Base {
BSONObj valid ( ) const {
return fromjson ( " { \" a \" : \" b \" } " ) ;
}
BSONObj invalid ( ) const {
BSONObj ret = valid ( ) ;
set ( ret , 7 , 0 ) ;
return ret ;
}
} ;
2009-01-21 10:58:53 -05:00
class NegativeStringSize : public Base {
BSONObj valid ( ) const {
return fromjson ( " { \" a \" : \" b \" } " ) ;
}
BSONObj invalid ( ) const {
BSONObj ret = valid ( ) ;
set ( ret , 10 , - 100 ) ;
return ret ;
}
} ;
2009-01-16 15:13:46 -05:00
class WrongSubobjectSize : public Base {
BSONObj valid ( ) const {
return fromjson ( " { \" a \" :{ \" b \" :1}} " ) ;
}
BSONObj invalid ( ) const {
BSONObj ret = valid ( ) ;
set ( ret , 0 , get ( ret , 0 ) + 1 ) ;
set ( ret , 7 , get ( ret , 7 ) + 1 ) ;
2009-09-18 14:25:23 -04:00
return ret . copy ( ) ;
2009-01-16 15:13:46 -05:00
}
2009-09-18 14:25:23 -04:00
} ;
2009-01-16 15:13:46 -05:00
class WrongDbrefNsSize : public Base {
BSONObj valid ( ) const {
return fromjson ( " { \" a \" : Dbref( \" b \" , \" ffffffffffffffffffffffff \" ) } " ) ;
}
BSONObj invalid ( ) const {
BSONObj ret = valid ( ) ;
set ( ret , 0 , get ( ret , 0 ) + 1 ) ;
set ( ret , 7 , get ( ret , 7 ) + 1 ) ;
return ret . copy ( ) ;
} ;
} ;
2009-09-18 14:25:23 -04:00
2009-01-16 15:13:46 -05:00
class NoFieldNameEnd : public Base {
BSONObj valid ( ) const {
return fromjson ( " { \" a \" :1} " ) ;
}
BSONObj invalid ( ) const {
BSONObj ret = valid ( ) ;
memset ( const_cast < char * > ( ret . objdata ( ) ) + 5 , 0xff , ret . objsize ( ) - 5 ) ;
return ret ;
2009-09-18 14:25:23 -04:00
}
2009-01-16 15:13:46 -05:00
} ;
2009-09-18 14:25:23 -04:00
2009-01-16 15:13:46 -05:00
class BadRegex : public Base {
BSONObj valid ( ) const {
return fromjson ( " { \" a \" :/c/i} " ) ;
}
BSONObj invalid ( ) const {
BSONObj ret = valid ( ) ;
memset ( const_cast < char * > ( ret . objdata ( ) ) + 7 , 0xff , ret . objsize ( ) - 7 ) ;
return ret ;
2009-09-18 14:25:23 -04:00
}
2009-01-16 15:13:46 -05:00
} ;
2009-09-18 14:25:23 -04:00
2009-01-16 15:13:46 -05:00
class BadRegexOptions : public Base {
BSONObj valid ( ) const {
return fromjson ( " { \" a \" :/c/i} " ) ;
}
BSONObj invalid ( ) const {
BSONObj ret = valid ( ) ;
memset ( const_cast < char * > ( ret . objdata ( ) ) + 9 , 0xff , ret . objsize ( ) - 9 ) ;
return ret ;
2009-09-18 14:25:23 -04:00
}
2009-01-16 15:13:46 -05:00
} ;
2009-01-18 13:11:43 -05:00
class CodeWScopeBase : public Base {
BSONObj valid ( ) const {
BSONObjBuilder b ;
BSONObjBuilder scope ;
scope . append ( " a " , " b " ) ;
b . appendCodeWScope ( " c " , " d " , scope . done ( ) ) ;
2009-02-09 13:04:32 -05:00
return b . obj ( ) ;
2009-01-18 13:11:43 -05:00
}
BSONObj invalid ( ) const {
BSONObj ret = valid ( ) ;
modify ( ret ) ;
return ret ;
}
protected :
virtual void modify ( BSONObj & o ) const = 0 ;
} ;
2009-09-18 14:25:23 -04:00
2009-01-18 13:11:43 -05:00
class CodeWScopeSmallSize : public CodeWScopeBase {
void modify ( BSONObj & o ) const {
set ( o , 7 , 7 ) ;
}
} ;
2009-09-18 14:25:23 -04:00
2009-01-18 13:11:43 -05:00
class CodeWScopeZeroStrSize : public CodeWScopeBase {
void modify ( BSONObj & o ) const {
set ( o , 11 , 0 ) ;
}
} ;
class CodeWScopeSmallStrSize : public CodeWScopeBase {
void modify ( BSONObj & o ) const {
set ( o , 11 , 1 ) ;
}
} ;
2009-09-18 14:25:23 -04:00
2009-01-18 13:11:43 -05:00
class CodeWScopeNoSizeForObj : public CodeWScopeBase {
void modify ( BSONObj & o ) const {
set ( o , 7 , 13 ) ;
}
2009-09-18 14:25:23 -04:00
} ;
2009-01-18 13:11:43 -05:00
class CodeWScopeSmallObjSize : public CodeWScopeBase {
void modify ( BSONObj & o ) const {
set ( o , 17 , 1 ) ;
}
2009-09-18 14:25:23 -04:00
} ;
2009-01-18 13:11:43 -05:00
class CodeWScopeBadObject : public CodeWScopeBase {
void modify ( BSONObj & o ) const {
set ( o , 21 , JSTypeMax + 1 ) ;
}
2009-09-18 14:25:23 -04:00
} ;
2009-01-18 13:11:43 -05:00
2009-01-16 15:13:46 -05:00
class NoSize {
public :
NoSize ( BSONType type ) : type_ ( type ) { }
void run ( ) {
const char data [ ] = { 0x07 , 0x00 , 0x00 , 0x00 , char ( type_ ) , ' a ' , 0x00 } ;
BSONObj o ( data ) ;
ASSERT ( ! o . valid ( ) ) ;
}
private :
BSONType type_ ;
} ;
2009-09-18 14:25:23 -04:00
2009-01-16 16:40:46 -05:00
// Randomized BSON parsing test. See if we seg fault.
class Fuzz {
public :
2009-01-17 08:57:27 -05:00
Fuzz ( double frequency ) : frequency_ ( frequency ) { }
2009-01-16 16:40:46 -05:00
void run ( ) {
2009-01-18 13:15:44 -05:00
BSONObj a = fromjson ( " { \" a \" : 1, \" b \" : \" c \" } " ) ;
fuzz ( a ) ;
a . valid ( ) ;
2009-09-18 14:25:23 -04:00
2009-01-18 13:15:44 -05:00
BSONObj b = fromjson ( " { \" one \" :2, \" two \" :5, \" three \" : {}, "
2011-01-04 00:40:41 -05:00
" \" four \" : { \" five \" : { \" six \" : 11 } }, "
" \" seven \" : [ \" a \" , \" bb \" , \" ccc \" , 5 ], "
" \" eight \" : Dbref( \" rrr \" , \" 01234567890123456789aaaa \" ), "
" \" _id \" : ObjectId( \" deadbeefdeadbeefdeadbeef \" ), "
" \" nine \" : { \" $binary \" : \" abc= \" , \" $type \" : \" 00 \" }, "
" \" ten \" : Date( 44 ), \" eleven \" : /foooooo/i } " ) ;
2009-01-18 13:15:44 -05:00
fuzz ( b ) ;
b . valid ( ) ;
}
private :
void fuzz ( BSONObj & o ) const {
2009-01-16 16:40:46 -05:00
for ( int i = 4 ; i < o . objsize ( ) ; + + i )
2009-01-16 16:51:06 -05:00
for ( unsigned char j = 1 ; j ; j < < = 1 )
2009-01-17 08:57:27 -05:00
if ( rand ( ) < int ( RAND_MAX * frequency_ ) ) {
2009-01-16 16:40:46 -05:00
char * c = const_cast < char * > ( o . objdata ( ) ) + i ;
if ( * c & j )
* c & = ~ j ;
else
* c | = j ;
2009-09-18 14:25:23 -04:00
}
2009-01-16 16:40:46 -05:00
}
2009-01-17 08:57:27 -05:00
double frequency_ ;
2009-01-16 16:40:46 -05:00
} ;
2009-09-18 14:25:23 -04:00
} // namespace Validation
2009-01-15 10:17:11 -05:00
} // namespace BSONObjTests
2009-09-18 14:25:23 -04:00
2009-01-16 14:21:46 -05:00
namespace OIDTests {
2009-09-18 14:25:23 -04:00
2009-01-16 14:21:46 -05:00
class init1 {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-01-16 14:21:46 -05:00
OID a ;
OID b ;
2009-09-18 14:25:23 -04:00
2009-01-16 14:21:46 -05:00
a . init ( ) ;
b . init ( ) ;
2009-09-18 14:25:23 -04:00
2009-01-16 14:21:46 -05:00
ASSERT ( a ! = b ) ;
}
} ;
2009-01-17 00:20:47 -05:00
class initParse1 {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-01-17 00:20:47 -05:00
OID a ;
OID b ;
2009-09-18 14:25:23 -04:00
2009-01-17 00:20:47 -05:00
a . init ( ) ;
b . init ( a . str ( ) ) ;
2009-09-18 14:25:23 -04:00
2009-01-17 00:20:47 -05:00
ASSERT ( a = = b ) ;
}
} ;
2009-09-15 14:50:17 -04:00
class append {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-09-15 14:50:17 -04:00
BSONObjBuilder b ;
b . appendOID ( " a " , 0 ) ;
b . appendOID ( " b " , 0 , false ) ;
b . appendOID ( " c " , 0 , true ) ;
BSONObj o = b . obj ( ) ;
2011-04-12 17:09:08 -04:00
keyTest ( o ) ;
2009-09-18 14:25:23 -04:00
2009-09-15 14:50:17 -04:00
ASSERT ( o [ " a " ] . __oid ( ) . str ( ) = = " 000000000000000000000000 " ) ;
ASSERT ( o [ " b " ] . __oid ( ) . str ( ) = = " 000000000000000000000000 " ) ;
ASSERT ( o [ " c " ] . __oid ( ) . str ( ) ! = " 000000000000000000000000 " ) ;
}
} ;
2009-10-29 11:58:32 -04:00
class increasing {
public :
2011-01-04 00:40:41 -05:00
BSONObj g ( ) {
2009-10-29 11:58:32 -04:00
BSONObjBuilder b ;
b . appendOID ( " _id " , 0 , true ) ;
return b . obj ( ) ;
}
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-10-29 11:58:32 -04:00
BSONObj a = g ( ) ;
BSONObj b = g ( ) ;
2011-01-04 00:40:41 -05:00
2009-10-29 11:58:32 -04:00
ASSERT ( a . woCompare ( b ) < 0 ) ;
2011-01-04 00:40:41 -05:00
// yes, there is a 1/1000 chance this won't increase time(0)
2009-10-29 11:58:32 -04:00
// and therefore inaccurately say the function is behaving
// buf if its broken, it will fail 999/1000, so i think that's good enough
2009-10-29 12:06:16 -04:00
sleepsecs ( 1 ) ;
2009-10-29 11:58:32 -04:00
BSONObj c = g ( ) ;
ASSERT ( a . woCompare ( c ) < 0 ) ;
}
} ;
2010-04-14 15:31:00 -04:00
2010-04-14 19:52:21 -04:00
class ToDate {
2010-04-14 15:31:00 -04:00
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-04-14 15:31:00 -04:00
OID oid ;
{
time_t before = : : time ( 0 ) ;
oid . init ( ) ;
time_t after = : : time ( 0 ) ;
ASSERT ( oid . asTimeT ( ) > = before ) ;
ASSERT ( oid . asTimeT ( ) < = after ) ;
}
{
Date_t before = jsTime ( ) ;
sleepsecs ( 1 ) ;
oid . init ( ) ;
Date_t after = jsTime ( ) ;
ASSERT ( oid . asDateT ( ) > = before ) ;
ASSERT ( oid . asDateT ( ) < = after ) ;
}
}
} ;
2010-04-14 19:52:21 -04:00
class FromDate {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-04-14 19:52:21 -04:00
OID min , oid , max ;
Date_t now = jsTime ( ) ;
oid . init ( ) ; // slight chance this has different time. If its a problem, can change.
min . init ( now ) ;
max . init ( now , true ) ;
ASSERT_EQUALS ( ( unsigned ) oid . asTimeT ( ) , now / 1000 ) ;
ASSERT_EQUALS ( ( unsigned ) min . asTimeT ( ) , now / 1000 ) ;
ASSERT_EQUALS ( ( unsigned ) max . asTimeT ( ) , now / 1000 ) ;
ASSERT ( BSON ( " " < < min ) . woCompare ( BSON ( " " < < oid ) ) < 0 ) ;
ASSERT ( BSON ( " " < < max ) . woCompare ( BSON ( " " < < oid ) ) > 0 ) ;
}
} ;
2009-02-10 11:21:13 -05:00
} // namespace OIDTests
2009-09-18 14:25:23 -04:00
2010-04-14 19:52:21 -04:00
2009-02-10 11:21:13 -05:00
namespace ValueStreamTests {
2009-09-18 14:25:23 -04:00
2009-02-10 11:21:13 -05:00
class LabelBase {
public :
2009-02-18 13:42:32 -05:00
virtual ~ LabelBase ( ) { }
2009-02-10 11:21:13 -05:00
void run ( ) {
ASSERT ( ! expected ( ) . woCompare ( actual ( ) ) ) ;
}
protected :
virtual BSONObj expected ( ) = 0 ;
virtual BSONObj actual ( ) = 0 ;
} ;
2009-09-18 14:25:23 -04:00
2009-02-10 11:21:13 -05:00
class LabelBasic : public LabelBase {
BSONObj expected ( ) {
return BSON ( " a " < < ( BSON ( " $gt " < < 1 ) ) ) ;
}
BSONObj actual ( ) {
return BSON ( " a " < < GT < < 1 ) ;
2009-09-18 14:25:23 -04:00
}
2009-02-10 11:21:13 -05:00
} ;
class LabelShares : public LabelBase {
BSONObj expected ( ) {
return BSON ( " z " < < " q " < < " a " < < ( BSON ( " $gt " < < 1 ) ) < < " x " < < " p " ) ;
}
BSONObj actual ( ) {
return BSON ( " z " < < " q " < < " a " < < GT < < 1 < < " x " < < " p " ) ;
2009-09-18 14:25:23 -04:00
}
} ;
2009-02-10 11:21:13 -05:00
class LabelDouble : public LabelBase {
BSONObj expected ( ) {
return BSON ( " a " < < ( BSON ( " $gt " < < 1 < < " $lte " < < " x " ) ) ) ;
}
BSONObj actual ( ) {
return BSON ( " a " < < GT < < 1 < < LTE < < " x " ) ;
2009-09-18 14:25:23 -04:00
}
} ;
2009-02-10 11:21:13 -05:00
class LabelDoubleShares : public LabelBase {
BSONObj expected ( ) {
return BSON ( " z " < < " q " < < " a " < < ( BSON ( " $gt " < < 1 < < " $lte " < < " x " ) ) < < " x " < < " p " ) ;
}
BSONObj actual ( ) {
return BSON ( " z " < < " q " < < " a " < < GT < < 1 < < LTE < < " x " < < " x " < < " p " ) ;
2009-09-18 14:25:23 -04:00
}
} ;
2009-01-15 10:17:11 -05:00
2009-03-27 13:31:13 -04:00
class LabelSize : public LabelBase {
BSONObj expected ( ) {
return BSON ( " a " < < BSON ( " $size " < < 4 ) ) ;
}
BSONObj actual ( ) {
2009-09-18 14:26:15 -04:00
return BSON ( " a " < < mongo : : SIZE < < 4 ) ;
2009-09-18 14:25:23 -04:00
}
} ;
2009-02-10 11:21:13 -05:00
class LabelMulti : public LabelBase {
BSONObj expected ( ) {
return BSON ( " z " < < " q "
2011-01-04 00:40:41 -05:00
< < " a " < < BSON ( " $gt " < < 1 < < " $lte " < < " x " )
< < " b " < < BSON ( " $ne " < < 1 < < " $ne " < < " f " < < " $ne " < < 22.3 )
< < " x " < < " p " ) ;
2009-02-10 11:21:13 -05:00
}
BSONObj actual ( ) {
return BSON ( " z " < < " q "
2011-01-04 00:40:41 -05:00
< < " a " < < GT < < 1 < < LTE < < " x "
< < " b " < < NE < < 1 < < NE < < " f " < < NE < < 22.3
< < " x " < < " p " ) ;
2009-09-18 14:25:23 -04:00
}
} ;
2010-07-19 13:28:26 -04:00
class LabelishOr : public LabelBase {
BSONObj expected ( ) {
return BSON ( " $or " < < BSON_ARRAY (
2011-01-04 00:40:41 -05:00
BSON ( " a " < < BSON ( " $gt " < < 1 < < " $lte " < < " x " ) )
< < BSON ( " b " < < BSON ( " $ne " < < 1 < < " $ne " < < " f " < < " $ne " < < 22.3 ) )
< < BSON ( " x " < < " p " ) ) ) ;
2010-07-19 13:28:26 -04:00
}
BSONObj actual ( ) {
2011-01-04 00:40:41 -05:00
return OR ( BSON ( " a " < < GT < < 1 < < LTE < < " x " ) ,
2010-07-19 13:28:26 -04:00
BSON ( " b " < < NE < < 1 < < NE < < " f " < < NE < < 22.3 ) ,
BSON ( " x " < < " p " ) ) ;
}
} ;
2009-09-18 14:25:23 -04:00
2009-02-10 11:21:13 -05:00
class Unallowed {
public :
void run ( ) {
2011-12-03 08:51:32 -05:00
ASSERT_THROWS ( BSON ( GT < < 4 ) , MsgAssertionException ) ;
ASSERT_THROWS ( BSON ( " a " < < 1 < < GT < < 4 ) , MsgAssertionException ) ;
2009-02-10 11:21:13 -05:00
}
} ;
2009-09-18 14:25:23 -04:00
2009-06-13 23:30:03 -04:00
class ElementAppend {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-06-13 23:30:03 -04:00
BSONObj a = BSON ( " a " < < 17 ) ;
BSONObj b = BSON ( " b " < < a [ " a " ] ) ;
ASSERT_EQUALS ( NumberInt , a [ " a " ] . type ( ) ) ;
ASSERT_EQUALS ( NumberInt , b [ " b " ] . type ( ) ) ;
ASSERT_EQUALS ( 17 , b [ " b " ] . number ( ) ) ;
}
} ;
2009-09-18 14:25:23 -04:00
2009-02-10 11:21:13 -05:00
} // namespace ValueStreamTests
2009-09-18 14:25:23 -04:00
2009-03-25 18:24:22 -04:00
class SubObjectBuilder {
public :
void run ( ) {
BSONObjBuilder b1 ;
b1 . append ( " a " , " bcd " ) ;
BSONObjBuilder b2 ( b1 . subobjStart ( " foo " ) ) ;
b2 . append ( " ggg " , 44.0 ) ;
b2 . done ( ) ;
b1 . append ( " f " , 10.0 ) ;
BSONObj ret = b1 . done ( ) ;
ASSERT ( ret . valid ( ) ) ;
ASSERT ( ret . woCompare ( fromjson ( " {a:'bcd',foo:{ggg:44},f:10} " ) ) = = 0 ) ;
}
2009-08-10 17:08:43 -04:00
} ;
2009-12-03 17:25:22 -05:00
class DateBuilder {
public :
void run ( ) {
BSONObj o = BSON ( " " < < Date_t ( 1234567890 ) ) ;
ASSERT ( o . firstElement ( ) . type ( ) = = Date ) ;
ASSERT ( o . firstElement ( ) . date ( ) = = Date_t ( 1234567890 ) ) ;
}
} ;
2009-10-13 12:33:25 -04:00
class DateNowBuilder {
public :
void run ( ) {
2009-12-03 17:25:22 -05:00
Date_t before = jsTime ( ) ;
2009-10-13 12:33:25 -04:00
BSONObj o = BSON ( " now " < < DATENOW ) ;
2009-12-03 17:25:22 -05:00
Date_t after = jsTime ( ) ;
2009-10-13 12:33:25 -04:00
ASSERT ( o . valid ( ) ) ;
BSONElement e = o [ " now " ] ;
ASSERT ( e . type ( ) = = Date ) ;
ASSERT ( e . date ( ) > = before ) ;
ASSERT ( e . date ( ) < = after ) ;
}
} ;
2009-10-15 13:59:30 -04:00
class TimeTBuilder {
public :
void run ( ) {
2009-12-03 17:25:22 -05:00
Date_t before = jsTime ( ) ;
2010-03-15 19:18:01 -04:00
sleepmillis ( 1 ) ;
2009-10-15 13:59:30 -04:00
time_t now = time ( NULL ) ;
2010-03-15 19:18:01 -04:00
sleepmillis ( 1 ) ;
2009-12-03 17:25:22 -05:00
Date_t after = jsTime ( ) ;
2009-10-15 13:59:30 -04:00
2009-10-15 15:23:53 -04:00
BSONObjBuilder b ;
b . appendTimeT ( " now " , now ) ;
BSONObj o = b . obj ( ) ;
2009-10-15 13:59:30 -04:00
ASSERT ( o . valid ( ) ) ;
BSONElement e = o [ " now " ] ;
ASSERT ( e . type ( ) = = Date ) ;
ASSERT ( e . date ( ) / 1000 > = before / 1000 ) ;
ASSERT ( e . date ( ) / 1000 < = after / 1000 ) ;
}
} ;
2010-11-23 11:28:49 -05:00
class MinMaxKeyBuilder {
public :
void run ( ) {
BSONObj min = BSON ( " a " < < MINKEY ) ;
BSONObj max = BSON ( " b " < < MAXKEY ) ;
ASSERT ( min . valid ( ) ) ;
ASSERT ( max . valid ( ) ) ;
BSONElement minElement = min [ " a " ] ;
BSONElement maxElement = max [ " b " ] ;
ASSERT ( minElement . type ( ) = = MinKey ) ;
ASSERT ( maxElement . type ( ) = = MaxKey ) ;
}
} ;
2009-08-10 17:08:43 -04:00
class MinMaxElementTest {
public :
2011-01-04 00:40:41 -05:00
BSONObj min ( int t ) {
2009-08-10 17:08:43 -04:00
BSONObjBuilder b ;
b . appendMinForType ( " a " , t ) ;
return b . obj ( ) ;
}
2011-01-04 00:40:41 -05:00
BSONObj max ( int t ) {
2009-08-10 17:08:43 -04:00
BSONObjBuilder b ;
b . appendMaxForType ( " a " , t ) ;
return b . obj ( ) ;
}
2011-01-04 00:40:41 -05:00
void run ( ) {
for ( int t = 1 ; t < JSTypeMax ; t + + ) {
2009-09-09 11:51:23 -04:00
stringstream ss ;
ss < < " type: " < < t ;
string s = ss . str ( ) ;
2011-06-21 10:12:04 -07:00
ASSERT ( min ( t ) . woCompare ( max ( t ) ) < = 0 ) ;
ASSERT ( max ( t ) . woCompare ( min ( t ) ) > = 0 ) ;
ASSERT ( min ( t ) . woCompare ( min ( t ) ) = = 0 ) ;
ASSERT ( max ( t ) . woCompare ( max ( t ) ) = = 0 ) ;
2009-08-10 17:08:43 -04:00
}
}
2009-03-25 18:24:22 -04:00
} ;
2009-09-18 14:25:23 -04:00
2009-09-09 12:25:02 -04:00
class ExtractFieldsTest {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-09-09 12:25:02 -04:00
BSONObj x = BSON ( " a " < < 10 < < " b " < < 11 ) ;
assert ( BSON ( " a " < < 10 ) . woCompare ( x . extractFields ( BSON ( " a " < < 1 ) ) ) = = 0 ) ;
assert ( BSON ( " b " < < 11 ) . woCompare ( x . extractFields ( BSON ( " b " < < 1 ) ) ) = = 0 ) ;
assert ( x . woCompare ( x . extractFields ( BSON ( " a " < < 1 < < " b " < < 1 ) ) ) = = 0 ) ;
2011-05-23 10:49:50 -04:00
assert ( ( string ) " a " = = x . extractFields ( BSON ( " a " < < 1 < < " c " < < 1 ) ) . firstElementFieldName ( ) ) ;
2009-09-09 12:25:02 -04:00
}
} ;
2009-09-18 14:25:23 -04:00
2009-09-09 12:25:02 -04:00
class ComparatorTest {
public :
2011-01-04 00:40:41 -05:00
BSONObj one ( string s ) {
2009-09-09 12:25:02 -04:00
return BSON ( " x " < < s ) ;
}
2011-01-04 00:40:41 -05:00
BSONObj two ( string x , string y ) {
2009-09-09 12:25:02 -04:00
BSONObjBuilder b ;
b . append ( " x " , x ) ;
if ( y . size ( ) )
b . append ( " y " , y ) ;
else
b . appendNull ( " y " ) ;
return b . obj ( ) ;
}
2009-09-18 14:25:23 -04:00
2011-01-04 00:40:41 -05:00
void test ( BSONObj order , BSONObj l , BSONObj r , bool wanted ) {
2009-09-09 12:25:02 -04:00
BSONObjCmp c ( order ) ;
bool got = c ( l , r ) ;
if ( got = = wanted )
return ;
cout < < " order: " < < order < < " l: " < < l < < " r: " < < r < < " wanted: " < < wanted < < " got: " < < got < < endl ;
}
2011-01-04 00:40:41 -05:00
void lt ( BSONObj order , BSONObj l , BSONObj r ) {
2009-09-09 12:25:02 -04:00
test ( order , l , r , 1 ) ;
}
2009-09-18 14:25:23 -04:00
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-09-09 12:25:02 -04:00
BSONObj s = BSON ( " x " < < 1 ) ;
BSONObj c = BSON ( " x " < < 1 < < " y " < < 1 ) ;
test ( s , one ( " A " ) , one ( " B " ) , 1 ) ;
test ( s , one ( " B " ) , one ( " A " ) , 0 ) ;
test ( c , two ( " A " , " A " ) , two ( " A " , " B " ) , 1 ) ;
test ( c , two ( " A " , " A " ) , two ( " B " , " A " ) , 1 ) ;
test ( c , two ( " B " , " A " ) , two ( " A " , " B " ) , 0 ) ;
lt ( c , one ( " A " ) , two ( " A " , " A " ) ) ;
lt ( c , one ( " A " ) , one ( " B " ) ) ;
lt ( c , two ( " A " , " " ) , two ( " B " , " A " ) ) ;
lt ( c , two ( " B " , " A " ) , two ( " C " , " A " ) ) ;
lt ( c , two ( " B " , " A " ) , one ( " C " ) ) ;
lt ( c , two ( " B " , " A " ) , two ( " C " , " " ) ) ;
2009-09-18 14:25:23 -04:00
2009-09-09 12:25:02 -04:00
}
} ;
2009-09-16 15:26:18 -04:00
namespace external_sort {
class Basic1 {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2011-06-16 16:35:07 -04:00
BSONObjExternalSorter sorter ( indexInterfaceForTheseTests ) ;
2009-09-16 15:26:18 -04:00
sorter . add ( BSON ( " x " < < 10 ) , 5 , 1 ) ;
sorter . add ( BSON ( " x " < < 2 ) , 3 , 1 ) ;
sorter . add ( BSON ( " x " < < 5 ) , 6 , 1 ) ;
sorter . add ( BSON ( " x " < < 5 ) , 7 , 1 ) ;
2009-09-18 14:25:23 -04:00
2009-09-16 15:26:18 -04:00
sorter . sort ( ) ;
2011-01-04 00:40:41 -05:00
2009-09-24 17:04:44 -04:00
auto_ptr < BSONObjExternalSorter : : Iterator > i = sorter . iterator ( ) ;
2009-09-16 15:26:18 -04:00
int num = 0 ;
2011-01-04 00:40:41 -05:00
while ( i - > more ( ) ) {
2009-09-24 17:04:44 -04:00
pair < BSONObj , DiskLoc > p = i - > next ( ) ;
2009-09-16 15:26:18 -04:00
if ( num = = 0 )
assert ( p . first [ " x " ] . number ( ) = = 2 ) ;
2011-01-04 00:40:41 -05:00
else if ( num < = 2 ) {
2009-09-16 15:26:18 -04:00
assert ( p . first [ " x " ] . number ( ) = = 5 ) ;
2009-09-24 11:57:45 -04:00
}
2009-09-16 15:26:18 -04:00
else if ( num = = 3 )
assert ( p . first [ " x " ] . number ( ) = = 10 ) ;
2009-09-18 14:25:23 -04:00
else
2009-09-16 15:26:18 -04:00
ASSERT ( 0 ) ;
num + + ;
}
2011-01-04 00:40:41 -05:00
2009-09-25 11:22:43 -04:00
ASSERT_EQUALS ( 0 , sorter . numFiles ( ) ) ;
2009-09-16 15:26:18 -04:00
}
} ;
class Basic2 {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2011-06-16 16:35:07 -04:00
BSONObjExternalSorter sorter ( indexInterfaceForTheseTests , BSONObj ( ) , 10 ) ;
2009-09-16 15:26:18 -04:00
sorter . add ( BSON ( " x " < < 10 ) , 5 , 11 ) ;
sorter . add ( BSON ( " x " < < 2 ) , 3 , 1 ) ;
sorter . add ( BSON ( " x " < < 5 ) , 6 , 1 ) ;
sorter . add ( BSON ( " x " < < 5 ) , 7 , 1 ) ;
2009-09-18 14:25:23 -04:00
2009-09-16 15:26:18 -04:00
sorter . sort ( ) ;
2011-01-04 00:40:41 -05:00
2009-09-24 17:04:44 -04:00
auto_ptr < BSONObjExternalSorter : : Iterator > i = sorter . iterator ( ) ;
2009-09-16 15:26:18 -04:00
int num = 0 ;
2011-01-04 00:40:41 -05:00
while ( i - > more ( ) ) {
2009-09-24 17:04:44 -04:00
pair < BSONObj , DiskLoc > p = i - > next ( ) ;
2011-01-04 00:40:41 -05:00
if ( num = = 0 ) {
2009-09-16 15:26:18 -04:00
assert ( p . first [ " x " ] . number ( ) = = 2 ) ;
ASSERT_EQUALS ( p . second . toString ( ) , " 3:1 " ) ;
}
else if ( num < = 2 )
assert ( p . first [ " x " ] . number ( ) = = 5 ) ;
2011-01-04 00:40:41 -05:00
else if ( num = = 3 ) {
2009-09-16 15:26:18 -04:00
assert ( p . first [ " x " ] . number ( ) = = 10 ) ;
ASSERT_EQUALS ( p . second . toString ( ) , " 5:b " ) ;
}
2009-09-18 14:25:23 -04:00
else
2009-09-16 15:26:18 -04:00
ASSERT ( 0 ) ;
num + + ;
}
2009-09-18 14:25:23 -04:00
2009-09-16 15:26:18 -04:00
}
} ;
class Basic3 {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2011-06-16 16:35:07 -04:00
BSONObjExternalSorter sorter ( indexInterfaceForTheseTests , BSONObj ( ) , 10 ) ;
2009-09-16 15:26:18 -04:00
sorter . sort ( ) ;
2009-09-24 17:04:44 -04:00
auto_ptr < BSONObjExternalSorter : : Iterator > i = sorter . iterator ( ) ;
assert ( ! i - > more ( ) ) ;
2009-09-18 14:25:23 -04:00
2009-09-16 15:26:18 -04:00
}
} ;
2009-09-24 11:57:45 -04:00
class ByDiskLock {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2011-06-16 16:35:07 -04:00
BSONObjExternalSorter sorter ( indexInterfaceForTheseTests ) ;
2009-09-24 11:57:45 -04:00
sorter . add ( BSON ( " x " < < 10 ) , 5 , 4 ) ;
sorter . add ( BSON ( " x " < < 2 ) , 3 , 0 ) ;
sorter . add ( BSON ( " x " < < 5 ) , 6 , 2 ) ;
sorter . add ( BSON ( " x " < < 5 ) , 7 , 3 ) ;
sorter . add ( BSON ( " x " < < 5 ) , 2 , 1 ) ;
2011-01-04 00:40:41 -05:00
2009-09-24 11:57:45 -04:00
sorter . sort ( ) ;
2009-09-24 17:04:44 -04:00
auto_ptr < BSONObjExternalSorter : : Iterator > i = sorter . iterator ( ) ;
2009-09-24 11:57:45 -04:00
int num = 0 ;
2011-01-04 00:40:41 -05:00
while ( i - > more ( ) ) {
2009-09-24 17:04:44 -04:00
pair < BSONObj , DiskLoc > p = i - > next ( ) ;
2009-09-24 11:57:45 -04:00
if ( num = = 0 )
assert ( p . first [ " x " ] . number ( ) = = 2 ) ;
2011-01-04 00:40:41 -05:00
else if ( num < = 3 ) {
2009-09-24 11:57:45 -04:00
assert ( p . first [ " x " ] . number ( ) = = 5 ) ;
}
else if ( num = = 4 )
assert ( p . first [ " x " ] . number ( ) = = 10 ) ;
else
ASSERT ( 0 ) ;
ASSERT_EQUALS ( num , p . second . getOfs ( ) ) ;
num + + ;
}
}
} ;
2009-09-16 15:26:18 -04:00
class Big1 {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2011-06-16 16:35:07 -04:00
BSONObjExternalSorter sorter ( indexInterfaceForTheseTests , BSONObj ( ) , 2000 ) ;
2011-01-04 00:40:41 -05:00
for ( int i = 0 ; i < 10000 ; i + + ) {
2009-09-16 15:26:18 -04:00
sorter . add ( BSON ( " x " < < rand ( ) % 10000 ) , 5 , i ) ;
}
2009-09-18 14:25:23 -04:00
2009-09-16 15:26:18 -04:00
sorter . sort ( ) ;
2009-09-18 14:25:23 -04:00
2009-09-24 17:04:44 -04:00
auto_ptr < BSONObjExternalSorter : : Iterator > i = sorter . iterator ( ) ;
2009-09-16 15:26:18 -04:00
int num = 0 ;
double prev = 0 ;
2011-01-04 00:40:41 -05:00
while ( i - > more ( ) ) {
2009-09-24 17:04:44 -04:00
pair < BSONObj , DiskLoc > p = i - > next ( ) ;
2009-09-16 15:26:18 -04:00
num + + ;
double cur = p . first [ " x " ] . number ( ) ;
assert ( cur > = prev ) ;
prev = cur ;
}
assert ( num = = 10000 ) ;
}
} ;
2011-01-04 00:40:41 -05:00
2009-09-25 11:11:48 -04:00
class Big2 {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-09-25 11:11:48 -04:00
const int total = 100000 ;
2011-06-16 16:35:07 -04:00
BSONObjExternalSorter sorter ( indexInterfaceForTheseTests , BSONObj ( ) , total * 2 ) ;
2011-01-04 00:40:41 -05:00
for ( int i = 0 ; i < total ; i + + ) {
2009-09-25 11:11:48 -04:00
sorter . add ( BSON ( " a " < < " b " ) , 5 , i ) ;
}
sorter . sort ( ) ;
2011-01-04 00:40:41 -05:00
2009-09-25 11:11:48 -04:00
auto_ptr < BSONObjExternalSorter : : Iterator > i = sorter . iterator ( ) ;
int num = 0 ;
double prev = 0 ;
2011-01-04 00:40:41 -05:00
while ( i - > more ( ) ) {
2009-09-25 11:11:48 -04:00
pair < BSONObj , DiskLoc > p = i - > next ( ) ;
num + + ;
double cur = p . first [ " x " ] . number ( ) ;
assert ( cur > = prev ) ;
prev = cur ;
}
assert ( num = = total ) ;
2009-09-25 11:22:43 -04:00
ASSERT ( sorter . numFiles ( ) > 2 ) ;
2009-09-25 11:11:48 -04:00
}
} ;
2009-09-16 15:26:18 -04:00
2009-09-24 17:17:11 -04:00
class D1 {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-09-24 17:17:11 -04:00
BSONObjBuilder b ;
b . appendNull ( " " ) ;
BSONObj x = b . obj ( ) ;
2011-01-04 00:40:41 -05:00
2011-06-16 16:35:07 -04:00
BSONObjExternalSorter sorter ( indexInterfaceForTheseTests ) ;
2009-09-24 17:17:11 -04:00
sorter . add ( x , DiskLoc ( 3 , 7 ) ) ;
sorter . add ( x , DiskLoc ( 4 , 7 ) ) ;
sorter . add ( x , DiskLoc ( 2 , 7 ) ) ;
sorter . add ( x , DiskLoc ( 1 , 7 ) ) ;
sorter . add ( x , DiskLoc ( 3 , 77 ) ) ;
2011-01-04 00:40:41 -05:00
2009-09-24 17:17:11 -04:00
sorter . sort ( ) ;
2011-01-04 00:40:41 -05:00
2009-09-24 17:17:11 -04:00
auto_ptr < BSONObjExternalSorter : : Iterator > i = sorter . iterator ( ) ;
while ( i - > more ( ) ) {
BSONObjExternalSorter : : Data d = i - > next ( ) ;
2010-05-25 21:53:55 -04:00
/*cout << d.second.toString() << endl;
2009-09-24 17:17:11 -04:00
cout < < d . first . objsize ( ) < < endl ;
2010-05-25 21:53:55 -04:00
cout < < " SORTER next: " < < d . first . toString ( ) < < endl ; */
2009-09-24 17:17:11 -04:00
}
}
} ;
}
2011-01-04 00:40:41 -05:00
2009-10-05 21:08:00 -04:00
class CompatBSON {
public :
2011-01-04 00:40:41 -05:00
2009-10-07 15:47:53 -04:00
# define JSONBSONTEST(j,s,m) ASSERT_EQUALS( fromjson( j ).objsize() , s ); ASSERT_EQUALS( fromjson( j ).md5() , m );
# define RAWBSONTEST(j,s,m) ASSERT_EQUALS( j.objsize() , s ); ASSERT_EQUALS( j.md5() , m );
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-10-07 15:47:53 -04:00
JSONBSONTEST ( " { 'x' : true } " , 9 , " 6fe24623e4efc5cf07f027f9c66b5456 " ) ;
JSONBSONTEST ( " { 'x' : null } " , 8 , " 12d43430ff6729af501faf0638e68888 " ) ;
JSONBSONTEST ( " { 'x' : 5.2 } " , 16 , " aaeeac4a58e9c30eec6b0b0319d0dff2 " ) ;
JSONBSONTEST ( " { 'x' : 'eliot' } " , 18 , " 331a3b8b7cbbe0706c80acdb45d4ebbe " ) ;
JSONBSONTEST ( " { 'x' : 5.2 , 'y' : 'truth' , 'z' : 1.1 } " , 40 , " 7c77b3a6e63e2f988ede92624409da58 " ) ;
JSONBSONTEST ( " { 'a' : { 'b' : 1.1 } } " , 24 , " 31887a4b9d55cd9f17752d6a8a45d51f " ) ;
JSONBSONTEST ( " { 'x' : 5.2 , 'y' : { 'a' : 'eliot' , b : true } , 'z' : null } " , 44 , " b3de8a0739ab329e7aea138d87235205 " ) ;
JSONBSONTEST ( " { 'x' : 5.2 , 'y' : [ 'a' , 'eliot' , 'b' , true ] , 'z' : null } " , 62 , " cb7bad5697714ba0cbf51d113b6a0ee8 " ) ;
2011-01-04 00:40:41 -05:00
2009-10-07 15:47:53 -04:00
RAWBSONTEST ( BSON ( " x " < < 4 ) , 12 , " d1ed8dbf79b78fa215e2ded74548d89d " ) ;
2011-01-04 00:40:41 -05:00
2009-10-05 21:08:00 -04:00
}
} ;
2011-01-04 00:40:41 -05:00
2009-10-16 23:41:21 -04:00
class CompareDottedFieldNamesTest {
public :
2011-01-04 00:40:41 -05:00
void t ( FieldCompareResult res , const string & l , const string & r ) {
2009-10-16 23:41:21 -04:00
ASSERT_EQUALS ( res , compareDottedFieldNames ( l , r ) ) ;
ASSERT_EQUALS ( - 1 * res , compareDottedFieldNames ( r , l ) ) ;
}
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-10-16 23:41:21 -04:00
t ( SAME , " x " , " x " ) ;
t ( SAME , " x.a " , " x.a " ) ;
t ( LEFT_BEFORE , " a " , " b " ) ;
t ( RIGHT_BEFORE , " b " , " a " ) ;
t ( LEFT_SUBFIELD , " a.x " , " a " ) ;
}
} ;
2009-11-02 13:30:59 -05:00
2011-01-04 00:40:41 -05:00
struct NestedDottedConversions {
void t ( const BSONObj & nest , const BSONObj & dot ) {
2009-11-02 13:30:59 -05:00
ASSERT_EQUALS ( nested2dotted ( nest ) , dot ) ;
ASSERT_EQUALS ( nest , dotted2nested ( dot ) ) ;
}
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-11-02 13:30:59 -05:00
t ( BSON ( " a " < < BSON ( " b " < < 1 ) ) , BSON ( " a.b " < < 1 ) ) ;
t ( BSON ( " a " < < BSON ( " b " < < 1 < < " c " < < 1 ) ) , BSON ( " a.b " < < 1 < < " a.c " < < 1 ) ) ;
t ( BSON ( " a " < < BSON ( " b " < < 1 < < " c " < < 1 ) < < " d " < < 1 ) , BSON ( " a.b " < < 1 < < " a.c " < < 1 < < " d " < < 1 ) ) ;
t ( BSON ( " a " < < BSON ( " b " < < 1 < < " c " < < 1 < < " e " < < BSON ( " f " < < 1 ) ) < < " d " < < 1 ) , BSON ( " a.b " < < 1 < < " a.c " < < 1 < < " a.e.f " < < 1 < < " d " < < 1 ) ) ;
}
} ;
2009-11-05 12:29:27 -05:00
2011-01-04 00:40:41 -05:00
struct BSONArrayBuilderTest {
void run ( ) {
2009-11-05 12:29:27 -05:00
int i = 0 ;
2009-11-05 12:55:33 -05:00
BSONObjBuilder objb ;
BSONArrayBuilder arrb ;
2009-11-05 12:29:27 -05:00
2009-11-05 12:55:33 -05:00
objb < < objb . numStr ( i + + ) < < 100 ;
arrb < < 100 ;
2009-11-05 12:29:27 -05:00
2009-11-05 12:55:33 -05:00
objb < < objb . numStr ( i + + ) < < 1.0 ;
arrb < < 1.0 ;
2009-11-05 12:29:27 -05:00
2009-11-05 12:55:33 -05:00
objb < < objb . numStr ( i + + ) < < " Hello " ;
arrb < < " Hello " ;
2009-11-05 12:29:27 -05:00
2009-11-05 12:55:33 -05:00
objb < < objb . numStr ( i + + ) < < string ( " World " ) ;
arrb < < string ( " World " ) ;
2009-11-05 12:29:27 -05:00
2009-11-05 12:55:33 -05:00
objb < < objb . numStr ( i + + ) < < BSON ( " a " < < 1 < < " b " < < " foo " ) ;
arrb < < BSON ( " a " < < 1 < < " b " < < " foo " ) ;
2009-11-05 12:29:27 -05:00
2009-11-05 12:55:33 -05:00
objb < < objb . numStr ( i + + ) < < BSON ( " a " < < 1 ) [ " a " ] ;
arrb < < BSON ( " a " < < 1 ) [ " a " ] ;
2009-11-05 12:29:27 -05:00
OID oid ;
oid . init ( ) ;
2009-11-05 12:55:33 -05:00
objb < < objb . numStr ( i + + ) < < oid ;
arrb < < oid ;
2009-11-05 12:29:27 -05:00
2009-11-05 12:55:33 -05:00
BSONObj obj = objb . obj ( ) ;
BSONArray arr = arrb . arr ( ) ;
ASSERT_EQUALS ( obj , arr ) ;
BSONObj o = BSON ( " obj " < < obj < < " arr " < < arr < < " arr2 " < < BSONArray ( obj ) ) ;
2011-04-12 17:09:08 -04:00
keyTest ( o ) ;
2009-11-05 12:55:33 -05:00
ASSERT_EQUALS ( o [ " obj " ] . type ( ) , Object ) ;
ASSERT_EQUALS ( o [ " arr " ] . type ( ) , Array ) ;
ASSERT_EQUALS ( o [ " arr2 " ] . type ( ) , Array ) ;
2009-11-05 12:29:27 -05:00
}
} ;
2011-01-04 00:40:41 -05:00
struct ArrayMacroTest {
void run ( ) {
2009-11-05 13:19:35 -05:00
BSONArray arr = BSON_ARRAY ( " hello " < < 1 < < BSON ( " foo " < < BSON_ARRAY ( " bar " < < " baz " < < " qux " ) ) ) ;
BSONObj obj = BSON ( " 0 " < < " hello "
2011-01-04 00:40:41 -05:00
< < " 1 " < < 1
< < " 2 " < < BSON ( " foo " < < BSON_ARRAY ( " bar " < < " baz " < < " qux " ) ) ) ;
2009-11-05 13:19:35 -05:00
ASSERT_EQUALS ( arr , obj ) ;
ASSERT_EQUALS ( arr [ " 2 " ] . type ( ) , Object ) ;
ASSERT_EQUALS ( arr [ " 2 " ] . embeddedObject ( ) [ " foo " ] . type ( ) , Array ) ;
}
} ;
2009-11-13 21:07:15 -05:00
class NumberParsing {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-11-13 21:07:15 -05:00
BSONObjBuilder a ;
BSONObjBuilder b ;
a . append ( " a " , ( int ) 1 ) ;
ASSERT ( b . appendAsNumber ( " a " , " 1 " ) ) ;
2011-01-04 00:40:41 -05:00
2009-11-13 21:07:15 -05:00
a . append ( " b " , 1.1 ) ;
ASSERT ( b . appendAsNumber ( " b " , " 1.1 " ) ) ;
a . append ( " c " , ( int ) - 1 ) ;
ASSERT ( b . appendAsNumber ( " c " , " -1 " ) ) ;
2011-01-04 00:40:41 -05:00
2009-11-13 21:07:15 -05:00
a . append ( " d " , - 1.1 ) ;
ASSERT ( b . appendAsNumber ( " d " , " -1.1 " ) ) ;
2009-11-13 21:19:38 -05:00
a . append ( " e " , ( long long ) 32131231231232313LL ) ;
2009-11-13 21:07:15 -05:00
ASSERT ( b . appendAsNumber ( " e " , " 32131231231232313 " ) ) ;
2011-01-04 00:40:41 -05:00
2009-11-13 21:07:15 -05:00
ASSERT ( ! b . appendAsNumber ( " f " , " zz " ) ) ;
ASSERT ( ! b . appendAsNumber ( " f " , " 5zz " ) ) ;
ASSERT ( ! b . appendAsNumber ( " f " , " zz5 " ) ) ;
ASSERT_EQUALS ( a . obj ( ) , b . obj ( ) ) ;
}
} ;
2011-01-04 00:40:41 -05:00
2009-12-18 01:50:43 -05:00
class bson2settest {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2009-12-18 01:50:43 -05:00
BSONObj o = BSON ( " z " < < 1 < < " a " < < 2 < < " m " < < 3 < < " c " < < 4 ) ;
BSONObjIteratorSorted i ( o ) ;
stringstream ss ;
while ( i . more ( ) )
ss < < i . next ( ) . fieldName ( ) ;
ASSERT_EQUALS ( " acmz " , ss . str ( ) ) ;
{
Timer t ;
2011-01-04 00:40:41 -05:00
for ( int i = 0 ; i < 10000 ; i + + ) {
2009-12-18 01:50:43 -05:00
BSONObjIteratorSorted j ( o ) ;
int l = 0 ;
while ( j . more ( ) )
l + = strlen ( j . next ( ) . fieldName ( ) ) ;
}
2011-05-27 01:06:25 -04:00
//unsigned long long tm = t.micros();
2011-05-25 16:13:47 -04:00
//cout << "time: " << tm << endl;
2009-12-18 01:50:43 -05:00
}
}
} ;
2009-11-13 21:07:15 -05:00
2010-01-16 11:08:32 -05:00
class checkForStorageTests {
public :
2011-01-04 00:40:41 -05:00
void good ( string s ) {
2010-01-16 11:08:32 -05:00
BSONObj o = fromjson ( s ) ;
if ( o . okForStorage ( ) )
return ;
throw UserException ( 12528 , ( string ) " should be ok for storage: " + s ) ;
}
2011-01-04 00:40:41 -05:00
void bad ( string s ) {
2010-01-16 11:08:32 -05:00
BSONObj o = fromjson ( s ) ;
if ( ! o . okForStorage ( ) )
return ;
throw UserException ( 12529 , ( string ) " should NOT be ok for storage: " + s ) ;
}
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-01-16 11:08:32 -05:00
good ( " {x:1} " ) ;
bad ( " {'x.y':1} " ) ;
good ( " {x:{a:2}} " ) ;
bad ( " {x:{'$a':2}} " ) ;
}
} ;
2010-01-26 10:03:30 -05:00
class InvalidIDFind {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-01-26 10:03:30 -05:00
BSONObj x = BSON ( " _id " < < 5 < < " t " < < 2 ) ;
{
char * crap = ( char * ) malloc ( x . objsize ( ) ) ;
memcpy ( crap , x . objdata ( ) , x . objsize ( ) ) ;
2011-04-01 17:35:11 -04:00
BSONObj y ( crap ) ;
2010-01-26 10:03:30 -05:00
ASSERT_EQUALS ( x , y ) ;
free ( crap ) ;
}
2011-01-04 00:40:41 -05:00
2010-01-26 10:03:30 -05:00
{
char * crap = ( char * ) malloc ( x . objsize ( ) ) ;
memcpy ( crap , x . objdata ( ) , x . objsize ( ) ) ;
int * foo = ( int * ) crap ;
foo [ 0 ] = 123123123 ;
int state = 0 ;
try {
2011-04-01 17:35:11 -04:00
BSONObj y ( crap ) ;
2010-01-26 10:03:30 -05:00
state = 1 ;
}
2011-01-04 00:40:41 -05:00
catch ( std : : exception & e ) {
2010-01-26 10:03:30 -05:00
state = 2 ;
ASSERT ( strstr ( e . what ( ) , " _id: 5 " ) > 0 ) ;
}
free ( crap ) ;
ASSERT_EQUALS ( 2 , state ) ;
}
2011-01-04 00:40:41 -05:00
2010-01-26 10:03:30 -05:00
}
} ;
2010-02-27 21:53:28 -05:00
class ElementSetTest {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-02-27 21:53:28 -05:00
BSONObj x = BSON ( " a " < < 1 < < " b " < < 1 < < " c " < < 2 ) ;
BSONElement a = x [ " a " ] ;
BSONElement b = x [ " b " ] ;
BSONElement c = x [ " c " ] ;
2011-05-25 16:13:47 -04:00
//cout << "c: " << c << endl;
2010-02-27 21:53:28 -05:00
ASSERT ( a . woCompare ( b ) ! = 0 ) ;
ASSERT ( a . woCompare ( b , false ) = = 0 ) ;
2011-01-04 00:40:41 -05:00
2010-02-27 21:53:28 -05:00
BSONElementSet s ;
s . insert ( a ) ;
ASSERT_EQUALS ( 1U , s . size ( ) ) ;
s . insert ( b ) ;
ASSERT_EQUALS ( 1U , s . size ( ) ) ;
ASSERT ( ! s . count ( c ) ) ;
ASSERT ( s . find ( a ) ! = s . end ( ) ) ;
ASSERT ( s . find ( b ) ! = s . end ( ) ) ;
ASSERT ( s . find ( c ) = = s . end ( ) ) ;
2011-01-04 00:40:41 -05:00
2010-02-27 21:53:28 -05:00
s . insert ( c ) ;
ASSERT_EQUALS ( 2U , s . size ( ) ) ;
ASSERT ( s . find ( a ) ! = s . end ( ) ) ;
ASSERT ( s . find ( b ) ! = s . end ( ) ) ;
ASSERT ( s . find ( c ) ! = s . end ( ) ) ;
ASSERT ( s . count ( a ) ) ;
ASSERT ( s . count ( b ) ) ;
ASSERT ( s . count ( c ) ) ;
2010-12-19 01:36:41 -05:00
{
BSONElementSet x ;
BSONObj o = fromjson ( " { 'a' : [ 1 , 2 , 1 ] } " ) ;
BSONObjIterator i ( o [ " a " ] . embeddedObjectUserCheck ( ) ) ;
2011-01-04 00:40:41 -05:00
while ( i . more ( ) ) {
2010-12-19 01:36:41 -05:00
x . insert ( i . next ( ) ) ;
}
ASSERT_EQUALS ( 2U , x . size ( ) ) ;
}
2010-02-27 21:53:28 -05:00
}
} ;
2010-03-31 12:27:10 -04:00
class EmbeddedNumbers {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-03-31 12:27:10 -04:00
BSONObj x = BSON ( " a " < < BSON ( " b " < < 1 ) ) ;
BSONObj y = BSON ( " a " < < BSON ( " b " < < 1.0 ) ) ;
2011-04-12 17:09:08 -04:00
keyTest ( x ) ; keyTest ( y ) ;
2010-03-31 12:27:10 -04:00
ASSERT_EQUALS ( x , y ) ;
ASSERT_EQUALS ( 0 , x . woCompare ( y ) ) ;
}
} ;
2010-04-21 15:02:37 -04:00
class BuilderPartialItearte {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-04-21 15:02:37 -04:00
{
BSONObjBuilder b ;
b . append ( " x " , 1 ) ;
b . append ( " y " , 2 ) ;
2011-01-04 00:40:41 -05:00
2010-04-21 15:02:37 -04:00
BSONObjIterator i = b . iterator ( ) ;
ASSERT ( i . more ( ) ) ;
ASSERT_EQUALS ( 1 , i . next ( ) . numberInt ( ) ) ;
ASSERT ( i . more ( ) ) ;
ASSERT_EQUALS ( 2 , i . next ( ) . numberInt ( ) ) ;
ASSERT ( ! i . more ( ) ) ;
b . append ( " z " , 3 ) ;
i = b . iterator ( ) ;
ASSERT ( i . more ( ) ) ;
ASSERT_EQUALS ( 1 , i . next ( ) . numberInt ( ) ) ;
ASSERT ( i . more ( ) ) ;
ASSERT_EQUALS ( 2 , i . next ( ) . numberInt ( ) ) ;
ASSERT ( i . more ( ) ) ;
ASSERT_EQUALS ( 3 , i . next ( ) . numberInt ( ) ) ;
ASSERT ( ! i . more ( ) ) ;
ASSERT_EQUALS ( BSON ( " x " < < 1 < < " y " < < 2 < < " z " < < 3 ) , b . obj ( ) ) ;
}
2011-01-04 00:40:41 -05:00
2010-04-21 15:02:37 -04:00
}
} ;
2010-06-21 11:18:33 -04:00
class BSONFieldTests {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-06-21 11:18:33 -04:00
{
BSONField < int > x ( " x " ) ;
BSONObj o = BSON ( x < < 5 ) ;
ASSERT_EQUALS ( BSON ( " x " < < 5 ) , o ) ;
}
{
BSONField < int > x ( " x " ) ;
BSONObj o = BSON ( x . make ( 5 ) ) ;
ASSERT_EQUALS ( BSON ( " x " < < 5 ) , o ) ;
}
{
BSONField < int > x ( " x " ) ;
BSONObj o = BSON ( x ( 5 ) ) ;
ASSERT_EQUALS ( BSON ( " x " < < 5 ) , o ) ;
o = BSON ( x . gt ( 5 ) ) ;
ASSERT_EQUALS ( BSON ( " x " < < BSON ( " $gt " < < 5 ) ) , o ) ;
}
}
} ;
2010-07-14 14:47:16 -04:00
class BSONForEachTest {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-07-14 14:47:16 -04:00
BSONObj obj = BSON ( " a " < < 1 < < " a " < < 2 < < " a " < < 3 ) ;
2011-01-04 00:40:41 -05:00
2010-07-14 14:47:16 -04:00
int count = 0 ;
2011-01-04 00:40:41 -05:00
BSONForEach ( e , obj ) {
2010-07-14 14:47:16 -04:00
ASSERT_EQUALS ( e . fieldName ( ) , string ( " a " ) ) ;
count + = e . Int ( ) ;
}
ASSERT_EQUALS ( count , 1 + 2 + 3 ) ;
}
} ;
2010-07-14 18:15:18 -04:00
class StringDataTest {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-07-14 18:15:18 -04:00
StringData a ( string ( " aaa " ) ) ;
2010-07-18 15:04:01 -04:00
ASSERT_EQUALS ( 3u , a . size ( ) ) ;
2010-07-14 18:15:18 -04:00
StringData b ( string ( " bbb " ) . c_str ( ) ) ;
2010-07-18 15:04:01 -04:00
ASSERT_EQUALS ( 3u , b . size ( ) ) ;
2010-07-14 18:15:18 -04:00
2010-07-19 19:06:41 -04:00
StringData c ( " ccc " , StringData : : LiteralTag ( ) ) ;
2010-07-18 15:04:01 -04:00
ASSERT_EQUALS ( 3u , c . size ( ) ) ;
2010-07-19 19:06:41 -04:00
2010-07-22 21:18:28 -04:00
// TODO update test when second parm takes StringData too
BSONObjBuilder builder ;
builder . append ( c , " value " ) ;
ASSERT_EQUALS ( builder . obj ( ) , BSON ( c . data ( ) < < " value " ) ) ;
2010-07-14 18:15:18 -04:00
}
} ;
2010-07-20 23:16:48 -04:00
class CompareOps {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-07-20 23:16:48 -04:00
BSONObj a = BSON ( " a " < < 1 ) ;
BSONObj b = BSON ( " a " < < 1 ) ;
BSONObj c = BSON ( " a " < < 2 ) ;
BSONObj d = BSON ( " a " < < 3 ) ;
BSONObj e = BSON ( " a " < < 4 ) ;
BSONObj f = BSON ( " a " < < 4 ) ;
ASSERT ( ! ( a < b ) ) ;
ASSERT ( a < = b ) ;
ASSERT ( a < c ) ;
2011-01-04 00:40:41 -05:00
2010-07-20 23:16:48 -04:00
ASSERT ( f > d ) ;
ASSERT ( f > = e ) ;
ASSERT ( ! ( f > e ) ) ;
}
} ;
2010-07-29 01:08:20 -04:00
class HashingTest {
public :
2011-01-04 00:40:41 -05:00
void run ( ) {
2010-07-29 01:08:20 -04:00
int N = 100000 ;
2011-01-04 00:40:41 -05:00
BSONObj x = BSON ( " name " < < " eliot was here "
2010-07-29 01:08:20 -04:00
< < " x " < < 5
< < " asdasdasdas " < < " asldkasldjasldjasldjlasjdlasjdlasdasdasdasdasdasdasd " ) ;
2011-01-04 00:40:41 -05:00
2010-07-29 01:08:20 -04:00
{
2011-05-27 01:06:25 -04:00
//Timer t;
2010-07-29 01:08:20 -04:00
for ( int i = 0 ; i < N ; i + + )
x . md5 ( ) ;
2011-05-27 01:06:25 -04:00
//int millis = t.millis();
2011-05-25 16:13:47 -04:00
//cout << "md5 : " << millis << endl;
2010-07-29 01:08:20 -04:00
}
2011-01-04 00:40:41 -05:00
2010-07-29 01:08:20 -04:00
{
2011-05-27 01:06:25 -04:00
//Timer t;
2010-07-29 01:08:20 -04:00
for ( int i = 0 ; i < N ; i + + )
x . toString ( ) ;
2011-05-27 01:06:25 -04:00
//int millis = t.millis();
2011-05-25 16:13:47 -04:00
//cout << "toString : " << millis << endl;
2010-07-29 01:08:20 -04:00
}
{
2011-05-27 01:06:25 -04:00
//Timer t;
2010-07-29 01:08:20 -04:00
for ( int i = 0 ; i < N ; i + + )
checksum ( x . objdata ( ) , x . objsize ( ) ) ;
2011-05-27 01:06:25 -04:00
//int millis = t.millis();
2011-05-25 16:13:47 -04:00
//cout << "checksum : " << millis << endl;
2011-01-04 00:40:41 -05:00
}
2010-07-29 01:08:20 -04:00
}
} ;
2011-01-04 00:40:41 -05:00
2009-05-12 16:37:23 -04:00
class All : public Suite {
2009-01-15 10:17:11 -05:00
public :
2011-01-04 00:40:41 -05:00
All ( ) : Suite ( " jsobj " ) {
2009-09-17 17:23:38 -04:00
}
2009-09-18 14:25:23 -04:00
2011-01-04 00:40:41 -05:00
void setupTests ( ) {
2009-03-25 18:24:22 -04:00
add < BufBuilderBasic > ( ) ;
2009-03-24 14:32:13 -04:00
add < BSONElementBasic > ( ) ;
2011-06-01 14:57:40 -04:00
add < BSONObjTests : : NullString > ( ) ;
2009-01-15 10:17:11 -05:00
add < BSONObjTests : : Create > ( ) ;
add < BSONObjTests : : WoCompareBasic > ( ) ;
add < BSONObjTests : : NumericCompareBasic > ( ) ;
add < BSONObjTests : : WoCompareEmbeddedObject > ( ) ;
add < BSONObjTests : : WoCompareEmbeddedArray > ( ) ;
add < BSONObjTests : : WoCompareOrdered > ( ) ;
2009-02-26 11:20:19 -05:00
add < BSONObjTests : : WoCompareDifferentLength > ( ) ;
2009-02-24 18:53:34 -05:00
add < BSONObjTests : : WoSortOrder > ( ) ;
2009-09-09 09:48:37 -04:00
add < BSONObjTests : : MultiKeySortOrder > ( ) ;
2009-02-27 18:14:45 -05:00
add < BSONObjTests : : TimestampTest > ( ) ;
2009-04-07 17:58:25 -04:00
add < BSONObjTests : : Nan > ( ) ;
2010-01-28 14:24:45 -05:00
add < BSONObjTests : : AsTempObj > ( ) ;
2010-02-02 21:34:21 -05:00
add < BSONObjTests : : AppendIntOrLL > ( ) ;
2010-03-01 17:14:23 -05:00
add < BSONObjTests : : AppendNumber > ( ) ;
2010-04-05 23:48:09 -07:00
add < BSONObjTests : : ToStringArray > ( ) ;
2010-08-08 23:39:09 -04:00
add < BSONObjTests : : ToStringNumber > ( ) ;
2010-10-01 17:42:35 -07:00
add < BSONObjTests : : AppendAs > ( ) ;
add < BSONObjTests : : ArrayAppendAs > ( ) ;
2011-01-17 15:31:22 -05:00
add < BSONObjTests : : GetField > ( ) ;
2009-01-16 15:13:46 -05:00
add < BSONObjTests : : Validation : : BadType > ( ) ;
add < BSONObjTests : : Validation : : EooBeforeEnd > ( ) ;
2009-02-03 13:27:46 -05:00
add < BSONObjTests : : Validation : : Undefined > ( ) ;
2009-01-16 15:13:46 -05:00
add < BSONObjTests : : Validation : : TotalSizeTooSmall > ( ) ;
add < BSONObjTests : : Validation : : EooMissing > ( ) ;
add < BSONObjTests : : Validation : : WrongStringSize > ( ) ;
2009-01-18 13:11:43 -05:00
add < BSONObjTests : : Validation : : ZeroStringSize > ( ) ;
2009-01-21 10:58:53 -05:00
add < BSONObjTests : : Validation : : NegativeStringSize > ( ) ;
2009-01-16 15:13:46 -05:00
add < BSONObjTests : : Validation : : WrongSubobjectSize > ( ) ;
add < BSONObjTests : : Validation : : WrongDbrefNsSize > ( ) ;
add < BSONObjTests : : Validation : : NoFieldNameEnd > ( ) ;
add < BSONObjTests : : Validation : : BadRegex > ( ) ;
add < BSONObjTests : : Validation : : BadRegexOptions > ( ) ;
2009-01-18 13:11:43 -05:00
add < BSONObjTests : : Validation : : CodeWScopeSmallSize > ( ) ;
add < BSONObjTests : : Validation : : CodeWScopeZeroStrSize > ( ) ;
add < BSONObjTests : : Validation : : CodeWScopeSmallStrSize > ( ) ;
add < BSONObjTests : : Validation : : CodeWScopeNoSizeForObj > ( ) ;
add < BSONObjTests : : Validation : : CodeWScopeSmallObjSize > ( ) ;
add < BSONObjTests : : Validation : : CodeWScopeBadObject > ( ) ;
2009-01-16 15:13:46 -05:00
add < BSONObjTests : : Validation : : NoSize > ( Symbol ) ;
add < BSONObjTests : : Validation : : NoSize > ( Code ) ;
add < BSONObjTests : : Validation : : NoSize > ( String ) ;
add < BSONObjTests : : Validation : : NoSize > ( CodeWScope ) ;
add < BSONObjTests : : Validation : : NoSize > ( DBRef ) ;
add < BSONObjTests : : Validation : : NoSize > ( Object ) ;
add < BSONObjTests : : Validation : : NoSize > ( Array ) ;
add < BSONObjTests : : Validation : : NoSize > ( BinData ) ;
2009-01-17 08:57:27 -05:00
add < BSONObjTests : : Validation : : Fuzz > ( .5 ) ;
add < BSONObjTests : : Validation : : Fuzz > ( .1 ) ;
add < BSONObjTests : : Validation : : Fuzz > ( .05 ) ;
add < BSONObjTests : : Validation : : Fuzz > ( .01 ) ;
add < BSONObjTests : : Validation : : Fuzz > ( .001 ) ;
2009-01-16 14:21:46 -05:00
add < OIDTests : : init1 > ( ) ;
2009-01-17 00:20:47 -05:00
add < OIDTests : : initParse1 > ( ) ;
2009-09-15 14:50:17 -04:00
add < OIDTests : : append > ( ) ;
2009-10-29 11:58:32 -04:00
add < OIDTests : : increasing > ( ) ;
2010-04-14 19:52:21 -04:00
add < OIDTests : : ToDate > ( ) ;
add < OIDTests : : FromDate > ( ) ;
2009-02-10 11:21:13 -05:00
add < ValueStreamTests : : LabelBasic > ( ) ;
add < ValueStreamTests : : LabelShares > ( ) ;
add < ValueStreamTests : : LabelDouble > ( ) ;
add < ValueStreamTests : : LabelDoubleShares > ( ) ;
2009-03-27 13:31:13 -04:00
add < ValueStreamTests : : LabelSize > ( ) ;
2009-02-10 11:21:13 -05:00
add < ValueStreamTests : : LabelMulti > ( ) ;
2010-07-19 13:28:26 -04:00
add < ValueStreamTests : : LabelishOr > ( ) ;
add < ValueStreamTests : : Unallowed > ( ) ;
add < ValueStreamTests : : ElementAppend > ( ) ;
2009-02-10 11:21:13 -05:00
add < ValueStreamTests : : Unallowed > ( ) ;
2009-06-13 23:30:03 -04:00
add < ValueStreamTests : : ElementAppend > ( ) ;
2009-03-25 18:24:22 -04:00
add < SubObjectBuilder > ( ) ;
2009-12-03 17:25:22 -05:00
add < DateBuilder > ( ) ;
2009-10-13 12:33:25 -04:00
add < DateNowBuilder > ( ) ;
2009-10-15 13:59:30 -04:00
add < TimeTBuilder > ( ) ;
2010-11-23 11:28:49 -05:00
add < MinMaxKeyBuilder > ( ) ;
2009-08-10 17:08:43 -04:00
add < MinMaxElementTest > ( ) ;
2009-09-09 12:25:02 -04:00
add < ComparatorTest > ( ) ;
add < ExtractFieldsTest > ( ) ;
2009-09-16 15:26:18 -04:00
add < external_sort : : Basic1 > ( ) ;
add < external_sort : : Basic2 > ( ) ;
add < external_sort : : Basic3 > ( ) ;
2009-09-24 11:57:45 -04:00
add < external_sort : : ByDiskLock > ( ) ;
2009-09-16 15:26:18 -04:00
add < external_sort : : Big1 > ( ) ;
2009-09-25 11:11:48 -04:00
add < external_sort : : Big2 > ( ) ;
2009-09-24 17:17:11 -04:00
add < external_sort : : D1 > ( ) ;
2009-10-05 21:08:00 -04:00
add < CompatBSON > ( ) ;
2009-10-16 23:41:21 -04:00
add < CompareDottedFieldNamesTest > ( ) ;
2009-11-02 13:30:59 -05:00
add < NestedDottedConversions > ( ) ;
2009-11-05 12:29:27 -05:00
add < BSONArrayBuilderTest > ( ) ;
2009-11-05 13:19:35 -05:00
add < ArrayMacroTest > ( ) ;
2009-11-13 21:07:15 -05:00
add < NumberParsing > ( ) ;
2009-12-18 01:50:43 -05:00
add < bson2settest > ( ) ;
2010-01-16 11:08:32 -05:00
add < checkForStorageTests > ( ) ;
2010-01-26 10:03:30 -05:00
add < InvalidIDFind > ( ) ;
2010-02-27 21:53:28 -05:00
add < ElementSetTest > ( ) ;
2010-03-31 12:27:10 -04:00
add < EmbeddedNumbers > ( ) ;
2010-04-21 15:02:37 -04:00
add < BuilderPartialItearte > ( ) ;
2010-06-21 11:18:33 -04:00
add < BSONFieldTests > ( ) ;
2010-07-14 14:47:16 -04:00
add < BSONForEachTest > ( ) ;
2010-07-14 18:15:18 -04:00
add < StringDataTest > ( ) ;
2010-07-20 23:16:48 -04:00
add < CompareOps > ( ) ;
2010-07-29 01:08:20 -04:00
add < HashingTest > ( ) ;
2009-01-14 17:17:24 -05:00
}
2009-09-17 17:23:38 -04:00
} myall ;
2011-01-04 00:40:41 -05:00
2008-12-11 19:16:06 -05:00
} // namespace JsobjTests