210
214
s->setObject( "blah" , o );
212
216
s->invoke( "return blah.x;" , 0, 0 );
213
ASSERT_EQUALS( 17 , s->getNumber( "return" ) );
217
ASSERT_EQUALS( 17 , s->getNumber( "__returnValue" ) );
214
218
s->invoke( "return blah.y;" , 0, 0 );
215
ASSERT_EQUALS( "eliot" , s->getString( "return" ) );
219
ASSERT_EQUALS( "eliot" , s->getString( "__returnValue" ) );
217
221
s->invoke( "return this.z;" , 0, &o );
218
ASSERT_EQUALS( "sara" , s->getString( "return" ) );
222
ASSERT_EQUALS( "sara" , s->getString( "__returnValue" ) );
220
224
s->invoke( "return this.z == 'sara';" , 0, &o );
221
ASSERT_EQUALS( true , s->getBoolean( "return" ) );
225
ASSERT_EQUALS( true , s->getBoolean( "__returnValue" ) );
223
227
s->invoke( "this.z == 'sara';" , 0, &o );
224
ASSERT_EQUALS( true , s->getBoolean( "return" ) );
228
ASSERT_EQUALS( true , s->getBoolean( "__returnValue" ) );
226
230
s->invoke( "this.z == 'asara';" , 0, &o );
227
ASSERT_EQUALS( false , s->getBoolean( "return" ) );
231
ASSERT_EQUALS( false , s->getBoolean( "__returnValue" ) );
229
233
s->invoke( "return this.x == 17;" , 0, &o );
230
ASSERT_EQUALS( true , s->getBoolean( "return" ) );
234
ASSERT_EQUALS( true , s->getBoolean( "__returnValue" ) );
232
236
s->invoke( "return this.x == 18;" , 0, &o );
233
ASSERT_EQUALS( false , s->getBoolean( "return" ) );
237
ASSERT_EQUALS( false , s->getBoolean( "__returnValue" ) );
235
239
s->invoke( "function(){ return this.x == 17; }" , 0, &o );
236
ASSERT_EQUALS( true , s->getBoolean( "return" ) );
240
ASSERT_EQUALS( true , s->getBoolean( "__returnValue" ) );
238
242
s->invoke( "function(){ return this.x == 18; }" , 0, &o );
239
ASSERT_EQUALS( false , s->getBoolean( "return" ) );
243
ASSERT_EQUALS( false , s->getBoolean( "__returnValue" ) );
241
245
s->invoke( "function (){ return this.x == 17; }" , 0, &o );
242
ASSERT_EQUALS( true , s->getBoolean( "return" ) );
246
ASSERT_EQUALS( true , s->getBoolean( "__returnValue" ) );
244
248
s->invoke( "function z(){ return this.x == 18; }" , 0, &o );
245
ASSERT_EQUALS( false , s->getBoolean( "return" ) );
249
ASSERT_EQUALS( false , s->getBoolean( "__returnValue" ) );
247
251
s->invoke( "function (){ this.x == 17; }" , 0, &o );
248
ASSERT_EQUALS( false , s->getBoolean( "return" ) );
252
ASSERT_EQUALS( false , s->getBoolean( "__returnValue" ) );
250
254
s->invoke( "function z(){ this.x == 18; }" , 0, &o );
251
ASSERT_EQUALS( false , s->getBoolean( "return" ) );
255
ASSERT_EQUALS( false , s->getBoolean( "__returnValue" ) );
253
257
s->invoke( "x = 5; for( ; x <10; x++){ a = 1; }" , 0, &o );
254
258
ASSERT_EQUALS( 10 , s->getNumber( "x" ) );
775
* Test exec() timeout value terminates execution (SERVER-8053)
780
scoped_ptr<Scope> scope(globalScriptEngine->newScope());
781
scope->localConnect("ExecTimeoutDB");
782
// assert timeout occured
783
ASSERT(!scope->exec("var a = 1; while (true) { ; }",
784
"ExecTimeout", false, true, false, 1));
789
* Test exec() timeout value terminates execution (SERVER-8053)
791
class ExecNoTimeout {
794
scoped_ptr<Scope> scope(globalScriptEngine->newScope());
795
scope->localConnect("ExecNoTimeoutDB");
796
// assert no timeout occured
797
ASSERT(scope->exec("var a = function() { return 1; }",
798
"ExecNoTimeout", false, true, false, 5 * 60 * 1000));
803
* Test invoke() timeout value terminates execution (SERVER-8053)
805
class InvokeTimeout {
808
scoped_ptr<Scope> scope(globalScriptEngine->newScope());
809
scope->localConnect("InvokeTimeoutDB");
811
// scope timeout after 500ms
814
scope->invokeSafe("function() { "
818
} catch (const DBException&) {
826
* Test invoke() timeout value does not terminate execution (SERVER-8053)
828
class InvokeNoTimeout {
831
scoped_ptr<Scope> scope(globalScriptEngine->newScope());
832
scope->localConnect("InvokeTimeoutDB");
834
// invoke completes before timeout
835
scope->invokeSafe("function() { "
836
" for (var i=0; i<1; i++) { ; } "
838
0, 0, 5 * 60 * 1000);
755
843
void dummy_function_to_force_dbeval_cpp_linking() {
873
_a = "unittest.dbref.a";
874
_b = "unittest.dbref.b";
883
client.insert( _a , BSON( "a" << "17" ) );
886
BSONObj fromA = client.findOne( _a , BSONObj() );
887
verify( fromA.valid() );
888
//cout << "Froma : " << fromA << endl;
890
b.append( "b" , 18 );
891
b.appendDBRef( "c" , "dbref.a" , fromA["_id"].__oid() );
892
client.insert( _b , b.obj() );
895
ASSERT( client.eval( "unittest" , "x = db.dbref.b.findOne(); assert.eq( 17 , x.c.fetch().a , 'ref working' );" ) );
897
// BSON DBRef <=> JS DBPointer
898
ASSERT( client.eval( "unittest", "x = db.dbref.b.findOne(); db.dbref.b.drop(); x.c = new DBPointer( x.c.ns, x.c.id ); db.dbref.b.insert( x );" ) );
899
ASSERT_EQUALS( DBRef, client.findOne( "unittest.dbref.b", "" )[ "c" ].type() );
901
// BSON Object <=> JS DBRef
902
ASSERT( client.eval( "unittest", "x = db.dbref.b.findOne(); db.dbref.b.drop(); x.c = new DBRef( x.c.ns, x.c.id ); db.dbref.b.insert( x );" ) );
903
ASSERT_EQUALS( Object, client.findOne( "unittest.dbref.b", "" )[ "c" ].type() );
904
ASSERT_EQUALS( string( "dbref.a" ), client.findOne( "unittest.dbref.b", "" )[ "c" ].embeddedObject().getStringField( "$ref" ) );
908
client.dropCollection( _a );
909
client.dropCollection( _b );
916
class InformalDBRef {
919
client.insert( ns(), BSON( "i" << 1 ) );
920
BSONObj obj = client.findOne( ns(), BSONObj() );
921
client.remove( ns(), BSONObj() );
922
client.insert( ns(), BSON( "r" << BSON( "$ref" << "jstests.informaldbref" << "$id" << obj["_id"].__oid() << "foo" << "bar" ) ) );
923
obj = client.findOne( ns(), BSONObj() );
924
ASSERT_EQUALS( "bar", obj[ "r" ].embeddedObject()[ "foo" ].str() );
926
ASSERT( client.eval( "unittest", "x = db.jstests.informaldbref.findOne(); y = { r:x.r }; db.jstests.informaldbref.drop(); y.r[ \"a\" ] = \"b\"; db.jstests.informaldbref.save( y );" ) );
927
obj = client.findOne( ns(), BSONObj() );
928
ASSERT_EQUALS( "bar", obj[ "r" ].embeddedObject()[ "foo" ].str() );
929
ASSERT_EQUALS( "b", obj[ "r" ].embeddedObject()[ "a" ].str() );
932
static const char *ns() { return "unittest.jstests.informaldbref"; }
958
namespace RoundTripTests {
960
// Inherit from this class to test round tripping of JSON objects
961
class TestRoundTrip {
963
virtual ~TestRoundTrip() {}
966
// Insert in Javascript -> Find using DBDirectClient
968
// Drop the collection
969
client.dropCollection( "unittest.testroundtrip" );
971
// Insert in Javascript
972
stringstream jsInsert;
973
jsInsert << "db.testroundtrip.insert(" << jsonIn() << ")";
974
ASSERT_TRUE( client.eval( "unittest" , jsInsert.str() ) );
976
// Find using DBDirectClient
977
BSONObj excludeIdProjection = BSON( "_id" << 0 );
978
BSONObj directFind = client.findOne( "unittest.testroundtrip",
980
&excludeIdProjection);
981
bsonEquals( bson(), directFind );
984
// Insert using DBDirectClient -> Find in Javascript
986
// Drop the collection
987
client.dropCollection( "unittest.testroundtrip" );
989
// Insert using DBDirectClient
990
client.insert( "unittest.testroundtrip" , bson() );
992
// Find in Javascript
994
jsFind << "dbref = db.testroundtrip.findOne( { } , { _id : 0 } )\n"
995
<< "assert.eq(dbref, " << jsonOut() << ")";
996
ASSERT_TRUE( client.eval( "unittest" , jsFind.str() ) );
1000
// Methods that must be defined by child classes
1001
virtual BSONObj bson() const = 0;
1002
virtual string json() const = 0;
1004
// This can be overriden if a different meaning of equality besides woCompare is needed
1005
virtual void bsonEquals( const BSONObj &expected, const BSONObj &actual ) {
1006
if ( expected.woCompare( actual ) ) {
1007
out() << "want:" << expected.jsonString() << " size: " << expected.objsize() << endl;
1008
out() << "got :" << actual.jsonString() << " size: " << actual.objsize() << endl;
1009
out() << expected.hexDump() << endl;
1010
out() << actual.hexDump() << endl;
1012
ASSERT( !expected.woCompare( actual ) );
1015
// This can be overriden if the JSON representation is altered on the round trip
1016
virtual string jsonIn() const {
1019
virtual string jsonOut() const {
1024
class DBRefTest : public TestRoundTrip {
1025
virtual BSONObj bson() const {
1028
memset( &o, 0, 12 );
1029
BSONObjBuilder subBuilder(b.subobjStart("a"));
1030
subBuilder.append("$ref", "ns");
1031
subBuilder.append("$id", o);
1035
virtual string json() const {
1036
return "{ \"a\" : DBRef( \"ns\", ObjectId( \"000000000000000000000000\" ) ) }";
1039
// A "fetch" function is added to the DBRef object when it is inserted using the
1040
// constructor, so we need to compare the fields individually
1041
virtual void bsonEquals( const BSONObj &expected, const BSONObj &actual ) {
1042
ASSERT_EQUALS( expected["a"].type() , actual["a"].type() );
1043
ASSERT_EQUALS( expected["a"]["$id"].OID() , actual["a"]["$id"].OID() );
1044
ASSERT_EQUALS( expected["a"]["$ref"].String() , actual["a"]["$ref"].String() );
1048
class DBPointerTest : public TestRoundTrip {
1049
virtual BSONObj bson() const {
1052
memset( &o, 0, 12 );
1053
b.appendDBRef( "a" , "ns" , o );
1056
virtual string json() const {
1057
return "{ \"a\" : DBPointer( \"ns\", ObjectId( \"000000000000000000000000\" ) ) }";
1061
class InformalDBRefTest : public TestRoundTrip {
1062
virtual BSONObj bson() const {
1064
BSONObjBuilder subBuilder(b.subobjStart("a"));
1065
subBuilder.append("$ref", "ns");
1066
subBuilder.append("$id", "000000000000000000000000");
1071
// Don't need to return anything because we are overriding both jsonOut and jsonIn
1072
virtual string json() const { return ""; }
1074
// Need to override these because the JSON doesn't actually round trip.
1075
// An object with "$ref" and "$id" fields is handled specially and different on the way out.
1076
virtual string jsonOut() const {
1077
return "{ \"a\" : DBRef( \"ns\", \"000000000000000000000000\" ) }";
1079
virtual string jsonIn() const {
1081
ss << "{ \"a\" : { \"$ref\" : \"ns\" , " <<
1082
"\"$id\" : \"000000000000000000000000\" } }";
1087
class InformalDBRefOIDTest : public TestRoundTrip {
1088
virtual BSONObj bson() const {
1091
memset( &o, 0, 12 );
1092
BSONObjBuilder subBuilder(b.subobjStart("a"));
1093
subBuilder.append("$ref", "ns");
1094
subBuilder.append("$id", o);
1099
// Don't need to return anything because we are overriding both jsonOut and jsonIn
1100
virtual string json() const { return ""; }
1102
// Need to override these because the JSON doesn't actually round trip.
1103
// An object with "$ref" and "$id" fields is handled specially and different on the way out.
1104
virtual string jsonOut() const {
1105
return "{ \"a\" : DBRef( \"ns\", ObjectId( \"000000000000000000000000\" ) ) }";
1107
virtual string jsonIn() const {
1109
ss << "{ \"a\" : { \"$ref\" : \"ns\" , " <<
1110
"\"$id\" : ObjectId( \"000000000000000000000000\" ) } }";
1115
class InformalDBRefExtraFieldTest : public TestRoundTrip {
1116
virtual BSONObj bson() const {
1119
memset( &o, 0, 12 );
1120
BSONObjBuilder subBuilder(b.subobjStart("a"));
1121
subBuilder.append("$ref", "ns");
1122
subBuilder.append("$id", o);
1123
subBuilder.append("otherfield", "value");
1128
// Don't need to return anything because we are overriding both jsonOut and jsonIn
1129
virtual string json() const { return ""; }
1131
// Need to override these because the JSON doesn't actually round trip.
1132
// An object with "$ref" and "$id" fields is handled specially and different on the way out.
1133
virtual string jsonOut() const {
1134
return "{ \"a\" : DBRef( \"ns\", ObjectId( \"000000000000000000000000\" ) ) }";
1136
virtual string jsonIn() const {
1138
ss << "{ \"a\" : { \"$ref\" : \"ns\" , " <<
1139
"\"$id\" : ObjectId( \"000000000000000000000000\" ) , " <<
1140
"\"otherfield\" : \"value\" } }";
1145
} // namespace RoundTripTests
935
1147
class BinDataType {