/*
* Copyright (C) 2010 10gen Inc.
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
// client.cpp
#include "pch.h"
#include "dbtests.h"
#include "mongo/client/dbclientcursor.h"
#include "mongo/db/d_concurrency.h"
#include "mongo/db/pdfile.h"
namespace ClientTests {
class Base {
public:
Base( string coll ) {
db.dropDatabase("test");
_ns = (string)"test." + coll;
}
virtual ~Base() {
db.dropCollection( _ns );
}
const char * ns() { return _ns.c_str(); }
string _ns;
DBDirectClient db;
};
class DropIndex : public Base {
public:
DropIndex() : Base( "dropindex" ) {}
void run() {
db.insert( ns() , BSON( "x" << 2 ) );
ASSERT_EQUALS( 1 , db.getIndexes( ns() )->itcount() );
db.ensureIndex( ns() , BSON( "x" << 1 ) );
ASSERT_EQUALS( 2 , db.getIndexes( ns() )->itcount() );
db.dropIndex( ns() , BSON( "x" << 1 ) );
ASSERT_EQUALS( 1 , db.getIndexes( ns() )->itcount() );
db.ensureIndex( ns() , BSON( "x" << 1 ) );
ASSERT_EQUALS( 2 , db.getIndexes( ns() )->itcount() );
db.dropIndexes( ns() );
ASSERT_EQUALS( 1 , db.getIndexes( ns() )->itcount() );
}
};
class ReIndex : public Base {
public:
ReIndex() : Base( "reindex" ) {}
void run() {
db.insert( ns() , BSON( "x" << 2 ) );
ASSERT_EQUALS( 1 , db.getIndexes( ns() )->itcount() );
db.ensureIndex( ns() , BSON( "x" << 1 ) );
ASSERT_EQUALS( 2 , db.getIndexes( ns() )->itcount() );
db.reIndex( ns() );
ASSERT_EQUALS( 2 , db.getIndexes( ns() )->itcount() );
}
};
class ReIndex2 : public Base {
public:
ReIndex2() : Base( "reindex2" ) {}
void run() {
db.insert( ns() , BSON( "x" << 2 ) );
ASSERT_EQUALS( 1 , db.getIndexes( ns() )->itcount() );
db.ensureIndex( ns() , BSON( "x" << 1 ) );
ASSERT_EQUALS( 2 , db.getIndexes( ns() )->itcount() );
BSONObj out;
ASSERT( db.runCommand( "test" , BSON( "reIndex" << "reindex2" ) , out ) );
ASSERT_EQUALS( 2 , out["nIndexes"].number() );
ASSERT_EQUALS( 2 , db.getIndexes( ns() )->itcount() );
}
};
/**
* Check that nIndexes is incremented correctly when an index builds (and that it is not
* incremented when an index fails to build), system.indexes has an entry added (or not), and
* system.namespaces has a doc added (or not).
*/
class BuildIndex : public Base {
public:
BuildIndex() : Base("buildIndex") {}
void run() {
Lock::DBWrite lock(ns());
Client::WriteContext ctx(ns());
db.insert(ns(), BSON("x" << 1 << "y" << 2));
db.insert(ns(), BSON("x" << 2 << "y" << 2));
ASSERT_EQUALS(1, nsdetails(ns())->nIndexes);
// _id index
ASSERT_EQUALS(1U, db.count("test.system.indexes"));
// test.buildindex
// test.buildindex_$id
// test.system.indexes
ASSERT_EQUALS(3U, db.count("test.system.namespaces"));
db.ensureIndex(ns(), BSON("y" << 1), true);
ASSERT_EQUALS(1, nsdetails(ns())->nIndexes);
ASSERT_EQUALS(1U, db.count("test.system.indexes"));
ASSERT_EQUALS(3U, db.count("test.system.namespaces"));
db.ensureIndex(ns(), BSON("x" << 1), true);
ASSERT_EQUALS(2, nsdetails(ns())->nIndexes);
ASSERT_EQUALS(2U, db.count("test.system.indexes"));
ASSERT_EQUALS(4U, db.count("test.system.namespaces"));
}
};
class CS_10 : public Base {
public:
CS_10() : Base( "CS_10" ) {}
void run() {
string longs( 770, 'c' );
for( int i = 0; i < 1111; ++i )
db.insert( ns(), BSON( "a" << i << "b" << longs ) );
db.ensureIndex( ns(), BSON( "a" << 1 << "b" << 1 ) );
auto_ptr< DBClientCursor > c = db.query( ns(), Query().sort( BSON( "a" << 1 << "b" << 1 ) ) );
ASSERT_EQUALS( 1111, c->itcount() );
}
};
class PushBack : public Base {
public:
PushBack() : Base( "PushBack" ) {}
void run() {
for( int i = 0; i < 10; ++i )
db.insert( ns(), BSON( "i" << i ) );
auto_ptr< DBClientCursor > c = db.query( ns(), Query().sort( BSON( "i" << 1 ) ) );
BSONObj o = c->next();
ASSERT( c->more() );
ASSERT_EQUALS( 9 , c->objsLeftInBatch() );
ASSERT( c->moreInCurrentBatch() );
c->putBack( o );
ASSERT( c->more() );
ASSERT_EQUALS( 10, c->objsLeftInBatch() );
ASSERT( c->moreInCurrentBatch() );
o = c->next();
BSONObj o2 = c->next();
BSONObj o3 = c->next();
c->putBack( o3 );
c->putBack( o2 );
c->putBack( o );
for( int i = 0; i < 10; ++i ) {
o = c->next();
ASSERT_EQUALS( i, o[ "i" ].number() );
}
ASSERT( !c->more() );
ASSERT_EQUALS( 0, c->objsLeftInBatch() );
ASSERT( !c->moreInCurrentBatch() );
c->putBack( o );
ASSERT( c->more() );
ASSERT_EQUALS( 1, c->objsLeftInBatch() );
ASSERT( c->moreInCurrentBatch() );
ASSERT_EQUALS( 1, c->itcount() );
}
};
class Create : public Base {
public:
Create() : Base( "Create" ) {}
void run() {
db.createCollection( "unittests.clienttests.create", 4096, true );
BSONObj info;
ASSERT( db.runCommand( "unittests", BSON( "collstats" << "clienttests.create" ), info ) );
}
};
class ConnectionStringTests {
public:
void run() {
{
ConnectionString s( "a/b,c,d" , ConnectionString::SET );
ASSERT_EQUALS( ConnectionString::SET , s.type() );
ASSERT_EQUALS( "a" , s.getSetName() );
vector v = s.getServers();
ASSERT_EQUALS( 3U , v.size() );
ASSERT_EQUALS( "b" , v[0].host() );
ASSERT_EQUALS( "c" , v[1].host() );
ASSERT_EQUALS( "d" , v[2].host() );
}
}
};
class All : public Suite {
public:
All() : Suite( "client" ) {
}
void setupTests() {
add();
add();
add();
add();
add();
add();
add();
add();
}
} all;
}